xref: /minix3/external/bsd/llvm/dist/clang/test/CodeGen/aarch64-varargs.c (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -triple aarch64 -emit-llvm -o - %s | FileCheck %s
2*f4a2713aSLionel Sambuc #include <stdarg.h>
3*f4a2713aSLionel Sambuc 
4*f4a2713aSLionel Sambuc // Obviously there's more than one way to implement va_arg. This test should at
5*f4a2713aSLionel Sambuc // least prevent unintentional regressions caused by refactoring.
6*f4a2713aSLionel Sambuc 
7*f4a2713aSLionel Sambuc va_list the_list;
8*f4a2713aSLionel Sambuc 
9*f4a2713aSLionel Sambuc int simple_int(void) {
10*f4a2713aSLionel Sambuc // CHECK-LABEL: define i32 @simple_int
11*f4a2713aSLionel Sambuc   return va_arg(the_list, int);
12*f4a2713aSLionel Sambuc // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 3)
13*f4a2713aSLionel Sambuc // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
14*f4a2713aSLionel Sambuc // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
15*f4a2713aSLionel Sambuc 
16*f4a2713aSLionel Sambuc // CHECK: [[VAARG_MAYBE_REG]]
17*f4a2713aSLionel Sambuc // CHECK: [[NEW_REG_OFFS:%[a-z_0-9]+]] = add i32 [[GR_OFFS]], 8
18*f4a2713aSLionel Sambuc // CHECK: store i32 [[NEW_REG_OFFS]], i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 3)
19*f4a2713aSLionel Sambuc // CHECK: [[INREG:%[a-z_0-9]+]] = icmp sle i32 [[NEW_REG_OFFS]], 0
20*f4a2713aSLionel Sambuc // CHECK: br i1 [[INREG]], label %[[VAARG_IN_REG:[a-z_.0-9]+]], label %[[VAARG_ON_STACK]]
21*f4a2713aSLionel Sambuc 
22*f4a2713aSLionel Sambuc // CHECK: [[VAARG_IN_REG]]
23*f4a2713aSLionel Sambuc // CHECK: [[REG_TOP:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 1)
24*f4a2713aSLionel Sambuc // CHECK: [[REG_ADDR:%[a-z_0-9]+]] = getelementptr i8* [[REG_TOP]], i32 [[GR_OFFS]]
25*f4a2713aSLionel Sambuc // CHECK: [[FROMREG_ADDR:%[a-z_0-9]+]] = bitcast i8* [[REG_ADDR]] to i32*
26*f4a2713aSLionel Sambuc // CHECK: br label %[[VAARG_END:[a-z._0-9]+]]
27*f4a2713aSLionel Sambuc 
28*f4a2713aSLionel Sambuc // CHECK: [[VAARG_ON_STACK]]
29*f4a2713aSLionel Sambuc // CHECK: [[STACK:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
30*f4a2713aSLionel Sambuc // CHECK: [[NEW_STACK:%[a-z_0-9]+]] = getelementptr i8* [[STACK]], i32 8
31*f4a2713aSLionel Sambuc // CHECK: store i8* [[NEW_STACK]], i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
32*f4a2713aSLionel Sambuc // CHECK: [[FROMSTACK_ADDR:%[a-z_0-9]+]] = bitcast i8* [[STACK]] to i32*
33*f4a2713aSLionel Sambuc // CHECK: br label %[[VAARG_END]]
34*f4a2713aSLionel Sambuc 
35*f4a2713aSLionel Sambuc // CHECK: [[VAARG_END]]
36*f4a2713aSLionel Sambuc // CHECK: [[ADDR:%[a-z._0-9]+]] = phi i32* [ [[FROMREG_ADDR]], %[[VAARG_IN_REG]] ], [ [[FROMSTACK_ADDR]], %[[VAARG_ON_STACK]] ]
37*f4a2713aSLionel Sambuc // CHECK: [[RESULT:%[a-z_0-9]+]] = load i32* [[ADDR]]
38*f4a2713aSLionel Sambuc // CHECK: ret i32 [[RESULT]]
39*f4a2713aSLionel Sambuc }
40*f4a2713aSLionel Sambuc 
41*f4a2713aSLionel Sambuc __int128 aligned_int(void) {
42*f4a2713aSLionel Sambuc // CHECK-LABEL: define i128 @aligned_int
43*f4a2713aSLionel Sambuc   return va_arg(the_list, __int128);
44*f4a2713aSLionel Sambuc // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 3)
45*f4a2713aSLionel Sambuc // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
46*f4a2713aSLionel Sambuc // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
47*f4a2713aSLionel Sambuc 
48*f4a2713aSLionel Sambuc // CHECK: [[VAARG_MAYBE_REG]]
49*f4a2713aSLionel Sambuc // CHECK: [[ALIGN_REGOFFS:%[a-z_0-9]+]] = add i32 [[GR_OFFS]], 15
50*f4a2713aSLionel Sambuc // CHECK: [[ALIGNED_REGOFFS:%[a-z_0-9]+]] = and i32 [[ALIGN_REGOFFS]], -16
51*f4a2713aSLionel Sambuc // CHECK: [[NEW_REG_OFFS:%[a-z_0-9]+]] = add i32 [[ALIGNED_REGOFFS]], 16
52*f4a2713aSLionel Sambuc // CHECK: store i32 [[NEW_REG_OFFS]], i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 3)
53*f4a2713aSLionel Sambuc // CHECK: [[INREG:%[a-z_0-9]+]] = icmp sle i32 [[NEW_REG_OFFS]], 0
54*f4a2713aSLionel Sambuc // CHECK: br i1 [[INREG]], label %[[VAARG_IN_REG:[a-z_.0-9]+]], label %[[VAARG_ON_STACK]]
55*f4a2713aSLionel Sambuc 
56*f4a2713aSLionel Sambuc // CHECK: [[VAARG_IN_REG]]
57*f4a2713aSLionel Sambuc // CHECK: [[REG_TOP:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 1)
58*f4a2713aSLionel Sambuc // CHECK: [[REG_ADDR:%[a-z_0-9]+]] = getelementptr i8* [[REG_TOP]], i32 [[ALIGNED_REGOFFS]]
59*f4a2713aSLionel Sambuc // CHECK: [[FROMREG_ADDR:%[a-z_0-9]+]] = bitcast i8* [[REG_ADDR]] to i128*
60*f4a2713aSLionel Sambuc // CHECK: br label %[[VAARG_END:[a-z._0-9]+]]
61*f4a2713aSLionel Sambuc 
62*f4a2713aSLionel Sambuc // CHECK: [[VAARG_ON_STACK]]
63*f4a2713aSLionel Sambuc // CHECK: [[STACK:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
64*f4a2713aSLionel Sambuc // CHECK: [[STACKINT:%[a-z_0-9]+]] = ptrtoint i8* [[STACK]] to i64
65*f4a2713aSLionel Sambuc // CHECK: [[ALIGN_STACK:%[a-z_0-9]+]] = add i64 [[STACKINT]], 15
66*f4a2713aSLionel Sambuc // CHECK: [[ALIGNED_STACK_INT:%[a-z_0-9]+]] = and i64 [[ALIGN_STACK]], -16
67*f4a2713aSLionel Sambuc // CHECK: [[ALIGNED_STACK_PTR:%[a-z_0-9]+]] = inttoptr i64 [[ALIGNED_STACK_INT]] to i8*
68*f4a2713aSLionel Sambuc // CHECK: [[NEW_STACK:%[a-z_0-9]+]] = getelementptr i8* [[ALIGNED_STACK_PTR]], i32 16
69*f4a2713aSLionel Sambuc // CHECK: store i8* [[NEW_STACK]], i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
70*f4a2713aSLionel Sambuc // CHECK: [[FROMSTACK_ADDR:%[a-z_0-9]+]] = bitcast i8* [[ALIGNED_STACK_PTR]] to i128*
71*f4a2713aSLionel Sambuc // CHECK: br label %[[VAARG_END]]
72*f4a2713aSLionel Sambuc 
73*f4a2713aSLionel Sambuc // CHECK: [[VAARG_END]]
74*f4a2713aSLionel Sambuc // CHECK: [[ADDR:%[a-z._0-9]+]] = phi i128* [ [[FROMREG_ADDR]], %[[VAARG_IN_REG]] ], [ [[FROMSTACK_ADDR]], %[[VAARG_ON_STACK]] ]
75*f4a2713aSLionel Sambuc // CHECK: [[RESULT:%[a-z_0-9]+]] = load i128* [[ADDR]]
76*f4a2713aSLionel Sambuc // CHECK: ret i128 [[RESULT]]
77*f4a2713aSLionel Sambuc }
78*f4a2713aSLionel Sambuc 
79*f4a2713aSLionel Sambuc struct bigstruct {
80*f4a2713aSLionel Sambuc   int a[10];
81*f4a2713aSLionel Sambuc };
82*f4a2713aSLionel Sambuc 
83*f4a2713aSLionel Sambuc struct bigstruct simple_indirect(void) {
84*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @simple_indirect
85*f4a2713aSLionel Sambuc   return va_arg(the_list, struct bigstruct);
86*f4a2713aSLionel Sambuc // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 3)
87*f4a2713aSLionel Sambuc // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
88*f4a2713aSLionel Sambuc // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
89*f4a2713aSLionel Sambuc 
90*f4a2713aSLionel Sambuc // CHECK: [[VAARG_MAYBE_REG]]
91*f4a2713aSLionel Sambuc // CHECK-NOT: and i32
92*f4a2713aSLionel Sambuc // CHECK: [[NEW_REG_OFFS:%[a-z_0-9]+]] = add i32 [[GR_OFFS]], 8
93*f4a2713aSLionel Sambuc // CHECK: store i32 [[NEW_REG_OFFS]], i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 3)
94*f4a2713aSLionel Sambuc // CHECK: [[INREG:%[a-z_0-9]+]] = icmp sle i32 [[NEW_REG_OFFS]], 0
95*f4a2713aSLionel Sambuc // CHECK: br i1 [[INREG]], label %[[VAARG_IN_REG:[a-z_.0-9]+]], label %[[VAARG_ON_STACK]]
96*f4a2713aSLionel Sambuc 
97*f4a2713aSLionel Sambuc // CHECK: [[VAARG_IN_REG]]
98*f4a2713aSLionel Sambuc // CHECK: [[REG_TOP:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 1)
99*f4a2713aSLionel Sambuc // CHECK: [[REG_ADDR:%[a-z_0-9]+]] = getelementptr i8* [[REG_TOP]], i32 [[GR_OFFS]]
100*f4a2713aSLionel Sambuc // CHECK: [[FROMREG_ADDR:%[a-z_0-9]+]] = bitcast i8* [[REG_ADDR]] to %struct.bigstruct**
101*f4a2713aSLionel Sambuc // CHECK: br label %[[VAARG_END:[a-z._0-9]+]]
102*f4a2713aSLionel Sambuc 
103*f4a2713aSLionel Sambuc // CHECK: [[VAARG_ON_STACK]]
104*f4a2713aSLionel Sambuc // CHECK: [[STACK:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
105*f4a2713aSLionel Sambuc // CHECK-NOT: and i64
106*f4a2713aSLionel Sambuc // CHECK: [[NEW_STACK:%[a-z_0-9]+]] = getelementptr i8* [[STACK]], i32 8
107*f4a2713aSLionel Sambuc // CHECK: store i8* [[NEW_STACK]], i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
108*f4a2713aSLionel Sambuc // CHECK: [[FROMSTACK_ADDR:%[a-z_0-9]+]] = bitcast i8* [[STACK]] to %struct.bigstruct**
109*f4a2713aSLionel Sambuc // CHECK: br label %[[VAARG_END]]
110*f4a2713aSLionel Sambuc 
111*f4a2713aSLionel Sambuc // CHECK: [[VAARG_END]]
112*f4a2713aSLionel Sambuc // CHECK: [[ADDR:%[a-z._0-9]+]] = phi %struct.bigstruct** [ [[FROMREG_ADDR]], %[[VAARG_IN_REG]] ], [ [[FROMSTACK_ADDR]], %[[VAARG_ON_STACK]] ]
113*f4a2713aSLionel Sambuc // CHECK: load %struct.bigstruct** [[ADDR]]
114*f4a2713aSLionel Sambuc }
115*f4a2713aSLionel Sambuc 
116*f4a2713aSLionel Sambuc struct aligned_bigstruct {
117*f4a2713aSLionel Sambuc   float a;
118*f4a2713aSLionel Sambuc   long double b;
119*f4a2713aSLionel Sambuc };
120*f4a2713aSLionel Sambuc 
121*f4a2713aSLionel Sambuc struct aligned_bigstruct simple_aligned_indirect(void) {
122*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @simple_aligned_indirect
123*f4a2713aSLionel Sambuc   return va_arg(the_list, struct aligned_bigstruct);
124*f4a2713aSLionel Sambuc // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 3)
125*f4a2713aSLionel Sambuc // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
126*f4a2713aSLionel Sambuc // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
127*f4a2713aSLionel Sambuc 
128*f4a2713aSLionel Sambuc // CHECK: [[VAARG_MAYBE_REG]]
129*f4a2713aSLionel Sambuc // CHECK: [[NEW_REG_OFFS:%[a-z_0-9]+]] = add i32 [[GR_OFFS]], 8
130*f4a2713aSLionel Sambuc // CHECK: store i32 [[NEW_REG_OFFS]], i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 3)
131*f4a2713aSLionel Sambuc // CHECK: [[INREG:%[a-z_0-9]+]] = icmp sle i32 [[NEW_REG_OFFS]], 0
132*f4a2713aSLionel Sambuc // CHECK: br i1 [[INREG]], label %[[VAARG_IN_REG:[a-z_.0-9]+]], label %[[VAARG_ON_STACK]]
133*f4a2713aSLionel Sambuc 
134*f4a2713aSLionel Sambuc // CHECK: [[VAARG_IN_REG]]
135*f4a2713aSLionel Sambuc // CHECK: [[REG_TOP:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 1)
136*f4a2713aSLionel Sambuc // CHECK: [[REG_ADDR:%[a-z_0-9]+]] = getelementptr i8* [[REG_TOP]], i32 [[GR_OFFS]]
137*f4a2713aSLionel Sambuc // CHECK: [[FROMREG_ADDR:%[a-z_0-9]+]] = bitcast i8* [[REG_ADDR]] to %struct.aligned_bigstruct**
138*f4a2713aSLionel Sambuc // CHECK: br label %[[VAARG_END:[a-z._0-9]+]]
139*f4a2713aSLionel Sambuc 
140*f4a2713aSLionel Sambuc // CHECK: [[VAARG_ON_STACK]]
141*f4a2713aSLionel Sambuc // CHECK: [[STACK:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
142*f4a2713aSLionel Sambuc // CHECK: [[NEW_STACK:%[a-z_0-9]+]] = getelementptr i8* [[STACK]], i32 8
143*f4a2713aSLionel Sambuc // CHECK: store i8* [[NEW_STACK]], i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
144*f4a2713aSLionel Sambuc // CHECK: [[FROMSTACK_ADDR:%[a-z_0-9]+]] = bitcast i8* [[STACK]] to %struct.aligned_bigstruct**
145*f4a2713aSLionel Sambuc // CHECK: br label %[[VAARG_END]]
146*f4a2713aSLionel Sambuc 
147*f4a2713aSLionel Sambuc // CHECK: [[VAARG_END]]
148*f4a2713aSLionel Sambuc // CHECK: [[ADDR:%[a-z._0-9]+]] = phi %struct.aligned_bigstruct** [ [[FROMREG_ADDR]], %[[VAARG_IN_REG]] ], [ [[FROMSTACK_ADDR]], %[[VAARG_ON_STACK]] ]
149*f4a2713aSLionel Sambuc // CHECK: load %struct.aligned_bigstruct** [[ADDR]]
150*f4a2713aSLionel Sambuc }
151*f4a2713aSLionel Sambuc 
152*f4a2713aSLionel Sambuc double simple_double(void) {
153*f4a2713aSLionel Sambuc // CHECK-LABEL: define double @simple_double
154*f4a2713aSLionel Sambuc   return va_arg(the_list, double);
155*f4a2713aSLionel Sambuc // CHECK: [[VR_OFFS:%[a-z_0-9]+]] = load i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 4)
156*f4a2713aSLionel Sambuc // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[VR_OFFS]], 0
157*f4a2713aSLionel Sambuc // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK]], label %[[VAARG_MAYBE_REG]]
158*f4a2713aSLionel Sambuc 
159*f4a2713aSLionel Sambuc // CHECK: [[VAARG_MAYBE_REG]]
160*f4a2713aSLionel Sambuc // CHECK: [[NEW_REG_OFFS:%[a-z_0-9]+]] = add i32 [[VR_OFFS]], 16
161*f4a2713aSLionel Sambuc // CHECK: store i32 [[NEW_REG_OFFS]], i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 4)
162*f4a2713aSLionel Sambuc // CHECK: [[INREG:%[a-z_0-9]+]] = icmp sle i32 [[NEW_REG_OFFS]], 0
163*f4a2713aSLionel Sambuc // CHECK: br i1 [[INREG]], label %[[VAARG_IN_REG:[a-z_.0-9]+]], label %[[VAARG_ON_STACK]]
164*f4a2713aSLionel Sambuc 
165*f4a2713aSLionel Sambuc // CHECK: [[VAARG_IN_REG]]
166*f4a2713aSLionel Sambuc // CHECK: [[REG_TOP:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 2)
167*f4a2713aSLionel Sambuc // CHECK: [[REG_ADDR:%[a-z_0-9]+]] = getelementptr i8* [[REG_TOP]], i32 [[VR_OFFS]]
168*f4a2713aSLionel Sambuc // CHECK: [[FROMREG_ADDR:%[a-z_0-9]+]] = bitcast i8* [[REG_ADDR]] to double*
169*f4a2713aSLionel Sambuc // CHECK: br label %[[VAARG_END]]
170*f4a2713aSLionel Sambuc 
171*f4a2713aSLionel Sambuc // CHECK: [[VAARG_ON_STACK]]
172*f4a2713aSLionel Sambuc // CHECK: [[STACK:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
173*f4a2713aSLionel Sambuc // CHECK: [[NEW_STACK:%[a-z_0-9]+]] = getelementptr i8* [[STACK]], i32 8
174*f4a2713aSLionel Sambuc // CHECK: store i8* [[NEW_STACK]], i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
175*f4a2713aSLionel Sambuc // CHECK: [[FROMSTACK_ADDR:%[a-z_0-9]+]] = bitcast i8* [[STACK]] to double*
176*f4a2713aSLionel Sambuc // CHECK: br label %[[VAARG_END]]
177*f4a2713aSLionel Sambuc 
178*f4a2713aSLionel Sambuc // CHECK: [[VAARG_END]]
179*f4a2713aSLionel Sambuc // CHECK: [[ADDR:%[a-z._0-9]+]] = phi double* [ [[FROMREG_ADDR]], %[[VAARG_IN_REG]] ], [ [[FROMSTACK_ADDR]], %[[VAARG_ON_STACK]] ]
180*f4a2713aSLionel Sambuc // CHECK: [[RESULT:%[a-z_0-9]+]] = load double* [[ADDR]]
181*f4a2713aSLionel Sambuc // CHECK: ret double [[RESULT]]
182*f4a2713aSLionel Sambuc }
183*f4a2713aSLionel Sambuc 
184*f4a2713aSLionel Sambuc struct hfa {
185*f4a2713aSLionel Sambuc   float a, b;
186*f4a2713aSLionel Sambuc };
187*f4a2713aSLionel Sambuc 
188*f4a2713aSLionel Sambuc struct hfa simple_hfa(void) {
189*f4a2713aSLionel Sambuc // CHECK-LABEL: define %struct.hfa @simple_hfa
190*f4a2713aSLionel Sambuc   return va_arg(the_list, struct hfa);
191*f4a2713aSLionel Sambuc // CHECK: [[VR_OFFS:%[a-z_0-9]+]] = load i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 4)
192*f4a2713aSLionel Sambuc // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[VR_OFFS]], 0
193*f4a2713aSLionel Sambuc // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
194*f4a2713aSLionel Sambuc 
195*f4a2713aSLionel Sambuc // CHECK: [[VAARG_MAYBE_REG]]
196*f4a2713aSLionel Sambuc // CHECK: [[NEW_REG_OFFS:%[a-z_0-9]+]] = add i32 [[VR_OFFS]], 32
197*f4a2713aSLionel Sambuc // CHECK: store i32 [[NEW_REG_OFFS]], i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 4)
198*f4a2713aSLionel Sambuc // CHECK: [[INREG:%[a-z_0-9]+]] = icmp sle i32 [[NEW_REG_OFFS]], 0
199*f4a2713aSLionel Sambuc // CHECK: br i1 [[INREG]], label %[[VAARG_IN_REG:[a-z_.0-9]+]], label %[[VAARG_ON_STACK]]
200*f4a2713aSLionel Sambuc 
201*f4a2713aSLionel Sambuc // CHECK: [[VAARG_IN_REG]]
202*f4a2713aSLionel Sambuc // CHECK: [[REG_TOP:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 2)
203*f4a2713aSLionel Sambuc // CHECK: [[FIRST_REG:%[a-z_0-9]+]] = getelementptr i8* [[REG_TOP]], i32 [[VR_OFFS]]
204*f4a2713aSLionel Sambuc // CHECK: [[EL_ADDR:%[a-z_0-9]+]] = getelementptr i8* [[FIRST_REG]], i32 0
205*f4a2713aSLionel Sambuc // CHECK: [[EL_TYPED:%[a-z_0-9]+]] = bitcast i8* [[EL_ADDR]] to float*
206*f4a2713aSLionel Sambuc // CHECK: [[EL_TMPADDR:%[a-z_0-9]+]] = getelementptr inbounds [2 x float]* %[[TMP_HFA:[a-z_.0-9]+]], i32 0, i32 0
207*f4a2713aSLionel Sambuc // CHECK: [[EL:%[a-z_0-9]+]] = load float* [[EL_TYPED]]
208*f4a2713aSLionel Sambuc // CHECK: store float [[EL]], float* [[EL_TMPADDR]]
209*f4a2713aSLionel Sambuc // CHECK: [[EL_ADDR:%[a-z_0-9]+]] = getelementptr i8* [[FIRST_REG]], i32 16
210*f4a2713aSLionel Sambuc // CHECK: [[EL_TYPED:%[a-z_0-9]+]] = bitcast i8* [[EL_ADDR]] to float*
211*f4a2713aSLionel Sambuc // CHECK: [[EL_TMPADDR:%[a-z_0-9]+]] = getelementptr inbounds [2 x float]* %[[TMP_HFA]], i32 0, i32 1
212*f4a2713aSLionel Sambuc // CHECK: [[EL:%[a-z_0-9]+]] = load float* [[EL_TYPED]]
213*f4a2713aSLionel Sambuc // CHECK: store float [[EL]], float* [[EL_TMPADDR]]
214*f4a2713aSLionel Sambuc // CHECK: [[FROMREG_ADDR:%[a-z_0-9]+]] = bitcast [2 x float]* %[[TMP_HFA]] to %struct.hfa*
215*f4a2713aSLionel Sambuc // CHECK: br label %[[VAARG_END:[a-z_.0-9]+]]
216*f4a2713aSLionel Sambuc 
217*f4a2713aSLionel Sambuc // CHECK: [[VAARG_ON_STACK]]
218*f4a2713aSLionel Sambuc // CHECK: [[STACK:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
219*f4a2713aSLionel Sambuc // CHECK: [[NEW_STACK:%[a-z_0-9]+]] = getelementptr i8* [[STACK]], i32 8
220*f4a2713aSLionel Sambuc // CHECK: store i8* [[NEW_STACK]], i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
221*f4a2713aSLionel Sambuc // CHECK: [[FROMSTACK_ADDR:%[a-z_0-9]+]] = bitcast i8* [[STACK]] to %struct.hfa*
222*f4a2713aSLionel Sambuc // CHECK: br label %[[VAARG_END]]
223*f4a2713aSLionel Sambuc 
224*f4a2713aSLionel Sambuc // CHECK: [[VAARG_END]]
225*f4a2713aSLionel Sambuc // CHECK: [[ADDR:%[a-z._0-9]+]] = phi %struct.hfa* [ [[FROMREG_ADDR]], %[[VAARG_IN_REG]] ], [ [[FROMSTACK_ADDR]], %[[VAARG_ON_STACK]] ]
226*f4a2713aSLionel Sambuc }
227*f4a2713aSLionel Sambuc 
228*f4a2713aSLionel Sambuc void check_start(int n, ...) {
229*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @check_start(i32 %n, ...)
230*f4a2713aSLionel Sambuc 
231*f4a2713aSLionel Sambuc   va_list the_list;
232*f4a2713aSLionel Sambuc   va_start(the_list, n);
233*f4a2713aSLionel Sambuc // CHECK: [[THE_LIST:%[a-z_0-9]+]] = alloca %struct.__va_list
234*f4a2713aSLionel Sambuc // CHECK: [[VOIDP_THE_LIST:%[a-z_0-9]+]] = bitcast %struct.__va_list* [[THE_LIST]] to i8*
235*f4a2713aSLionel Sambuc // CHECK: call void @llvm.va_start(i8* [[VOIDP_THE_LIST]])
236*f4a2713aSLionel Sambuc }
237*f4a2713aSLionel Sambuc 
238*f4a2713aSLionel Sambuc 
239