1*67e74705SXin Li // RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -o - %s | FileCheck %s
2*67e74705SXin Li
3*67e74705SXin Li // This isn't really testing anything ARM-specific; it's just a convenient
4*67e74705SXin Li // 32-bit platform.
5*67e74705SXin Li
6*67e74705SXin Li #define SWIFTCALL __attribute__((swiftcall))
7*67e74705SXin Li #define OUT __attribute__((swift_indirect_result))
8*67e74705SXin Li #define ERROR __attribute__((swift_error_result))
9*67e74705SXin Li #define CONTEXT __attribute__((swift_context))
10*67e74705SXin Li
11*67e74705SXin Li /*****************************************************************************/
12*67e74705SXin Li /****************************** PARAMETER ABIS *******************************/
13*67e74705SXin Li /*****************************************************************************/
14*67e74705SXin Li
indirect_result_1(OUT int * arg0,OUT float * arg1)15*67e74705SXin Li SWIFTCALL void indirect_result_1(OUT int *arg0, OUT float *arg1) {}
16*67e74705SXin Li // CHECK-LABEL: define {{.*}} void @indirect_result_1(i32* noalias sret align 4 dereferenceable(4){{.*}}, float* noalias align 4 dereferenceable(4){{.*}})
17*67e74705SXin Li
18*67e74705SXin Li // TODO: maybe this shouldn't suppress sret.
indirect_result_2(OUT int * arg0,OUT float * arg1)19*67e74705SXin Li SWIFTCALL int indirect_result_2(OUT int *arg0, OUT float *arg1) { __builtin_unreachable(); }
20*67e74705SXin Li // CHECK-LABEL: define {{.*}} i32 @indirect_result_2(i32* noalias align 4 dereferenceable(4){{.*}}, float* noalias align 4 dereferenceable(4){{.*}})
21*67e74705SXin Li
22*67e74705SXin Li typedef struct { char array[1024]; } struct_reallybig;
indirect_result_3(OUT int * arg0,OUT float * arg1)23*67e74705SXin Li SWIFTCALL struct_reallybig indirect_result_3(OUT int *arg0, OUT float *arg1) { __builtin_unreachable(); }
24*67e74705SXin Li // CHECK-LABEL: define {{.*}} void @indirect_result_3({{.*}}* noalias sret {{.*}}, i32* noalias align 4 dereferenceable(4){{.*}}, float* noalias align 4 dereferenceable(4){{.*}})
25*67e74705SXin Li
context_1(CONTEXT void * self)26*67e74705SXin Li SWIFTCALL void context_1(CONTEXT void *self) {}
27*67e74705SXin Li // CHECK-LABEL: define {{.*}} void @context_1(i8* swiftself
28*67e74705SXin Li
context_2(void * arg0,CONTEXT void * self)29*67e74705SXin Li SWIFTCALL void context_2(void *arg0, CONTEXT void *self) {}
30*67e74705SXin Li // CHECK-LABEL: define {{.*}} void @context_2(i8*{{.*}}, i8* swiftself
31*67e74705SXin Li
context_error_1(CONTEXT int * self,ERROR float ** error)32*67e74705SXin Li SWIFTCALL void context_error_1(CONTEXT int *self, ERROR float **error) {}
33*67e74705SXin Li // CHECK-LABEL: define {{.*}} void @context_error_1(i32* swiftself{{.*}}, float** swifterror)
34*67e74705SXin Li // CHECK: [[TEMP:%.*]] = alloca float*, align 4
35*67e74705SXin Li // CHECK: [[T0:%.*]] = load float*, float** [[ERRORARG:%.*]], align 4
36*67e74705SXin Li // CHECK: store float* [[T0]], float** [[TEMP]], align 4
37*67e74705SXin Li // CHECK: [[T0:%.*]] = load float*, float** [[TEMP]], align 4
38*67e74705SXin Li // CHECK: store float* [[T0]], float** [[ERRORARG]], align 4
test_context_error_1()39*67e74705SXin Li void test_context_error_1() {
40*67e74705SXin Li int x;
41*67e74705SXin Li float *error;
42*67e74705SXin Li context_error_1(&x, &error);
43*67e74705SXin Li }
44*67e74705SXin Li // CHECK-LABEL: define void @test_context_error_1()
45*67e74705SXin Li // CHECK: [[X:%.*]] = alloca i32, align 4
46*67e74705SXin Li // CHECK: [[ERROR:%.*]] = alloca float*, align 4
47*67e74705SXin Li // CHECK: [[TEMP:%.*]] = alloca swifterror float*, align 4
48*67e74705SXin Li // CHECK: [[T0:%.*]] = load float*, float** [[ERROR]], align 4
49*67e74705SXin Li // CHECK: store float* [[T0]], float** [[TEMP]], align 4
50*67e74705SXin Li // CHECK: call [[SWIFTCC:swiftcc]] void @context_error_1(i32* swiftself [[X]], float** swifterror [[TEMP]])
51*67e74705SXin Li // CHECK: [[T0:%.*]] = load float*, float** [[TEMP]], align 4
52*67e74705SXin Li // CHECK: store float* [[T0]], float** [[ERROR]], align 4
53*67e74705SXin Li
context_error_2(short s,CONTEXT int * self,ERROR float ** error)54*67e74705SXin Li SWIFTCALL void context_error_2(short s, CONTEXT int *self, ERROR float **error) {}
55*67e74705SXin Li // CHECK-LABEL: define {{.*}} void @context_error_2(i16{{.*}}, i32* swiftself{{.*}}, float** swifterror)
56*67e74705SXin Li
57*67e74705SXin Li /*****************************************************************************/
58*67e74705SXin Li /********************************** LOWERING *********************************/
59*67e74705SXin Li /*****************************************************************************/
60*67e74705SXin Li
61*67e74705SXin Li typedef float float4 __attribute__((ext_vector_type(4)));
62*67e74705SXin Li typedef float float8 __attribute__((ext_vector_type(8)));
63*67e74705SXin Li typedef double double2 __attribute__((ext_vector_type(2)));
64*67e74705SXin Li typedef double double4 __attribute__((ext_vector_type(4)));
65*67e74705SXin Li typedef int int3 __attribute__((ext_vector_type(3)));
66*67e74705SXin Li typedef int int4 __attribute__((ext_vector_type(4)));
67*67e74705SXin Li typedef int int5 __attribute__((ext_vector_type(5)));
68*67e74705SXin Li typedef int int8 __attribute__((ext_vector_type(8)));
69*67e74705SXin Li
70*67e74705SXin Li #define TEST(TYPE) \
71*67e74705SXin Li SWIFTCALL TYPE return_##TYPE(void) { \
72*67e74705SXin Li TYPE result = {}; \
73*67e74705SXin Li return result; \
74*67e74705SXin Li } \
75*67e74705SXin Li SWIFTCALL void take_##TYPE(TYPE v) { \
76*67e74705SXin Li } \
77*67e74705SXin Li void test_##TYPE() { \
78*67e74705SXin Li take_##TYPE(return_##TYPE()); \
79*67e74705SXin Li }
80*67e74705SXin Li
81*67e74705SXin Li /*****************************************************************************/
82*67e74705SXin Li /*********************************** STRUCTS *********************************/
83*67e74705SXin Li /*****************************************************************************/
84*67e74705SXin Li
85*67e74705SXin Li typedef struct {
86*67e74705SXin Li } struct_empty;
87*67e74705SXin Li TEST(struct_empty);
88*67e74705SXin Li // CHECK-LABEL: define {{.*}} @return_struct_empty()
89*67e74705SXin Li // CHECK: ret void
90*67e74705SXin Li // CHECK-LABEL: define {{.*}} @take_struct_empty()
91*67e74705SXin Li // CHECK: ret void
92*67e74705SXin Li
93*67e74705SXin Li typedef struct {
94*67e74705SXin Li int x;
95*67e74705SXin Li char c0;
96*67e74705SXin Li char c1;
97*67e74705SXin Li float f0;
98*67e74705SXin Li float f1;
99*67e74705SXin Li } struct_1;
100*67e74705SXin Li TEST(struct_1);
101*67e74705SXin Li // CHECK-LABEL: define {{.*}} @return_struct_1()
102*67e74705SXin Li // CHECK: [[RET:%.*]] = alloca [[REC:%.*]], align 4
103*67e74705SXin Li // CHECK: [[VAR:%.*]] = alloca [[REC]], align 4
104*67e74705SXin Li // CHECK: @llvm.memset
105*67e74705SXin Li // CHECK: @llvm.memcpy
106*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[RET]] to [[AGG:{ i32, i16, \[2 x i8\], float, float }]]*
107*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
108*67e74705SXin Li // CHECK: [[FIRST:%.*]] = load i32, i32* [[T0]], align 4
109*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
110*67e74705SXin Li // CHECK: [[SECOND:%.*]] = load i16, i16* [[T0]], align 4
111*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
112*67e74705SXin Li // CHECK: [[THIRD:%.*]] = load float, float* [[T0]], align
113*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 4
114*67e74705SXin Li // CHECK: [[FOURTH:%.*]] = load float, float* [[T0]], align
115*67e74705SXin Li // CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ i32, i16, float, float }]] undef, i32 [[FIRST]], 0
116*67e74705SXin Li // CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], i16 [[SECOND]], 1
117*67e74705SXin Li // CHECK: [[T2:%.*]] = insertvalue [[UAGG]] [[T1]], float [[THIRD]], 2
118*67e74705SXin Li // CHECK: [[T3:%.*]] = insertvalue [[UAGG]] [[T2]], float [[FOURTH]], 3
119*67e74705SXin Li // CHECK: ret [[UAGG]] [[T3]]
120*67e74705SXin Li // CHECK-LABEL: define {{.*}} @take_struct_1(i32, i16, float, float)
121*67e74705SXin Li // CHECK: [[V:%.*]] = alloca [[REC]], align 4
122*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[V]] to [[AGG]]*
123*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
124*67e74705SXin Li // CHECK: store i32 %0, i32* [[T0]], align 4
125*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
126*67e74705SXin Li // CHECK: store i16 %1, i16* [[T0]], align 4
127*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
128*67e74705SXin Li // CHECK: store float %2, float* [[T0]], align 4
129*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 4
130*67e74705SXin Li // CHECK: store float %3, float* [[T0]], align 4
131*67e74705SXin Li // CHECK: ret void
132*67e74705SXin Li // CHECK-LABEL: define void @test_struct_1()
133*67e74705SXin Li // CHECK: [[TMP:%.*]] = alloca [[REC]], align 4
134*67e74705SXin Li // CHECK: [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_struct_1()
135*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]*
136*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
137*67e74705SXin Li // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0
138*67e74705SXin Li // CHECK: store i32 [[T1]], i32* [[T0]], align 4
139*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
140*67e74705SXin Li // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1
141*67e74705SXin Li // CHECK: store i16 [[T1]], i16* [[T0]], align 4
142*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
143*67e74705SXin Li // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 2
144*67e74705SXin Li // CHECK: store float [[T1]], float* [[T0]], align 4
145*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 4
146*67e74705SXin Li // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 3
147*67e74705SXin Li // CHECK: store float [[T1]], float* [[T0]], align 4
148*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]*
149*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
150*67e74705SXin Li // CHECK: [[FIRST:%.*]] = load i32, i32* [[T0]], align 4
151*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
152*67e74705SXin Li // CHECK: [[SECOND:%.*]] = load i16, i16* [[T0]], align 4
153*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
154*67e74705SXin Li // CHECK: [[THIRD:%.*]] = load float, float* [[T0]], align 4
155*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 4
156*67e74705SXin Li // CHECK: [[FOURTH:%.*]] = load float, float* [[T0]], align 4
157*67e74705SXin Li // CHECK: call [[SWIFTCC]] void @take_struct_1(i32 [[FIRST]], i16 [[SECOND]], float [[THIRD]], float [[FOURTH]])
158*67e74705SXin Li // CHECK: ret void
159*67e74705SXin Li
160*67e74705SXin Li typedef struct {
161*67e74705SXin Li int x;
162*67e74705SXin Li char c0;
163*67e74705SXin Li __attribute__((aligned(2))) char c1;
164*67e74705SXin Li float f0;
165*67e74705SXin Li float f1;
166*67e74705SXin Li } struct_2;
167*67e74705SXin Li TEST(struct_2);
168*67e74705SXin Li // CHECK-LABEL: define {{.*}} @return_struct_2()
169*67e74705SXin Li // CHECK: [[RET:%.*]] = alloca [[REC:%.*]], align 4
170*67e74705SXin Li // CHECK: [[VAR:%.*]] = alloca [[REC]], align 4
171*67e74705SXin Li // CHECK: @llvm.memcpy
172*67e74705SXin Li // CHECK: @llvm.memcpy
173*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[RET]] to [[AGG:{ i32, i32, float, float }]]*
174*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
175*67e74705SXin Li // CHECK: [[FIRST:%.*]] = load i32, i32* [[T0]], align 4
176*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
177*67e74705SXin Li // CHECK: [[SECOND:%.*]] = load i32, i32* [[T0]], align 4
178*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
179*67e74705SXin Li // CHECK: [[THIRD:%.*]] = load float, float* [[T0]], align
180*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
181*67e74705SXin Li // CHECK: [[FOURTH:%.*]] = load float, float* [[T0]], align
182*67e74705SXin Li // CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ i32, i32, float, float }]] undef, i32 [[FIRST]], 0
183*67e74705SXin Li // CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], i32 [[SECOND]], 1
184*67e74705SXin Li // CHECK: [[T2:%.*]] = insertvalue [[UAGG]] [[T1]], float [[THIRD]], 2
185*67e74705SXin Li // CHECK: [[T3:%.*]] = insertvalue [[UAGG]] [[T2]], float [[FOURTH]], 3
186*67e74705SXin Li // CHECK: ret [[UAGG]] [[T3]]
187*67e74705SXin Li // CHECK-LABEL: define {{.*}} @take_struct_2(i32, i32, float, float)
188*67e74705SXin Li // CHECK: [[V:%.*]] = alloca [[REC]], align 4
189*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[V]] to [[AGG]]*
190*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
191*67e74705SXin Li // CHECK: store i32 %0, i32* [[T0]], align 4
192*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
193*67e74705SXin Li // CHECK: store i32 %1, i32* [[T0]], align 4
194*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
195*67e74705SXin Li // CHECK: store float %2, float* [[T0]], align 4
196*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
197*67e74705SXin Li // CHECK: store float %3, float* [[T0]], align 4
198*67e74705SXin Li // CHECK: ret void
199*67e74705SXin Li // CHECK-LABEL: define void @test_struct_2()
200*67e74705SXin Li // CHECK: [[TMP:%.*]] = alloca [[REC]], align 4
201*67e74705SXin Li // CHECK: [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_struct_2()
202*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]*
203*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
204*67e74705SXin Li // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0
205*67e74705SXin Li // CHECK: store i32 [[T1]], i32* [[T0]], align 4
206*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
207*67e74705SXin Li // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1
208*67e74705SXin Li // CHECK: store i32 [[T1]], i32* [[T0]], align 4
209*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
210*67e74705SXin Li // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 2
211*67e74705SXin Li // CHECK: store float [[T1]], float* [[T0]], align 4
212*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
213*67e74705SXin Li // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 3
214*67e74705SXin Li // CHECK: store float [[T1]], float* [[T0]], align 4
215*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]*
216*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
217*67e74705SXin Li // CHECK: [[FIRST:%.*]] = load i32, i32* [[T0]], align 4
218*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
219*67e74705SXin Li // CHECK: [[SECOND:%.*]] = load i32, i32* [[T0]], align 4
220*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
221*67e74705SXin Li // CHECK: [[THIRD:%.*]] = load float, float* [[T0]], align 4
222*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
223*67e74705SXin Li // CHECK: [[FOURTH:%.*]] = load float, float* [[T0]], align 4
224*67e74705SXin Li // CHECK: call [[SWIFTCC]] void @take_struct_2(i32 [[FIRST]], i32 [[SECOND]], float [[THIRD]], float [[FOURTH]])
225*67e74705SXin Li // CHECK: ret void
226*67e74705SXin Li
227*67e74705SXin Li // There's no way to put a field randomly in the middle of an otherwise
228*67e74705SXin Li // empty storage unit in C, so that case has to be tested in C++, which
229*67e74705SXin Li // can use empty structs to introduce arbitrary padding. (In C, they end up
230*67e74705SXin Li // with size 0 and so don't affect layout.)
231*67e74705SXin Li
232*67e74705SXin Li // Misaligned data rule.
233*67e74705SXin Li typedef struct {
234*67e74705SXin Li char c0;
235*67e74705SXin Li __attribute__((packed)) float f;
236*67e74705SXin Li } struct_misaligned_1;
237*67e74705SXin Li TEST(struct_misaligned_1)
238*67e74705SXin Li // CHECK-LABEL: define {{.*}} @return_struct_misaligned_1()
239*67e74705SXin Li // CHECK: [[RET:%.*]] = alloca [[REC:%.*]], align
240*67e74705SXin Li // CHECK: [[VAR:%.*]] = alloca [[REC]], align
241*67e74705SXin Li // CHECK: @llvm.memset
242*67e74705SXin Li // CHECK: @llvm.memcpy
243*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[RET]] to [[AGG:{ i32, i8 }]]*
244*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
245*67e74705SXin Li // CHECK: [[FIRST:%.*]] = load i32, i32* [[T0]], align
246*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
247*67e74705SXin Li // CHECK: [[SECOND:%.*]] = load i8, i8* [[T0]], align
248*67e74705SXin Li // CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ i32, i8 }]] undef, i32 [[FIRST]], 0
249*67e74705SXin Li // CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], i8 [[SECOND]], 1
250*67e74705SXin Li // CHECK: ret [[UAGG]] [[T1]]
251*67e74705SXin Li // CHECK-LABEL: define {{.*}} @take_struct_misaligned_1(i32, i8)
252*67e74705SXin Li // CHECK: [[V:%.*]] = alloca [[REC]], align
253*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[V]] to [[AGG]]*
254*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
255*67e74705SXin Li // CHECK: store i32 %0, i32* [[T0]], align
256*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
257*67e74705SXin Li // CHECK: store i8 %1, i8* [[T0]], align
258*67e74705SXin Li // CHECK: ret void
259*67e74705SXin Li
260*67e74705SXin Li // Too many scalars.
261*67e74705SXin Li typedef struct {
262*67e74705SXin Li int x[5];
263*67e74705SXin Li } struct_big_1;
264*67e74705SXin Li TEST(struct_big_1)
265*67e74705SXin Li
266*67e74705SXin Li // CHECK-LABEL: define {{.*}} void @return_struct_big_1({{.*}} noalias sret
267*67e74705SXin Li
268*67e74705SXin Li // Should not be byval.
269*67e74705SXin Li // CHECK-LABEL: define {{.*}} void @take_struct_big_1({{.*}}*{{( %.*)?}})
270*67e74705SXin Li
271*67e74705SXin Li /*****************************************************************************/
272*67e74705SXin Li /********************************* TYPE MERGING ******************************/
273*67e74705SXin Li /*****************************************************************************/
274*67e74705SXin Li
275*67e74705SXin Li typedef union {
276*67e74705SXin Li float f;
277*67e74705SXin Li double d;
278*67e74705SXin Li } union_het_fp;
279*67e74705SXin Li TEST(union_het_fp)
280*67e74705SXin Li // CHECK-LABEL: define {{.*}} @return_union_het_fp()
281*67e74705SXin Li // CHECK: [[RET:%.*]] = alloca [[REC:%.*]], align 4
282*67e74705SXin Li // CHECK: [[VAR:%.*]] = alloca [[REC]], align 4
283*67e74705SXin Li // CHECK: @llvm.memcpy
284*67e74705SXin Li // CHECK: @llvm.memcpy
285*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[RET]] to [[AGG:{ i32, i32 }]]*
286*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
287*67e74705SXin Li // CHECK: [[FIRST:%.*]] = load i32, i32* [[T0]], align 4
288*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
289*67e74705SXin Li // CHECK: [[SECOND:%.*]] = load i32, i32* [[T0]], align 4
290*67e74705SXin Li // CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ i32, i32 }]] undef, i32 [[FIRST]], 0
291*67e74705SXin Li // CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], i32 [[SECOND]], 1
292*67e74705SXin Li // CHECK: ret [[UAGG]] [[T1]]
293*67e74705SXin Li // CHECK-LABEL: define {{.*}} @take_union_het_fp(i32, i32)
294*67e74705SXin Li // CHECK: [[V:%.*]] = alloca [[REC]], align 4
295*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[V]] to [[AGG]]*
296*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
297*67e74705SXin Li // CHECK: store i32 %0, i32* [[T0]], align 4
298*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
299*67e74705SXin Li // CHECK: store i32 %1, i32* [[T0]], align 4
300*67e74705SXin Li // CHECK: ret void
301*67e74705SXin Li // CHECK-LABEL: define void @test_union_het_fp()
302*67e74705SXin Li // CHECK: [[TMP:%.*]] = alloca [[REC]], align 4
303*67e74705SXin Li // CHECK: [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_union_het_fp()
304*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]*
305*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
306*67e74705SXin Li // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0
307*67e74705SXin Li // CHECK: store i32 [[T1]], i32* [[T0]], align 4
308*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
309*67e74705SXin Li // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1
310*67e74705SXin Li // CHECK: store i32 [[T1]], i32* [[T0]], align 4
311*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]*
312*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
313*67e74705SXin Li // CHECK: [[FIRST:%.*]] = load i32, i32* [[T0]], align 4
314*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
315*67e74705SXin Li // CHECK: [[SECOND:%.*]] = load i32, i32* [[T0]], align 4
316*67e74705SXin Li // CHECK: call [[SWIFTCC]] void @take_union_het_fp(i32 [[FIRST]], i32 [[SECOND]])
317*67e74705SXin Li // CHECK: ret void
318*67e74705SXin Li
319*67e74705SXin Li
320*67e74705SXin Li typedef union {
321*67e74705SXin Li float f1;
322*67e74705SXin Li float f2;
323*67e74705SXin Li } union_hom_fp;
324*67e74705SXin Li TEST(union_hom_fp)
325*67e74705SXin Li // CHECK-LABEL: define void @test_union_hom_fp()
326*67e74705SXin Li // CHECK: [[TMP:%.*]] = alloca [[REC:%.*]], align 4
327*67e74705SXin Li // CHECK: [[CALL:%.*]] = call [[SWIFTCC]] float @return_union_hom_fp()
328*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG:{ float }]]*
329*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
330*67e74705SXin Li // CHECK: store float [[CALL]], float* [[T0]], align 4
331*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]*
332*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
333*67e74705SXin Li // CHECK: [[FIRST:%.*]] = load float, float* [[T0]], align 4
334*67e74705SXin Li // CHECK: call [[SWIFTCC]] void @take_union_hom_fp(float [[FIRST]])
335*67e74705SXin Li // CHECK: ret void
336*67e74705SXin Li
337*67e74705SXin Li typedef union {
338*67e74705SXin Li float f1;
339*67e74705SXin Li float4 fv2;
340*67e74705SXin Li } union_hom_fp_partial;
341*67e74705SXin Li TEST(union_hom_fp_partial)
342*67e74705SXin Li // CHECK-LABEL: define void @test_union_hom_fp_partial()
343*67e74705SXin Li // CHECK: [[TMP:%.*]] = alloca [[REC:%.*]], align 16
344*67e74705SXin Li // CHECK: [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG:{ float, float, float, float }]] @return_union_hom_fp_partial()
345*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG:{ float, float, float, float }]]*
346*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
347*67e74705SXin Li // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0
348*67e74705SXin Li // CHECK: store float [[T1]], float* [[T0]], align
349*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
350*67e74705SXin Li // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1
351*67e74705SXin Li // CHECK: store float [[T1]], float* [[T0]], align
352*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
353*67e74705SXin Li // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 2
354*67e74705SXin Li // CHECK: store float [[T1]], float* [[T0]], align
355*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
356*67e74705SXin Li // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 3
357*67e74705SXin Li // CHECK: store float [[T1]], float* [[T0]], align
358*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]*
359*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
360*67e74705SXin Li // CHECK: [[FIRST:%.*]] = load float, float* [[T0]], align
361*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
362*67e74705SXin Li // CHECK: [[SECOND:%.*]] = load float, float* [[T0]], align
363*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
364*67e74705SXin Li // CHECK: [[THIRD:%.*]] = load float, float* [[T0]], align
365*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
366*67e74705SXin Li // CHECK: [[FOURTH:%.*]] = load float, float* [[T0]], align
367*67e74705SXin Li // CHECK: call [[SWIFTCC]] void @take_union_hom_fp_partial(float [[FIRST]], float [[SECOND]], float [[THIRD]], float [[FOURTH]])
368*67e74705SXin Li // CHECK: ret void
369*67e74705SXin Li
370*67e74705SXin Li typedef union {
371*67e74705SXin Li struct { int x, y; } f1;
372*67e74705SXin Li float4 fv2;
373*67e74705SXin Li } union_het_fpv_partial;
374*67e74705SXin Li TEST(union_het_fpv_partial)
375*67e74705SXin Li // CHECK-LABEL: define void @test_union_het_fpv_partial()
376*67e74705SXin Li // CHECK: [[TMP:%.*]] = alloca [[REC:%.*]], align 16
377*67e74705SXin Li // CHECK: [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG:{ i32, i32, float, float }]] @return_union_het_fpv_partial()
378*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG:{ i32, i32, float, float }]]*
379*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
380*67e74705SXin Li // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0
381*67e74705SXin Li // CHECK: store i32 [[T1]], i32* [[T0]], align
382*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
383*67e74705SXin Li // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1
384*67e74705SXin Li // CHECK: store i32 [[T1]], i32* [[T0]], align
385*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
386*67e74705SXin Li // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 2
387*67e74705SXin Li // CHECK: store float [[T1]], float* [[T0]], align
388*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
389*67e74705SXin Li // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 3
390*67e74705SXin Li // CHECK: store float [[T1]], float* [[T0]], align
391*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]*
392*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
393*67e74705SXin Li // CHECK: [[FIRST:%.*]] = load i32, i32* [[T0]], align
394*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
395*67e74705SXin Li // CHECK: [[SECOND:%.*]] = load i32, i32* [[T0]], align
396*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
397*67e74705SXin Li // CHECK: [[THIRD:%.*]] = load float, float* [[T0]], align
398*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
399*67e74705SXin Li // CHECK: [[FOURTH:%.*]] = load float, float* [[T0]], align
400*67e74705SXin Li // CHECK: call [[SWIFTCC]] void @take_union_het_fpv_partial(i32 [[FIRST]], i32 [[SECOND]], float [[THIRD]], float [[FOURTH]])
401*67e74705SXin Li // CHECK: ret void
402*67e74705SXin Li
403*67e74705SXin Li /*****************************************************************************/
404*67e74705SXin Li /****************************** VECTOR LEGALIZATION **************************/
405*67e74705SXin Li /*****************************************************************************/
406*67e74705SXin Li
407*67e74705SXin Li TEST(int4)
408*67e74705SXin Li // CHECK-LABEL: define {{.*}} <4 x i32> @return_int4()
409*67e74705SXin Li // CHECK-LABEL: define {{.*}} @take_int4(<4 x i32>
410*67e74705SXin Li
411*67e74705SXin Li TEST(int8)
412*67e74705SXin Li // CHECK-LABEL: define {{.*}} @return_int8()
413*67e74705SXin Li // CHECK: [[RET:%.*]] = alloca [[REC:<8 x i32>]], align 32
414*67e74705SXin Li // CHECK: [[VAR:%.*]] = alloca [[REC]], align
415*67e74705SXin Li // CHECK: store
416*67e74705SXin Li // CHECK: load
417*67e74705SXin Li // CHECK: store
418*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[RET]] to [[AGG:{ <4 x i32>, <4 x i32> }]]*
419*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
420*67e74705SXin Li // CHECK: [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align
421*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
422*67e74705SXin Li // CHECK: [[SECOND:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align
423*67e74705SXin Li // CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ <4 x i32>, <4 x i32> }]] undef, <4 x i32> [[FIRST]], 0
424*67e74705SXin Li // CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], <4 x i32> [[SECOND]], 1
425*67e74705SXin Li // CHECK: ret [[UAGG]] [[T1]]
426*67e74705SXin Li // CHECK-LABEL: define {{.*}} @take_int8(<4 x i32>, <4 x i32>)
427*67e74705SXin Li // CHECK: [[V:%.*]] = alloca [[REC]], align
428*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[V]] to [[AGG]]*
429*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
430*67e74705SXin Li // CHECK: store <4 x i32> %0, <4 x i32>* [[T0]], align
431*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
432*67e74705SXin Li // CHECK: store <4 x i32> %1, <4 x i32>* [[T0]], align
433*67e74705SXin Li // CHECK: ret void
434*67e74705SXin Li // CHECK-LABEL: define void @test_int8()
435*67e74705SXin Li // CHECK: [[TMP1:%.*]] = alloca [[REC]], align
436*67e74705SXin Li // CHECK: [[TMP2:%.*]] = alloca [[REC]], align
437*67e74705SXin Li // CHECK: [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_int8()
438*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP1]] to [[AGG]]*
439*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
440*67e74705SXin Li // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0
441*67e74705SXin Li // CHECK: store <4 x i32> [[T1]], <4 x i32>* [[T0]], align
442*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
443*67e74705SXin Li // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1
444*67e74705SXin Li // CHECK: store <4 x i32> [[T1]], <4 x i32>* [[T0]], align
445*67e74705SXin Li // CHECK: [[V:%.*]] = load [[REC]], [[REC]]* [[TMP1]], align
446*67e74705SXin Li // CHECK: store [[REC]] [[V]], [[REC]]* [[TMP2]], align
447*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP2]] to [[AGG]]*
448*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
449*67e74705SXin Li // CHECK: [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align
450*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
451*67e74705SXin Li // CHECK: [[SECOND:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align
452*67e74705SXin Li // CHECK: call [[SWIFTCC]] void @take_int8(<4 x i32> [[FIRST]], <4 x i32> [[SECOND]])
453*67e74705SXin Li // CHECK: ret void
454*67e74705SXin Li
455*67e74705SXin Li TEST(int5)
456*67e74705SXin Li // CHECK-LABEL: define {{.*}} @return_int5()
457*67e74705SXin Li // CHECK: [[RET:%.*]] = alloca [[REC:<5 x i32>]], align 32
458*67e74705SXin Li // CHECK: [[VAR:%.*]] = alloca [[REC]], align
459*67e74705SXin Li // CHECK: store
460*67e74705SXin Li // CHECK: load
461*67e74705SXin Li // CHECK: store
462*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[RET]] to [[AGG:{ <4 x i32>, i32 }]]*
463*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
464*67e74705SXin Li // CHECK: [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align
465*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
466*67e74705SXin Li // CHECK: [[SECOND:%.*]] = load i32, i32* [[T0]], align
467*67e74705SXin Li // CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ <4 x i32>, i32 }]] undef, <4 x i32> [[FIRST]], 0
468*67e74705SXin Li // CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], i32 [[SECOND]], 1
469*67e74705SXin Li // CHECK: ret [[UAGG]] [[T1]]
470*67e74705SXin Li // CHECK-LABEL: define {{.*}} @take_int5(<4 x i32>, i32)
471*67e74705SXin Li // CHECK: [[V:%.*]] = alloca [[REC]], align
472*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[V]] to [[AGG]]*
473*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
474*67e74705SXin Li // CHECK: store <4 x i32> %0, <4 x i32>* [[T0]], align
475*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
476*67e74705SXin Li // CHECK: store i32 %1, i32* [[T0]], align
477*67e74705SXin Li // CHECK: ret void
478*67e74705SXin Li // CHECK-LABEL: define void @test_int5()
479*67e74705SXin Li // CHECK: [[TMP1:%.*]] = alloca [[REC]], align
480*67e74705SXin Li // CHECK: [[TMP2:%.*]] = alloca [[REC]], align
481*67e74705SXin Li // CHECK: [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_int5()
482*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP1]] to [[AGG]]*
483*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
484*67e74705SXin Li // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0
485*67e74705SXin Li // CHECK: store <4 x i32> [[T1]], <4 x i32>* [[T0]], align
486*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
487*67e74705SXin Li // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1
488*67e74705SXin Li // CHECK: store i32 [[T1]], i32* [[T0]], align
489*67e74705SXin Li // CHECK: [[V:%.*]] = load [[REC]], [[REC]]* [[TMP1]], align
490*67e74705SXin Li // CHECK: store [[REC]] [[V]], [[REC]]* [[TMP2]], align
491*67e74705SXin Li // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP2]] to [[AGG]]*
492*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
493*67e74705SXin Li // CHECK: [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align
494*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
495*67e74705SXin Li // CHECK: [[SECOND:%.*]] = load i32, i32* [[T0]], align
496*67e74705SXin Li // CHECK: call [[SWIFTCC]] void @take_int5(<4 x i32> [[FIRST]], i32 [[SECOND]])
497*67e74705SXin Li // CHECK: ret void
498*67e74705SXin Li
499*67e74705SXin Li typedef struct {
500*67e74705SXin Li int x;
501*67e74705SXin Li int3 v __attribute__((packed));
502*67e74705SXin Li } misaligned_int3;
503*67e74705SXin Li TEST(misaligned_int3)
504*67e74705SXin Li // CHECK-LABEL: define {{.*}} @take_misaligned_int3(i32, i32, i32, i32)
505