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