Revert "[llvm] Improve llvm.objectsize computation by computing GEP, alloca and mallo...
[llvm-project.git] / clang / test / CodeGen / arm-abi-vector.c
blobc2a8902007980b7ed5fcc6fad5c9a467b55028c9
1 // 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
3 // RUN: %clang_cc1 -triple arm-linux-androideabi -emit-llvm -o - %s | FileCheck -check-prefix=ANDROID %s
5 #include <stdarg.h>
7 typedef __attribute__(( ext_vector_type(2) )) int __int2;
8 typedef __attribute__(( ext_vector_type(3) )) char __char3;
9 typedef __attribute__(( ext_vector_type(5) )) char __char5;
10 typedef __attribute__(( ext_vector_type(9) )) char __char9;
11 typedef __attribute__(( ext_vector_type(19) )) char __char19;
12 typedef __attribute__(( ext_vector_type(3) )) short __short3;
13 typedef __attribute__(( ext_vector_type(5) )) short __short5;
15 // Passing legal vector types as varargs.
16 double varargs_vec_2i(int fixed, ...) {
17 // CHECK: varargs_vec_2i
18 // CHECK: [[VAR:%.*]] = alloca <2 x i32>, align 8
19 // CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
20 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 8
21 // CHECK: [[VEC:%.*]] = load <2 x i32>, ptr [[AP_ALIGN]], align 8
22 // CHECK: store <2 x i32> [[VEC]], ptr [[VAR]], align 8
23 // APCS-GNU: varargs_vec_2i
24 // APCS-GNU: [[VAR:%.*]] = alloca <2 x i32>, align 8
25 // APCS-GNU: [[AP:%.*]] = load ptr,
26 // APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP]], i32 8
27 // APCS-GNU: [[VEC:%.*]] = load <2 x i32>, ptr [[AP]], align 4
28 // APCS-GNU: store <2 x i32> [[VEC]], ptr [[VAR]], align 8
29 // ANDROID: varargs_vec_2i
30 // ANDROID: [[VAR:%.*]] = alloca <2 x i32>, align 8
31 // ANDROID: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
32 // ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 8
33 // ANDROID: [[VEC:%.*]] = load <2 x i32>, ptr [[AP_ALIGN]], align 8
34 // ANDROID: store <2 x i32> [[VEC]], ptr [[VAR]], align 8
35 va_list ap;
36 double sum = fixed;
37 va_start(ap, fixed);
38 __int2 c3 = va_arg(ap, __int2);
39 sum = sum + c3.x + c3.y;
40 va_end(ap);
41 return sum;
44 double test_2i(__int2 *in) {
45 // CHECK: test_2i
46 // CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_2i(i32 noundef 3, <2 x i32> noundef {{%.*}})
47 // APCS-GNU: test_2i
48 // APCS-GNU: call double (i32, ...) @varargs_vec_2i(i32 noundef 3, <2 x i32> noundef {{%.*}})
49 // ANDROID: test_2i
50 // ANDROID: call double (i32, ...) @varargs_vec_2i(i32 noundef 3, <2 x i32> noundef {{%.*}})
51 return varargs_vec_2i(3, *in);
54 double varargs_vec_3c(int fixed, ...) {
55 // CHECK: varargs_vec_3c
56 // CHECK: alloca <3 x i8>, align 4
57 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP:%.*]], i32 4
58 // APCS-GNU: varargs_vec_3c
59 // APCS-GNU: alloca <3 x i8>, align 4
60 // APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP:%.*]], i32 4
61 // ANDROID: varargs_vec_3c
62 // ANDROID: alloca <3 x i8>, align 4
63 // ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP:%.*]], i32 4
64 va_list ap;
65 double sum = fixed;
66 va_start(ap, fixed);
67 __char3 c3 = va_arg(ap, __char3);
68 sum = sum + c3.x + c3.y;
69 va_end(ap);
70 return sum;
73 double test_3c(__char3 *in) {
74 // CHECK: test_3c
75 // CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_3c(i32 noundef 3, i32 {{%.*}})
76 // APCS-GNU: test_3c
77 // APCS-GNU: call double (i32, ...) @varargs_vec_3c(i32 noundef 3, i32 {{%.*}})
78 // ANDROID: test_3c
79 // ANDROID: call double (i32, ...) @varargs_vec_3c(i32 noundef 3, <3 x i8> noundef {{%.*}})
80 return varargs_vec_3c(3, *in);
83 double varargs_vec_5c(int fixed, ...) {
84 // CHECK: varargs_vec_5c
85 // CHECK: [[VAR:%.*]] = alloca <5 x i8>, align 8
86 // CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
87 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 8
88 // CHECK: [[VEC:%.*]] = load <5 x i8>, ptr [[AP_ALIGN]], align 8
89 // CHECK: store <5 x i8> [[VEC]], ptr [[VAR]], align 8
90 // APCS-GNU: varargs_vec_5c
91 // APCS-GNU: [[VAR:%.*]] = alloca <5 x i8>, align 8
92 // APCS-GNU: [[AP:%.*]] = load ptr,
93 // APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP]], i32 8
94 // APCS-GNU: [[VEC:%.*]] = load <5 x i8>, ptr [[AP]], align 4
95 // APCS-GNU: store <5 x i8> [[VEC]], ptr [[VAR]], align 8
96 // ANDROID: varargs_vec_5c
97 // ANDROID: [[VAR:%.*]] = alloca <5 x i8>, align 8
98 // ANDROID: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
99 // ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 8
100 // ANDROID: [[VEC:%.*]] = load <5 x i8>, ptr [[AP_ALIGN]], align 8
101 // ANDROID: store <5 x i8> [[VEC]], ptr [[VAR]], align 8
102 va_list ap;
103 double sum = fixed;
104 va_start(ap, fixed);
105 __char5 c5 = va_arg(ap, __char5);
106 sum = sum + c5.x + c5.y;
107 va_end(ap);
108 return sum;
111 double test_5c(__char5 *in) {
112 // CHECK: test_5c
113 // CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_5c(i32 noundef 5, <2 x i32> {{%.*}})
114 // APCS-GNU: test_5c
115 // APCS-GNU: call double (i32, ...) @varargs_vec_5c(i32 noundef 5, <2 x i32> {{%.*}})
116 // ANDROID: test_5c
117 // ANDROID: call double (i32, ...) @varargs_vec_5c(i32 noundef 5, <2 x i32> {{%.*}})
118 return varargs_vec_5c(5, *in);
121 double varargs_vec_9c(int fixed, ...) {
122 // CHECK: varargs_vec_9c
123 // CHECK: [[VAR:%.*]] = alloca <9 x i8>, align 16
124 // CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
125 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 16
126 // CHECK: [[T0:%.*]] = load <9 x i8>, ptr [[AP_ALIGN]], align 8
127 // CHECK: store <9 x i8> [[T0]], ptr [[VAR]], align 16
128 // APCS-GNU: varargs_vec_9c
129 // APCS-GNU: [[VAR:%.*]] = alloca <9 x i8>, align 16
130 // APCS-GNU: [[AP:%.*]] = load ptr,
131 // APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP]], i32 16
132 // APCS-GNU: [[VEC:%.*]] = load <9 x i8>, ptr [[AP]], align 4
133 // APCS-GNU: store <9 x i8> [[VEC]], ptr [[VAR]], align 16
134 // ANDROID: varargs_vec_9c
135 // ANDROID: [[VAR:%.*]] = alloca <9 x i8>, align 16
136 // ANDROID: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
137 // ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 16
138 // ANDROID: [[T0:%.*]] = load <9 x i8>, ptr [[AP_ALIGN]], align 8
139 // ANDROID: store <9 x i8> [[T0]], ptr [[VAR]], align 16
140 va_list ap;
141 double sum = fixed;
142 va_start(ap, fixed);
143 __char9 c9 = va_arg(ap, __char9);
144 sum = sum + c9.x + c9.y;
145 va_end(ap);
146 return sum;
149 double test_9c(__char9 *in) {
150 // CHECK: test_9c
151 // CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_9c(i32 noundef 9, <4 x i32> {{%.*}})
152 // APCS-GNU: test_9c
153 // APCS-GNU: call double (i32, ...) @varargs_vec_9c(i32 noundef 9, <4 x i32> {{%.*}})
154 // ANDROID: test_9c
155 // ANDROID: call double (i32, ...) @varargs_vec_9c(i32 noundef 9, <4 x i32> {{%.*}})
156 return varargs_vec_9c(9, *in);
159 double varargs_vec_19c(int fixed, ...) {
160 // CHECK: varargs_vec_19c
161 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP:%.*]], i32 4
162 // CHECK: [[VAR2:%.*]] = load ptr, ptr [[AP]]
163 // APCS-GNU: varargs_vec_19c
164 // APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP:%.*]], i32 4
165 // APCS-GNU: [[VAR2:%.*]] = load ptr, ptr [[AP]]
166 // ANDROID: varargs_vec_19c
167 // ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP:%.*]], i32 4
168 // ANDROID: [[VAR2:%.*]] = load ptr, ptr [[AP]]
169 va_list ap;
170 double sum = fixed;
171 va_start(ap, fixed);
172 __char19 c19 = va_arg(ap, __char19);
173 sum = sum + c19.x + c19.y;
174 va_end(ap);
175 return sum;
178 double test_19c(__char19 *in) {
179 // CHECK: test_19c
180 // CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_19c(i32 noundef 19, ptr noundef {{%.*}})
181 // APCS-GNU: test_19c
182 // APCS-GNU: call double (i32, ...) @varargs_vec_19c(i32 noundef 19, ptr noundef {{%.*}})
183 // ANDROID: test_19c
184 // ANDROID: call double (i32, ...) @varargs_vec_19c(i32 noundef 19, ptr noundef {{%.*}})
185 return varargs_vec_19c(19, *in);
188 double varargs_vec_3s(int fixed, ...) {
189 // CHECK: varargs_vec_3s
190 // CHECK: alloca <3 x i16>, align 8
191 // CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
192 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 8
193 // APCS-GNU: varargs_vec_3s
194 // APCS-GNU: [[VAR:%.*]] = alloca <3 x i16>, align 8
195 // APCS-GNU: [[AP:%.*]] = load ptr,
196 // APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP]], i32 8
197 // APCS-GNU: [[VEC:%.*]] = load <4 x i16>, ptr [[AP]], align 4
198 // ANDROID: varargs_vec_3s
199 // ANDROID: alloca <3 x i16>, align 8
200 // ANDROID: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
201 // ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 8
202 va_list ap;
203 double sum = fixed;
204 va_start(ap, fixed);
205 __short3 c3 = va_arg(ap, __short3);
206 sum = sum + c3.x + c3.y;
207 va_end(ap);
208 return sum;
211 double test_3s(__short3 *in) {
212 // CHECK: test_3s
213 // CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_3s(i32 noundef 3, <2 x i32> {{%.*}})
214 // APCS-GNU: test_3s
215 // APCS-GNU: call double (i32, ...) @varargs_vec_3s(i32 noundef 3, <2 x i32> {{%.*}})
216 // ANDROID: test_3s
217 // ANDROID: call double (i32, ...) @varargs_vec_3s(i32 noundef 3, <3 x i16> noundef {{%.*}})
218 return varargs_vec_3s(3, *in);
221 double varargs_vec_5s(int fixed, ...) {
222 // CHECK: varargs_vec_5s
223 // CHECK: [[VAR_ALIGN:%.*]] = alloca <5 x i16>, align 16
224 // CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
225 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 16
226 // CHECK: [[VEC:%.*]] = load <5 x i16>, ptr [[AP_ALIGN]], align 8
227 // CHECK: store <5 x i16> [[VEC]], ptr [[VAR_ALIGN]], align 16
228 // APCS-GNU: varargs_vec_5s
229 // APCS-GNU: [[VAR:%.*]] = alloca <5 x i16>, align 16
230 // APCS-GNU: [[AP:%.*]] = load ptr,
231 // APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP]], i32 16
232 // APCS-GNU: [[VEC:%.*]] = load <5 x i16>, ptr [[AP]], align 4
233 // ANDROID: varargs_vec_5s
234 // ANDROID: [[VAR_ALIGN:%.*]] = alloca <5 x i16>, align 16
235 // ANDROID: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
236 // ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 16
237 // ANDROID: [[VEC:%.*]] = load <5 x i16>, ptr [[AP_ALIGN]], align 8
238 // ANDROID: store <5 x i16> [[VEC]], ptr [[VAR_ALIGN]], align 16
239 va_list ap;
240 double sum = fixed;
241 va_start(ap, fixed);
242 __short5 c5 = va_arg(ap, __short5);
243 sum = sum + c5.x + c5.y;
244 va_end(ap);
245 return sum;
248 double test_5s(__short5 *in) {
249 // CHECK: test_5s
250 // CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_5s(i32 noundef 5, <4 x i32> {{%.*}})
251 // APCS-GNU: test_5s
252 // APCS-GNU: call double (i32, ...) @varargs_vec_5s(i32 noundef 5, <4 x i32> {{%.*}})
253 // ANDROID: test_5s
254 // ANDROID: call double (i32, ...) @varargs_vec_5s(i32 noundef 5, <4 x i32> {{%.*}})
255 return varargs_vec_5s(5, *in);
258 // Pass struct as varargs.
259 typedef struct
261 __int2 i2;
262 float f;
263 } StructWithVec;
265 double varargs_struct(int fixed, ...) {
266 // CHECK: varargs_struct
267 // CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
268 // CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 16
269 // APCS-GNU: varargs_struct
270 // APCS-GNU: [[VAR_ALIGN:%.*]] = alloca %struct.StructWithVec
271 // APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr {{%.*}}, i32 16
272 // APCS-GNU: call void @llvm.memcpy
273 // ANDROID: varargs_struct
274 // ANDROID: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
275 // ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 16
276 va_list ap;
277 double sum = fixed;
278 va_start(ap, fixed);
279 StructWithVec c3 = va_arg(ap, StructWithVec);
280 sum = sum + c3.i2.x + c3.i2.y + c3.f;
281 va_end(ap);
282 return sum;
285 double test_struct(StructWithVec* d) {
286 // CHECK: test_struct
287 // CHECK: call arm_aapcscc double (i32, ...) @varargs_struct(i32 noundef 3, [2 x i64] {{%.*}})
288 // APCS-GNU: test_struct
289 // APCS-GNU: call double (i32, ...) @varargs_struct(i32 noundef 3, [2 x i64] {{%.*}})
290 // ANDROID: test_struct
291 // ANDROID: call double (i32, ...) @varargs_struct(i32 noundef 3, [2 x i64] {{%.*}})
292 return varargs_struct(3, *d);