1 // RUN: %clang_cc1 -triple arm64-apple-ios7 -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s
2
3 #include <stdarg.h>
4
5 typedef __attribute__(( ext_vector_type(3) )) char __char3;
6 typedef __attribute__(( ext_vector_type(4) )) char __char4;
7 typedef __attribute__(( ext_vector_type(5) )) char __char5;
8 typedef __attribute__(( ext_vector_type(9) )) char __char9;
9 typedef __attribute__(( ext_vector_type(19) )) char __char19;
10 typedef __attribute__(( ext_vector_type(3) )) short __short3;
11 typedef __attribute__(( ext_vector_type(5) )) short __short5;
12 typedef __attribute__(( ext_vector_type(3) )) int __int3;
13 typedef __attribute__(( ext_vector_type(5) )) int __int5;
14 typedef __attribute__(( ext_vector_type(3) )) double __double3;
15
varargs_vec_3c(int fixed,...)16 double varargs_vec_3c(int fixed, ...) {
17 // CHECK: varargs_vec_3c
18 // CHECK: alloca <3 x i8>, align 4
19 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_CUR:%.*]], i64 8
20 // CHECK: bitcast i8* [[AP_CUR]] to <3 x i8>*
21 va_list ap;
22 double sum = fixed;
23 va_start(ap, fixed);
24 __char3 c3 = va_arg(ap, __char3);
25 sum = sum + c3.x + c3.y;
26 va_end(ap);
27 return sum;
28 }
29
test_3c(__char3 * in)30 double test_3c(__char3 *in) {
31 // CHECK: test_3c
32 // CHECK: call double (i32, ...) @varargs_vec_3c(i32 3, i32 {{%.*}})
33 return varargs_vec_3c(3, *in);
34 }
35
varargs_vec_4c(int fixed,...)36 double varargs_vec_4c(int fixed, ...) {
37 // CHECK: varargs_vec_4c
38 // CHECK: alloca <4 x i8>, align 4
39 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_CUR:%.*]], i64 8
40 // CHECK: bitcast i8* [[AP_CUR]] to <4 x i8>*
41 va_list ap;
42 double sum = fixed;
43 va_start(ap, fixed);
44 __char4 c4 = va_arg(ap, __char4);
45 sum = sum + c4.x + c4.y;
46 va_end(ap);
47 return sum;
48 }
49
test_4c(__char4 * in)50 double test_4c(__char4 *in) {
51 // CHECK: test_4c
52 // CHECK: call double (i32, ...) @varargs_vec_4c(i32 4, i32 {{%.*}})
53 return varargs_vec_4c(4, *in);
54 }
55
varargs_vec_5c(int fixed,...)56 double varargs_vec_5c(int fixed, ...) {
57 // CHECK: varargs_vec_5c
58 // CHECK: alloca <5 x i8>, align 8
59 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_CUR:%.*]], i64 8
60 // CHECK: bitcast i8* [[AP_CUR]] to <5 x i8>*
61 va_list ap;
62 double sum = fixed;
63 va_start(ap, fixed);
64 __char5 c5 = va_arg(ap, __char5);
65 sum = sum + c5.x + c5.y;
66 va_end(ap);
67 return sum;
68 }
69
test_5c(__char5 * in)70 double test_5c(__char5 *in) {
71 // CHECK: test_5c
72 // CHECK: call double (i32, ...) @varargs_vec_5c(i32 5, <2 x i32> {{%.*}})
73 return varargs_vec_5c(5, *in);
74 }
75
varargs_vec_9c(int fixed,...)76 double varargs_vec_9c(int fixed, ...) {
77 // CHECK: varargs_vec_9c
78 // CHECK: alloca <9 x i8>, align 16
79 // CHECK: [[ALIGN:%.*]] = and i64 {{%.*}}, -16
80 // CHECK: [[AP_ALIGN:%.*]] = inttoptr i64 [[ALIGN]] to i8*
81 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_ALIGN]], i64 16
82 // CHECK: bitcast i8* [[AP_ALIGN]] to <9 x i8>*
83 va_list ap;
84 double sum = fixed;
85 va_start(ap, fixed);
86 __char9 c9 = va_arg(ap, __char9);
87 sum = sum + c9.x + c9.y;
88 va_end(ap);
89 return sum;
90 }
91
test_9c(__char9 * in)92 double test_9c(__char9 *in) {
93 // CHECK: test_9c
94 // CHECK: call double (i32, ...) @varargs_vec_9c(i32 9, <4 x i32> {{%.*}})
95 return varargs_vec_9c(9, *in);
96 }
97
varargs_vec_19c(int fixed,...)98 double varargs_vec_19c(int fixed, ...) {
99 // CHECK: varargs_vec_19c
100 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_CUR:%.*]], i64 8
101 // CHECK: [[VAR:%.*]] = bitcast i8* [[AP_CUR]] to <19 x i8>**
102 // CHECK: [[VAR2:%.*]] = load <19 x i8>*, <19 x i8>** [[VAR]]
103 va_list ap;
104 double sum = fixed;
105 va_start(ap, fixed);
106 __char19 c19 = va_arg(ap, __char19);
107 sum = sum + c19.x + c19.y;
108 va_end(ap);
109 return sum;
110 }
111
test_19c(__char19 * in)112 double test_19c(__char19 *in) {
113 // CHECK: test_19c
114 // CHECK: call double (i32, ...) @varargs_vec_19c(i32 19, <19 x i8>* {{%.*}})
115 return varargs_vec_19c(19, *in);
116 }
117
varargs_vec_3s(int fixed,...)118 double varargs_vec_3s(int fixed, ...) {
119 // CHECK: varargs_vec_3s
120 // CHECK: alloca <3 x i16>, align 8
121 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_CUR:%.*]], i64 8
122 // CHECK: bitcast i8* [[AP_CUR]] to <3 x i16>*
123 va_list ap;
124 double sum = fixed;
125 va_start(ap, fixed);
126 __short3 c3 = va_arg(ap, __short3);
127 sum = sum + c3.x + c3.y;
128 va_end(ap);
129 return sum;
130 }
131
test_3s(__short3 * in)132 double test_3s(__short3 *in) {
133 // CHECK: test_3s
134 // CHECK: call double (i32, ...) @varargs_vec_3s(i32 3, <2 x i32> {{%.*}})
135 return varargs_vec_3s(3, *in);
136 }
137
varargs_vec_5s(int fixed,...)138 double varargs_vec_5s(int fixed, ...) {
139 // CHECK: varargs_vec_5s
140 // CHECK: alloca <5 x i16>, align 16
141 // CHECK: [[ALIGN:%.*]] = and i64 {{%.*}}, -16
142 // CHECK: [[AP_ALIGN:%.*]] = inttoptr i64 [[ALIGN]] to i8*
143 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_ALIGN]], i64 16
144 // CHECK: bitcast i8* [[AP_ALIGN]] to <5 x i16>*
145 va_list ap;
146 double sum = fixed;
147 va_start(ap, fixed);
148 __short5 c5 = va_arg(ap, __short5);
149 sum = sum + c5.x + c5.y;
150 va_end(ap);
151 return sum;
152 }
153
test_5s(__short5 * in)154 double test_5s(__short5 *in) {
155 // CHECK: test_5s
156 // CHECK: call double (i32, ...) @varargs_vec_5s(i32 5, <4 x i32> {{%.*}})
157 return varargs_vec_5s(5, *in);
158 }
159
varargs_vec_3i(int fixed,...)160 double varargs_vec_3i(int fixed, ...) {
161 // CHECK: varargs_vec_3i
162 // CHECK: alloca <3 x i32>, align 16
163 // CHECK: [[ALIGN:%.*]] = and i64 {{%.*}}, -16
164 // CHECK: [[AP_ALIGN:%.*]] = inttoptr i64 [[ALIGN]] to i8*
165 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_ALIGN]], i64 16
166 // CHECK: bitcast i8* [[AP_ALIGN]] to <3 x i32>*
167 va_list ap;
168 double sum = fixed;
169 va_start(ap, fixed);
170 __int3 c3 = va_arg(ap, __int3);
171 sum = sum + c3.x + c3.y;
172 va_end(ap);
173 return sum;
174 }
175
test_3i(__int3 * in)176 double test_3i(__int3 *in) {
177 // CHECK: test_3i
178 // CHECK: call double (i32, ...) @varargs_vec_3i(i32 3, <4 x i32> {{%.*}})
179 return varargs_vec_3i(3, *in);
180 }
181
varargs_vec_5i(int fixed,...)182 double varargs_vec_5i(int fixed, ...) {
183 // CHECK: varargs_vec_5i
184 // CHECK: alloca <5 x i32>, align 16
185 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_CUR:%.*]], i64 8
186 // CHECK: [[VAR:%.*]] = bitcast i8* [[AP_CUR]] to <5 x i32>**
187 // CHECK: [[VAR2:%.*]] = load <5 x i32>*, <5 x i32>** [[VAR]]
188 va_list ap;
189 double sum = fixed;
190 va_start(ap, fixed);
191 __int5 c5 = va_arg(ap, __int5);
192 sum = sum + c5.x + c5.y;
193 va_end(ap);
194 return sum;
195 }
196
test_5i(__int5 * in)197 double test_5i(__int5 *in) {
198 // CHECK: test_5i
199 // CHECK: call double (i32, ...) @varargs_vec_5i(i32 5, <5 x i32>* {{%.*}})
200 return varargs_vec_5i(5, *in);
201 }
202
varargs_vec_3d(int fixed,...)203 double varargs_vec_3d(int fixed, ...) {
204 // CHECK: varargs_vec_3d
205 // CHECK: alloca <3 x double>, align 16
206 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_CUR:%.*]], i64 8
207 // CHECK: [[VAR:%.*]] = bitcast i8* [[AP_CUR]] to <3 x double>**
208 // CHECK: [[VAR2:%.*]] = load <3 x double>*, <3 x double>** [[VAR]]
209 va_list ap;
210 double sum = fixed;
211 va_start(ap, fixed);
212 __double3 c3 = va_arg(ap, __double3);
213 sum = sum + c3.x + c3.y;
214 va_end(ap);
215 return sum;
216 }
217
test_3d(__double3 * in)218 double test_3d(__double3 *in) {
219 // CHECK: test_3d
220 // CHECK: call double (i32, ...) @varargs_vec_3d(i32 3, <3 x double>* {{%.*}})
221 return varargs_vec_3d(3, *in);
222 }
223
varargs_vec(int fixed,...)224 double varargs_vec(int fixed, ...) {
225 // CHECK: varargs_vec
226 va_list ap;
227 double sum = fixed;
228 va_start(ap, fixed);
229 __char3 c3 = va_arg(ap, __char3);
230 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_CUR:%.*]], i64 8
231 // CHECK: bitcast i8* [[AP_CUR]] to <3 x i8>*
232 sum = sum + c3.x + c3.y;
233 __char5 c5 = va_arg(ap, __char5);
234 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_CUR:%.*]], i64 8
235 // CHECK: bitcast i8* [[AP_CUR]] to <5 x i8>*
236 sum = sum + c5.x + c5.y;
237 __char9 c9 = va_arg(ap, __char9);
238 // CHECK: [[ALIGN:%.*]] = and i64 {{%.*}}, -16
239 // CHECK: [[AP_ALIGN:%.*]] = inttoptr i64 [[ALIGN]] to i8*
240 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_ALIGN]], i64 16
241 // CHECK: bitcast i8* [[AP_ALIGN]] to <9 x i8>*
242 sum = sum + c9.x + c9.y;
243 __char19 c19 = va_arg(ap, __char19);
244 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_CUR:%.*]], i64 8
245 // CHECK: [[VAR:%.*]] = bitcast i8* [[AP_CUR]] to <19 x i8>**
246 // CHECK: [[VAR2:%.*]] = load <19 x i8>*, <19 x i8>** [[VAR]]
247 sum = sum + c19.x + c19.y;
248 __short3 s3 = va_arg(ap, __short3);
249 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_CUR:%.*]], i64 8
250 // CHECK: bitcast i8* [[AP_CUR]] to <3 x i16>*
251 sum = sum + s3.x + s3.y;
252 __short5 s5 = va_arg(ap, __short5);
253 // CHECK: [[ALIGN:%.*]] = and i64 {{%.*}}, -16
254 // CHECK: [[AP_ALIGN:%.*]] = inttoptr i64 [[ALIGN]] to i8*
255 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_ALIGN]], i64 16
256 // CHECK: bitcast i8* [[AP_ALIGN]] to <5 x i16>*
257 sum = sum + s5.x + s5.y;
258 __int3 i3 = va_arg(ap, __int3);
259 // CHECK: [[ALIGN:%.*]] = and i64 {{%.*}}, -16
260 // CHECK: [[AP_ALIGN:%.*]] = inttoptr i64 [[ALIGN]] to i8*
261 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_ALIGN]], i64 16
262 // CHECK: bitcast i8* [[AP_ALIGN]] to <3 x i32>*
263 sum = sum + i3.x + i3.y;
264 __int5 i5 = va_arg(ap, __int5);
265 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_CUR:%.*]], i64 8
266 // CHECK: [[VAR:%.*]] = bitcast i8* [[AP_CUR]] to <5 x i32>**
267 // CHECK: [[VAR2:%.*]] = load <5 x i32>*, <5 x i32>** [[VAR]]
268 sum = sum + i5.x + i5.y;
269 __double3 d3 = va_arg(ap, __double3);
270 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_CUR:%.*]], i64 8
271 // CHECK: [[VAR:%.*]] = bitcast i8* [[AP_CUR]] to <3 x double>**
272 // CHECK: [[VAR2:%.*]] = load <3 x double>*, <3 x double>** [[VAR]]
273 sum = sum + d3.x + d3.y;
274 va_end(ap);
275 return sum;
276 }
277
test(__char3 * c3,__char5 * c5,__char9 * c9,__char19 * c19,__short3 * s3,__short5 * s5,__int3 * i3,__int5 * i5,__double3 * d3)278 double test(__char3 *c3, __char5 *c5, __char9 *c9, __char19 *c19,
279 __short3 *s3, __short5 *s5, __int3 *i3, __int5 *i5,
280 __double3 *d3) {
281 double ret = varargs_vec(3, *c3, *c5, *c9, *c19, *s3, *s5, *i3, *i5, *d3);
282 // CHECK: call double (i32, ...) @varargs_vec(i32 3, i32 {{%.*}}, <2 x i32> {{%.*}}, <4 x i32> {{%.*}}, <19 x i8>* {{%.*}}, <2 x i32> {{%.*}}, <4 x i32> {{%.*}}, <4 x i32> {{%.*}}, <5 x i32>* {{%.*}}, <3 x double>* {{%.*}})
283 return ret;
284 }
285
args_vec_3c(int fixed,__char3 c3)286 __attribute__((noinline)) double args_vec_3c(int fixed, __char3 c3) {
287 // CHECK: args_vec_3c
288 // CHECK: [[C3:%.*]] = alloca <3 x i8>, align 4
289 // CHECK: [[TMP:%.*]] = bitcast <3 x i8>* [[C3]] to i32*
290 // CHECK: store i32 {{%.*}}, i32* [[TMP]]
291 double sum = fixed;
292 sum = sum + c3.x + c3.y;
293 return sum;
294 }
295
fixed_3c(__char3 * in)296 double fixed_3c(__char3 *in) {
297 // CHECK: fixed_3c
298 // CHECK: call double @args_vec_3c(i32 3, i32 {{%.*}})
299 return args_vec_3c(3, *in);
300 }
301
args_vec_5c(int fixed,__char5 c5)302 __attribute__((noinline)) double args_vec_5c(int fixed, __char5 c5) {
303 // CHECK: args_vec_5c
304 // CHECK: [[C5:%.*]] = alloca <5 x i8>, align 8
305 // CHECK: [[TMP:%.*]] = bitcast <5 x i8>* [[C5]] to <2 x i32>*
306 // CHECK: store <2 x i32> {{%.*}}, <2 x i32>* [[TMP]], align 8
307 double sum = fixed;
308 sum = sum + c5.x + c5.y;
309 return sum;
310 }
311
fixed_5c(__char5 * in)312 double fixed_5c(__char5 *in) {
313 // CHECK: fixed_5c
314 // CHECK: call double @args_vec_5c(i32 5, <2 x i32> {{%.*}})
315 return args_vec_5c(5, *in);
316 }
317
args_vec_9c(int fixed,__char9 c9)318 __attribute__((noinline)) double args_vec_9c(int fixed, __char9 c9) {
319 // CHECK: args_vec_9c
320 // CHECK: [[C9:%.*]] = alloca <9 x i8>, align 16
321 // CHECK: [[TMP:%.*]] = bitcast <9 x i8>* [[C9]] to <4 x i32>*
322 // CHECK: store <4 x i32> {{%.*}}, <4 x i32>* [[TMP]], align 16
323 double sum = fixed;
324 sum = sum + c9.x + c9.y;
325 return sum;
326 }
327
fixed_9c(__char9 * in)328 double fixed_9c(__char9 *in) {
329 // CHECK: fixed_9c
330 // CHECK: call double @args_vec_9c(i32 9, <4 x i32> {{%.*}})
331 return args_vec_9c(9, *in);
332 }
333
args_vec_19c(int fixed,__char19 c19)334 __attribute__((noinline)) double args_vec_19c(int fixed, __char19 c19) {
335 // CHECK: args_vec_19c
336 // CHECK: [[C19:%.*]] = load <19 x i8>, <19 x i8>* {{.*}}, align 16
337 double sum = fixed;
338 sum = sum + c19.x + c19.y;
339 return sum;
340 }
341
fixed_19c(__char19 * in)342 double fixed_19c(__char19 *in) {
343 // CHECK: fixed_19c
344 // CHECK: call double @args_vec_19c(i32 19, <19 x i8>* {{%.*}})
345 return args_vec_19c(19, *in);
346 }
347
args_vec_3s(int fixed,__short3 c3)348 __attribute__((noinline)) double args_vec_3s(int fixed, __short3 c3) {
349 // CHECK: args_vec_3s
350 // CHECK: [[C3:%.*]] = alloca <3 x i16>, align 8
351 // CHECK: [[TMP:%.*]] = bitcast <3 x i16>* [[C3]] to <2 x i32>*
352 // CHECK: store <2 x i32> {{%.*}}, <2 x i32>* [[TMP]], align 8
353 double sum = fixed;
354 sum = sum + c3.x + c3.y;
355 return sum;
356 }
357
fixed_3s(__short3 * in)358 double fixed_3s(__short3 *in) {
359 // CHECK: fixed_3s
360 // CHECK: call double @args_vec_3s(i32 3, <2 x i32> {{%.*}})
361 return args_vec_3s(3, *in);
362 }
363
args_vec_5s(int fixed,__short5 c5)364 __attribute__((noinline)) double args_vec_5s(int fixed, __short5 c5) {
365 // CHECK: args_vec_5s
366 // CHECK: [[C5:%.*]] = alloca <5 x i16>, align 16
367 // CHECK: [[TMP:%.*]] = bitcast <5 x i16>* [[C5]] to <4 x i32>*
368 // CHECK: store <4 x i32> {{%.*}}, <4 x i32>* [[TMP]], align 16
369 double sum = fixed;
370 sum = sum + c5.x + c5.y;
371 return sum;
372 }
373
fixed_5s(__short5 * in)374 double fixed_5s(__short5 *in) {
375 // CHECK: fixed_5s
376 // CHECK: call double @args_vec_5s(i32 5, <4 x i32> {{%.*}})
377 return args_vec_5s(5, *in);
378 }
379
args_vec_3i(int fixed,__int3 c3)380 __attribute__((noinline)) double args_vec_3i(int fixed, __int3 c3) {
381 // CHECK: args_vec_3i
382 // CHECK: [[C3:%.*]] = alloca <3 x i32>, align 16
383 // CHECK: [[TMP:%.*]] = bitcast <3 x i32>* [[C3]] to <4 x i32>*
384 // CHECK: store <4 x i32> {{%.*}}, <4 x i32>* [[TMP]], align 16
385 double sum = fixed;
386 sum = sum + c3.x + c3.y;
387 return sum;
388 }
389
fixed_3i(__int3 * in)390 double fixed_3i(__int3 *in) {
391 // CHECK: fixed_3i
392 // CHECK: call double @args_vec_3i(i32 3, <4 x i32> {{%.*}})
393 return args_vec_3i(3, *in);
394 }
395
args_vec_5i(int fixed,__int5 c5)396 __attribute__((noinline)) double args_vec_5i(int fixed, __int5 c5) {
397 // CHECK: args_vec_5i
398 // CHECK: [[C5:%.*]] = load <5 x i32>, <5 x i32>* {{%.*}}, align 16
399 double sum = fixed;
400 sum = sum + c5.x + c5.y;
401 return sum;
402 }
403
fixed_5i(__int5 * in)404 double fixed_5i(__int5 *in) {
405 // CHECK: fixed_5i
406 // CHECK: call double @args_vec_5i(i32 5, <5 x i32>* {{%.*}})
407 return args_vec_5i(5, *in);
408 }
409
args_vec_3d(int fixed,__double3 c3)410 __attribute__((noinline)) double args_vec_3d(int fixed, __double3 c3) {
411 // CHECK: args_vec_3d
412 // CHECK: [[CAST:%.*]] = bitcast <3 x double>* {{%.*}} to <4 x double>*
413 // CHECK: [[LOAD:%.*]] = load <4 x double>, <4 x double>* [[CAST]]
414 // CHECK: shufflevector <4 x double> [[LOAD]], <4 x double> undef, <3 x i32> <i32 0, i32 1, i32 2>
415 double sum = fixed;
416 sum = sum + c3.x + c3.y;
417 return sum;
418 }
419
fixed_3d(__double3 * in)420 double fixed_3d(__double3 *in) {
421 // CHECK: fixed_3d
422 // CHECK: call double @args_vec_3d(i32 3, <3 x double>* {{%.*}})
423 return args_vec_3d(3, *in);
424 }
425