1 // RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -triple s390x-linux-gnu \ 2 // RUN: -emit-llvm -o - %s | FileCheck %s 3 // RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -triple s390x-linux-gnu -target-feature +vector \ 4 // RUN: -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-VECTOR %s 5 // RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -triple s390x-linux-gnu -target-cpu z13 \ 6 // RUN: -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-VECTOR %s 7 // RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -triple s390x-linux-gnu -target-cpu arch11 \ 8 // RUN: -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-VECTOR %s 9 // RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -triple s390x-linux-gnu -target-cpu z14 \ 10 // RUN: -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-VECTOR %s 11 // RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -triple s390x-linux-gnu -target-cpu arch12 \ 12 // RUN: -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-VECTOR %s 13 // RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -triple s390x-linux-gnu -target-cpu z15 \ 14 // RUN: -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-VECTOR %s 15 // RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -triple s390x-linux-gnu -target-cpu arch13 \ 16 // RUN: -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-VECTOR %s 17 // RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -triple s390x-linux-gnu -target-cpu z16 \ 18 // RUN: -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-VECTOR %s 19 // RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -triple s390x-linux-gnu -target-cpu arch14 \ 20 // RUN: -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-VECTOR %s 21 22 // Vector types 23 24 typedef __attribute__((vector_size(1))) char v1i8; 25 26 typedef __attribute__((vector_size(2))) char v2i8; 27 typedef __attribute__((vector_size(2))) short v1i16; 28 29 typedef __attribute__((vector_size(4))) char v4i8; 30 typedef __attribute__((vector_size(4))) short v2i16; 31 typedef __attribute__((vector_size(4))) int v1i32; 32 typedef __attribute__((vector_size(4))) float v1f32; 33 34 typedef __attribute__((vector_size(8))) char v8i8; 35 typedef __attribute__((vector_size(8))) short v4i16; 36 typedef __attribute__((vector_size(8))) int v2i32; 37 typedef __attribute__((vector_size(8))) long long v1i64; 38 typedef __attribute__((vector_size(8))) float v2f32; 39 typedef __attribute__((vector_size(8))) double v1f64; 40 41 typedef __attribute__((vector_size(16))) char v16i8; 42 typedef __attribute__((vector_size(16))) short v8i16; 43 typedef __attribute__((vector_size(16))) int v4i32; 44 typedef __attribute__((vector_size(16))) long long v2i64; 45 typedef __attribute__((vector_size(16))) __int128 v1i128; 46 typedef __attribute__((vector_size(16))) float v4f32; 47 typedef __attribute__((vector_size(16))) double v2f64; 48 typedef __attribute__((vector_size(16))) long double v1f128; 49 50 typedef __attribute__((vector_size(32))) char v32i8; 51 52 unsigned int align = __alignof__ (v16i8); 53 // CHECK: @align ={{.*}} global i32 16 54 // CHECK-VECTOR: @align ={{.*}} global i32 8 55 56 v1i8 pass_v1i8(v1i8 arg) { return arg; } 57 // CHECK-LABEL: define{{.*}} void @pass_v1i8(<1 x i8>* noalias sret(<1 x i8>) align 1 %{{.*}}, <1 x i8>* %0) 58 // CHECK-VECTOR-LABEL: define{{.*}} <1 x i8> @pass_v1i8(<1 x i8> %{{.*}}) 59 60 v2i8 pass_v2i8(v2i8 arg) { return arg; } 61 // CHECK-LABEL: define{{.*}} void @pass_v2i8(<2 x i8>* noalias sret(<2 x i8>) align 2 %{{.*}}, <2 x i8>* %0) 62 // CHECK-VECTOR-LABEL: define{{.*}} <2 x i8> @pass_v2i8(<2 x i8> %{{.*}}) 63 64 v4i8 pass_v4i8(v4i8 arg) { return arg; } 65 // CHECK-LABEL: define{{.*}} void @pass_v4i8(<4 x i8>* noalias sret(<4 x i8>) align 4 %{{.*}}, <4 x i8>* %0) 66 // CHECK-VECTOR-LABEL: define{{.*}} <4 x i8> @pass_v4i8(<4 x i8> %{{.*}}) 67 68 v8i8 pass_v8i8(v8i8 arg) { return arg; } 69 // CHECK-LABEL: define{{.*}} void @pass_v8i8(<8 x i8>* noalias sret(<8 x i8>) align 8 %{{.*}}, <8 x i8>* %0) 70 // CHECK-VECTOR-LABEL: define{{.*}} <8 x i8> @pass_v8i8(<8 x i8> %{{.*}}) 71 72 v16i8 pass_v16i8(v16i8 arg) { return arg; } 73 // CHECK-LABEL: define{{.*}} void @pass_v16i8(<16 x i8>* noalias sret(<16 x i8>) align 16 %{{.*}}, <16 x i8>* %0) 74 // CHECK-VECTOR-LABEL: define{{.*}} <16 x i8> @pass_v16i8(<16 x i8> %{{.*}}) 75 76 v32i8 pass_v32i8(v32i8 arg) { return arg; } 77 // CHECK-LABEL: define{{.*}} void @pass_v32i8(<32 x i8>* noalias sret(<32 x i8>) align 32 %{{.*}}, <32 x i8>* %0) 78 // CHECK-VECTOR-LABEL: define{{.*}} void @pass_v32i8(<32 x i8>* noalias sret(<32 x i8>) align 8 %{{.*}}, <32 x i8>* %0) 79 80 v1i16 pass_v1i16(v1i16 arg) { return arg; } 81 // CHECK-LABEL: define{{.*}} void @pass_v1i16(<1 x i16>* noalias sret(<1 x i16>) align 2 %{{.*}}, <1 x i16>* %0) 82 // CHECK-VECTOR-LABEL: define{{.*}} <1 x i16> @pass_v1i16(<1 x i16> %{{.*}}) 83 84 v2i16 pass_v2i16(v2i16 arg) { return arg; } 85 // CHECK-LABEL: define{{.*}} void @pass_v2i16(<2 x i16>* noalias sret(<2 x i16>) align 4 %{{.*}}, <2 x i16>* %0) 86 // CHECK-VECTOR-LABEL: define{{.*}} <2 x i16> @pass_v2i16(<2 x i16> %{{.*}}) 87 88 v4i16 pass_v4i16(v4i16 arg) { return arg; } 89 // CHECK-LABEL: define{{.*}} void @pass_v4i16(<4 x i16>* noalias sret(<4 x i16>) align 8 %{{.*}}, <4 x i16>* %0) 90 // CHECK-VECTOR-LABEL: define{{.*}} <4 x i16> @pass_v4i16(<4 x i16> %{{.*}}) 91 92 v8i16 pass_v8i16(v8i16 arg) { return arg; } 93 // CHECK-LABEL: define{{.*}} void @pass_v8i16(<8 x i16>* noalias sret(<8 x i16>) align 16 %{{.*}}, <8 x i16>* %0) 94 // CHECK-VECTOR-LABEL: define{{.*}} <8 x i16> @pass_v8i16(<8 x i16> %{{.*}}) 95 96 v1i32 pass_v1i32(v1i32 arg) { return arg; } 97 // CHECK-LABEL: define{{.*}} void @pass_v1i32(<1 x i32>* noalias sret(<1 x i32>) align 4 %{{.*}}, <1 x i32>* %0) 98 // CHECK-VECTOR-LABEL: define{{.*}} <1 x i32> @pass_v1i32(<1 x i32> %{{.*}}) 99 100 v2i32 pass_v2i32(v2i32 arg) { return arg; } 101 // CHECK-LABEL: define{{.*}} void @pass_v2i32(<2 x i32>* noalias sret(<2 x i32>) align 8 %{{.*}}, <2 x i32>* %0) 102 // CHECK-VECTOR-LABEL: define{{.*}} <2 x i32> @pass_v2i32(<2 x i32> %{{.*}}) 103 104 v4i32 pass_v4i32(v4i32 arg) { return arg; } 105 // CHECK-LABEL: define{{.*}} void @pass_v4i32(<4 x i32>* noalias sret(<4 x i32>) align 16 %{{.*}}, <4 x i32>* %0) 106 // CHECK-VECTOR-LABEL: define{{.*}} <4 x i32> @pass_v4i32(<4 x i32> %{{.*}}) 107 108 v1i64 pass_v1i64(v1i64 arg) { return arg; } 109 // CHECK-LABEL: define{{.*}} void @pass_v1i64(<1 x i64>* noalias sret(<1 x i64>) align 8 %{{.*}}, <1 x i64>* %0) 110 // CHECK-VECTOR-LABEL: define{{.*}} <1 x i64> @pass_v1i64(<1 x i64> %{{.*}}) 111 112 v2i64 pass_v2i64(v2i64 arg) { return arg; } 113 // CHECK-LABEL: define{{.*}} void @pass_v2i64(<2 x i64>* noalias sret(<2 x i64>) align 16 %{{.*}}, <2 x i64>* %0) 114 // CHECK-VECTOR-LABEL: define{{.*}} <2 x i64> @pass_v2i64(<2 x i64> %{{.*}}) 115 116 v1i128 pass_v1i128(v1i128 arg) { return arg; } 117 // CHECK-LABEL: define{{.*}} void @pass_v1i128(<1 x i128>* noalias sret(<1 x i128>) align 16 %{{.*}}, <1 x i128>* %0) 118 // CHECK-VECTOR-LABEL: define{{.*}} <1 x i128> @pass_v1i128(<1 x i128> %{{.*}}) 119 120 v1f32 pass_v1f32(v1f32 arg) { return arg; } 121 // CHECK-LABEL: define{{.*}} void @pass_v1f32(<1 x float>* noalias sret(<1 x float>) align 4 %{{.*}}, <1 x float>* %0) 122 // CHECK-VECTOR-LABEL: define{{.*}} <1 x float> @pass_v1f32(<1 x float> %{{.*}}) 123 124 v2f32 pass_v2f32(v2f32 arg) { return arg; } 125 // CHECK-LABEL: define{{.*}} void @pass_v2f32(<2 x float>* noalias sret(<2 x float>) align 8 %{{.*}}, <2 x float>* %0) 126 // CHECK-VECTOR-LABEL: define{{.*}} <2 x float> @pass_v2f32(<2 x float> %{{.*}}) 127 128 v4f32 pass_v4f32(v4f32 arg) { return arg; } 129 // CHECK-LABEL: define{{.*}} void @pass_v4f32(<4 x float>* noalias sret(<4 x float>) align 16 %{{.*}}, <4 x float>* %0) 130 // CHECK-VECTOR-LABEL: define{{.*}} <4 x float> @pass_v4f32(<4 x float> %{{.*}}) 131 132 v1f64 pass_v1f64(v1f64 arg) { return arg; } 133 // CHECK-LABEL: define{{.*}} void @pass_v1f64(<1 x double>* noalias sret(<1 x double>) align 8 %{{.*}}, <1 x double>* %0) 134 // CHECK-VECTOR-LABEL: define{{.*}} <1 x double> @pass_v1f64(<1 x double> %{{.*}}) 135 136 v2f64 pass_v2f64(v2f64 arg) { return arg; } 137 // CHECK-LABEL: define{{.*}} void @pass_v2f64(<2 x double>* noalias sret(<2 x double>) align 16 %{{.*}}, <2 x double>* %0) 138 // CHECK-VECTOR-LABEL: define{{.*}} <2 x double> @pass_v2f64(<2 x double> %{{.*}}) 139 140 v1f128 pass_v1f128(v1f128 arg) { return arg; } 141 // CHECK-LABEL: define{{.*}} void @pass_v1f128(<1 x fp128>* noalias sret(<1 x fp128>) align 16 %{{.*}}, <1 x fp128>* %0) 142 // CHECK-VECTOR-LABEL: define{{.*}} <1 x fp128> @pass_v1f128(<1 x fp128> %{{.*}}) 143 144 145 // Vector-like aggregate types 146 147 struct agg_v1i8 { v1i8 a; }; 148 struct agg_v1i8 pass_agg_v1i8(struct agg_v1i8 arg) { return arg; } 149 // CHECK-LABEL: define{{.*}} void @pass_agg_v1i8(%struct.agg_v1i8* noalias sret(%struct.agg_v1i8) align 1 %{{.*}}, i8 %{{.*}}) 150 // CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_v1i8(%struct.agg_v1i8* noalias sret(%struct.agg_v1i8) align 1 %{{.*}}, <1 x i8> %{{.*}}) 151 152 struct agg_v2i8 { v2i8 a; }; 153 struct agg_v2i8 pass_agg_v2i8(struct agg_v2i8 arg) { return arg; } 154 // CHECK-LABEL: define{{.*}} void @pass_agg_v2i8(%struct.agg_v2i8* noalias sret(%struct.agg_v2i8) align 2 %{{.*}}, i16 %{{.*}}) 155 // CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_v2i8(%struct.agg_v2i8* noalias sret(%struct.agg_v2i8) align 2 %{{.*}}, <2 x i8> %{{.*}}) 156 157 struct agg_v4i8 { v4i8 a; }; 158 struct agg_v4i8 pass_agg_v4i8(struct agg_v4i8 arg) { return arg; } 159 // CHECK-LABEL: define{{.*}} void @pass_agg_v4i8(%struct.agg_v4i8* noalias sret(%struct.agg_v4i8) align 4 %{{.*}}, i32 %{{.*}}) 160 // CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_v4i8(%struct.agg_v4i8* noalias sret(%struct.agg_v4i8) align 4 %{{.*}}, <4 x i8> %{{.*}}) 161 162 struct agg_v8i8 { v8i8 a; }; 163 struct agg_v8i8 pass_agg_v8i8(struct agg_v8i8 arg) { return arg; } 164 // CHECK-LABEL: define{{.*}} void @pass_agg_v8i8(%struct.agg_v8i8* noalias sret(%struct.agg_v8i8) align 8 %{{.*}}, i64 %{{.*}}) 165 // CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_v8i8(%struct.agg_v8i8* noalias sret(%struct.agg_v8i8) align 8 %{{.*}}, <8 x i8> %{{.*}}) 166 167 struct agg_v16i8 { v16i8 a; }; 168 struct agg_v16i8 pass_agg_v16i8(struct agg_v16i8 arg) { return arg; } 169 // CHECK-LABEL: define{{.*}} void @pass_agg_v16i8(%struct.agg_v16i8* noalias sret(%struct.agg_v16i8) align 16 %{{.*}}, %struct.agg_v16i8* %{{.*}}) 170 // CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_v16i8(%struct.agg_v16i8* noalias sret(%struct.agg_v16i8) align 8 %{{.*}}, <16 x i8> %{{.*}}) 171 172 struct agg_v32i8 { v32i8 a; }; 173 struct agg_v32i8 pass_agg_v32i8(struct agg_v32i8 arg) { return arg; } 174 // CHECK-LABEL: define{{.*}} void @pass_agg_v32i8(%struct.agg_v32i8* noalias sret(%struct.agg_v32i8) align 32 %{{.*}}, %struct.agg_v32i8* %{{.*}}) 175 // CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_v32i8(%struct.agg_v32i8* noalias sret(%struct.agg_v32i8) align 8 %{{.*}}, %struct.agg_v32i8* %{{.*}}) 176 177 178 // Verify that the following are *not* vector-like aggregate types 179 180 struct agg_novector1 { v4i8 a; v4i8 b; }; 181 struct agg_novector1 pass_agg_novector1(struct agg_novector1 arg) { return arg; } 182 // CHECK-LABEL: define{{.*}} void @pass_agg_novector1(%struct.agg_novector1* noalias sret(%struct.agg_novector1) align 4 %{{.*}}, i64 %{{.*}}) 183 // CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_novector1(%struct.agg_novector1* noalias sret(%struct.agg_novector1) align 4 %{{.*}}, i64 %{{.*}}) 184 185 struct agg_novector2 { v4i8 a; float b; }; 186 struct agg_novector2 pass_agg_novector2(struct agg_novector2 arg) { return arg; } 187 // CHECK-LABEL: define{{.*}} void @pass_agg_novector2(%struct.agg_novector2* noalias sret(%struct.agg_novector2) align 4 %{{.*}}, i64 %{{.*}}) 188 // CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_novector2(%struct.agg_novector2* noalias sret(%struct.agg_novector2) align 4 %{{.*}}, i64 %{{.*}}) 189 190 struct agg_novector3 { v4i8 a; int : 0; }; 191 struct agg_novector3 pass_agg_novector3(struct agg_novector3 arg) { return arg; } 192 // CHECK-LABEL: define{{.*}} void @pass_agg_novector3(%struct.agg_novector3* noalias sret(%struct.agg_novector3) align 4 %{{.*}}, i32 %{{.*}}) 193 // CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_novector3(%struct.agg_novector3* noalias sret(%struct.agg_novector3) align 4 %{{.*}}, i32 %{{.*}}) 194 195 struct agg_novector4 { v4i8 a __attribute__((aligned (8))); }; 196 struct agg_novector4 pass_agg_novector4(struct agg_novector4 arg) { return arg; } 197 // CHECK-LABEL: define{{.*}} void @pass_agg_novector4(%struct.agg_novector4* noalias sret(%struct.agg_novector4) align 8 %{{.*}}, i64 %{{.*}}) 198 // CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_novector4(%struct.agg_novector4* noalias sret(%struct.agg_novector4) align 8 %{{.*}}, i64 %{{.*}}) 199 200 201 // Accessing variable argument lists 202 203 v1i8 va_v1i8(__builtin_va_list l) { return __builtin_va_arg(l, v1i8); } 204 // CHECK-LABEL: define{{.*}} void @va_v1i8(<1 x i8>* noalias sret(<1 x i8>) align 1 %{{.*}}, %struct.__va_list_tag* %{{.*}}) 205 // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 206 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] 207 // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 208 // CHECK: br i1 [[FITS_IN_REGS]], 209 // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 210 // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 211 // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 212 // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] 213 // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] 214 // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to <1 x i8>** 215 // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 216 // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] 217 // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 218 // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 219 // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 220 // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to <1 x i8>** 221 // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 222 // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] 223 // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi <1 x i8>** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] 224 // CHECK: [[INDIRECT_ARG:%[^ ]+]] = load <1 x i8>*, <1 x i8>** [[VA_ARG_ADDR]] 225 // CHECK: ret void 226 // CHECK-VECTOR-LABEL: define{{.*}} <1 x i8> @va_v1i8(%struct.__va_list_tag* %{{.*}}) 227 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 228 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 229 // CHECK-VECTOR: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[OVERFLOW_ARG_AREA]] to <1 x i8>* 230 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA1:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 231 // CHECK-VECTOR: store i8* [[OVERFLOW_ARG_AREA1]], i8** [[OVERFLOW_ARG_AREA_PTR]] 232 // CHECK-VECTOR: [[RET:%[^ ]+]] = load <1 x i8>, <1 x i8>* [[MEM_ADDR]] 233 // CHECK-VECTOR: ret <1 x i8> [[RET]] 234 235 v2i8 va_v2i8(__builtin_va_list l) { return __builtin_va_arg(l, v2i8); } 236 // CHECK-LABEL: define{{.*}} void @va_v2i8(<2 x i8>* noalias sret(<2 x i8>) align 2 %{{.*}}, %struct.__va_list_tag* %{{.*}}) 237 // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 238 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] 239 // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 240 // CHECK: br i1 [[FITS_IN_REGS]], 241 // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 242 // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 243 // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 244 // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] 245 // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] 246 // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to <2 x i8>** 247 // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 248 // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] 249 // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 250 // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 251 // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 252 // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to <2 x i8>** 253 // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 254 // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] 255 // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi <2 x i8>** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] 256 // CHECK: [[INDIRECT_ARG:%[^ ]+]] = load <2 x i8>*, <2 x i8>** [[VA_ARG_ADDR]] 257 // CHECK: ret void 258 // CHECK-VECTOR-LABEL: define{{.*}} <2 x i8> @va_v2i8(%struct.__va_list_tag* %{{.*}}) 259 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 260 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 261 // CHECK-VECTOR: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[OVERFLOW_ARG_AREA]] to <2 x i8>* 262 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA1:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 263 // CHECK-VECTOR: store i8* [[OVERFLOW_ARG_AREA1]], i8** [[OVERFLOW_ARG_AREA_PTR]] 264 // CHECK-VECTOR: [[RET:%[^ ]+]] = load <2 x i8>, <2 x i8>* [[MEM_ADDR]] 265 // CHECK-VECTOR: ret <2 x i8> [[RET]] 266 267 v4i8 va_v4i8(__builtin_va_list l) { return __builtin_va_arg(l, v4i8); } 268 // CHECK-LABEL: define{{.*}} void @va_v4i8(<4 x i8>* noalias sret(<4 x i8>) align 4 %{{.*}}, %struct.__va_list_tag* %{{.*}}) 269 // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 270 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] 271 // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 272 // CHECK: br i1 [[FITS_IN_REGS]], 273 // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 274 // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 275 // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 276 // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] 277 // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] 278 // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to <4 x i8>** 279 // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 280 // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] 281 // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 282 // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 283 // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 284 // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to <4 x i8>** 285 // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 286 // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] 287 // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi <4 x i8>** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] 288 // CHECK: [[INDIRECT_ARG:%[^ ]+]] = load <4 x i8>*, <4 x i8>** [[VA_ARG_ADDR]] 289 // CHECK: ret void 290 // CHECK-VECTOR-LABEL: define{{.*}} <4 x i8> @va_v4i8(%struct.__va_list_tag* %{{.*}}) 291 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 292 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 293 // CHECK-VECTOR: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[OVERFLOW_ARG_AREA]] to <4 x i8>* 294 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA1:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 295 // CHECK-VECTOR: store i8* [[OVERFLOW_ARG_AREA1]], i8** [[OVERFLOW_ARG_AREA_PTR]] 296 // CHECK-VECTOR: [[RET:%[^ ]+]] = load <4 x i8>, <4 x i8>* [[MEM_ADDR]] 297 // CHECK-VECTOR: ret <4 x i8> [[RET]] 298 299 v8i8 va_v8i8(__builtin_va_list l) { return __builtin_va_arg(l, v8i8); } 300 // CHECK-LABEL: define{{.*}} void @va_v8i8(<8 x i8>* noalias sret(<8 x i8>) align 8 %{{.*}}, %struct.__va_list_tag* %{{.*}}) 301 // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 302 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] 303 // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 304 // CHECK: br i1 [[FITS_IN_REGS]], 305 // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 306 // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 307 // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 308 // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] 309 // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] 310 // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to <8 x i8>** 311 // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 312 // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] 313 // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 314 // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 315 // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 316 // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to <8 x i8>** 317 // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 318 // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] 319 // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi <8 x i8>** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] 320 // CHECK: [[INDIRECT_ARG:%[^ ]+]] = load <8 x i8>*, <8 x i8>** [[VA_ARG_ADDR]] 321 // CHECK: ret void 322 // CHECK-VECTOR-LABEL: define{{.*}} <8 x i8> @va_v8i8(%struct.__va_list_tag* %{{.*}}) 323 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 324 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 325 // CHECK-VECTOR: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[OVERFLOW_ARG_AREA]] to <8 x i8>* 326 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA1:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 327 // CHECK-VECTOR: store i8* [[OVERFLOW_ARG_AREA1]], i8** [[OVERFLOW_ARG_AREA_PTR]] 328 // CHECK-VECTOR: [[RET:%[^ ]+]] = load <8 x i8>, <8 x i8>* [[MEM_ADDR]] 329 // CHECK-VECTOR: ret <8 x i8> [[RET]] 330 331 v16i8 va_v16i8(__builtin_va_list l) { return __builtin_va_arg(l, v16i8); } 332 // CHECK-LABEL: define{{.*}} void @va_v16i8(<16 x i8>* noalias sret(<16 x i8>) align 16 %{{.*}}, %struct.__va_list_tag* %{{.*}}) 333 // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 334 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] 335 // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 336 // CHECK: br i1 [[FITS_IN_REGS]], 337 // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 338 // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 339 // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 340 // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] 341 // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] 342 // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to <16 x i8>** 343 // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 344 // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] 345 // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 346 // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 347 // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 348 // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to <16 x i8>** 349 // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 350 // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] 351 // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi <16 x i8>** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] 352 // CHECK: [[INDIRECT_ARG:%[^ ]+]] = load <16 x i8>*, <16 x i8>** [[VA_ARG_ADDR]] 353 // CHECK: ret void 354 // CHECK-VECTOR-LABEL: define{{.*}} <16 x i8> @va_v16i8(%struct.__va_list_tag* %{{.*}}) 355 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 356 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 357 // CHECK-VECTOR: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[OVERFLOW_ARG_AREA]] to <16 x i8>* 358 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA1:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 16 359 // CHECK-VECTOR: store i8* [[OVERFLOW_ARG_AREA1]], i8** [[OVERFLOW_ARG_AREA_PTR]] 360 // CHECK-VECTOR: [[RET:%[^ ]+]] = load <16 x i8>, <16 x i8>* [[MEM_ADDR]] 361 // CHECK-VECTOR: ret <16 x i8> [[RET]] 362 363 v32i8 va_v32i8(__builtin_va_list l) { return __builtin_va_arg(l, v32i8); } 364 // CHECK-LABEL: define{{.*}} void @va_v32i8(<32 x i8>* noalias sret(<32 x i8>) align 32 %{{.*}}, %struct.__va_list_tag* %{{.*}}) 365 // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 366 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] 367 // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 368 // CHECK: br i1 [[FITS_IN_REGS]], 369 // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 370 // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 371 // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 372 // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] 373 // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] 374 // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to <32 x i8>** 375 // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 376 // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] 377 // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 378 // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 379 // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 380 // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to <32 x i8>** 381 // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 382 // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] 383 // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi <32 x i8>** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] 384 // CHECK: [[INDIRECT_ARG:%[^ ]+]] = load <32 x i8>*, <32 x i8>** [[VA_ARG_ADDR]] 385 // CHECK: ret void 386 // CHECK-VECTOR-LABEL: define{{.*}} void @va_v32i8(<32 x i8>* noalias sret(<32 x i8>) align 8 %{{.*}}, %struct.__va_list_tag* %{{.*}}) 387 // CHECK-VECTOR: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 388 // CHECK-VECTOR: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] 389 // CHECK-VECTOR: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 390 // CHECK-VECTOR: br i1 [[FITS_IN_REGS]], 391 // CHECK-VECTOR: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 392 // CHECK-VECTOR: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 393 // CHECK-VECTOR: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 394 // CHECK-VECTOR: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] 395 // CHECK-VECTOR: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] 396 // CHECK-VECTOR: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to <32 x i8>** 397 // CHECK-VECTOR: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 398 // CHECK-VECTOR: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] 399 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 400 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 401 // CHECK-VECTOR: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 402 // CHECK-VECTOR: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to <32 x i8>** 403 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 404 // CHECK-VECTOR: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] 405 // CHECK-VECTOR: [[VA_ARG_ADDR:%[^ ]+]] = phi <32 x i8>** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] 406 // CHECK-VECTOR: [[INDIRECT_ARG:%[^ ]+]] = load <32 x i8>*, <32 x i8>** [[VA_ARG_ADDR]] 407 // CHECK-VECTOR: ret void 408 409 struct agg_v1i8 va_agg_v1i8(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_v1i8); } 410 // CHECK-LABEL: define{{.*}} void @va_agg_v1i8(%struct.agg_v1i8* noalias sret(%struct.agg_v1i8) align 1 %{{.*}}, %struct.__va_list_tag* %{{.*}}) 411 // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 412 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] 413 // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 414 // CHECK: br i1 [[FITS_IN_REGS]], 415 // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 416 // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 23 417 // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 418 // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] 419 // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] 420 // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_v1i8* 421 // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 422 // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] 423 // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 424 // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 425 // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 7 426 // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_v1i8* 427 // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 428 // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] 429 // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_v1i8* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] 430 // CHECK: ret void 431 // CHECK-VECTOR-LABEL: define{{.*}} void @va_agg_v1i8(%struct.agg_v1i8* noalias sret(%struct.agg_v1i8) align 1 %{{.*}}, %struct.__va_list_tag* %{{.*}}) 432 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 433 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 434 // CHECK-VECTOR: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[OVERFLOW_ARG_AREA]] to %struct.agg_v1i8* 435 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA1:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 436 // CHECK-VECTOR: store i8* [[OVERFLOW_ARG_AREA1]], i8** [[OVERFLOW_ARG_AREA_PTR]] 437 // CHECK-VECTOR: ret void 438 439 struct agg_v2i8 va_agg_v2i8(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_v2i8); } 440 // CHECK-LABEL: define{{.*}} void @va_agg_v2i8(%struct.agg_v2i8* noalias sret(%struct.agg_v2i8) align 2 %{{.*}}, %struct.__va_list_tag* %{{.*}}) 441 // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 442 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] 443 // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 444 // CHECK: br i1 [[FITS_IN_REGS]], 445 // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 446 // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 22 447 // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 448 // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] 449 // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] 450 // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_v2i8* 451 // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 452 // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] 453 // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 454 // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 455 // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 6 456 // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_v2i8* 457 // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 458 // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] 459 // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_v2i8* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] 460 // CHECK: ret void 461 // CHECK-VECTOR-LABEL: define{{.*}} void @va_agg_v2i8(%struct.agg_v2i8* noalias sret(%struct.agg_v2i8) align 2 %{{.*}}, %struct.__va_list_tag* %{{.*}}) 462 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 463 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 464 // CHECK-VECTOR: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[OVERFLOW_ARG_AREA]] to %struct.agg_v2i8* 465 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA1:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 466 // CHECK-VECTOR: store i8* [[OVERFLOW_ARG_AREA1]], i8** [[OVERFLOW_ARG_AREA_PTR]] 467 // CHECK-VECTOR: ret void 468 469 struct agg_v4i8 va_agg_v4i8(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_v4i8); } 470 // CHECK-LABEL: define{{.*}} void @va_agg_v4i8(%struct.agg_v4i8* noalias sret(%struct.agg_v4i8) align 4 %{{.*}}, %struct.__va_list_tag* %{{.*}}) 471 // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 472 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] 473 // CHECK: [[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 // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 20 477 // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 478 // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] 479 // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] 480 // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_v4i8* 481 // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 482 // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] 483 // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 484 // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 485 // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 4 486 // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_v4i8* 487 // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 488 // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] 489 // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_v4i8* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] 490 // CHECK: ret void 491 // CHECK-VECTOR-LABEL: define{{.*}} void @va_agg_v4i8(%struct.agg_v4i8* noalias sret(%struct.agg_v4i8) align 4 %{{.*}}, %struct.__va_list_tag* %{{.*}}) 492 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 493 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 494 // CHECK-VECTOR: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[OVERFLOW_ARG_AREA]] to %struct.agg_v4i8* 495 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA1:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 496 // CHECK-VECTOR: store i8* [[OVERFLOW_ARG_AREA1]], i8** [[OVERFLOW_ARG_AREA_PTR]] 497 // CHECK-VECTOR: ret void 498 499 struct agg_v8i8 va_agg_v8i8(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_v8i8); } 500 // CHECK-LABEL: define{{.*}} void @va_agg_v8i8(%struct.agg_v8i8* noalias sret(%struct.agg_v8i8) align 8 %{{.*}}, %struct.__va_list_tag* %{{.*}}) 501 // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 502 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] 503 // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 504 // CHECK: br i1 [[FITS_IN_REGS]], 505 // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 506 // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 507 // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 508 // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] 509 // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] 510 // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_v8i8* 511 // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 512 // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] 513 // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 514 // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 515 // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 516 // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_v8i8* 517 // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 518 // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] 519 // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_v8i8* [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] 520 // CHECK: ret void 521 // CHECK-VECTOR-LABEL: define{{.*}} void @va_agg_v8i8(%struct.agg_v8i8* noalias sret(%struct.agg_v8i8) align 8 %{{.*}}, %struct.__va_list_tag* %{{.*}}) 522 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 523 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 524 // CHECK-VECTOR: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[OVERFLOW_ARG_AREA]] to %struct.agg_v8i8* 525 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA1:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 526 // CHECK-VECTOR: store i8* [[OVERFLOW_ARG_AREA1]], i8** [[OVERFLOW_ARG_AREA_PTR]] 527 // CHECK-VECTOR: ret void 528 529 struct agg_v16i8 va_agg_v16i8(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_v16i8); } 530 // CHECK-LABEL: define{{.*}} void @va_agg_v16i8(%struct.agg_v16i8* noalias sret(%struct.agg_v16i8) align 16 %{{.*}}, %struct.__va_list_tag* %{{.*}}) 531 // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 532 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] 533 // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 534 // CHECK: br i1 [[FITS_IN_REGS]], 535 // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 536 // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 537 // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 538 // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] 539 // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] 540 // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_v16i8** 541 // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 542 // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] 543 // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 544 // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 545 // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 546 // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_v16i8** 547 // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 548 // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] 549 // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_v16i8** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] 550 // CHECK: [[INDIRECT_ARG:%[^ ]+]] = load %struct.agg_v16i8*, %struct.agg_v16i8** [[VA_ARG_ADDR]] 551 // CHECK: ret void 552 // CHECK-VECTOR-LABEL: define{{.*}} void @va_agg_v16i8(%struct.agg_v16i8* noalias sret(%struct.agg_v16i8) align 8 %{{.*}}, %struct.__va_list_tag* %{{.*}}) 553 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 554 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 555 // CHECK-VECTOR: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[OVERFLOW_ARG_AREA]] to %struct.agg_v16i8* 556 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA1:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 16 557 // CHECK-VECTOR: store i8* [[OVERFLOW_ARG_AREA1]], i8** [[OVERFLOW_ARG_AREA_PTR]] 558 // CHECK-VECTOR: ret void 559 560 struct agg_v32i8 va_agg_v32i8(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_v32i8); } 561 // CHECK-LABEL: define{{.*}} void @va_agg_v32i8(%struct.agg_v32i8* noalias sret(%struct.agg_v32i8) align 32 %{{.*}}, %struct.__va_list_tag* %{{.*}}) 562 // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 563 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] 564 // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 565 // CHECK: br i1 [[FITS_IN_REGS]], 566 // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 567 // CHECK: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 568 // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 569 // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] 570 // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] 571 // CHECK: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_v32i8** 572 // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 573 // CHECK: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] 574 // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 575 // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 576 // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 577 // CHECK: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_v32i8** 578 // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 579 // CHECK: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] 580 // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_v32i8** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] 581 // CHECK: [[INDIRECT_ARG:%[^ ]+]] = load %struct.agg_v32i8*, %struct.agg_v32i8** [[VA_ARG_ADDR]] 582 // CHECK: ret void 583 // CHECK-VECTOR-LABEL: define{{.*}} void @va_agg_v32i8(%struct.agg_v32i8* noalias sret(%struct.agg_v32i8) align 8 %{{.*}}, %struct.__va_list_tag* %{{.*}}) 584 // CHECK-VECTOR: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 0 585 // CHECK-VECTOR: [[REG_COUNT:%[^ ]+]] = load i64, i64* [[REG_COUNT_PTR]] 586 // CHECK-VECTOR: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 587 // CHECK-VECTOR: br i1 [[FITS_IN_REGS]], 588 // CHECK-VECTOR: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8 589 // CHECK-VECTOR: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 16 590 // CHECK-VECTOR: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 3 591 // CHECK-VECTOR: [[REG_SAVE_AREA:%[^ ]+]] = load i8*, i8** [[REG_SAVE_AREA_PTR:[^ ]+]] 592 // CHECK-VECTOR: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i64 [[REG_OFFSET]] 593 // CHECK-VECTOR: [[REG_ADDR:%[^ ]+]] = bitcast i8* [[RAW_REG_ADDR]] to %struct.agg_v32i8** 594 // CHECK-VECTOR: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1 595 // CHECK-VECTOR: store i64 [[REG_COUNT1]], i64* [[REG_COUNT_PTR]] 596 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{.*}}, i32 0, i32 2 597 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load i8*, i8** [[OVERFLOW_ARG_AREA_PTR]] 598 // CHECK-VECTOR: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 0 599 // CHECK-VECTOR: [[MEM_ADDR:%[^ ]+]] = bitcast i8* [[RAW_MEM_ADDR]] to %struct.agg_v32i8** 600 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, i8* [[OVERFLOW_ARG_AREA]], i64 8 601 // CHECK-VECTOR: store i8* [[OVERFLOW_ARG_AREA2]], i8** [[OVERFLOW_ARG_AREA_PTR]] 602 // CHECK-VECTOR: [[VA_ARG_ADDR:%[^ ]+]] = phi %struct.agg_v32i8** [ [[REG_ADDR]], %{{.*}} ], [ [[MEM_ADDR]], %{{.*}} ] 603 // CHECK-VECTOR: [[INDIRECT_ARG:%[^ ]+]] = load %struct.agg_v32i8*, %struct.agg_v32i8** [[VA_ARG_ADDR]] 604 // CHECK-VECTOR: ret void 605