blob: 296359d8ea2cee306130c5b9c5c83a4e6333cf86 [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
3
4#include <stdarg.h>
5
6typedef __attribute__(( ext_vector_type(2) )) int __int2;
Manman Ren97f81572012-10-16 19:18:39 +00007typedef __attribute__(( ext_vector_type(3) )) char __char3;
8typedef __attribute__(( ext_vector_type(5) )) char __char5;
9typedef __attribute__(( ext_vector_type(9) )) char __char9;
10typedef __attribute__(( ext_vector_type(19) )) char __char19;
11typedef __attribute__(( ext_vector_type(3) )) short __short3;
12typedef __attribute__(( ext_vector_type(5) )) short __short5;
Manman Rend105e732012-10-16 19:01:37 +000013
14// Passing legal vector types as varargs.
15double varargs_vec_2i(int fixed, ...) {
16// CHECK: varargs_vec_2i
17// CHECK: %c3 = alloca <2 x i32>, align 8
18// CHECK: %3 = and i32 %2, -8
19// CHECK: %ap.align = inttoptr i32 %3 to i8*
20// CHECK: %ap.next = getelementptr i8* %ap.align, i32 8
21// CHECK: bitcast i8* %ap.align to <2 x i32>*
22// APCS-GNU: varargs_vec_2i
23// APCS-GNU: %c3 = alloca <2 x i32>, align 8
24// APCS-GNU: %var.align = alloca <2 x i32>
25// APCS-GNU: %ap.next = getelementptr i8* %ap.cur, i32 8
26// APCS-GNU: %1 = bitcast <2 x i32>* %var.align to i8*
27// APCS-GNU: call void @llvm.memcpy
28// APCS-GNU: %2 = load <2 x i32>* %var.align
29 va_list ap;
30 double sum = fixed;
31 va_start(ap, fixed);
32 __int2 c3 = va_arg(ap, __int2);
33 sum = sum + c3.x + c3.y;
34 va_end(ap);
35 return sum;
36}
37
38double test_2i(__int2 *in) {
39// CHECK: test_2i
40// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_2i(i32 3, <2 x i32> %1)
41// APCS-GNU: test_2i
42// APCS-GNU: call double (i32, ...)* @varargs_vec_2i(i32 3, <2 x i32> %1)
43 return varargs_vec_2i(3, *in);
44}
Manman Ren97f81572012-10-16 19:18:39 +000045
46double varargs_vec_3c(int fixed, ...) {
47// CHECK: varargs_vec_3c
48// CHECK: %c3 = alloca <3 x i8>, align 4
49// CHECK: %ap.next = getelementptr i8* %ap.cur, i32 4
50// CHECK: %1 = bitcast i8* %ap.cur to <3 x i8>*
51// APCS-GNU: varargs_vec_3c
52// APCS-GNU: %c3 = alloca <3 x i8>, align 4
53// APCS-GNU: %ap.next = getelementptr i8* %ap.cur, i32 4
54// APCS-GNU: bitcast i8* %ap.cur to <3 x i8>*
55 va_list ap;
56 double sum = fixed;
57 va_start(ap, fixed);
58 __char3 c3 = va_arg(ap, __char3);
59 sum = sum + c3.x + c3.y;
60 va_end(ap);
61 return sum;
62}
63
64double test_3c(__char3 *in) {
65// CHECK: test_3c
66// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_3c(i32 3, i32 %2)
67// APCS-GNU: test_3c
68// APCS-GNU: call double (i32, ...)* @varargs_vec_3c(i32 3, i32 %2)
69 return varargs_vec_3c(3, *in);
70}
71
72double varargs_vec_5c(int fixed, ...) {
73// CHECK: varargs_vec_5c
74// CHECK: %c5 = alloca <5 x i8>, align 8
75// CHECK: %3 = and i32 %2, -8
76// CHECK: %ap.align = inttoptr i32 %3 to i8*
77// CHECK: %ap.next = getelementptr i8* %ap.align, i32 8
78// CHECK: bitcast i8* %ap.align to <5 x i8>*
79// APCS-GNU: varargs_vec_5c
80// APCS-GNU: %c5 = alloca <5 x i8>, align 8
81// APCS-GNU: %var.align = alloca <5 x i8>
82// APCS-GNU: %ap.next = getelementptr i8* %ap.cur, i32 8
83// APCS-GNU: %1 = bitcast <5 x i8>* %var.align to i8*
84// APCS-GNU: call void @llvm.memcpy
85// APCS-GNU: %2 = load <5 x i8>* %var.align
86 va_list ap;
87 double sum = fixed;
88 va_start(ap, fixed);
89 __char5 c5 = va_arg(ap, __char5);
90 sum = sum + c5.x + c5.y;
91 va_end(ap);
92 return sum;
93}
94
95double test_5c(__char5 *in) {
96// CHECK: test_5c
97// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_5c(i32 5, <2 x i32> %3)
98// APCS-GNU: test_5c
99// APCS-GNU: call double (i32, ...)* @varargs_vec_5c(i32 5, <2 x i32> %3)
100 return varargs_vec_5c(5, *in);
101}
102
103double varargs_vec_9c(int fixed, ...) {
104// CHECK: varargs_vec_9c
105// CHECK: %c9 = alloca <9 x i8>, align 16
106// CHECK: %var.align = alloca <9 x i8>
107// CHECK: %3 = and i32 %2, -8
108// CHECK: %ap.align = inttoptr i32 %3 to i8*
109// CHECK: %ap.next = getelementptr i8* %ap.align, i32 16
110// CHECK: %4 = bitcast <9 x i8>* %var.align to i8*
111// CHECK: call void @llvm.memcpy
112// CHECK: %5 = load <9 x i8>* %var.align
113// APCS-GNU: varargs_vec_9c
114// APCS-GNU: %c9 = alloca <9 x i8>, align 16
115// APCS-GNU: %var.align = alloca <9 x i8>
116// APCS-GNU: %ap.next = getelementptr i8* %ap.cur, i32 16
117// APCS-GNU: %1 = bitcast <9 x i8>* %var.align to i8*
118// APCS-GNU: call void @llvm.memcpy
119// APCS-GNU: %2 = load <9 x i8>* %var.align
120 va_list ap;
121 double sum = fixed;
122 va_start(ap, fixed);
123 __char9 c9 = va_arg(ap, __char9);
124 sum = sum + c9.x + c9.y;
125 va_end(ap);
126 return sum;
127}
128
129double test_9c(__char9 *in) {
130// CHECK: test_9c
131// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_9c(i32 9, <4 x i32> %3)
132// APCS-GNU: test_9c
133// APCS-GNU: call double (i32, ...)* @varargs_vec_9c(i32 9, <4 x i32> %3)
134 return varargs_vec_9c(9, *in);
135}
136
137double varargs_vec_19c(int fixed, ...) {
138// CHECK: varargs_vec_19c
139// CHECK: %ap.next = getelementptr i8* %ap.cur, i32 4
140// CHECK: %1 = bitcast i8* %ap.cur to i8**
141// CHECK: %2 = load i8** %1
142// CHECK: bitcast i8* %2 to <19 x i8>*
143// APCS-GNU: varargs_vec_19c
144// APCS-GNU: %ap.next = getelementptr i8* %ap.cur, i32 4
145// APCS-GNU: %1 = bitcast i8* %ap.cur to i8**
146// APCS-GNU: %2 = load i8** %1
147// APCS-GNU: bitcast i8* %2 to <19 x i8>*
148 va_list ap;
149 double sum = fixed;
150 va_start(ap, fixed);
151 __char19 c19 = va_arg(ap, __char19);
152 sum = sum + c19.x + c19.y;
153 va_end(ap);
154 return sum;
155}
156
157double test_19c(__char19 *in) {
158// CHECK: test_19c
159// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_19c(i32 19, <19 x i8>* %tmp)
160// APCS-GNU: test_19c
161// APCS-GNU: call double (i32, ...)* @varargs_vec_19c(i32 19, <19 x i8>* %tmp)
162 return varargs_vec_19c(19, *in);
163}
164
165double varargs_vec_3s(int fixed, ...) {
166// CHECK: varargs_vec_3s
167// CHECK: %c3 = alloca <3 x i16>, align 8
168// CHECK: %3 = and i32 %2, -8
169// CHECK: %ap.align = inttoptr i32 %3 to i8*
170// CHECK: %ap.next = getelementptr i8* %ap.align, i32 8
171// CHECK: bitcast i8* %ap.align to <3 x i16>*
172// APCS-GNU: varargs_vec_3s
173// APCS-GNU: %c3 = alloca <3 x i16>, align 8
174// APCS-GNU: %var.align = alloca <3 x i16>
175// APCS-GNU: %ap.next = getelementptr i8* %ap.cur, i32 8
176// APCS-GNU: %1 = bitcast <3 x i16>* %var.align to i8*
177// APCS-GNU: call void @llvm.memcpy
178// APCS-GNU: %2 = load <3 x i16>* %var.align
179 va_list ap;
180 double sum = fixed;
181 va_start(ap, fixed);
182 __short3 c3 = va_arg(ap, __short3);
183 sum = sum + c3.x + c3.y;
184 va_end(ap);
185 return sum;
186}
187
188double test_3s(__short3 *in) {
189// CHECK: test_3s
190// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_3s(i32 3, <2 x i32> %2)
191// APCS-GNU: test_3s
192// APCS-GNU: call double (i32, ...)* @varargs_vec_3s(i32 3, <2 x i32> %2)
193 return varargs_vec_3s(3, *in);
194}
195
196double varargs_vec_5s(int fixed, ...) {
197// CHECK: varargs_vec_5s
198// CHECK: %c5 = alloca <5 x i16>, align 16
199// CHECK: %var.align = alloca <5 x i16>
200// CHECK: %3 = and i32 %2, -8
201// CHECK: %ap.align = inttoptr i32 %3 to i8*
202// CHECK: %ap.next = getelementptr i8* %ap.align, i32 16
203// CHECK: %4 = bitcast <5 x i16>* %var.align to i8*
204// CHECK: call void @llvm.memcpy
205// CHECK: %5 = load <5 x i16>* %var.align
206// APCS-GNU: varargs_vec_5s
207// APCS-GNU: %c5 = alloca <5 x i16>, align 16
208// APCS-GNU: %var.align = alloca <5 x i16>
209// APCS-GNU: %ap.next = getelementptr i8* %ap.cur, i32 16
210// APCS-GNU: %1 = bitcast <5 x i16>* %var.align to i8*
211// APCS-GNU: call void @llvm.memcpy
212// APCS-GNU: %2 = load <5 x i16>* %var.align
213 va_list ap;
214 double sum = fixed;
215 va_start(ap, fixed);
216 __short5 c5 = va_arg(ap, __short5);
217 sum = sum + c5.x + c5.y;
218 va_end(ap);
219 return sum;
220}
221
222double test_5s(__short5 *in) {
223// CHECK: test_5s
224// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_5s(i32 5, <4 x i32> %3)
225// APCS-GNU: test_5s
226// APCS-GNU: call double (i32, ...)* @varargs_vec_5s(i32 5, <4 x i32> %3)
227 return varargs_vec_5s(5, *in);
228}