summaryrefslogtreecommitdiffstats
path: root/test/CodeGen
diff options
context:
space:
mode:
authorJF Bastien <jfbastien@apple.com>2018-07-25 04:29:03 +0000
committerJF Bastien <jfbastien@apple.com>2018-07-25 04:29:03 +0000
commit1df8e57db9c247fc74542ce89cf0e90ec1d0881f (patch)
tree8bf65289c085a5104c13a18666cb91cb3c6667ce /test/CodeGen
parent32655dde06d972cb8fab41a9d9e56f71c7093a60 (diff)
CodeGen: use non-zero memset when possible for automatic variables
Summary: Right now automatic variables are either initialized with bzero followed by a few stores, or memcpy'd from a synthesized global. We end up encountering a fair amount of code where memcpy of non-zero byte patterns would be better than memcpy from a global because it touches less memory and generates a smaller binary. The optimizer could reason about this, but it's not really worth it when clang already knows. This code could definitely be more clever but I'm not sure it's worth it. In particular we could track a histogram of bytes seen and figure out (as we do with bzero) if a memset could be followed by a handful of stores. Similarly, we could tune the heuristics for GlobalSize, but using the same as for bzero seems conservatively OK for now. <rdar://problem/42563091> Reviewers: dexonsmith Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D49771 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@337887 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGen')
-rw-r--r--test/CodeGen/init.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/test/CodeGen/init.c b/test/CodeGen/init.c
index 0353ba8be1..71aba39b12 100644
--- a/test/CodeGen/init.c
+++ b/test/CodeGen/init.c
@@ -140,6 +140,72 @@ void test10(int X) {
// CHECK: call void @bar
}
+void nonzeroMemseti8() {
+ char arr[33] = { 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, };
+ // CHECK-LABEL: @nonzeroMemseti8(
+ // CHECK-NOT: store
+ // CHECK-NOT: memcpy
+ // CHECK: call void @llvm.memset.p0i8.i32(i8* {{.*}}, i8 42, i32 33, i1 false)
+}
+
+void nonzeroMemseti16() {
+ unsigned short arr[17] = { 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, };
+ // CHECK-LABEL: @nonzeroMemseti16(
+ // CHECK-NOT: store
+ // CHECK-NOT: memcpy
+ // CHECK: call void @llvm.memset.p0i8.i32(i8* {{.*}}, i8 66, i32 34, i1 false)
+}
+
+void nonzeroMemseti32() {
+ unsigned arr[9] = { 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, };
+ // CHECK-LABEL: @nonzeroMemseti32(
+ // CHECK-NOT: store
+ // CHECK-NOT: memcpy
+ // CHECK: call void @llvm.memset.p0i8.i32(i8* {{.*}}, i8 -16, i32 36, i1 false)
+}
+
+void nonzeroMemseti64() {
+ unsigned long long arr[7] = { 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA, };
+ // CHECK-LABEL: @nonzeroMemseti64(
+ // CHECK-NOT: store
+ // CHECK-NOT: memcpy
+ // CHECK: call void @llvm.memset.p0i8.i32(i8* {{.*}}, i8 -86, i32 56, i1 false)
+}
+
+void nonzeroMemsetf32() {
+ float arr[9] = { 0x1.cacacap+75, 0x1.cacacap+75, 0x1.cacacap+75, 0x1.cacacap+75, 0x1.cacacap+75, 0x1.cacacap+75, 0x1.cacacap+75, 0x1.cacacap+75, 0x1.cacacap+75, };
+ // CHECK-LABEL: @nonzeroMemsetf32(
+ // CHECK-NOT: store
+ // CHECK-NOT: memcpy
+ // CHECK: call void @llvm.memset.p0i8.i32(i8* {{.*}}, i8 101, i32 36, i1 false)
+}
+
+void nonzeroMemsetf64() {
+ double arr[7] = { 0x1.4444444444444p+69, 0x1.4444444444444p+69, 0x1.4444444444444p+69, 0x1.4444444444444p+69, 0x1.4444444444444p+69, 0x1.4444444444444p+69, 0x1.4444444444444p+69, };
+ // CHECK-LABEL: @nonzeroMemsetf64(
+ // CHECK-NOT: store
+ // CHECK-NOT: memcpy
+ // CHECK: call void @llvm.memset.p0i8.i32(i8* {{.*}}, i8 68, i32 56, i1 false)
+}
+
+void nonzeroPaddedUnionMemset() {
+ union U { char c; int i; };
+ union U arr[9] = { 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, };
+ // CHECK-LABEL: @nonzeroPaddedUnionMemset(
+ // CHECK-NOT: store
+ // CHECK-NOT: memcpy
+ // CHECK: call void @llvm.memset.p0i8.i32(i8* {{.*}}, i8 -16, i32 36, i1 false)
+}
+
+void nonzeroNestedMemset() {
+ union U { char c; int i; };
+ struct S { union U u; short i; };
+ struct S arr[5] = { { {0xF0}, 0xF0F0 }, { {0xF0}, 0xF0F0 }, { {0xF0}, 0xF0F0 }, { {0xF0}, 0xF0F0 }, { {0xF0}, 0xF0F0 }, };
+ // CHECK-LABEL: @nonzeroNestedMemset(
+ // CHECK-NOT: store
+ // CHECK-NOT: memcpy
+ // CHECK: call void @llvm.memset.p0i8.i32(i8* {{.*}}, i8 -16, i32 40, i1 false)
+}
// PR9257
struct test11S {