1920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// RUN: %clang_cc1 -triple armv7-apple-darwin -target-abi aapcs -emit-llvm -o - %s | FileCheck %s
2920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// RUN: %clang_cc1 -triple armv7-apple-darwin -target-abi apcs-gnu -emit-llvm -o - %s | FileCheck -check-prefix=APCS-GNU %s
3920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
4920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson#include <stdarg.h>
5920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
6920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsontypedef __attribute__(( ext_vector_type(2) ))  int __int2;
7920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsontypedef __attribute__(( ext_vector_type(3) ))  char __char3;
8920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsontypedef __attribute__(( ext_vector_type(5) ))  char __char5;
9920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsontypedef __attribute__(( ext_vector_type(9) ))  char __char9;
10920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsontypedef __attribute__(( ext_vector_type(19) )) char __char19;
11920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsontypedef __attribute__(( ext_vector_type(3) ))  short __short3;
12920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsontypedef __attribute__(( ext_vector_type(5) ))  short __short5;
13920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
14920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// Passing legal vector types as varargs.
15920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsondouble varargs_vec_2i(int fixed, ...) {
16920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: varargs_vec_2i
17920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: alloca <2 x i32>, align 8
18920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: [[ALIGN:%.*]] = and i32 [[VAR:%.*]], -8
19920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to i8*
20920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_ALIGN]], i32 8
21920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: bitcast i8* [[AP_ALIGN]] to <2 x i32>*
22920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: varargs_vec_2i
23920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: alloca <2 x i32>, align 8
24920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: [[VAR_ALIGN:%.*]] = alloca <2 x i32>
25920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr i8* {{%.*}}, i32 8
26920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: bitcast <2 x i32>* [[VAR_ALIGN]] to i8*
27920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: call void @llvm.memcpy
28920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: load <2 x i32>* [[VAR_ALIGN]]
29920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  va_list ap;
30920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  double sum = fixed;
31920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  va_start(ap, fixed);
32920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  __int2 c3 = va_arg(ap, __int2);
33920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  sum = sum + c3.x + c3.y;
34920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  va_end(ap);
35920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  return sum;
36920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson}
37920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
38920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsondouble test_2i(__int2 *in) {
39920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: test_2i
40920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_2i(i32 3, <2 x i32> {{%.*}})
41920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: test_2i
42920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: call double (i32, ...)* @varargs_vec_2i(i32 3, <2 x i32> {{%.*}})
43920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  return varargs_vec_2i(3, *in);
44920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson}
45920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
46920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsondouble varargs_vec_3c(int fixed, ...) {
47920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: varargs_vec_3c
48920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: alloca <3 x i8>, align 4
49920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP:%.*]], i32 4
50920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: bitcast i8* [[AP]] to <3 x i8>*
51920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: varargs_vec_3c
52920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: alloca <3 x i8>, align 4
53920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr i8* [[AP:%.*]], i32 4
54920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: bitcast i8* [[AP]] to <3 x i8>*
55920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  va_list ap;
56920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  double sum = fixed;
57920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  va_start(ap, fixed);
58920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  __char3 c3 = va_arg(ap, __char3);
59920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  sum = sum + c3.x + c3.y;
60920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  va_end(ap);
61920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  return sum;
62920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson}
63920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
64920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsondouble test_3c(__char3 *in) {
65920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: test_3c
66920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_3c(i32 3, i32 {{%.*}})
67920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: test_3c
68920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: call double (i32, ...)* @varargs_vec_3c(i32 3, i32 {{%.*}})
69920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  return varargs_vec_3c(3, *in);
70920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson}
71920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
72920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsondouble varargs_vec_5c(int fixed, ...) {
73920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: varargs_vec_5c
74920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: alloca <5 x i8>, align 8
75920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
76920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to i8*
77920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_ALIGN]], i32 8
78920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: bitcast i8* [[AP_ALIGN]] to <5 x i8>*
79920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: varargs_vec_5c
80920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: alloca <5 x i8>, align 8
81920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: [[VAR_ALIGN:%.*]] = alloca <5 x i8>
82920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr i8* {{%.*}}, i32 8
83920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: bitcast <5 x i8>* [[VAR_ALIGN]] to i8*
84920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: call void @llvm.memcpy
85920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: load <5 x i8>* [[VAR_ALIGN]]
86920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  va_list ap;
87920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  double sum = fixed;
88920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  va_start(ap, fixed);
89920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  __char5 c5 = va_arg(ap, __char5);
90920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  sum = sum + c5.x + c5.y;
91920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  va_end(ap);
92920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  return sum;
93920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson}
94920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
95920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsondouble test_5c(__char5 *in) {
96920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: test_5c
97920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_5c(i32 5, <2 x i32> {{%.*}})
98920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: test_5c
99920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: call double (i32, ...)* @varargs_vec_5c(i32 5, <2 x i32> {{%.*}})
100920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  return varargs_vec_5c(5, *in);
101920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson}
102920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
103920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsondouble varargs_vec_9c(int fixed, ...) {
104920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: varargs_vec_9c
105920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: alloca <9 x i8>, align 16
106920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: [[VAR_ALIGN:%.*]] = alloca <9 x i8>
107920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
108920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to i8*
109920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_ALIGN]], i32 16
110920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: bitcast <9 x i8>* [[VAR_ALIGN]] to i8*
111920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: call void @llvm.memcpy
112920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: load <9 x i8>* [[VAR_ALIGN]]
113920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: varargs_vec_9c
114920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: alloca <9 x i8>, align 16
115920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: [[VAR_ALIGN:%.*]] = alloca <9 x i8>
116920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr i8* {{%.*}}, i32 16
117920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: bitcast <9 x i8>* [[VAR_ALIGN]] to i8*
118920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: call void @llvm.memcpy
119920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: load <9 x i8>* [[VAR_ALIGN]]
120920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  va_list ap;
121920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  double sum = fixed;
122920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  va_start(ap, fixed);
123920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  __char9 c9 = va_arg(ap, __char9);
124920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  sum = sum + c9.x + c9.y;
125920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  va_end(ap);
126920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  return sum;
127920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson}
128920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
129920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsondouble test_9c(__char9 *in) {
130920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: test_9c
131920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: call arm_aapcscc double (i32, ...)* @varargs_vec_9c(i32 9, <4 x i32> {{%.*}})
132920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: test_9c
133920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// APCS-GNU: call double (i32, ...)* @varargs_vec_9c(i32 9, <4 x i32> {{%.*}})
134920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  return varargs_vec_9c(9, *in);
135920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson}
136920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
137920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsondouble varargs_vec_19c(int fixed, ...) {
138920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: varargs_vec_19c
139920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP:%.*]], i32 4
140920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: [[VAR:%.*]] = bitcast i8* [[AP]] to i8**
141920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson// CHECK: [[VAR2:%.*]] = load i8** [[VAR]]
142// CHECK: bitcast i8* [[VAR2]] to <19 x i8>*
143// APCS-GNU: varargs_vec_19c
144// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr i8* [[AP:%.*]], i32 4
145// APCS-GNU: [[VAR:%.*]] = bitcast i8* [[AP]] to i8**
146// APCS-GNU: [[VAR2:%.*]] = load i8** [[VAR]]
147// APCS-GNU: bitcast i8* [[VAR2]] 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>* {{%.*}})
160// APCS-GNU: test_19c
161// APCS-GNU: call double (i32, ...)* @varargs_vec_19c(i32 19, <19 x i8>* {{%.*}})
162  return varargs_vec_19c(19, *in);
163}
164
165double varargs_vec_3s(int fixed, ...) {
166// CHECK: varargs_vec_3s
167// CHECK: alloca <3 x i16>, align 8
168// CHECK: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
169// CHECK: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] 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: alloca <3 x i16>, align 8
174// APCS-GNU: [[VAR_ALIGN:%.*]] = alloca <3 x i16>
175// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr i8* {{%.*}}, i32 8
176// APCS-GNU: bitcast <3 x i16>* [[VAR_ALIGN]] to i8*
177// APCS-GNU: call void @llvm.memcpy
178// APCS-GNU: 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> {{%.*}})
191// APCS-GNU: test_3s
192// APCS-GNU: call double (i32, ...)* @varargs_vec_3s(i32 3, <2 x i32> {{%.*}})
193  return varargs_vec_3s(3, *in);
194}
195
196double varargs_vec_5s(int fixed, ...) {
197// CHECK: varargs_vec_5s
198// CHECK: alloca <5 x i16>, align 16
199// CHECK: [[VAR_ALIGN:%.*]] = alloca <5 x i16>
200// CHECK: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
201// CHECK: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to i8*
202// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_ALIGN]], i32 16
203// CHECK: bitcast <5 x i16>* [[VAR_ALIGN]] to i8*
204// CHECK: call void @llvm.memcpy
205// CHECK: load <5 x i16>* [[VAR_ALIGN]]
206// APCS-GNU: varargs_vec_5s
207// APCS-GNU: alloca <5 x i16>, align 16
208// APCS-GNU: [[VAR_ALIGN:%.*]] = alloca <5 x i16>
209// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr i8* {{%.*}}, i32 16
210// APCS-GNU: bitcast <5 x i16>* [[VAR_ALIGN]] to i8*
211// APCS-GNU: call void @llvm.memcpy
212// APCS-GNU: 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> {{%.*}})
225// APCS-GNU: test_5s
226// APCS-GNU: call double (i32, ...)* @varargs_vec_5s(i32 5, <4 x i32> {{%.*}})
227  return varargs_vec_5s(5, *in);
228}
229
230// Pass struct as varargs.
231typedef struct
232{
233  __int2 i2;
234  float f;
235} StructWithVec;
236
237double varargs_struct(int fixed, ...) {
238// CHECK: varargs_struct
239// CHECK: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
240// CHECK: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to i8*
241// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_ALIGN]], i32 16
242// CHECK: bitcast i8* [[AP_ALIGN]] to %struct.StructWithVec*
243// APCS-GNU: varargs_struct
244// APCS-GNU: [[VAR_ALIGN:%.*]] = alloca %struct.StructWithVec
245// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr i8* {{%.*}}, i32 16
246// APCS-GNU: bitcast %struct.StructWithVec* [[VAR_ALIGN]] to i8*
247// APCS-GNU: call void @llvm.memcpy
248  va_list ap;
249  double sum = fixed;
250  va_start(ap, fixed);
251  StructWithVec c3 = va_arg(ap, StructWithVec);
252  sum = sum + c3.i2.x + c3.i2.y + c3.f;
253  va_end(ap);
254  return sum;
255}
256
257double test_struct(StructWithVec* d) {
258// CHECK: test_struct
259// CHECK: call arm_aapcscc double (i32, ...)* @varargs_struct(i32 3, [2 x i64] {{%.*}})
260// APCS-GNU: test_struct
261// APCS-GNU: call double (i32, ...)* @varargs_struct(i32 3, [2 x i64] {{%.*}})
262  return varargs_struct(3, *d);
263}
264