aboutsummaryrefslogtreecommitdiff
path: root/clang/test/CodeGenCXX/assign-construct-memcpy.cpp
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2012-09-30 12:43:37 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2012-09-30 12:43:37 +0000
commit1ca66919a5af71949c02f55a1d1d8be8f613f8c2 (patch)
treebe98a4ca5014fc6f643adaa7f7d324f1487e7280 /clang/test/CodeGenCXX/assign-construct-memcpy.cpp
parentaae78b861f75236cf5248be03dfbdde21ebe30f7 (diff)
downloadllvm-1ca66919a5af71949c02f55a1d1d8be8f613f8c2.zip
llvm-1ca66919a5af71949c02f55a1d1d8be8f613f8c2.tar.gz
llvm-1ca66919a5af71949c02f55a1d1d8be8f613f8c2.tar.bz2
CodeGen: Copy tail padding when we're not dealing with a trivial copy assign or move assign operator.
This fixes a regression from r162254, the optimizer has problems reasoning about the smaller memcpy as it's often not safe to widen a store but making it smaller is. llvm-svn: 164917
Diffstat (limited to 'clang/test/CodeGenCXX/assign-construct-memcpy.cpp')
-rw-r--r--clang/test/CodeGenCXX/assign-construct-memcpy.cpp89
1 files changed, 89 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/assign-construct-memcpy.cpp b/clang/test/CodeGenCXX/assign-construct-memcpy.cpp
new file mode 100644
index 0000000..3d42051
--- /dev/null
+++ b/clang/test/CodeGenCXX/assign-construct-memcpy.cpp
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin12 -emit-llvm -o - -std=c++11 %s -DPOD | FileCheck %s -check-prefix=CHECK-POD
+// RUN: %clang_cc1 -triple x86_64-apple-darwin12 -emit-llvm -o - -std=c++11 %s | FileCheck %s -check-prefix=CHECK-NONPOD
+
+// Declare the reserved placement operators.
+typedef __typeof__(sizeof(0)) size_t;
+void *operator new(size_t, void*) throw();
+void operator delete(void*, void*) throw();
+void *operator new[](size_t, void*) throw();
+void operator delete[](void*, void*) throw();
+template<typename T> T &&move(T&);
+
+struct foo {
+#ifndef POD
+ foo() {} // non-POD
+#endif
+ void *a, *b;
+ bool c;
+};
+
+// It is not legal to copy the tail padding in all cases, but if it is it can
+// yield better codegen.
+
+foo *test1(void *f, const foo &x) {
+ return new (f) foo(x);
+// CHECK-POD: test1
+// CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8
+
+// CHECK-NONPOD: test1
+// CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8
+}
+
+foo *test2(const foo &x) {
+ return new foo(x);
+// CHECK-POD: test2
+// CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8
+
+// CHECK-NONPOD: test2
+// CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8
+}
+
+foo test3(const foo &x) {
+ foo f = x;
+ return f;
+// CHECK-POD: test3
+// CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8
+
+// CHECK-NONPOD: test3
+// CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8
+}
+
+foo *test4(foo &&x) {
+ return new foo(x);
+// CHECK-POD: test4
+// CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8
+
+// CHECK-NONPOD: test4
+// CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8
+}
+
+void test5(foo &f, const foo &x) {
+ f = x;
+// CHECK-POD: test5
+// CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8
+
+// CHECK-NONPOD: test5
+// CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 17, i32 8
+}
+
+extern foo globtest;
+
+void test6(foo &&x) {
+ globtest = move(x);
+// CHECK-POD: test6
+// CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8
+
+// CHECK-NONPOD: test6
+// CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 17, i32 8
+}
+
+void byval(foo f);
+
+void test7(const foo &x) {
+ byval(x);
+// CHECK-POD: test7
+// CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8
+
+// CHECK-NONPOD: test7
+// CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 24, i32 8
+}