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