blob: cc736d24a425c54f39c2a26ae4289fd6617c85b2 [file] [log] [blame]
Manman Rend105e732012-10-16 19:01:37 +00001// RUN: %clang_cc1 -triple armv7-apple-darwin -target-abi aapcs -emit-llvm -o - %s | FileCheck %s
2// RUN: %clang_cc1 -triple armv7-apple-darwin -target-abi apcs-gnu -emit-llvm -o - %s | FileCheck -check-prefix=APCS-GNU %s
Manman Ren3f784bf2012-10-16 22:02:26 +00003// XFAIL: *
Manman Rend105e732012-10-16 19:01:37 +00004
5#include <stdarg.h>
6
7typedef __attribute__(( ext_vector_type(2) )) int __int2;
Manman Ren97f81572012-10-16 19:18:39 +00008typedef __attribute__(( ext_vector_type(3) )) char __char3;
9typedef __attribute__(( ext_vector_type(5) )) char __char5;
10typedef __attribute__(( ext_vector_type(9) )) char __char9;
11typedef __attribute__(( ext_vector_type(19) )) char __char19;
12typedef __attribute__(( ext_vector_type(3) )) short __short3;
13typedef __attribute__(( ext_vector_type(5) )) short __short5;
Manman Rend105e732012-10-16 19:01:37 +000014
15// Passing legal vector types as varargs.
16double varargs_vec_2i(int fixed, ...) {
17// CHECK: varargs_vec_2i
18// CHECK: %c3 = alloca <2 x i32>, align 8
19// CHECK: %3 = and i32 %2, -8
20// CHECK: %ap.align = inttoptr i32 %3 to i8*
21// CHECK: %ap.next = getelementptr i8* %ap.align, i32 8
22// CHECK: bitcast i8* %ap.align to <2 x i32>*
23// APCS-GNU: varargs_vec_2i
24// APCS-GNU: %c3 = alloca <2 x i32>, align 8
25// APCS-GNU: %var.align = alloca <2 x i32>
26// APCS-GNU: %ap.next = getelementptr i8* %ap.cur, i32 8
27// APCS-GNU: %1 = bitcast <2 x i32>* %var.align to i8*
28// APCS-GNU: call void @llvm.memcpy
29// APCS-GNU: %2 = load <2 x i32>* %var.align
30 va_list ap;
31 double sum = fixed;
32 va_start(ap, fixed);
33 __int2 c3 = va_arg(ap, __int2);
34 sum = sum + c3.x + c3.y;
35 va_end(ap);
36 return sum;
37}
38
39double test_2i(__int2 *in) {
40// CHECK: test_2i
41// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_2i(i32 3, <2 x i32> %1)
42// APCS-GNU: test_2i
43// APCS-GNU: call double (i32, ...)* @varargs_vec_2i(i32 3, <2 x i32> %1)
44 return varargs_vec_2i(3, *in);
45}
Manman Ren97f81572012-10-16 19:18:39 +000046
47double varargs_vec_3c(int fixed, ...) {
48// CHECK: varargs_vec_3c
49// CHECK: %c3 = alloca <3 x i8>, align 4
50// CHECK: %ap.next = getelementptr i8* %ap.cur, i32 4
51// CHECK: %1 = bitcast i8* %ap.cur to <3 x i8>*
52// APCS-GNU: varargs_vec_3c
53// APCS-GNU: %c3 = alloca <3 x i8>, align 4
54// APCS-GNU: %ap.next = getelementptr i8* %ap.cur, i32 4
55// APCS-GNU: bitcast i8* %ap.cur to <3 x i8>*
56 va_list ap;
57 double sum = fixed;
58 va_start(ap, fixed);
59 __char3 c3 = va_arg(ap, __char3);
60 sum = sum + c3.x + c3.y;
61 va_end(ap);
62 return sum;
63}
64
65double test_3c(__char3 *in) {
66// CHECK: test_3c
67// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_3c(i32 3, i32 %2)
68// APCS-GNU: test_3c
69// APCS-GNU: call double (i32, ...)* @varargs_vec_3c(i32 3, i32 %2)
70 return varargs_vec_3c(3, *in);
71}
72
73double varargs_vec_5c(int fixed, ...) {
74// CHECK: varargs_vec_5c
75// CHECK: %c5 = alloca <5 x i8>, align 8
76// CHECK: %3 = and i32 %2, -8
77// CHECK: %ap.align = inttoptr i32 %3 to i8*
78// CHECK: %ap.next = getelementptr i8* %ap.align, i32 8
79// CHECK: bitcast i8* %ap.align to <5 x i8>*
80// APCS-GNU: varargs_vec_5c
81// APCS-GNU: %c5 = alloca <5 x i8>, align 8
82// APCS-GNU: %var.align = alloca <5 x i8>
83// APCS-GNU: %ap.next = getelementptr i8* %ap.cur, i32 8
84// APCS-GNU: %1 = bitcast <5 x i8>* %var.align to i8*
85// APCS-GNU: call void @llvm.memcpy
86// APCS-GNU: %2 = load <5 x i8>* %var.align
87 va_list ap;
88 double sum = fixed;
89 va_start(ap, fixed);
90 __char5 c5 = va_arg(ap, __char5);
91 sum = sum + c5.x + c5.y;
92 va_end(ap);
93 return sum;
94}
95
96double test_5c(__char5 *in) {
97// CHECK: test_5c
98// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_5c(i32 5, <2 x i32> %3)
99// APCS-GNU: test_5c
100// APCS-GNU: call double (i32, ...)* @varargs_vec_5c(i32 5, <2 x i32> %3)
101 return varargs_vec_5c(5, *in);
102}
103
104double varargs_vec_9c(int fixed, ...) {
105// CHECK: varargs_vec_9c
106// CHECK: %c9 = alloca <9 x i8>, align 16
107// CHECK: %var.align = alloca <9 x i8>
108// CHECK: %3 = and i32 %2, -8
109// CHECK: %ap.align = inttoptr i32 %3 to i8*
110// CHECK: %ap.next = getelementptr i8* %ap.align, i32 16
111// CHECK: %4 = bitcast <9 x i8>* %var.align to i8*
112// CHECK: call void @llvm.memcpy
113// CHECK: %5 = load <9 x i8>* %var.align
114// APCS-GNU: varargs_vec_9c
115// APCS-GNU: %c9 = alloca <9 x i8>, align 16
116// APCS-GNU: %var.align = alloca <9 x i8>
117// APCS-GNU: %ap.next = getelementptr i8* %ap.cur, i32 16
118// APCS-GNU: %1 = bitcast <9 x i8>* %var.align to i8*
119// APCS-GNU: call void @llvm.memcpy
120// APCS-GNU: %2 = load <9 x i8>* %var.align
121 va_list ap;
122 double sum = fixed;
123 va_start(ap, fixed);
124 __char9 c9 = va_arg(ap, __char9);
125 sum = sum + c9.x + c9.y;
126 va_end(ap);
127 return sum;
128}
129
130double test_9c(__char9 *in) {
131// CHECK: test_9c
132// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_9c(i32 9, <4 x i32> %3)
133// APCS-GNU: test_9c
134// APCS-GNU: call double (i32, ...)* @varargs_vec_9c(i32 9, <4 x i32> %3)
135 return varargs_vec_9c(9, *in);
136}
137
138double varargs_vec_19c(int fixed, ...) {
139// CHECK: varargs_vec_19c
140// CHECK: %ap.next = getelementptr i8* %ap.cur, i32 4
141// CHECK: %1 = bitcast i8* %ap.cur to i8**
142// CHECK: %2 = load i8** %1
143// CHECK: bitcast i8* %2 to <19 x i8>*
144// APCS-GNU: varargs_vec_19c
145// APCS-GNU: %ap.next = getelementptr i8* %ap.cur, i32 4
146// APCS-GNU: %1 = bitcast i8* %ap.cur to i8**
147// APCS-GNU: %2 = load i8** %1
148// APCS-GNU: bitcast i8* %2 to <19 x i8>*
149 va_list ap;
150 double sum = fixed;
151 va_start(ap, fixed);
152 __char19 c19 = va_arg(ap, __char19);
153 sum = sum + c19.x + c19.y;
154 va_end(ap);
155 return sum;
156}
157
158double test_19c(__char19 *in) {
159// CHECK: test_19c
160// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_19c(i32 19, <19 x i8>* %tmp)
161// APCS-GNU: test_19c
162// APCS-GNU: call double (i32, ...)* @varargs_vec_19c(i32 19, <19 x i8>* %tmp)
163 return varargs_vec_19c(19, *in);
164}
165
166double varargs_vec_3s(int fixed, ...) {
167// CHECK: varargs_vec_3s
168// CHECK: %c3 = alloca <3 x i16>, align 8
169// CHECK: %3 = and i32 %2, -8
170// CHECK: %ap.align = inttoptr i32 %3 to i8*
171// CHECK: %ap.next = getelementptr i8* %ap.align, i32 8
172// CHECK: bitcast i8* %ap.align to <3 x i16>*
173// APCS-GNU: varargs_vec_3s
174// APCS-GNU: %c3 = alloca <3 x i16>, align 8
175// APCS-GNU: %var.align = alloca <3 x i16>
176// APCS-GNU: %ap.next = getelementptr i8* %ap.cur, i32 8
177// APCS-GNU: %1 = bitcast <3 x i16>* %var.align to i8*
178// APCS-GNU: call void @llvm.memcpy
179// APCS-GNU: %2 = load <3 x i16>* %var.align
180 va_list ap;
181 double sum = fixed;
182 va_start(ap, fixed);
183 __short3 c3 = va_arg(ap, __short3);
184 sum = sum + c3.x + c3.y;
185 va_end(ap);
186 return sum;
187}
188
189double test_3s(__short3 *in) {
190// CHECK: test_3s
191// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_3s(i32 3, <2 x i32> %2)
192// APCS-GNU: test_3s
193// APCS-GNU: call double (i32, ...)* @varargs_vec_3s(i32 3, <2 x i32> %2)
194 return varargs_vec_3s(3, *in);
195}
196
197double varargs_vec_5s(int fixed, ...) {
198// CHECK: varargs_vec_5s
199// CHECK: %c5 = alloca <5 x i16>, align 16
200// CHECK: %var.align = alloca <5 x i16>
201// CHECK: %3 = and i32 %2, -8
202// CHECK: %ap.align = inttoptr i32 %3 to i8*
203// CHECK: %ap.next = getelementptr i8* %ap.align, i32 16
204// CHECK: %4 = bitcast <5 x i16>* %var.align to i8*
205// CHECK: call void @llvm.memcpy
206// CHECK: %5 = load <5 x i16>* %var.align
207// APCS-GNU: varargs_vec_5s
208// APCS-GNU: %c5 = alloca <5 x i16>, align 16
209// APCS-GNU: %var.align = alloca <5 x i16>
210// APCS-GNU: %ap.next = getelementptr i8* %ap.cur, i32 16
211// APCS-GNU: %1 = bitcast <5 x i16>* %var.align to i8*
212// APCS-GNU: call void @llvm.memcpy
213// APCS-GNU: %2 = load <5 x i16>* %var.align
214 va_list ap;
215 double sum = fixed;
216 va_start(ap, fixed);
217 __short5 c5 = va_arg(ap, __short5);
218 sum = sum + c5.x + c5.y;
219 va_end(ap);
220 return sum;
221}
222
223double test_5s(__short5 *in) {
224// CHECK: test_5s
225// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_5s(i32 5, <4 x i32> %3)
226// APCS-GNU: test_5s
227// APCS-GNU: call double (i32, ...)* @varargs_vec_5s(i32 5, <4 x i32> %3)
228 return varargs_vec_5s(5, *in);
229}
Manman Ren93371022012-10-16 19:51:48 +0000230
231// Pass struct as varargs.
232typedef struct
233{
234 __int2 i2;
235 float f;
236} StructWithVec;
237
238double varargs_struct(int fixed, ...) {
239// CHECK: varargs_struct
240// CHECK: %3 = and i32 %2, -8
241// CHECK: %ap.align = inttoptr i32 %3 to i8*
242// CHECK: %ap.next = getelementptr i8* %ap.align, i32 16
243// CHECK: bitcast i8* %ap.align to %struct.StructWithVec*
244// APCS-GNU: varargs_struct
245// APCS-GNU: %var.align = alloca %struct.StructWithVec
246// APCS-GNU: %ap.next = getelementptr i8* %ap.cur, i32 16
247// APCS-GNU: %1 = bitcast %struct.StructWithVec* %var.align to i8*
248// APCS-GNU: call void @llvm.memcpy
249 va_list ap;
250 double sum = fixed;
251 va_start(ap, fixed);
252 StructWithVec c3 = va_arg(ap, StructWithVec);
253 sum = sum + c3.i2.x + c3.i2.y + c3.f;
254 va_end(ap);
255 return sum;
256}
257
258double test_struct(StructWithVec* d) {
259// CHECK: test_struct
260// CHECK: call arm_aapcscc double (i32, ...)* @varargs_struct(i32 3, [2 x i64] %3)
261// APCS-GNU: test_struct
262// APCS-GNU: call double (i32, ...)* @varargs_struct(i32 3, [2 x i64] %3)
263 return varargs_struct(3, *d);
264}