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