1*67e74705SXin Li // RUN: %clang_cc1 -triple s390x-linux-gnu \
2*67e74705SXin Li // RUN: -emit-llvm -o - %s | FileCheck %s
3*67e74705SXin Li // RUN: %clang_cc1 -triple s390x-linux-gnu -target-feature +vector \
4*67e74705SXin Li // RUN: -emit-llvm -o - %s | FileCheck %s
5*67e74705SXin Li // RUN: %clang_cc1 -triple s390x-linux-gnu -target-cpu z13 \
6*67e74705SXin Li // RUN: -emit-llvm -o - %s | FileCheck %s
7*67e74705SXin Li
8*67e74705SXin Li // Scalar types
9*67e74705SXin Li
pass_char(char arg)10*67e74705SXin Li char pass_char(char arg) { return arg; }
11*67e74705SXin Li // CHECK-LABEL: define signext i8 @pass_char(i8 signext %{{.*}})
12*67e74705SXin Li
pass_short(short arg)13*67e74705SXin Li short pass_short(short arg) { return arg; }
14*67e74705SXin Li // CHECK-LABEL: define signext i16 @pass_short(i16 signext %{{.*}})
15*67e74705SXin Li
pass_int(int arg)16*67e74705SXin Li int pass_int(int arg) { return arg; }
17*67e74705SXin Li // CHECK-LABEL: define signext i32 @pass_int(i32 signext %{{.*}})
18*67e74705SXin Li
pass_long(long arg)19*67e74705SXin Li long pass_long(long arg) { return arg; }
20*67e74705SXin Li // CHECK-LABEL: define i64 @pass_long(i64 %{{.*}})
21*67e74705SXin Li
pass_longlong(long long arg)22*67e74705SXin Li long long pass_longlong(long long arg) { return arg; }
23*67e74705SXin Li // CHECK-LABEL: define i64 @pass_longlong(i64 %{{.*}})
24*67e74705SXin Li
pass_int128(__int128 arg)25*67e74705SXin Li __int128 pass_int128(__int128 arg) { return arg; }
26*67e74705SXin Li // CHECK-LABEL: define void @pass_int128(i128* noalias sret %{{.*}}, i128*)
27*67e74705SXin Li
pass_float(float arg)28*67e74705SXin Li float pass_float(float arg) { return arg; }
29*67e74705SXin Li // CHECK-LABEL: define float @pass_float(float %{{.*}})
30*67e74705SXin Li
pass_double(double arg)31*67e74705SXin Li double pass_double(double arg) { return arg; }
32*67e74705SXin Li // CHECK-LABEL: define double @pass_double(double %{{.*}})
33*67e74705SXin Li
pass_longdouble(long double arg)34*67e74705SXin Li long double pass_longdouble(long double arg) { return arg; }
35*67e74705SXin Li // CHECK-LABEL: define void @pass_longdouble(fp128* noalias sret %{{.*}}, fp128*)
36*67e74705SXin Li
37*67e74705SXin Li
38*67e74705SXin Li // Complex types
39*67e74705SXin Li
pass_complex_char(_Complex char arg)40*67e74705SXin Li _Complex char pass_complex_char(_Complex char arg) { return arg; }
41*67e74705SXin Li // CHECK-LABEL: define void @pass_complex_char({ i8, i8 }* noalias sret %{{.*}}, { i8, i8 }* %{{.*}}arg)
42*67e74705SXin Li
pass_complex_short(_Complex short arg)43*67e74705SXin Li _Complex short pass_complex_short(_Complex short arg) { return arg; }
44*67e74705SXin Li // CHECK-LABEL: define void @pass_complex_short({ i16, i16 }* noalias sret %{{.*}}, { i16, i16 }* %{{.*}}arg)
45*67e74705SXin Li
pass_complex_int(_Complex int arg)46*67e74705SXin Li _Complex int pass_complex_int(_Complex int arg) { return arg; }
47*67e74705SXin Li // CHECK-LABEL: define void @pass_complex_int({ i32, i32 }* noalias sret %{{.*}}, { i32, i32 }* %{{.*}}arg)
48*67e74705SXin Li
pass_complex_long(_Complex long arg)49*67e74705SXin Li _Complex long pass_complex_long(_Complex long arg) { return arg; }
50*67e74705SXin Li // CHECK-LABEL: define void @pass_complex_long({ i64, i64 }* noalias sret %{{.*}}, { i64, i64 }* %{{.*}}arg)
51*67e74705SXin Li
pass_complex_longlong(_Complex long long arg)52*67e74705SXin Li _Complex long long pass_complex_longlong(_Complex long long arg) { return arg; }
53*67e74705SXin Li // CHECK-LABEL: define void @pass_complex_longlong({ i64, i64 }* noalias sret %{{.*}}, { i64, i64 }* %{{.*}}arg)
54*67e74705SXin Li
pass_complex_float(_Complex float arg)55*67e74705SXin Li _Complex float pass_complex_float(_Complex float arg) { return arg; }
56*67e74705SXin Li // CHECK-LABEL: define void @pass_complex_float({ float, float }* noalias sret %{{.*}}, { float, float }* %{{.*}}arg)
57*67e74705SXin Li
pass_complex_double(_Complex double arg)58*67e74705SXin Li _Complex double pass_complex_double(_Complex double arg) { return arg; }
59*67e74705SXin Li // CHECK-LABEL: define void @pass_complex_double({ double, double }* noalias sret %{{.*}}, { double, double }* %{{.*}}arg)
60*67e74705SXin Li
pass_complex_longdouble(_Complex long double arg)61*67e74705SXin Li _Complex long double pass_complex_longdouble(_Complex long double arg) { return arg; }
62*67e74705SXin Li // CHECK-LABEL: define void @pass_complex_longdouble({ fp128, fp128 }* noalias sret %{{.*}}, { fp128, fp128 }* %{{.*}}arg)
63*67e74705SXin Li
64*67e74705SXin Li
65*67e74705SXin Li // Aggregate types
66*67e74705SXin Li
67*67e74705SXin Li struct agg_1byte { char a[1]; };
pass_agg_1byte(struct agg_1byte arg)68*67e74705SXin Li struct agg_1byte pass_agg_1byte(struct agg_1byte arg) { return arg; }
69*67e74705SXin Li // CHECK-LABEL: define void @pass_agg_1byte(%struct.agg_1byte* noalias sret %{{.*}}, i8 %{{.*}})
70*67e74705SXin Li
71*67e74705SXin Li struct agg_2byte { char a[2]; };
pass_agg_2byte(struct agg_2byte arg)72*67e74705SXin Li struct agg_2byte pass_agg_2byte(struct agg_2byte arg) { return arg; }
73*67e74705SXin Li // CHECK-LABEL: define void @pass_agg_2byte(%struct.agg_2byte* noalias sret %{{.*}}, i16 %{{.*}})
74*67e74705SXin Li
75*67e74705SXin Li struct agg_3byte { char a[3]; };
pass_agg_3byte(struct agg_3byte arg)76*67e74705SXin Li struct agg_3byte pass_agg_3byte(struct agg_3byte arg) { return arg; }
77*67e74705SXin Li // CHECK-LABEL: define void @pass_agg_3byte(%struct.agg_3byte* noalias sret %{{.*}}, %struct.agg_3byte* %{{.*}})
78*67e74705SXin Li
79*67e74705SXin Li struct agg_4byte { char a[4]; };
pass_agg_4byte(struct agg_4byte arg)80*67e74705SXin Li struct agg_4byte pass_agg_4byte(struct agg_4byte arg) { return arg; }
81*67e74705SXin Li // CHECK-LABEL: define void @pass_agg_4byte(%struct.agg_4byte* noalias sret %{{.*}}, i32 %{{.*}})
82*67e74705SXin Li
83*67e74705SXin Li struct agg_5byte { char a[5]; };
pass_agg_5byte(struct agg_5byte arg)84*67e74705SXin Li struct agg_5byte pass_agg_5byte(struct agg_5byte arg) { return arg; }
85*67e74705SXin Li // CHECK-LABEL: define void @pass_agg_5byte(%struct.agg_5byte* noalias sret %{{.*}}, %struct.agg_5byte* %{{.*}})
86*67e74705SXin Li
87*67e74705SXin Li struct agg_6byte { char a[6]; };
pass_agg_6byte(struct agg_6byte arg)88*67e74705SXin Li struct agg_6byte pass_agg_6byte(struct agg_6byte arg) { return arg; }
89*67e74705SXin Li // CHECK-LABEL: define void @pass_agg_6byte(%struct.agg_6byte* noalias sret %{{.*}}, %struct.agg_6byte* %{{.*}})
90*67e74705SXin Li
91*67e74705SXin Li struct agg_7byte { char a[7]; };
pass_agg_7byte(struct agg_7byte arg)92*67e74705SXin Li struct agg_7byte pass_agg_7byte(struct agg_7byte arg) { return arg; }
93*67e74705SXin Li // CHECK-LABEL: define void @pass_agg_7byte(%struct.agg_7byte* noalias sret %{{.*}}, %struct.agg_7byte* %{{.*}})
94*67e74705SXin Li
95*67e74705SXin Li struct agg_8byte { char a[8]; };
pass_agg_8byte(struct agg_8byte arg)96*67e74705SXin Li struct agg_8byte pass_agg_8byte(struct agg_8byte arg) { return arg; }
97*67e74705SXin Li // CHECK-LABEL: define void @pass_agg_8byte(%struct.agg_8byte* noalias sret %{{.*}}, i64 %{{.*}})
98*67e74705SXin Li
99*67e74705SXin Li struct agg_16byte { char a[16]; };
pass_agg_16byte(struct agg_16byte arg)100*67e74705SXin Li struct agg_16byte pass_agg_16byte(struct agg_16byte arg) { return arg; }
101*67e74705SXin Li // CHECK-LABEL: define void @pass_agg_16byte(%struct.agg_16byte* noalias sret %{{.*}}, %struct.agg_16byte* %{{.*}})
102*67e74705SXin Li
103*67e74705SXin Li
104*67e74705SXin Li // Float-like aggregate types
105*67e74705SXin Li
106*67e74705SXin Li struct agg_float { float a; };
pass_agg_float(struct agg_float arg)107*67e74705SXin Li struct agg_float pass_agg_float(struct agg_float arg) { return arg; }
108*67e74705SXin Li // CHECK-LABEL: define void @pass_agg_float(%struct.agg_float* noalias sret %{{.*}}, float %{{.*}})
109*67e74705SXin Li
110*67e74705SXin Li struct agg_double { double a; };
pass_agg_double(struct agg_double arg)111*67e74705SXin Li struct agg_double pass_agg_double(struct agg_double arg) { return arg; }
112*67e74705SXin Li // CHECK-LABEL: define void @pass_agg_double(%struct.agg_double* noalias sret %{{.*}}, double %{{.*}})
113*67e74705SXin Li
114*67e74705SXin Li struct agg_longdouble { long double a; };
pass_agg_longdouble(struct agg_longdouble arg)115*67e74705SXin Li struct agg_longdouble pass_agg_longdouble(struct agg_longdouble arg) { return arg; }
116*67e74705SXin Li // CHECK-LABEL: define void @pass_agg_longdouble(%struct.agg_longdouble* noalias sret %{{.*}}, %struct.agg_longdouble* %{{.*}})
117*67e74705SXin Li
118*67e74705SXin Li struct agg_float_a8 { float a __attribute__((aligned (8))); };
pass_agg_float_a8(struct agg_float_a8 arg)119*67e74705SXin Li struct agg_float_a8 pass_agg_float_a8(struct agg_float_a8 arg) { return arg; }
120*67e74705SXin Li // CHECK-LABEL: define void @pass_agg_float_a8(%struct.agg_float_a8* noalias sret %{{.*}}, double %{{.*}})
121*67e74705SXin Li
122*67e74705SXin Li struct agg_float_a16 { float a __attribute__((aligned (16))); };
pass_agg_float_a16(struct agg_float_a16 arg)123*67e74705SXin Li struct agg_float_a16 pass_agg_float_a16(struct agg_float_a16 arg) { return arg; }
124*67e74705SXin Li // CHECK-LABEL: define void @pass_agg_float_a16(%struct.agg_float_a16* noalias sret %{{.*}}, %struct.agg_float_a16* %{{.*}})
125*67e74705SXin Li
126*67e74705SXin Li
127*67e74705SXin Li // Verify that the following are *not* float-like aggregate types
128*67e74705SXin Li
129*67e74705SXin Li struct agg_nofloat1 { float a; float b; };
pass_agg_nofloat1(struct agg_nofloat1 arg)130*67e74705SXin Li struct agg_nofloat1 pass_agg_nofloat1(struct agg_nofloat1 arg) { return arg; }
131*67e74705SXin Li // CHECK-LABEL: define void @pass_agg_nofloat1(%struct.agg_nofloat1* noalias sret %{{.*}}, i64 %{{.*}})
132*67e74705SXin Li
133*67e74705SXin Li struct agg_nofloat2 { float a; int b; };
pass_agg_nofloat2(struct agg_nofloat2 arg)134*67e74705SXin Li struct agg_nofloat2 pass_agg_nofloat2(struct agg_nofloat2 arg) { return arg; }
135*67e74705SXin Li // CHECK-LABEL: define void @pass_agg_nofloat2(%struct.agg_nofloat2* noalias sret %{{.*}}, i64 %{{.*}})
136*67e74705SXin Li
137*67e74705SXin Li struct agg_nofloat3 { float a; int : 0; };
pass_agg_nofloat3(struct agg_nofloat3 arg)138*67e74705SXin Li struct agg_nofloat3 pass_agg_nofloat3(struct agg_nofloat3 arg) { return arg; }
139*67e74705SXin Li // CHECK-LABEL: define void @pass_agg_nofloat3(%struct.agg_nofloat3* noalias sret %{{.*}}, i32 %{{.*}})
140*67e74705SXin Li
141*67e74705SXin Li
142*67e74705SXin Li // Accessing variable argument lists
143*67e74705SXin Li
va_int(__builtin_va_list l)144*67e74705SXin Li int va_int(__builtin_va_list l) { return __builtin_va_arg(l, int); }
145*67e74705SXin Li // CHECK-LABEL: define signext i32 @va_int(%struct.__va_list_tag* %{{.*}})
146*67e74705SXin Li // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0
147*67e74705SXin Li // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]]
148*67e74705SXin Li // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5
149*67e74705SXin Li // CHECK: br i1 [[FITS_IN_REGS]],
150*67e74705SXin Li // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8
151*67e74705SXin Li // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 20
152*67e74705SXin Li // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3
153*67e74705SXin Li // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]]
154*67e74705SXin Li // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]]
155*67e74705SXin Li // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to i32*
156*67e74705SXin Li // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1
157*67e74705SXin Li // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]]
158*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2
159*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]]
160*67e74705SXin Li // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 4
161*67e74705SXin Li // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to i32*
162*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8
163*67e74705SXin Li // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]]
164*67e74705SXin Li // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi i32* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ]
165*67e74705SXin Li // CHECK: [[RET:%[^ ]+]] = load i32, i32* [[VA_ARG_ADDR]]
166*67e74705SXin Li // CHECK: ret i32 [[RET]]
167*67e74705SXin Li
va_long(__builtin_va_list l)168*67e74705SXin Li long va_long(__builtin_va_list l) { return __builtin_va_arg(l, long); }
169*67e74705SXin Li // CHECK-LABEL: define i64 @va_long(%struct.__va_list_tag* %{{.*}})
170*67e74705SXin Li // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0
171*67e74705SXin Li // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]]
172*67e74705SXin Li // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5
173*67e74705SXin Li // CHECK: br i1 [[FITS_IN_REGS]],
174*67e74705SXin Li // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8
175*67e74705SXin Li // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16
176*67e74705SXin Li // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3
177*67e74705SXin Li // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]]
178*67e74705SXin Li // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]]
179*67e74705SXin Li // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to i64*
180*67e74705SXin Li // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1
181*67e74705SXin Li // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]]
182*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2
183*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]]
184*67e74705SXin Li // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0
185*67e74705SXin Li // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to i64*
186*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8
187*67e74705SXin Li // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]]
188*67e74705SXin Li // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi i64* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ]
189*67e74705SXin Li // CHECK: [[RET:%[^ ]+]] = load i64, i64* [[VA_ARG_ADDR]]
190*67e74705SXin Li // CHECK: ret i64 [[RET]]
191*67e74705SXin Li
va_longlong(__builtin_va_list l)192*67e74705SXin Li long long va_longlong(__builtin_va_list l) { return __builtin_va_arg(l, long long); }
193*67e74705SXin Li // CHECK-LABEL: define i64 @va_longlong(%struct.__va_list_tag* %{{.*}})
194*67e74705SXin Li // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0
195*67e74705SXin Li // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]]
196*67e74705SXin Li // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5
197*67e74705SXin Li // CHECK: br i1 [[FITS_IN_REGS]],
198*67e74705SXin Li // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8
199*67e74705SXin Li // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16
200*67e74705SXin Li // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3
201*67e74705SXin Li // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]]
202*67e74705SXin Li // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]]
203*67e74705SXin Li // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to i64*
204*67e74705SXin Li // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1
205*67e74705SXin Li // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]]
206*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2
207*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]]
208*67e74705SXin Li // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0
209*67e74705SXin Li // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to i64*
210*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8
211*67e74705SXin Li // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]]
212*67e74705SXin Li // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi i64* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ]
213*67e74705SXin Li // CHECK: [[RET:%[^ ]+]] = load i64, i64* [[VA_ARG_ADDR]]
214*67e74705SXin Li // CHECK: ret i64 [[RET]]
215*67e74705SXin Li
va_double(__builtin_va_list l)216*67e74705SXin Li double va_double(__builtin_va_list l) { return __builtin_va_arg(l, double); }
217*67e74705SXin Li // CHECK-LABEL: define double @va_double(%struct.__va_list_tag* %{{.*}})
218*67e74705SXin Li // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 1
219*67e74705SXin Li // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]]
220*67e74705SXin Li // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 4
221*67e74705SXin Li // CHECK: br i1 [[FITS_IN_REGS]],
222*67e74705SXin Li // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8
223*67e74705SXin Li // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 128
224*67e74705SXin Li // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3
225*67e74705SXin Li // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]]
226*67e74705SXin Li // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]]
227*67e74705SXin Li // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to double*
228*67e74705SXin Li // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1
229*67e74705SXin Li // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]]
230*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2
231*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]]
232*67e74705SXin Li // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0
233*67e74705SXin Li // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to double*
234*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8
235*67e74705SXin Li // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]]
236*67e74705SXin Li // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi double* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ]
237*67e74705SXin Li // CHECK: [[RET:%[^ ]+]] = load double, double* [[VA_ARG_ADDR]]
238*67e74705SXin Li // CHECK: ret double [[RET]]
239*67e74705SXin Li
va_longdouble(__builtin_va_list l)240*67e74705SXin Li long double va_longdouble(__builtin_va_list l) { return __builtin_va_arg(l, long double); }
241*67e74705SXin Li // CHECK-LABEL: define void @va_longdouble(fp128* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}})
242*67e74705SXin Li // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0
243*67e74705SXin Li // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]]
244*67e74705SXin Li // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5
245*67e74705SXin Li // CHECK: br i1 [[FITS_IN_REGS]],
246*67e74705SXin Li // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8
247*67e74705SXin Li // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16
248*67e74705SXin Li // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3
249*67e74705SXin Li // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]]
250*67e74705SXin Li // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]]
251*67e74705SXin Li // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to fp128**
252*67e74705SXin Li // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1
253*67e74705SXin Li // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]]
254*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2
255*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]]
256*67e74705SXin Li // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0
257*67e74705SXin Li // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to fp128**
258*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8
259*67e74705SXin Li // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]]
260*67e74705SXin Li // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi fp128** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ]
261*67e74705SXin Li // CHECK: [[INDIRECT_ARG:%[^ ]+]] = load fp128*, fp128** [[VA_ARG_ADDR]]
262*67e74705SXin Li // CHECK: [[RET:%[^ ]+]] = load fp128, fp128* [[INDIRECT_ARG]]
263*67e74705SXin Li // CHECK: store fp128 [[RET]], fp128* %{{.*}}
264*67e74705SXin Li // CHECK: ret void
265*67e74705SXin Li
va_complex_char(__builtin_va_list l)266*67e74705SXin Li _Complex char va_complex_char(__builtin_va_list l) { return __builtin_va_arg(l, _Complex char); }
267*67e74705SXin Li // CHECK-LABEL: define void @va_complex_char({ i8, i8 }* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}}
268*67e74705SXin Li // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0
269*67e74705SXin Li // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]]
270*67e74705SXin Li // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5
271*67e74705SXin Li // CHECK: br i1 [[FITS_IN_REGS]],
272*67e74705SXin Li // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8
273*67e74705SXin Li // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16
274*67e74705SXin Li // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3
275*67e74705SXin Li // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]]
276*67e74705SXin Li // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]]
277*67e74705SXin Li // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to { i8, i8 }**
278*67e74705SXin Li // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1
279*67e74705SXin Li // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]]
280*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2
281*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]]
282*67e74705SXin Li // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0
283*67e74705SXin Li // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to { i8, i8 }**
284*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8
285*67e74705SXin Li // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]]
286*67e74705SXin Li // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi { i8, i8 }** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ]
287*67e74705SXin Li // CHECK: [[INDIRECT_ARG:%[^ ]+]] = load { i8, i8 }*, { i8, i8 }** [[VA_ARG_ADDR]]
288*67e74705SXin Li // CHECK: ret void
289*67e74705SXin Li
va_agg_1byte(__builtin_va_list l)290*67e74705SXin Li struct agg_1byte va_agg_1byte(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_1byte); }
291*67e74705SXin Li // CHECK-LABEL: define void @va_agg_1byte(%struct.agg_1byte* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}}
292*67e74705SXin Li // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0
293*67e74705SXin Li // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]]
294*67e74705SXin Li // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5
295*67e74705SXin Li // CHECK: br i1 [[FITS_IN_REGS]],
296*67e74705SXin Li // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8
297*67e74705SXin Li // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 23
298*67e74705SXin Li // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3
299*67e74705SXin Li // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]]
300*67e74705SXin Li // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]]
301*67e74705SXin Li // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_1byte*
302*67e74705SXin Li // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1
303*67e74705SXin Li // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]]
304*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2
305*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]]
306*67e74705SXin Li // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 7
307*67e74705SXin Li // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_1byte*
308*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8
309*67e74705SXin Li // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]]
310*67e74705SXin Li // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_1byte* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ]
311*67e74705SXin Li // CHECK: ret void
312*67e74705SXin Li
va_agg_2byte(__builtin_va_list l)313*67e74705SXin Li struct agg_2byte va_agg_2byte(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_2byte); }
314*67e74705SXin Li // CHECK-LABEL: define void @va_agg_2byte(%struct.agg_2byte* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}}
315*67e74705SXin Li // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0
316*67e74705SXin Li // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]]
317*67e74705SXin Li // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5
318*67e74705SXin Li // CHECK: br i1 [[FITS_IN_REGS]],
319*67e74705SXin Li // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8
320*67e74705SXin Li // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 22
321*67e74705SXin Li // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3
322*67e74705SXin Li // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]]
323*67e74705SXin Li // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]]
324*67e74705SXin Li // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_2byte*
325*67e74705SXin Li // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1
326*67e74705SXin Li // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]]
327*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2
328*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]]
329*67e74705SXin Li // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 6
330*67e74705SXin Li // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_2byte*
331*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8
332*67e74705SXin Li // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]]
333*67e74705SXin Li // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_2byte* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ]
334*67e74705SXin Li // CHECK: ret void
335*67e74705SXin Li
va_agg_3byte(__builtin_va_list l)336*67e74705SXin Li struct agg_3byte va_agg_3byte(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_3byte); }
337*67e74705SXin Li // CHECK-LABEL: define void @va_agg_3byte(%struct.agg_3byte* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}}
338*67e74705SXin Li // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0
339*67e74705SXin Li // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]]
340*67e74705SXin Li // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5
341*67e74705SXin Li // CHECK: br i1 [[FITS_IN_REGS]],
342*67e74705SXin Li // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8
343*67e74705SXin Li // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16
344*67e74705SXin Li // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3
345*67e74705SXin Li // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]]
346*67e74705SXin Li // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]]
347*67e74705SXin Li // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_3byte**
348*67e74705SXin Li // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1
349*67e74705SXin Li // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]]
350*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2
351*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]]
352*67e74705SXin Li // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0
353*67e74705SXin Li // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_3byte**
354*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8
355*67e74705SXin Li // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]]
356*67e74705SXin Li // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_3byte** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ]
357*67e74705SXin Li // CHECK: [[INDIRECT_ARG:%[^ ]+]] = load %struct.agg_3byte*, %struct.agg_3byte** [[VA_ARG_ADDR]]
358*67e74705SXin Li // CHECK: ret void
359*67e74705SXin Li
va_agg_4byte(__builtin_va_list l)360*67e74705SXin Li struct agg_4byte va_agg_4byte(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_4byte); }
361*67e74705SXin Li // CHECK-LABEL: define void @va_agg_4byte(%struct.agg_4byte* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}}
362*67e74705SXin Li // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0
363*67e74705SXin Li // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]]
364*67e74705SXin Li // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5
365*67e74705SXin Li // CHECK: br i1 [[FITS_IN_REGS]],
366*67e74705SXin Li // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8
367*67e74705SXin Li // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 20
368*67e74705SXin Li // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3
369*67e74705SXin Li // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]]
370*67e74705SXin Li // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]]
371*67e74705SXin Li // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_4byte*
372*67e74705SXin Li // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1
373*67e74705SXin Li // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]]
374*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2
375*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]]
376*67e74705SXin Li // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 4
377*67e74705SXin Li // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_4byte*
378*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8
379*67e74705SXin Li // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]]
380*67e74705SXin Li // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_4byte* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ]
381*67e74705SXin Li // CHECK: ret void
382*67e74705SXin Li
va_agg_8byte(__builtin_va_list l)383*67e74705SXin Li struct agg_8byte va_agg_8byte(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_8byte); }
384*67e74705SXin Li // CHECK-LABEL: define void @va_agg_8byte(%struct.agg_8byte* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}}
385*67e74705SXin Li // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0
386*67e74705SXin Li // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]]
387*67e74705SXin Li // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5
388*67e74705SXin Li // CHECK: br i1 [[FITS_IN_REGS]],
389*67e74705SXin Li // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8
390*67e74705SXin Li // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16
391*67e74705SXin Li // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3
392*67e74705SXin Li // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]]
393*67e74705SXin Li // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]]
394*67e74705SXin Li // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_8byte*
395*67e74705SXin Li // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1
396*67e74705SXin Li // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]]
397*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2
398*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]]
399*67e74705SXin Li // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0
400*67e74705SXin Li // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_8byte*
401*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8
402*67e74705SXin Li // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]]
403*67e74705SXin Li // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_8byte* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ]
404*67e74705SXin Li // CHECK: ret void
405*67e74705SXin Li
va_agg_float(__builtin_va_list l)406*67e74705SXin Li struct agg_float va_agg_float(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_float); }
407*67e74705SXin Li // CHECK-LABEL: define void @va_agg_float(%struct.agg_float* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}}
408*67e74705SXin Li // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 1
409*67e74705SXin Li // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]]
410*67e74705SXin Li // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 4
411*67e74705SXin Li // CHECK: br i1 [[FITS_IN_REGS]],
412*67e74705SXin Li // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8
413*67e74705SXin Li // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 128
414*67e74705SXin Li // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3
415*67e74705SXin Li // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]]
416*67e74705SXin Li // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]]
417*67e74705SXin Li // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_float*
418*67e74705SXin Li // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1
419*67e74705SXin Li // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]]
420*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2
421*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]]
422*67e74705SXin Li // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 4
423*67e74705SXin Li // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_float*
424*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8
425*67e74705SXin Li // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]]
426*67e74705SXin Li // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_float* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ]
427*67e74705SXin Li // CHECK: ret void
428*67e74705SXin Li
va_agg_double(__builtin_va_list l)429*67e74705SXin Li struct agg_double va_agg_double(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_double); }
430*67e74705SXin Li // CHECK-LABEL: define void @va_agg_double(%struct.agg_double* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}}
431*67e74705SXin Li // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 1
432*67e74705SXin Li // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]]
433*67e74705SXin Li // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 4
434*67e74705SXin Li // CHECK: br i1 [[FITS_IN_REGS]],
435*67e74705SXin Li // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8
436*67e74705SXin Li // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 128
437*67e74705SXin Li // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3
438*67e74705SXin Li // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]]
439*67e74705SXin Li // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]]
440*67e74705SXin Li // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_double*
441*67e74705SXin Li // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1
442*67e74705SXin Li // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]]
443*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2
444*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]]
445*67e74705SXin Li // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0
446*67e74705SXin Li // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_double*
447*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8
448*67e74705SXin Li // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]]
449*67e74705SXin Li // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_double* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ]
450*67e74705SXin Li // CHECK: ret void
451*67e74705SXin Li
va_agg_longdouble(__builtin_va_list l)452*67e74705SXin Li struct agg_longdouble va_agg_longdouble(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_longdouble); }
453*67e74705SXin Li // CHECK-LABEL: define void @va_agg_longdouble(%struct.agg_longdouble* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}}
454*67e74705SXin Li // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0
455*67e74705SXin Li // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]]
456*67e74705SXin Li // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5
457*67e74705SXin Li // CHECK: br i1 [[FITS_IN_REGS]],
458*67e74705SXin Li // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8
459*67e74705SXin Li // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16
460*67e74705SXin Li // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3
461*67e74705SXin Li // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]]
462*67e74705SXin Li // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]]
463*67e74705SXin Li // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_longdouble**
464*67e74705SXin Li // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1
465*67e74705SXin Li // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]]
466*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2
467*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]]
468*67e74705SXin Li // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0
469*67e74705SXin Li // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_longdouble**
470*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8
471*67e74705SXin Li // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]]
472*67e74705SXin Li // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_longdouble** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ]
473*67e74705SXin Li // CHECK: [[INDIRECT_ARG:%[^ ]+]] = load %struct.agg_longdouble*, %struct.agg_longdouble** [[VA_ARG_ADDR]]
474*67e74705SXin Li // CHECK: ret void
475*67e74705SXin Li
va_agg_float_a8(__builtin_va_list l)476*67e74705SXin Li struct agg_float_a8 va_agg_float_a8(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_float_a8); }
477*67e74705SXin Li // CHECK-LABEL: define void @va_agg_float_a8(%struct.agg_float_a8* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}}
478*67e74705SXin Li // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 1
479*67e74705SXin Li // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]]
480*67e74705SXin Li // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 4
481*67e74705SXin Li // CHECK: br i1 [[FITS_IN_REGS]],
482*67e74705SXin Li // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8
483*67e74705SXin Li // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 128
484*67e74705SXin Li // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3
485*67e74705SXin Li // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]]
486*67e74705SXin Li // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]]
487*67e74705SXin Li // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_float_a8*
488*67e74705SXin Li // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1
489*67e74705SXin Li // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]]
490*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2
491*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]]
492*67e74705SXin Li // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0
493*67e74705SXin Li // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_float_a8*
494*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8
495*67e74705SXin Li // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]]
496*67e74705SXin Li // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_float_a8* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ]
497*67e74705SXin Li // CHECK: ret void
498*67e74705SXin Li
va_agg_float_a16(__builtin_va_list l)499*67e74705SXin Li struct agg_float_a16 va_agg_float_a16(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_float_a16); }
500*67e74705SXin Li // CHECK-LABEL: define void @va_agg_float_a16(%struct.agg_float_a16* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}}
501*67e74705SXin Li // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0
502*67e74705SXin Li // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]]
503*67e74705SXin Li // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5
504*67e74705SXin Li // CHECK: br i1 [[FITS_IN_REGS]],
505*67e74705SXin Li // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8
506*67e74705SXin Li // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16
507*67e74705SXin Li // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3
508*67e74705SXin Li // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]]
509*67e74705SXin Li // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]]
510*67e74705SXin Li // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_float_a16**
511*67e74705SXin Li // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1
512*67e74705SXin Li // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]]
513*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2
514*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]]
515*67e74705SXin Li // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0
516*67e74705SXin Li // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_float_a16**
517*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8
518*67e74705SXin Li // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]]
519*67e74705SXin Li // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_float_a16** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ]
520*67e74705SXin Li // CHECK: [[INDIRECT_ARG:%[^ ]+]] = load %struct.agg_float_a16*, %struct.agg_float_a16** [[VA_ARG_ADDR]]
521*67e74705SXin Li // CHECK: ret void
522*67e74705SXin Li
va_agg_nofloat1(__builtin_va_list l)523*67e74705SXin Li struct agg_nofloat1 va_agg_nofloat1(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_nofloat1); }
524*67e74705SXin Li // CHECK-LABEL: define void @va_agg_nofloat1(%struct.agg_nofloat1* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}}
525*67e74705SXin Li // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0
526*67e74705SXin Li // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]]
527*67e74705SXin Li // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5
528*67e74705SXin Li // CHECK: br i1 [[FITS_IN_REGS]],
529*67e74705SXin Li // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8
530*67e74705SXin Li // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16
531*67e74705SXin Li // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3
532*67e74705SXin Li // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]]
533*67e74705SXin Li // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]]
534*67e74705SXin Li // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_nofloat1*
535*67e74705SXin Li // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1
536*67e74705SXin Li // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]]
537*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2
538*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]]
539*67e74705SXin Li // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0
540*67e74705SXin Li // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_nofloat1*
541*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8
542*67e74705SXin Li // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]]
543*67e74705SXin Li // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_nofloat1* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ]
544*67e74705SXin Li // CHECK: ret void
545*67e74705SXin Li
va_agg_nofloat2(__builtin_va_list l)546*67e74705SXin Li struct agg_nofloat2 va_agg_nofloat2(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_nofloat2); }
547*67e74705SXin Li // CHECK-LABEL: define void @va_agg_nofloat2(%struct.agg_nofloat2* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}}
548*67e74705SXin Li // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0
549*67e74705SXin Li // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]]
550*67e74705SXin Li // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5
551*67e74705SXin Li // CHECK: br i1 [[FITS_IN_REGS]],
552*67e74705SXin Li // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8
553*67e74705SXin Li // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16
554*67e74705SXin Li // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3
555*67e74705SXin Li // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]]
556*67e74705SXin Li // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]]
557*67e74705SXin Li // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_nofloat2*
558*67e74705SXin Li // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1
559*67e74705SXin Li // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]]
560*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2
561*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]]
562*67e74705SXin Li // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0
563*67e74705SXin Li // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_nofloat2*
564*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8
565*67e74705SXin Li // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]]
566*67e74705SXin Li // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_nofloat2* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ]
567*67e74705SXin Li // CHECK: ret void
568*67e74705SXin Li
va_agg_nofloat3(__builtin_va_list l)569*67e74705SXin Li struct agg_nofloat3 va_agg_nofloat3(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_nofloat3); }
570*67e74705SXin Li // CHECK-LABEL: define void @va_agg_nofloat3(%struct.agg_nofloat3* noalias sret %{{.*}}, %struct.__va_list_tag* %{{.*}}
571*67e74705SXin Li // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0
572*67e74705SXin Li // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]]
573*67e74705SXin Li // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5
574*67e74705SXin Li // CHECK: br i1 [[FITS_IN_REGS]],
575*67e74705SXin Li // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8
576*67e74705SXin Li // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 20
577*67e74705SXin Li // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3
578*67e74705SXin Li // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]]
579*67e74705SXin Li // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]]
580*67e74705SXin Li // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_nofloat3*
581*67e74705SXin Li // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1
582*67e74705SXin Li // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]]
583*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2
584*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]]
585*67e74705SXin Li // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 4
586*67e74705SXin Li // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_nofloat3*
587*67e74705SXin Li // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8
588*67e74705SXin Li // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]]
589*67e74705SXin Li // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_nofloat3* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ]
590*67e74705SXin Li // CHECK: ret void
591*67e74705SXin Li
592