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