// 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-LABEL: 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-LABEL: 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-LABEL: 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); }