summaryrefslogtreecommitdiff
path: root/contrib/compiler-rt/lib/sanitizer_common/sanitizer_libc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/compiler-rt/lib/sanitizer_common/sanitizer_libc.cc')
-rw-r--r--contrib/compiler-rt/lib/sanitizer_common/sanitizer_libc.cc12
1 files changed, 12 insertions, 0 deletions
diff --git a/contrib/compiler-rt/lib/sanitizer_common/sanitizer_libc.cc b/contrib/compiler-rt/lib/sanitizer_common/sanitizer_libc.cc
index 4b462bfe9728..4032cb10461f 100644
--- a/contrib/compiler-rt/lib/sanitizer_common/sanitizer_libc.cc
+++ b/contrib/compiler-rt/lib/sanitizer_common/sanitizer_libc.cc
@@ -73,6 +73,18 @@ void *internal_memmove(void *dest, const void *src, uptr n) {
}
void *internal_memset(void* s, int c, uptr n) {
+ // Optimize for the most performance-critical case:
+ if ((reinterpret_cast<uptr>(s) % 16) == 0 && (n % 16) == 0) {
+ u64 *p = reinterpret_cast<u64*>(s);
+ u64 *e = p + n / 8;
+ u64 v = c;
+ v |= v << 8;
+ v |= v << 16;
+ v |= v << 32;
+ for (; p < e; p += 2)
+ p[0] = p[1] = v;
+ return s;
+ }
// The next line prevents Clang from making a call to memset() instead of the
// loop below.
// FIXME: building the runtime with -ffreestanding is a better idea. However