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