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 | |