1 // RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10 < %s | FileCheck %s
2 
3 struct Test1S {
4  long NumDecls;
5  long X;
6  long Y;
7 };
8 struct Test2S {
9  long NumDecls;
10  long X;
11 };
12 
13 // Make sure we don't generate extra memcpy for lvalues
14 void test1a(struct Test1S, struct Test2S);
15 // CHECK-LABEL: define void @test1(
16 // CHECK-NOT: memcpy
17 // CHECK: call void @test1a
18 void test1(struct Test1S *A, struct Test2S *B) {
19   test1a(*A, *B);
20 }
21 
22 // The above gets tricker when the byval argument requires higher alignment
23 // than the natural alignment of the type in question.
24 // rdar://9483886
25 
26 // Make sure we do generate a memcpy when we cannot guarantee alignment.
27 struct Test3S {
28   int a,b,c,d,e,f,g,h,i,j,k,l;
29 };
30 void test2a(struct Test3S q);
31 // CHECK-LABEL: define void @test2(
32 // CHECK: alloca %struct.Test3S, align 8
33 // CHECK: memcpy
34 // CHECK: call void @test2a
35 void test2(struct Test3S *q) {
36   test2a(*q);
37 }
38 
39 // But make sure we don't generate a memcpy when we can guarantee alignment.
40 void fooey(void);
41 // CHECK-LABEL: define void @test3(
42 // CHECK: alloca %struct.Test3S, align 8
43 // CHECK: call void @fooey
44 // CHECK-NOT: memcpy
45 // CHECK: call void @test2a
46 // CHECK-NOT: memcpy
47 // CHECK: call void @test2a
48 void test3(struct Test3S a) {
49   struct Test3S b = a;
50   fooey();
51   test2a(a);
52   test2a(b);
53 }
54