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