Clang Project

clang_source_code/test/CodeGen/arm-swiftcall.c
1// RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -o - %s | FileCheck %s
2// RUN: %clang_cc1 -triple armv7s-apple-ios9 -emit-llvm -o - %s | FileCheck %s
3// RUN: %clang_cc1 -triple armv7k-apple-ios9 -emit-llvm -o - %s | FileCheck %s
4
5#define SWIFTCALL __attribute__((swiftcall))
6#define OUT __attribute__((swift_indirect_result))
7#define ERROR __attribute__((swift_error_result))
8#define CONTEXT __attribute__((swift_context))
9
10/*****************************************************************************/
11/****************************** PARAMETER ABIS *******************************/
12/*****************************************************************************/
13
14SWIFTCALL void indirect_result_1(OUT int *arg0, OUT float *arg1) {}
15// CHECK-LABEL: define {{.*}} void @indirect_result_1(i32* noalias sret align 4 dereferenceable(4){{.*}}, float* noalias align 4 dereferenceable(4){{.*}})
16
17// TODO: maybe this shouldn't suppress sret.
18SWIFTCALL int indirect_result_2(OUT int *arg0, OUT float *arg1) {  __builtin_unreachable(); }
19// CHECK-LABEL: define {{.*}} i32 @indirect_result_2(i32* noalias align 4 dereferenceable(4){{.*}}, float* noalias align 4 dereferenceable(4){{.*}})
20
21typedef struct { char array[1024]; } struct_reallybig;
22SWIFTCALL struct_reallybig indirect_result_3(OUT int *arg0, OUT float *arg1) { __builtin_unreachable(); }
23// CHECK-LABEL: define {{.*}} void @indirect_result_3({{.*}}* noalias sret {{.*}}, i32* noalias align 4 dereferenceable(4){{.*}}, float* noalias align 4 dereferenceable(4){{.*}})
24
25SWIFTCALL void context_1(CONTEXT void *self) {}
26// CHECK-LABEL: define {{.*}} void @context_1(i8* swiftself
27
28SWIFTCALL void context_2(void *arg0, CONTEXT void *self) {}
29// CHECK-LABEL: define {{.*}} void @context_2(i8*{{.*}}, i8* swiftself
30
31SWIFTCALL void context_error_1(CONTEXT int *self, ERROR float **error) {}
32// CHECK-LABEL: define {{.*}} void @context_error_1(i32* swiftself{{.*}}, float** swifterror)
33// CHECK:       [[TEMP:%.*]] = alloca float*, align 4
34// CHECK:       [[T0:%.*]] = load float*, float** [[ERRORARG:%.*]], align 4
35// CHECK:       store float* [[T0]], float** [[TEMP]], align 4
36// CHECK:       [[T0:%.*]] = load float*, float** [[TEMP]], align 4
37// CHECK:       store float* [[T0]], float** [[ERRORARG]], align 4
38void test_context_error_1() {
39  int x;
40  float *error;
41  context_error_1(&x, &error);
42}
43// CHECK-LABEL: define void @test_context_error_1()
44// CHECK:       [[X:%.*]] = alloca i32, align 4
45// CHECK:       [[ERROR:%.*]] = alloca float*, align 4
46// CHECK:       [[TEMP:%.*]] = alloca swifterror float*, align 4
47// CHECK:       [[T0:%.*]] = load float*, float** [[ERROR]], align 4
48// CHECK:       store float* [[T0]], float** [[TEMP]], align 4
49// CHECK:       call [[SWIFTCC:swiftcc]] void @context_error_1(i32* swiftself [[X]], float** swifterror [[TEMP]])
50// CHECK:       [[T0:%.*]] = load float*, float** [[TEMP]], align 4
51// CHECK:       store float* [[T0]], float** [[ERROR]], align 4
52
53SWIFTCALL void context_error_2(short s, CONTEXT int *self, ERROR float **error) {}
54// CHECK-LABEL: define {{.*}} void @context_error_2(i16{{.*}}, i32* swiftself{{.*}}, float** swifterror)
55
56/*****************************************************************************/
57/********************************** LOWERING *********************************/
58/*****************************************************************************/
59
60typedef float float3 __attribute__((ext_vector_type(3)));
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)));
69typedef char char16 __attribute__((ext_vector_type(16)));
70typedef short short8 __attribute__((ext_vector_type(8)));
71typedef long long long2 __attribute__((ext_vector_type(2)));
72
73#define TEST(TYPE)                       \
74  SWIFTCALL TYPE return_##TYPE(void) {   \
75    TYPE result = {};                    \
76    return result;                       \
77  }                                      \
78  SWIFTCALL void take_##TYPE(TYPE v) {   \
79  }                                      \
80  void test_##TYPE() {                   \
81    take_##TYPE(return_##TYPE());        \
82  }
83
84/*****************************************************************************/
85/*********************************** STRUCTS *********************************/
86/*****************************************************************************/
87
88typedef struct {
89} struct_empty;
90TEST(struct_empty);
91// CHECK-LABEL: define {{.*}} @return_struct_empty()
92// CHECK:   ret void
93// CHECK-LABEL: define {{.*}} @take_struct_empty()
94// CHECK:   ret void
95
96typedef struct {
97  int x;
98  char c0;
99  char c1;
100  float f0;
101  float f1;
102} struct_1;
103TEST(struct_1);
104// CHECK-LABEL: define {{.*}} @return_struct_1()
105// CHECK:   [[RET:%.*]] = alloca [[REC:%.*]], align 4
106// CHECK:   @llvm.memset
107// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[RET]] to [[AGG:{ i32, i16, \[2 x i8\], float, float }]]*
108// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
109// CHECK:   [[FIRST:%.*]] = load i32, i32* [[T0]], align 4
110// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
111// CHECK:   [[SECOND:%.*]] = load i16, i16* [[T0]], align 4
112// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
113// CHECK:   [[THIRD:%.*]] = load float, float* [[T0]], align
114// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 4
115// CHECK:   [[FOURTH:%.*]] = load float, float* [[T0]], align
116// CHECK:   [[T0:%.*]] = insertvalue [[UAGG:{ i32, i16, float, float }]] undef, i32 [[FIRST]], 0
117// CHECK:   [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], i16 [[SECOND]], 1
118// CHECK:   [[T2:%.*]] = insertvalue [[UAGG]] [[T1]], float [[THIRD]], 2
119// CHECK:   [[T3:%.*]] = insertvalue [[UAGG]] [[T2]], float [[FOURTH]], 3
120// CHECK:   ret [[UAGG]] [[T3]]
121// CHECK-LABEL: define {{.*}} @take_struct_1(i32, i16, float, float)
122// CHECK:   [[V:%.*]] = alloca [[REC]], align 4
123// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[V]] to [[AGG]]*
124// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
125// CHECK:   store i32 %0, i32* [[T0]], align 4
126// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
127// CHECK:   store i16 %1, i16* [[T0]], align 4
128// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
129// CHECK:   store float %2, float* [[T0]], align 4
130// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 4
131// CHECK:   store float %3, float* [[T0]], align 4
132// CHECK:   ret void
133// CHECK-LABEL: define void @test_struct_1()
134// CHECK:   [[TMP:%.*]] = alloca [[REC]], align 4
135// CHECK:   [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_struct_1()
136// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]*
137// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
138// CHECK:   [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0
139// CHECK:   store i32 [[T1]], i32* [[T0]], align 4
140// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
141// CHECK:   [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1
142// CHECK:   store i16 [[T1]], i16* [[T0]], align 4
143// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
144// CHECK:   [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 2
145// CHECK:   store float [[T1]], float* [[T0]], align 4
146// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 4
147// CHECK:   [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 3
148// CHECK:   store float [[T1]], float* [[T0]], align 4
149// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]*
150// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
151// CHECK:   [[FIRST:%.*]] = load i32, i32* [[T0]], align 4
152// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
153// CHECK:   [[SECOND:%.*]] = load i16, i16* [[T0]], align 4
154// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
155// CHECK:   [[THIRD:%.*]] = load float, float* [[T0]], align 4
156// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 4
157// CHECK:   [[FOURTH:%.*]] = load float, float* [[T0]], align 4
158// CHECK:   call [[SWIFTCC]] void @take_struct_1(i32 [[FIRST]], i16 [[SECOND]], float [[THIRD]], float [[FOURTH]])
159// CHECK:   ret void
160
161typedef struct {
162  int x;
163  char c0;
164  __attribute__((aligned(2))) char c1;
165  float f0;
166  float f1;
167} struct_2;
168TEST(struct_2);
169// CHECK-LABEL: define {{.*}} @return_struct_2()
170// CHECK:   [[RET:%.*]] = alloca [[REC:%.*]], align 4
171// CHECK:   @llvm.memcpy
172// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[RET]] to [[AGG:{ i32, i32, float, float }]]*
173// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
174// CHECK:   [[FIRST:%.*]] = load i32, i32* [[T0]], align 4
175// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
176// CHECK:   [[SECOND:%.*]] = load i32, i32* [[T0]], align 4
177// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
178// CHECK:   [[THIRD:%.*]] = load float, float* [[T0]], align
179// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
180// CHECK:   [[FOURTH:%.*]] = load float, float* [[T0]], align
181// CHECK:   [[T0:%.*]] = insertvalue [[UAGG:{ i32, i32, float, float }]] undef, i32 [[FIRST]], 0
182// CHECK:   [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], i32 [[SECOND]], 1
183// CHECK:   [[T2:%.*]] = insertvalue [[UAGG]] [[T1]], float [[THIRD]], 2
184// CHECK:   [[T3:%.*]] = insertvalue [[UAGG]] [[T2]], float [[FOURTH]], 3
185// CHECK:   ret [[UAGG]] [[T3]]
186// CHECK-LABEL: define {{.*}} @take_struct_2(i32, i32, float, float)
187// CHECK:   [[V:%.*]] = alloca [[REC]], align 4
188// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[V]] to [[AGG]]*
189// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
190// CHECK:   store i32 %0, i32* [[T0]], align 4
191// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
192// CHECK:   store i32 %1, i32* [[T0]], align 4
193// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
194// CHECK:   store float %2, float* [[T0]], align 4
195// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
196// CHECK:   store float %3, float* [[T0]], align 4
197// CHECK:   ret void
198// CHECK-LABEL: define void @test_struct_2()
199// CHECK:   [[TMP:%.*]] = alloca [[REC]], align 4
200// CHECK:   [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_struct_2()
201// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]*
202// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
203// CHECK:   [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0
204// CHECK:   store i32 [[T1]], i32* [[T0]], align 4
205// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
206// CHECK:   [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1
207// CHECK:   store i32 [[T1]], i32* [[T0]], align 4
208// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
209// CHECK:   [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 2
210// CHECK:   store float [[T1]], float* [[T0]], align 4
211// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
212// CHECK:   [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 3
213// CHECK:   store float [[T1]], float* [[T0]], align 4
214// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]*
215// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
216// CHECK:   [[FIRST:%.*]] = load i32, i32* [[T0]], align 4
217// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
218// CHECK:   [[SECOND:%.*]] = load i32, i32* [[T0]], align 4
219// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
220// CHECK:   [[THIRD:%.*]] = load float, float* [[T0]], align 4
221// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
222// CHECK:   [[FOURTH:%.*]] = load float, float* [[T0]], align 4
223// CHECK:   call [[SWIFTCC]] void @take_struct_2(i32 [[FIRST]], i32 [[SECOND]], float [[THIRD]], float [[FOURTH]])
224// CHECK:   ret void
225
226// There's no way to put a field randomly in the middle of an otherwise
227// empty storage unit in C, so that case has to be tested in C++, which
228// can use empty structs to introduce arbitrary padding.  (In C, they end up
229// with size 0 and so don't affect layout.)
230
231// Misaligned data rule.
232typedef struct {
233  char c0;
234  __attribute__((packed)) float f;
235} struct_misaligned_1;
236TEST(struct_misaligned_1)
237// CHECK-LABEL: define {{.*}} @return_struct_misaligned_1()
238// CHECK:   [[RET:%.*]] = alloca [[REC:%.*]], align
239// CHECK:   @llvm.memset
240// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[RET]] to [[AGG:{ i32, i8 }]]*
241// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
242// CHECK:   [[FIRST:%.*]] = load i32, i32* [[T0]], align
243// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
244// CHECK:   [[SECOND:%.*]] = load i8, i8* [[T0]], align
245// CHECK:   [[T0:%.*]] = insertvalue [[UAGG:{ i32, i8 }]] undef, i32 [[FIRST]], 0
246// CHECK:   [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], i8 [[SECOND]], 1
247// CHECK:   ret [[UAGG]] [[T1]]
248// CHECK-LABEL: define {{.*}} @take_struct_misaligned_1(i32, i8)
249// CHECK:   [[V:%.*]] = alloca [[REC]], align
250// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[V]] to [[AGG]]*
251// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
252// CHECK:   store i32 %0, i32* [[T0]], align
253// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
254// CHECK:   store i8 %1, i8* [[T0]], align
255// CHECK:   ret void
256
257// Too many scalars.
258typedef struct {
259  int x[5];
260} struct_big_1;
261TEST(struct_big_1)
262
263// CHECK-LABEL: define {{.*}} void @return_struct_big_1({{.*}} noalias sret
264
265// Should not be byval.
266// CHECK-LABEL: define {{.*}} void @take_struct_big_1({{.*}}*{{( %.*)?}})
267
268/*****************************************************************************/
269/********************************* TYPE MERGING ******************************/
270/*****************************************************************************/
271
272typedef union {
273  float f;
274  double d;
275} union_het_fp;
276TEST(union_het_fp)
277// CHECK-LABEL: define {{.*}} @return_union_het_fp()
278// CHECK:   [[RET:%.*]] = alloca [[REC:%.*]], align {{(4|8)}}
279// CHECK:   @llvm.memcpy
280// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[RET]] to [[AGG:{ i32, i32 }]]*
281// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
282// CHECK:   [[FIRST:%.*]] = load i32, i32* [[T0]], align {{(4|8)}}
283// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
284// CHECK:   [[SECOND:%.*]] = load i32, i32* [[T0]], align {{(4|8)}}
285// CHECK:   [[T0:%.*]] = insertvalue [[UAGG:{ i32, i32 }]] undef, i32 [[FIRST]], 0
286// CHECK:   [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], i32 [[SECOND]], 1
287// CHECK:   ret [[UAGG]] [[T1]]
288// CHECK-LABEL: define {{.*}} @take_union_het_fp(i32, i32)
289// CHECK:   [[V:%.*]] = alloca [[REC]], align {{(4|8)}}
290// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[V]] to [[AGG]]*
291// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
292// CHECK:   store i32 %0, i32* [[T0]], align {{(4|8)}}
293// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
294// CHECK:   store i32 %1, i32* [[T0]], align {{(4|8)}}
295// CHECK:   ret void
296// CHECK-LABEL: define void @test_union_het_fp()
297// CHECK:   [[TMP:%.*]] = alloca [[REC]], align {{(4|8)}}
298// CHECK:   [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_union_het_fp()
299// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]*
300// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
301// CHECK:   [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0
302// CHECK:   store i32 [[T1]], i32* [[T0]], align {{(4|8)}}
303// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
304// CHECK:   [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1
305// CHECK:   store i32 [[T1]], i32* [[T0]], align {{(4|8)}}
306// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]*
307// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
308// CHECK:   [[FIRST:%.*]] = load i32, i32* [[T0]], align {{(4|8)}}
309// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
310// CHECK:   [[SECOND:%.*]] = load i32, i32* [[T0]], align {{(4|8)}}
311// CHECK:   call [[SWIFTCC]] void @take_union_het_fp(i32 [[FIRST]], i32 [[SECOND]])
312// CHECK:   ret void
313
314
315typedef union {
316  float f1;
317  float f2;
318} union_hom_fp;
319TEST(union_hom_fp)
320// CHECK-LABEL: define void @test_union_hom_fp()
321// CHECK:   [[TMP:%.*]] = alloca [[REC:%.*]], align 4
322// CHECK:   [[CALL:%.*]] = call [[SWIFTCC]] float @return_union_hom_fp()
323// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG:{ float }]]*
324// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
325// CHECK:   store float [[CALL]], float* [[T0]], align 4
326// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]*
327// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
328// CHECK:   [[FIRST:%.*]] = load float, float* [[T0]], align 4
329// CHECK:   call [[SWIFTCC]] void @take_union_hom_fp(float [[FIRST]])
330// CHECK:   ret void
331
332typedef union {
333  float f1;
334  float4 fv2;
335} union_hom_fp_partial;
336TEST(union_hom_fp_partial)
337// CHECK-LABEL: define void @test_union_hom_fp_partial()
338// CHECK:   [[TMP:%.*]] = alloca [[REC:%.*]], align 16
339// CHECK:   [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG:{ float, float, float, float }]] @return_union_hom_fp_partial()
340// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG:{ float, float, float, float }]]*
341// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
342// CHECK:   [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0
343// CHECK:   store float [[T1]], float* [[T0]], align
344// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
345// CHECK:   [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1
346// CHECK:   store float [[T1]], float* [[T0]], align
347// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
348// CHECK:   [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 2
349// CHECK:   store float [[T1]], float* [[T0]], align
350// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
351// CHECK:   [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 3
352// CHECK:   store float [[T1]], float* [[T0]], align
353// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]*
354// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
355// CHECK:   [[FIRST:%.*]] = load float, float* [[T0]], align
356// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
357// CHECK:   [[SECOND:%.*]] = load float, float* [[T0]], align
358// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
359// CHECK:   [[THIRD:%.*]] = load float, float* [[T0]], align
360// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
361// CHECK:   [[FOURTH:%.*]] = load float, float* [[T0]], align
362// CHECK:   call [[SWIFTCC]] void @take_union_hom_fp_partial(float [[FIRST]], float [[SECOND]], float [[THIRD]], float [[FOURTH]])
363// CHECK:   ret void
364
365typedef union {
366  struct { int x, y; } f1;
367  float4 fv2;
368} union_het_fpv_partial;
369TEST(union_het_fpv_partial)
370// CHECK-LABEL: define void @test_union_het_fpv_partial()
371// CHECK:   [[TMP:%.*]] = alloca [[REC:%.*]], align 16
372// CHECK:   [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG:{ i32, i32, float, float }]] @return_union_het_fpv_partial()
373// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG:{ i32, i32, float, float }]]*
374// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
375// CHECK:   [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0
376// CHECK:   store i32 [[T1]], i32* [[T0]], align
377// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
378// CHECK:   [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1
379// CHECK:   store i32 [[T1]], i32* [[T0]], align
380// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
381// CHECK:   [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 2
382// CHECK:   store float [[T1]], float* [[T0]], align
383// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
384// CHECK:   [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 3
385// CHECK:   store float [[T1]], float* [[T0]], align
386// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]*
387// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
388// CHECK:   [[FIRST:%.*]] = load i32, i32* [[T0]], align
389// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
390// CHECK:   [[SECOND:%.*]] = load i32, i32* [[T0]], align
391// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
392// CHECK:   [[THIRD:%.*]] = load float, float* [[T0]], align
393// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 3
394// CHECK:   [[FOURTH:%.*]] = load float, float* [[T0]], align
395// CHECK:   call [[SWIFTCC]] void @take_union_het_fpv_partial(i32 [[FIRST]], i32 [[SECOND]], float [[THIRD]], float [[FOURTH]])
396// CHECK:   ret void
397
398/*****************************************************************************/
399/****************************** VECTOR LEGALIZATION **************************/
400/*****************************************************************************/
401
402TEST(int4)
403// CHECK-LABEL: define {{.*}} <4 x i32> @return_int4()
404// CHECK-LABEL: define {{.*}} @take_int4(<4 x i32>
405
406TEST(int8)
407// CHECK-LABEL: define {{.*}} @return_int8()
408// CHECK:   [[RET:%.*]] = alloca [[REC:<8 x i32>]], align 32
409// CHECK:   store
410// CHECK:   load
411// CHECK:   store
412// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[RET]] to [[AGG:{ <4 x i32>, <4 x i32> }]]*
413// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
414// CHECK:   [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align
415// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
416// CHECK:   [[SECOND:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align
417// CHECK:   [[T0:%.*]] = insertvalue [[UAGG:{ <4 x i32>, <4 x i32> }]] undef, <4 x i32> [[FIRST]], 0
418// CHECK:   [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], <4 x i32> [[SECOND]], 1
419// CHECK:   ret [[UAGG]] [[T1]]
420// CHECK-LABEL: define {{.*}} @take_int8(<4 x i32>, <4 x i32>)
421// CHECK:   [[V:%.*]] = alloca [[REC]], align
422// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[V]] to [[AGG]]*
423// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
424// CHECK:   store <4 x i32> %0, <4 x i32>* [[T0]], align
425// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
426// CHECK:   store <4 x i32> %1, <4 x i32>* [[T0]], align
427// CHECK:   ret void
428// CHECK-LABEL: define void @test_int8()
429// CHECK:   [[TMP1:%.*]] = alloca [[REC]], align
430// CHECK:   [[TMP2:%.*]] = alloca [[REC]], align
431// CHECK:   [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_int8()
432// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP1]] to [[AGG]]*
433// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
434// CHECK:   [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0
435// CHECK:   store <4 x i32> [[T1]], <4 x i32>* [[T0]], align
436// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
437// CHECK:   [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1
438// CHECK:   store <4 x i32> [[T1]], <4 x i32>* [[T0]], align
439// CHECK:   [[V:%.*]] = load [[REC]], [[REC]]* [[TMP1]], align
440// CHECK:   store [[REC]] [[V]], [[REC]]* [[TMP2]], align
441// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP2]] to [[AGG]]*
442// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
443// CHECK:   [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align
444// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
445// CHECK:   [[SECOND:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align
446// CHECK:   call [[SWIFTCC]] void @take_int8(<4 x i32> [[FIRST]], <4 x i32> [[SECOND]])
447// CHECK:   ret void
448
449TEST(int5)
450// CHECK-LABEL: define {{.*}} @return_int5()
451// CHECK:   [[RET:%.*]] = alloca [[REC:<5 x i32>]], align 32
452// CHECK:   store
453// CHECK:   load
454// CHECK:   store
455// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[RET]] to [[AGG:{ <4 x i32>, i32 }]]*
456// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
457// CHECK:   [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align
458// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
459// CHECK:   [[SECOND:%.*]] = load i32, i32* [[T0]], align
460// CHECK:   [[T0:%.*]] = insertvalue [[UAGG:{ <4 x i32>, i32 }]] undef, <4 x i32> [[FIRST]], 0
461// CHECK:   [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], i32 [[SECOND]], 1
462// CHECK:   ret [[UAGG]] [[T1]]
463// CHECK-LABEL: define {{.*}} @take_int5(<4 x i32>, i32)
464// CHECK:   [[V:%.*]] = alloca [[REC]], align
465// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[V]] to [[AGG]]*
466// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
467// CHECK:   store <4 x i32> %0, <4 x i32>* [[T0]], align
468// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
469// CHECK:   store i32 %1, i32* [[T0]], align
470// CHECK:   ret void
471// CHECK-LABEL: define void @test_int5()
472// CHECK:   [[TMP1:%.*]] = alloca [[REC]], align
473// CHECK:   [[TMP2:%.*]] = alloca [[REC]], align
474// CHECK:   [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_int5()
475// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP1]] to [[AGG]]*
476// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
477// CHECK:   [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0
478// CHECK:   store <4 x i32> [[T1]], <4 x i32>* [[T0]], align
479// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
480// CHECK:   [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1
481// CHECK:   store i32 [[T1]], i32* [[T0]], align
482// CHECK:   [[V:%.*]] = load [[REC]], [[REC]]* [[TMP1]], align
483// CHECK:   store [[REC]] [[V]], [[REC]]* [[TMP2]], align
484// CHECK:   [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP2]] to [[AGG]]*
485// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
486// CHECK:   [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align
487// CHECK:   [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1
488// CHECK:   [[SECOND:%.*]] = load i32, i32* [[T0]], align
489// CHECK:   call [[SWIFTCC]] void @take_int5(<4 x i32> [[FIRST]], i32 [[SECOND]])
490// CHECK:   ret void
491
492typedef struct {
493  int x;
494  int3 v __attribute__((packed));
495} misaligned_int3;
496TEST(misaligned_int3)
497// CHECK-LABEL: define {{.*}} @take_misaligned_int3(i32, i32, i32, i32)
498
499typedef struct {
500  float f0;
501} struct_f1;
502TEST(struct_f1)
503// CHECK-LABEL: define swiftcc float @return_struct_f1()
504// CHECK-LABEL: define swiftcc void @take_struct_f1(float)
505
506typedef struct {
507  float f0;
508  float f1;
509} struct_f2;
510TEST(struct_f2)
511// CHECK-LABEL: define swiftcc { float, float } @return_struct_f2()
512// CHECK-LABEL: define swiftcc void @take_struct_f2(float, float)
513
514typedef struct {
515  float f0;
516  float f1;
517  float f2;
518} struct_f3;
519TEST(struct_f3)
520// CHECK-LABEL: define swiftcc { float, float, float } @return_struct_f3()
521// CHECK-LABEL: define swiftcc void @take_struct_f3(float, float, float)
522
523typedef struct {
524  float f0;
525  float f1;
526  float f2;
527  float f3;
528} struct_f4;
529TEST(struct_f4)
530// CHECK-LABEL: define swiftcc { float, float, float, float } @return_struct_f4()
531// CHECK-LABEL: define swiftcc void @take_struct_f4(float, float, float, float)
532
533
534typedef struct {
535  double d0;
536} struct_d1;
537TEST(struct_d1)
538// CHECK-LABEL: define swiftcc double @return_struct_d1()
539// CHECK-LABEL: define swiftcc void @take_struct_d1(double)
540
541typedef struct {
542  double d0;
543  double d1;
544} struct_d2;
545TEST(struct_d2)
546// CHECK-LABEL: define swiftcc { double, double } @return_struct_d2()
547// CHECK-LABEL: define swiftcc void @take_struct_d2(double, double)
548
549typedef struct {
550  double d0;
551  double d1;
552  double d2;
553} struct_d3;
554TEST(struct_d3)
555// CHECK-LABEL: define swiftcc { double, double, double } @return_struct_d3()
556// CHECK-LABEL: define swiftcc void @take_struct_d3(double, double, double)
557
558typedef struct {
559  double d0;
560  double d1;
561  double d2;
562  double d3;
563} struct_d4;
564TEST(struct_d4)
565// CHECK-LABEL: define swiftcc { double, double, double, double } @return_struct_d4()
566// CHECK-LABEL: define swiftcc void @take_struct_d4(double, double, double, double)
567
568typedef struct {
569  double d0;
570  double d1;
571  double d2;
572  double d3;
573  double d4;
574} struct_d5;
575TEST(struct_d5)
576// CHECK: define swiftcc void @return_struct_d5([[STRUCT5:%.*]]* noalias sret
577// CHECK: define swiftcc void @take_struct_d5([[STRUCT5]]
578
579typedef struct {
580  char c0;
581} struct_c1;
582TEST(struct_c1)
583// CHECK-LABEL: define swiftcc i8 @return_struct_c1()
584// CHECK-LABEL: define swiftcc void @take_struct_c1(i8)
585
586typedef struct {
587  char c0;
588  char c1;
589} struct_c2;
590TEST(struct_c2)
591// CHECK-LABEL: define swiftcc i16 @return_struct_c2()
592// CHECK-LABEL: define swiftcc void @take_struct_c2(i16)
593//
594
595typedef struct {
596  char c0;
597  char c1;
598  char c2;
599} struct_c3;
600TEST(struct_c3)
601// CHECK-LABEL: define swiftcc i32 @return_struct_c3()
602// CHECK-LABEL: define swiftcc void @take_struct_c3(i32)
603
604typedef struct {
605  char c0;
606  char c1;
607  char c2;
608  char c3;
609} struct_c4;
610TEST(struct_c4)
611// CHECK-LABEL: define swiftcc i32 @return_struct_c4()
612// CHECK-LABEL: define swiftcc void @take_struct_c4(i32)
613
614typedef struct {
615  char c0;
616  char c1;
617  char c2;
618  char c3;
619  char c4;
620} struct_c5;
621TEST(struct_c5)
622// CHECK-LABEL: define swiftcc { i32, i8 } @return_struct_c5()
623// CHECK-LABEL: define swiftcc void @take_struct_c5(i32, i8)
624
625typedef struct {
626  short s0;
627} struct_s1;
628TEST(struct_s1)
629// CHECK-LABEL: define swiftcc i16 @return_struct_s1()
630// CHECK-LABEL: define swiftcc void @take_struct_s1(i16)
631
632typedef struct {
633  short s0;
634  short s1;
635} struct_s2;
636TEST(struct_s2)
637// CHECK-LABEL: define swiftcc i32 @return_struct_s2()
638// CHECK-LABEL: define swiftcc void @take_struct_s2(i32)
639
640typedef struct {
641  short s0;
642  short s1;
643  short s2;
644} struct_s3;
645TEST(struct_s3)
646// CHECK-LABEL: define swiftcc { i32, i16 } @return_struct_s3()
647// CHECK-LABEL: define swiftcc void @take_struct_s3(i32, i16)
648
649typedef struct {
650  short s0;
651  short s1;
652  short s2;
653  short s3;
654} struct_s4;
655TEST(struct_s4)
656// CHECK-LABEL: define swiftcc { i32, i32 } @return_struct_s4()
657// CHECK-LABEL: define swiftcc void @take_struct_s4(i32, i32)
658
659typedef struct {
660  short s0;
661  short s1;
662  short s2;
663  short s3;
664  short s4;
665} struct_s5;
666TEST(struct_s5)
667// CHECK-LABEL: define swiftcc { i32, i32, i16 } @return_struct_s5()
668// CHECK-LABEL: define swiftcc void @take_struct_s5(i32, i32, i16)
669
670
671typedef struct {
672  int i0;
673} struct_i1;
674TEST(struct_i1)
675// CHECK-LABEL: define swiftcc i32 @return_struct_i1()
676// CHECK-LABEL: define swiftcc void @take_struct_i1(i32)
677
678typedef struct {
679  int i0;
680  int i1;
681} struct_i2;
682TEST(struct_i2)
683// CHECK-LABEL: define swiftcc { i32, i32 } @return_struct_i2()
684// CHECK-LABEL: define swiftcc void @take_struct_i2(i32, i32)
685
686typedef struct {
687  int i0;
688  int i1;
689  int i2;
690} struct_i3;
691TEST(struct_i3)
692// CHECK-LABEL: define swiftcc { i32, i32, i32 } @return_struct_i3()
693// CHECK-LABEL: define swiftcc void @take_struct_i3(i32, i32, i32)
694
695typedef struct {
696  int i0;
697  int i1;
698  int i2;
699  int i3;
700} struct_i4;
701TEST(struct_i4)
702// CHECK-LABEL: define swiftcc { i32, i32, i32, i32 } @return_struct_i4()
703// CHECK-LABEL: define swiftcc void @take_struct_i4(i32, i32, i32, i32)
704
705typedef struct {
706  long long l0;
707} struct_l1;
708TEST(struct_l1)
709// CHECK-LABEL: define swiftcc i64 @return_struct_l1()
710// CHECK-LABEL: define swiftcc void @take_struct_l1(i64)
711
712typedef struct {
713  long long l0;
714  long long l1;
715} struct_l2;
716TEST(struct_l2)
717// CHECK-LABEL: define swiftcc { i64, i64 } @return_struct_l2()
718// CHECK-LABEL: define swiftcc void @take_struct_l2(i64, i64)
719
720typedef struct {
721  long long l0;
722  long long l1;
723  long long l2;
724} struct_l3;
725TEST(struct_l3)
726// CHECK: define swiftcc void @return_struct_l3([[STRUCT:%.*]]* noalias sret
727// CHECK: define swiftcc void @take_struct_l3([[STRUCT]]
728
729typedef struct {
730  long long l0;
731  long long l1;
732  long long l2;
733  long long l3;
734} struct_l4;
735TEST(struct_l4)
736// CHECK: define swiftcc void @return_struct_l4([[STRUCT:%.*]]* noalias sret
737// CHECK: define swiftcc void @take_struct_l4([[STRUCT]]
738
739typedef struct {
740  long long l0;
741  long long l1;
742  long long l2;
743  long long l3;
744  long long l4;
745} struct_l5;
746TEST(struct_l5)
747// CHECK: define swiftcc void @return_struct_l5([[STRUCT5:%.*]]* noalias sret
748// CHECK: define swiftcc void @take_struct_l5([[STRUCT5]]*
749
750typedef struct {
751  char16 c0;
752} struct_vc1;
753TEST(struct_vc1)
754// CHECK-LABEL: define swiftcc <16 x i8> @return_struct_vc1()
755// CHECK-LABEL: define swiftcc void @take_struct_vc1(<16 x i8>)
756
757typedef struct {
758  char16 c0;
759  char16 c1;
760} struct_vc2;
761TEST(struct_vc2)
762// CHECK-LABEL: define swiftcc { <16 x i8>, <16 x i8> } @return_struct_vc2()
763// CHECK-LABEL: define swiftcc void @take_struct_vc2(<16 x i8>, <16 x i8>)
764
765typedef struct {
766  char16 c0;
767  char16 c1;
768  char16 c2;
769} struct_vc3;
770TEST(struct_vc3)
771// CHECK-LABEL: define swiftcc { <16 x i8>, <16 x i8>, <16 x i8> } @return_struct_vc3()
772// CHECK-LABEL: define swiftcc void @take_struct_vc3(<16 x i8>, <16 x i8>, <16 x i8>)
773
774typedef struct {
775  char16 c0;
776  char16 c1;
777  char16 c2;
778  char16 c3;
779} struct_vc4;
780TEST(struct_vc4)
781// CHECK-LABEL: define swiftcc { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } @return_struct_vc4()
782// CHECK-LABEL: define swiftcc void @take_struct_vc4(<16 x i8>, <16 x i8>, <16 x i8>, <16 x i8>)
783
784typedef struct {
785  char16 c0;
786  char16 c1;
787  char16 c2;
788  char16 c3;
789  char16 c4;
790} struct_vc5;
791TEST(struct_vc5)
792// CHECK: define swiftcc void @return_struct_vc5([[STRUCT:%.*]]* noalias sret
793// CHECK: define swiftcc void @take_struct_vc5([[STRUCT]]
794
795typedef struct {
796  short8 c0;
797} struct_vs1;
798TEST(struct_vs1)
799// CHECK-LABEL: define swiftcc <8 x i16> @return_struct_vs1()
800// CHECK-LABEL: define swiftcc void @take_struct_vs1(<8 x i16>)
801
802typedef struct {
803  short8 c0;
804  short8 c1;
805} struct_vs2;
806TEST(struct_vs2)
807// CHECK-LABEL: define swiftcc { <8 x i16>, <8 x i16> } @return_struct_vs2()
808// CHECK-LABEL: define swiftcc void @take_struct_vs2(<8 x i16>, <8 x i16>)
809
810typedef struct {
811  short8 c0;
812  short8 c1;
813  short8 c2;
814} struct_vs3;
815TEST(struct_vs3)
816// CHECK-LABEL: define swiftcc { <8 x i16>, <8 x i16>, <8 x i16> } @return_struct_vs3()
817// CHECK-LABEL: define swiftcc void @take_struct_vs3(<8 x i16>, <8 x i16>, <8 x i16>)
818
819typedef struct {
820  short8 c0;
821  short8 c1;
822  short8 c2;
823  short8 c3;
824} struct_vs4;
825TEST(struct_vs4)
826// CHECK-LABEL: define swiftcc { <8 x i16>, <8 x i16>, <8 x i16>, <8 x i16> } @return_struct_vs4()
827// CHECK-LABEL: define swiftcc void @take_struct_vs4(<8 x i16>, <8 x i16>, <8 x i16>, <8 x i16>)
828
829typedef struct {
830  short8 c0;
831  short8 c1;
832  short8 c2;
833  short8 c3;
834  short8 c4;
835} struct_vs5;
836TEST(struct_vs5)
837// CHECK: define swiftcc void @return_struct_vs5([[STRUCT:%.*]]* noalias sret
838// CHECK: define swiftcc void @take_struct_vs5([[STRUCT]]
839
840typedef struct {
841  int4 c0;
842} struct_vi1;
843TEST(struct_vi1)
844// CHECK-LABEL: define swiftcc <4 x i32> @return_struct_vi1()
845// CHECK-LABEL: define swiftcc void @take_struct_vi1(<4 x i32>)
846
847typedef struct {
848  int4 c0;
849  int4 c1;
850} struct_vi2;
851TEST(struct_vi2)
852// CHECK-LABEL: define swiftcc { <4 x i32>, <4 x i32> } @return_struct_vi2()
853// CHECK-LABEL: define swiftcc void @take_struct_vi2(<4 x i32>, <4 x i32>)
854
855typedef struct {
856  int4 c0;
857  int4 c1;
858  int4 c2;
859} struct_vi3;
860TEST(struct_vi3)
861// CHECK-LABEL: define swiftcc { <4 x i32>, <4 x i32>, <4 x i32> } @return_struct_vi3()
862// CHECK-LABEL: define swiftcc void @take_struct_vi3(<4 x i32>, <4 x i32>, <4 x i32>)
863
864typedef struct {
865  int4 c0;
866  int4 c1;
867  int4 c2;
868  int4 c3;
869} struct_vi4;
870TEST(struct_vi4)
871// CHECK-LABEL: define swiftcc { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } @return_struct_vi4()
872// CHECK-LABEL: define swiftcc void @take_struct_vi4(<4 x i32>, <4 x i32>, <4 x i32>, <4 x i32>)
873
874typedef struct {
875  int4 c0;
876  int4 c1;
877  int4 c2;
878  int4 c3;
879  int4 c4;
880} struct_vi5;
881TEST(struct_vi5)
882// CHECK: define swiftcc void @return_struct_vi5([[STRUCT:%.*]]* noalias sret
883// CHECK: define swiftcc void @take_struct_vi5([[STRUCT]]
884
885typedef struct {
886  long2 c0;
887} struct_vl1;
888TEST(struct_vl1)
889// CHECK-LABEL: define swiftcc <2 x i64> @return_struct_vl1()
890// CHECK-LABEL: define swiftcc void @take_struct_vl1(<2 x i64>)
891
892typedef struct {
893  long2 c0;
894  long2 c1;
895  long2 c2;
896  long2 c3;
897} struct_vl4;
898TEST(struct_vl4)
899// CHECK-LABEL: define swiftcc { <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @return_struct_vl4()
900// CHECK-LABEL: define swiftcc void @take_struct_vl4(<2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>)
901
902typedef struct {
903  long2 c0;
904  long2 c1;
905  long2 c2;
906  long2 c3;
907  long2 c4;
908} struct_vl5;
909TEST(struct_vl5)
910// CHECK: define swiftcc void @return_struct_vl5([[STRUCT:%.*]]* noalias sret
911// CHECK: define swiftcc void @take_struct_vl5([[STRUCT]]
912
913typedef struct {
914  double2 c0;
915} struct_vd1;
916TEST(struct_vd1)
917// CHECK-LABEL: define swiftcc <2 x double> @return_struct_vd1()
918// CHECK-LABEL: define swiftcc void @take_struct_vd1(<2 x double>)
919
920typedef struct {
921  double2 c0;
922  double2 c1;
923  double2 c2;
924  double2 c3;
925} struct_vd4;
926TEST(struct_vd4)
927// CHECK-LABEL: define swiftcc { <2 x double>, <2 x double>, <2 x double>, <2 x double> } @return_struct_vd4()
928// CHECK-LABEL: define swiftcc void @take_struct_vd4(<2 x double>, <2 x double>, <2 x double>, <2 x double>)
929
930typedef struct {
931  double2 c0;
932  double2 c1;
933  double2 c2;
934  double2 c3;
935  double2 c4;
936} struct_vd5;
937TEST(struct_vd5)
938// CHECK: define swiftcc void @return_struct_vd5([[STRUCT:%.*]]* noalias sret
939// CHECK: define swiftcc void @take_struct_vd5([[STRUCT]]
940
941typedef struct {
942  double4 c0;
943} struct_vd41;
944TEST(struct_vd41)
945// CHECK-LABEL: define swiftcc { <2 x double>, <2 x double> } @return_struct_vd41()
946// CHECK-LABEL: define swiftcc void @take_struct_vd41(<2 x double>, <2 x double>)
947
948typedef struct {
949  double4 c0;
950  double4 c1;
951} struct_vd42;
952TEST(struct_vd42)
953// CHECK-LABEL: define swiftcc { <2 x double>, <2 x double>, <2 x double>, <2 x double> } @return_struct_vd42()
954// CHECK-LABEL: define swiftcc void @take_struct_vd42(<2 x double>, <2 x double>, <2 x double>, <2 x double>)
955
956typedef struct {
957  double4 c0;
958  double4 c1;
959  double4 c2;
960} struct_vd43;
961TEST(struct_vd43)
962// CHECK: define swiftcc void @return_struct_vd43([[STRUCT:%.*]]* noalias sret
963// CHECK: define swiftcc void @take_struct_vd43([[STRUCT]]
964
965typedef struct {
966  float4 c0;
967} struct_vf1;
968TEST(struct_vf1)
969// CHECK-LABEL: define swiftcc <4 x float> @return_struct_vf1()
970// CHECK-LABEL: define swiftcc void @take_struct_vf1(<4 x float>)
971
972typedef struct {
973  float4 c0;
974  float4 c1;
975} struct_vf2;
976TEST(struct_vf2)
977// CHECK-LABEL: define swiftcc { <4 x float>, <4 x float> } @return_struct_vf2()
978// CHECK-LABEL: define swiftcc void @take_struct_vf2(<4 x float>, <4 x float>)
979
980typedef struct {
981  float4 c0;
982  float4 c1;
983  float4 c2;
984  float4 c3;
985} struct_vf4;
986TEST(struct_vf4)
987// CHECK-LABEL: define swiftcc { <4 x float>, <4 x float>, <4 x float>, <4 x float> } @return_struct_vf4()
988// CHECK-LABEL: define swiftcc void @take_struct_vf4(<4 x float>, <4 x float>, <4 x float>, <4 x float>)
989
990typedef struct {
991  float4 c0;
992  float4 c1;
993  float4 c2;
994  float4 c3;
995  float4 c4;
996} struct_vf5;
997TEST(struct_vf5)
998// CHECK: define swiftcc void @return_struct_vf5([[STRUCT:%.*]]* noalias sret
999// CHECK: define swiftcc void @take_struct_vf5([[STRUCT]]
1000
1001typedef struct {
1002  float8 c0;
1003} struct_vf81;
1004TEST(struct_vf81)
1005// CHECK-LABEL: define swiftcc { <4 x float>, <4 x float> } @return_struct_vf81()
1006// CHECK-LABEL: define swiftcc void @take_struct_vf81(<4 x float>, <4 x float>)
1007
1008typedef struct {
1009  float3 f3;
1010} struct_v1f3;
1011TEST(struct_v1f3)
1012// CHECK-LABEL: define swiftcc { <2 x float>, float } @return_struct_v1f3()
1013// CHECK-LABEL: define swiftcc void @take_struct_v1f3(<2 x float>, float)
1014