diff options
Diffstat (limited to 'clang/test/CodeGen/byval-memcpy-elim.c')
-rw-r--r-- | clang/test/CodeGen/byval-memcpy-elim.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/clang/test/CodeGen/byval-memcpy-elim.c b/clang/test/CodeGen/byval-memcpy-elim.c new file mode 100644 index 0000000..76cdafb --- /dev/null +++ b/clang/test/CodeGen/byval-memcpy-elim.c @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10 < %s | FileCheck %s + +struct Test1S { + long NumDecls; + long X; + long Y; +}; +struct Test2S { + long NumDecls; + long X; +}; + +// Make sure we don't generate extra memcpy for lvalues +void test1a(struct Test1S, struct Test2S); +// CHECK: define void @test1( +// CHECK-NOT: memcpy +// CHECK: call void @test1a +void test1(struct Test1S *A, struct Test2S *B) { + test1a(*A, *B); +} + +// The above gets tricker when the byval argument requires higher alignment +// than the natural alignment of the type in question. +// rdar://9483886 + +// Make sure we do generate a memcpy when we cannot guarantee alignment. +struct Test3S { + int a,b,c,d,e,f,g,h,i,j,k,l; +}; +void test2a(struct Test3S q); +// CHECK: define void @test2( +// CHECK: alloca %struct.Test3S, align 8 +// CHECK: memcpy +// CHECK: call void @test2a +void test2(struct Test3S *q) { + test2a(*q); +} + +// But make sure we don't generate a memcpy when we can guarantee alignment. +void fooey(void); +// CHECK: define void @test3( +// CHECK: alloca %struct.Test3S, align 8 +// CHECK: call void @fooey +// CHECK-NOT: memcpy +// CHECK: call void @test2a +// CHECK-NOT: memcpy +// CHECK: call void @test2a +void test3(struct Test3S a) { + struct Test3S b = a; + fooey(); + test2a(a); + test2a(b); +} |