1 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -target-cpu core2 -emit-llvm -o - %s | FileCheck %s 2 // RUN: %clang_cc1 -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s 3 4 // REQUIRES: aarch64-registered-target,x86-registered-target 5 6 #define SWIFTCALL __attribute__((swiftcall)) 7 #define OUT __attribute__((swift_indirect_result)) 8 #define ERROR __attribute__((swift_error_result)) 9 #define CONTEXT __attribute__((swift_context)) 10 11 // CHECK: [[STRUCT2_RESULT:@.*]] = private {{.*}} constant [[STRUCT2_TYPE:%.*]] { i32 0, i8 0, i8 undef, i8 0, float 0.000000e+00, float 0.000000e+00 } 12 13 /*****************************************************************************/ 14 /****************************** PARAMETER ABIS *******************************/ 15 /*****************************************************************************/ 16 17 SWIFTCALL void indirect_result_1(OUT int *arg0, OUT float *arg1) {} 18 // CHECK-LABEL: define {{.*}} void @indirect_result_1(i32* noalias sret align 4 dereferenceable(4){{.*}}, float* noalias align 4 dereferenceable(4){{.*}}) 19 20 // TODO: maybe this shouldn't suppress sret. 21 SWIFTCALL int indirect_result_2(OUT int *arg0, OUT float *arg1) { __builtin_unreachable(); } 22 // CHECK-LABEL: define {{.*}} i32 @indirect_result_2(i32* noalias align 4 dereferenceable(4){{.*}}, float* noalias align 4 dereferenceable(4){{.*}}) 23 24 typedef struct { char array[1024]; } struct_reallybig; 25 SWIFTCALL struct_reallybig indirect_result_3(OUT int *arg0, OUT float *arg1) { __builtin_unreachable(); } 26 // CHECK-LABEL: define {{.*}} void @indirect_result_3({{.*}}* noalias sret {{.*}}, i32* noalias align 4 dereferenceable(4){{.*}}, float* noalias align 4 dereferenceable(4){{.*}}) 27 28 SWIFTCALL void context_1(CONTEXT void *self) {} 29 // CHECK-LABEL: define {{.*}} void @context_1(i8* swiftself 30 31 SWIFTCALL void context_2(void *arg0, CONTEXT void *self) {} 32 // CHECK-LABEL: define {{.*}} void @context_2(i8*{{.*}}, i8* swiftself 33 34 SWIFTCALL void context_error_1(CONTEXT int *self, ERROR float **error) {} 35 // CHECK-LABEL: define {{.*}} void @context_error_1(i32* swiftself{{.*}}, float** swifterror) 36 // CHECK: [[TEMP:%.*]] = alloca float*, align 8 37 // CHECK: [[T0:%.*]] = load float*, float** [[ERRORARG:%.*]], align 8 38 // CHECK: store float* [[T0]], float** [[TEMP]], align 8 39 // CHECK: [[T0:%.*]] = load float*, float** [[TEMP]], align 8 40 // CHECK: store float* [[T0]], float** [[ERRORARG]], align 8 41 void test_context_error_1() { 42 int x; 43 float *error; 44 context_error_1(&x, &error); 45 } 46 // CHECK-LABEL: define void @test_context_error_1() 47 // CHECK: [[X:%.*]] = alloca i32, align 4 48 // CHECK: [[ERROR:%.*]] = alloca float*, align 8 49 // CHECK: [[TEMP:%.*]] = alloca swifterror float*, align 8 50 // CHECK: [[T0:%.*]] = load float*, float** [[ERROR]], align 8 51 // CHECK: store float* [[T0]], float** [[TEMP]], align 8 52 // CHECK: call [[SWIFTCC:swiftcc]] void @context_error_1(i32* swiftself [[X]], float** swifterror [[TEMP]]) 53 // CHECK: [[T0:%.*]] = load float*, float** [[TEMP]], align 8 54 // CHECK: store float* [[T0]], float** [[ERROR]], align 8 55 56 SWIFTCALL void context_error_2(short s, CONTEXT int *self, ERROR float **error) {} 57 // CHECK-LABEL: define {{.*}} void @context_error_2(i16{{.*}}, i32* swiftself{{.*}}, float** swifterror) 58 59 /*****************************************************************************/ 60 /********************************** LOWERING *********************************/ 61 /*****************************************************************************/ 62 63 typedef float float4 __attribute__((ext_vector_type(4))); 64 typedef float float8 __attribute__((ext_vector_type(8))); 65 typedef double double2 __attribute__((ext_vector_type(2))); 66 typedef double double4 __attribute__((ext_vector_type(4))); 67 typedef int int3 __attribute__((ext_vector_type(3))); 68 typedef int int4 __attribute__((ext_vector_type(4))); 69 typedef int int5 __attribute__((ext_vector_type(5))); 70 typedef int int8 __attribute__((ext_vector_type(8))); 71 typedef char char16 __attribute__((ext_vector_type(16))); 72 typedef short short8 __attribute__((ext_vector_type(8))); 73 typedef long long long2 __attribute__((ext_vector_type(2))); 74 75 #define TEST(TYPE) \ 76 SWIFTCALL TYPE return_##TYPE(void) { \ 77 TYPE result = {}; \ 78 return result; \ 79 } \ 80 SWIFTCALL void take_##TYPE(TYPE v) { \ 81 } \ 82 void test_##TYPE() { \ 83 take_##TYPE(return_##TYPE()); \ 84 } 85 86 /*****************************************************************************/ 87 /*********************************** STRUCTS *********************************/ 88 /*****************************************************************************/ 89 90 typedef struct { 91 } struct_empty; 92 TEST(struct_empty); 93 // CHECK-LABEL: define {{.*}} @return_struct_empty() 94 // CHECK: ret void 95 // CHECK-LABEL: define {{.*}} @take_struct_empty() 96 // CHECK: ret void 97 98 typedef struct { 99 int x; 100 char c0; 101 char c1; 102 float f0; 103 float f1; 104 } struct_1; 105 TEST(struct_1); 106 // CHECK-LABEL: define swiftcc { i64, i64 } @return_struct_1() {{.*}}{ 107 // CHECK: [[RET:%.*]] = alloca [[STRUCT1:%.*]], align 4 108 // CHECK: [[VAR:%.*]] = alloca [[STRUCT1]], align 4 109 // CHECK: call void @llvm.memset 110 // CHECK: call void @llvm.memcpy 111 // CHECK: [[CAST:%.*]] = bitcast [[STRUCT1]]* %retval to { i64, i64 }* 112 // CHECK: [[GEP0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 0 113 // CHECK: [[T0:%.*]] = load i64, i64* [[GEP0]], align 4 114 // CHECK: [[GEP1:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 1 115 // CHECK: [[T1:%.*]] = load i64, i64* [[GEP1]], align 4 116 // CHECK: [[R0:%.*]] = insertvalue { i64, i64 } undef, i64 [[T0]], 0 117 // CHECK: [[R1:%.*]] = insertvalue { i64, i64 } [[R0]], i64 [[T1]], 1 118 // CHECK: ret { i64, i64 } [[R1]] 119 // CHECK: } 120 // CHECK-LABEL: define swiftcc void @take_struct_1(i64, i64) {{.*}}{ 121 // CHECK: [[V:%.*]] = alloca [[STRUCT1:%.*]], align 4 122 // CHECK: [[CAST:%.*]] = bitcast [[STRUCT1]]* [[V]] to { i64, i64 }* 123 // CHECK: [[GEP0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 0 124 // CHECK: store i64 %0, i64* [[GEP0]], align 4 125 // CHECK: [[GEP1:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 1 126 // CHECK: store i64 %1, i64* [[GEP1]], align 4 127 // CHECK: ret void 128 // CHECK: } 129 // CHECK-LABEL: define void @test_struct_1() {{.*}}{ 130 // CHECK: [[AGG:%.*]] = alloca [[STRUCT1:%.*]], align 4 131 // CHECK: [[RET:%.*]] = call swiftcc { i64, i64 } @return_struct_1() 132 // CHECK: [[CAST:%.*]] = bitcast [[STRUCT1]]* [[AGG]] to { i64, i64 }* 133 // CHECK: [[GEP0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 0 134 // CHECK: [[E0:%.*]] = extractvalue { i64, i64 } [[RET]], 0 135 // CHECK: store i64 [[E0]], i64* [[GEP0]], align 4 136 // CHECK: [[GEP1:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 1 137 // CHECK: [[E1:%.*]] = extractvalue { i64, i64 } [[RET]], 1 138 // CHECK: store i64 [[E1]], i64* [[GEP1]], align 4 139 // CHECK: [[CAST2:%.*]] = bitcast [[STRUCT1]]* [[AGG]] to { i64, i64 }* 140 // CHECK: [[GEP2:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST2]], i32 0, i32 0 141 // CHECK: [[V0:%.*]] = load i64, i64* [[GEP2]], align 4 142 // CHECK: [[GEP3:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST2]], i32 0, i32 1 143 // CHECK: [[V1:%.*]] = load i64, i64* [[GEP3]], align 4 144 // CHECK: call swiftcc void @take_struct_1(i64 [[V0]], i64 [[V1]]) 145 // CHECK: ret void 146 // CHECK: } 147 148 typedef struct { 149 int x; 150 char c0; 151 __attribute__((aligned(2))) char c1; 152 float f0; 153 float f1; 154 } struct_2; 155 TEST(struct_2); 156 // CHECK-LABEL: define swiftcc { i64, i64 } @return_struct_2() {{.*}}{ 157 // CHECK: [[RET:%.*]] = alloca [[STRUCT2_TYPE]], align 4 158 // CHECK: [[VAR:%.*]] = alloca [[STRUCT2_TYPE]], align 4 159 // CHECK: [[CASTVAR:%.*]] = bitcast {{.*}} [[VAR]] 160 // CHECK: call void @llvm.memcpy{{.*}}({{.*}}[[CASTVAR]], {{.*}}[[STRUCT2_RESULT]] 161 // CHECK: [[CASTRET:%.*]] = bitcast {{.*}} [[RET]] 162 // CHECK: [[CASTVAR:%.*]] = bitcast {{.*}} [[VAR]] 163 // CHECK: call void @llvm.memcpy{{.*}}({{.*}}[[CASTRET]], {{.*}}[[CASTVAR]] 164 // CHECK: [[CAST:%.*]] = bitcast [[STRUCT2_TYPE]]* [[RET]] to { i64, i64 }* 165 // CHECK: [[GEP0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 0 166 // CHECK: [[T0:%.*]] = load i64, i64* [[GEP0]], align 4 167 // CHECK: [[GEP1:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 1 168 // CHECK: [[T1:%.*]] = load i64, i64* [[GEP1]], align 4 169 // CHECK: [[R0:%.*]] = insertvalue { i64, i64 } undef, i64 [[T0]], 0 170 // CHECK: [[R1:%.*]] = insertvalue { i64, i64 } [[R0]], i64 [[T1]], 1 171 // CHECK: ret { i64, i64 } [[R1]] 172 // CHECK: } 173 // CHECK-LABEL: define swiftcc void @take_struct_2(i64, i64) {{.*}}{ 174 // CHECK: [[V:%.*]] = alloca [[STRUCT:%.*]], align 4 175 // CHECK: [[CAST:%.*]] = bitcast [[STRUCT]]* [[V]] to { i64, i64 }* 176 // CHECK: [[GEP0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 0 177 // CHECK: store i64 %0, i64* [[GEP0]], align 4 178 // CHECK: [[GEP1:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 1 179 // CHECK: store i64 %1, i64* [[GEP1]], align 4 180 // CHECK: ret void 181 // CHECK: } 182 // CHECK-LABEL: define void @test_struct_2() {{.*}} { 183 // CHECK: [[TMP:%.*]] = alloca [[STRUCT2_TYPE]], align 4 184 // CHECK: [[CALL:%.*]] = call swiftcc { i64, i64 } @return_struct_2() 185 // CHECK: [[CAST_TMP:%.*]] = bitcast [[STRUCT2_TYPE]]* [[TMP]] to { i64, i64 }* 186 // CHECK: [[GEP:%.*]] = getelementptr inbounds {{.*}} [[CAST_TMP]], i32 0, i32 0 187 // CHECK: [[T0:%.*]] = extractvalue { i64, i64 } [[CALL]], 0 188 // CHECK: store i64 [[T0]], i64* [[GEP]], align 4 189 // CHECK: [[GEP:%.*]] = getelementptr inbounds {{.*}} [[CAST_TMP]], i32 0, i32 1 190 // CHECK: [[T0:%.*]] = extractvalue { i64, i64 } [[CALL]], 1 191 // CHECK: store i64 [[T0]], i64* [[GEP]], align 4 192 // CHECK: [[CAST:%.*]] = bitcast [[STRUCT2_TYPE]]* [[TMP]] to { i64, i64 }* 193 // CHECK: [[GEP:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 0 194 // CHECK: [[R0:%.*]] = load i64, i64* [[GEP]], align 4 195 // CHECK: [[GEP:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 1 196 // CHECK: [[R1:%.*]] = load i64, i64* [[GEP]], align 4 197 // CHECK: call swiftcc void @take_struct_2(i64 [[R0]], i64 [[R1]]) 198 // CHECK: ret void 199 // CHECK: } 200 201 // There's no way to put a field randomly in the middle of an otherwise 202 // empty storage unit in C, so that case has to be tested in C++, which 203 // can use empty structs to introduce arbitrary padding. (In C, they end up 204 // with size 0 and so don't affect layout.) 205 206 // Misaligned data rule. 207 typedef struct { 208 char c0; 209 __attribute__((packed)) float f; 210 } struct_misaligned_1; 211 TEST(struct_misaligned_1) 212 // CHECK-LABEL: define swiftcc i64 @return_struct_misaligned_1() 213 // CHECK: [[RET:%.*]] = alloca [[STRUCT:%.*]], align 1 214 // CHECK: [[RES:%.*]] = alloca [[STRUCT]], align 1 215 // CHECK: [[CAST:%.*]] = bitcast [[STRUCT]]* [[RES]] to i8* 216 // CHECK: call void @llvm.memset{{.*}}(i8* [[CAST]], i8 0, i64 5 217 // CHECK: [[CASTRET:%.*]] = bitcast [[STRUCT]]* [[RET]] to i8* 218 // CHECK: [[CASTRES:%.*]] = bitcast [[STRUCT]]* [[RES]] to i8* 219 // CHECK: call void @llvm.memcpy{{.*}}(i8* [[CASTRET]], i8* [[CASTRES]], i64 5 220 // CHECK: [[CAST:%.*]] = bitcast [[STRUCT]]* [[RET]] to { i64 }* 221 // CHECK: [[GEP:%.*]] = getelementptr inbounds { i64 }, { i64 }* [[CAST]], i32 0, i32 0 222 // CHECK: [[R0:%.*]] = load i64, i64* [[GEP]], align 1 223 // CHECK: ret i64 [[R0]] 224 // CHECK:} 225 // CHECK-LABEL: define swiftcc void @take_struct_misaligned_1(i64) {{.*}}{ 226 // CHECK: [[V:%.*]] = alloca [[STRUCT:%.*]], align 1 227 // CHECK: [[CAST:%.*]] = bitcast [[STRUCT]]* [[V]] to { i64 }* 228 // CHECK: [[GEP:%.*]] = getelementptr inbounds { i64 }, { i64 }* [[CAST]], i32 0, i32 0 229 // CHECK: store i64 %0, i64* [[GEP]], align 1 230 // CHECK: ret void 231 // CHECK: } 232 // CHECK: define void @test_struct_misaligned_1() {{.*}}{ 233 // CHECK: [[AGG:%.*]] = alloca [[STRUCT:%.*]], align 1 234 // CHECK: [[CALL:%.*]] = call swiftcc i64 @return_struct_misaligned_1() 235 // CHECK: [[T0:%.*]] = bitcast [[STRUCT]]* [[AGG]] to { i64 }* 236 // CHECK: [[T1:%.*]] = getelementptr inbounds { i64 }, { i64 }* [[T0]], i32 0, i32 0 237 // CHECK: store i64 [[CALL]], i64* [[T1]], align 1 238 // CHECK: [[T0:%.*]] = bitcast [[STRUCT]]* [[AGG]] to { i64 }* 239 // CHECK: [[T1:%.*]] = getelementptr inbounds { i64 }, { i64 }* [[T0]], i32 0, i32 0 240 // CHECK: [[P:%.*]] = load i64, i64* [[T1]], align 1 241 // CHECK: call swiftcc void @take_struct_misaligned_1(i64 [[P]]) 242 // CHECK: ret void 243 // CHECK: } 244 245 // Too many scalars. 246 typedef struct { 247 long long x[5]; 248 } struct_big_1; 249 TEST(struct_big_1) 250 251 // CHECK-LABEL: define {{.*}} void @return_struct_big_1({{.*}} noalias sret 252 253 // Should not be byval. 254 // CHECK-LABEL: define {{.*}} void @take_struct_big_1({{.*}}*{{( %.*)?}}) 255 256 /*****************************************************************************/ 257 /********************************* TYPE MERGING ******************************/ 258 /*****************************************************************************/ 259 260 typedef union { 261 float f; 262 double d; 263 } union_het_fp; 264 TEST(union_het_fp) 265 // CHECK-LABEL: define swiftcc i64 @return_union_het_fp() 266 // CHECK: [[RET:%.*]] = alloca [[UNION:%.*]], align 8 267 // CHECK: [[RES:%.*]] = alloca [[UNION]], align 8 268 // CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[RES]] to i8* 269 // CHECK: call void @llvm.memcpy{{.*}}(i8* [[CAST]] 270 // CHECK: [[CASTRET:%.*]] = bitcast [[UNION]]* [[RET]] to i8* 271 // CHECK: [[CASTRES:%.*]] = bitcast [[UNION]]* [[RES]] to i8* 272 // CHECK: call void @llvm.memcpy{{.*}}(i8* [[CASTRET]], i8* [[CASTRES]] 273 // CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[RET]] to { i64 }* 274 // CHECK: [[GEP:%.*]] = getelementptr inbounds { i64 }, { i64 }* [[CAST]], i32 0, i32 0 275 // CHECK: [[R0:%.*]] = load i64, i64* [[GEP]], align 8 276 // CHECK: ret i64 [[R0]] 277 // CHECK-LABEL: define swiftcc void @take_union_het_fp(i64) {{.*}}{ 278 // CHECK: [[V:%.*]] = alloca [[UNION:%.*]], align 8 279 // CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[V]] to { i64 }* 280 // CHECK: [[GEP:%.*]] = getelementptr inbounds { i64 }, { i64 }* [[CAST]], i32 0, i32 0 281 // CHECK: store i64 %0, i64* [[GEP]], align 8 282 // CHECK: ret void 283 // CHECK: } 284 // CHECK-LABEL: define void @test_union_het_fp() {{.*}}{ 285 // CHECK: [[AGG:%.*]] = alloca [[UNION:%.*]], align 8 286 // CHECK: [[CALL:%.*]] = call swiftcc i64 @return_union_het_fp() 287 // CHECK: [[T0:%.*]] = bitcast [[UNION]]* [[AGG]] to { i64 }* 288 // CHECK: [[T1:%.*]] = getelementptr inbounds { i64 }, { i64 }* [[T0]], i32 0, i32 0 289 // CHECK: store i64 [[CALL]], i64* [[T1]], align 8 290 // CHECK: [[T0:%.*]] = bitcast [[UNION]]* [[AGG]] to { i64 }* 291 // CHECK: [[T1:%.*]] = getelementptr inbounds { i64 }, { i64 }* [[T0]], i32 0, i32 0 292 // CHECK: [[V0:%.*]] = load i64, i64* [[T1]], align 8 293 // CHECK: call swiftcc void @take_union_het_fp(i64 [[V0]]) 294 // CHECK: ret void 295 // CHECK: } 296 297 298 typedef union { 299 float f1; 300 float f2; 301 } union_hom_fp; 302 TEST(union_hom_fp) 303 // CHECK-LABEL: define void @test_union_hom_fp() 304 // CHECK: [[TMP:%.*]] = alloca [[REC:%.*]], align 4 305 // CHECK: [[CALL:%.*]] = call [[SWIFTCC]] float @return_union_hom_fp() 306 // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG:{ float }]]* 307 // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 308 // CHECK: store float [[CALL]], float* [[T0]], align 4 309 // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]* 310 // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 311 // CHECK: [[FIRST:%.*]] = load float, float* [[T0]], align 4 312 // CHECK: call [[SWIFTCC]] void @take_union_hom_fp(float [[FIRST]]) 313 // CHECK: ret void 314 315 typedef union { 316 float f1; 317 float4 fv2; 318 } union_hom_fp_partial; 319 TEST(union_hom_fp_partial) 320 // CHECK: define void @test_union_hom_fp_partial() 321 // CHECK: [[AGG:%.*]] = alloca [[UNION:%.*]], align 16 322 // CHECK: [[CALL:%.*]] = call swiftcc { i64, i64 } @return_union_hom_fp_partial() 323 // CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[AGG]] to { i64, i64 }* 324 // CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 0 325 // CHECK: [[T1:%.*]] = extractvalue { i64, i64 } [[CALL]], 0 326 // CHECK: store i64 [[T1]], i64* [[T0]], align 16 327 // CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 1 328 // CHECK: [[T1:%.*]] = extractvalue { i64, i64 } [[CALL]], 1 329 // CHECK: store i64 [[T1]], i64* [[T0]], align 8 330 // CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[AGG]] to { i64, i64 }* 331 // CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 0 332 // CHECK: [[V0:%.*]] = load i64, i64* [[T0]], align 16 333 // CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 1 334 // CHECK: [[V1:%.*]] = load i64, i64* [[T0]], align 8 335 // CHECK: call swiftcc void @take_union_hom_fp_partial(i64 [[V0]], i64 [[V1]]) 336 // CHECK: ret void 337 // CHECK: } 338 339 typedef union { 340 struct { int x, y; } f1; 341 float4 fv2; 342 } union_het_fpv_partial; 343 TEST(union_het_fpv_partial) 344 // CHECK-LABEL: define void @test_union_het_fpv_partial() 345 // CHECK: [[AGG:%.*]] = alloca [[UNION:%.*]], align 16 346 // CHECK: [[CALL:%.*]] = call swiftcc { i64, i64 } @return_union_het_fpv_partial() 347 // CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[AGG]] to { i64, i64 }* 348 // CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 0 349 // CHECK: [[T1:%.*]] = extractvalue { i64, i64 } [[CALL]], 0 350 // CHECK: store i64 [[T1]], i64* [[T0]], align 16 351 // CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 1 352 // CHECK: [[T1:%.*]] = extractvalue { i64, i64 } [[CALL]], 1 353 // CHECK: store i64 [[T1]], i64* [[T0]], align 8 354 // CHECK: [[CAST:%.*]] = bitcast [[UNION]]* [[AGG]] to { i64, i64 }* 355 // CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 0 356 // CHECK: [[V0:%.*]] = load i64, i64* [[T0]], align 16 357 // CHECK: [[T0:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[CAST]], i32 0, i32 1 358 // CHECK: [[V1:%.*]] = load i64, i64* [[T0]], align 8 359 // CHECK: call swiftcc void @take_union_het_fpv_partial(i64 [[V0]], i64 [[V1]]) 360 // CHECK: ret void 361 // CHECK: } 362 363 /*****************************************************************************/ 364 /****************************** VECTOR LEGALIZATION **************************/ 365 /*****************************************************************************/ 366 367 TEST(int4) 368 // CHECK-LABEL: define {{.*}} <4 x i32> @return_int4() 369 // CHECK-LABEL: define {{.*}} @take_int4(<4 x i32> 370 371 TEST(int8) 372 // CHECK-LABEL: define {{.*}} @return_int8() 373 // CHECK: [[RET:%.*]] = alloca [[REC:<8 x i32>]], align 16 374 // CHECK: [[VAR:%.*]] = alloca [[REC]], align 375 // CHECK: store 376 // CHECK: load 377 // CHECK: store 378 // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[RET]] to [[AGG:{ <4 x i32>, <4 x i32> }]]* 379 // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 380 // CHECK: [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align 381 // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 382 // CHECK: [[SECOND:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align 383 // CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ <4 x i32>, <4 x i32> }]] undef, <4 x i32> [[FIRST]], 0 384 // CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], <4 x i32> [[SECOND]], 1 385 // CHECK: ret [[UAGG]] [[T1]] 386 // CHECK-LABEL: define {{.*}} @take_int8(<4 x i32>, <4 x i32>) 387 // CHECK: [[V:%.*]] = alloca [[REC]], align 388 // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[V]] to [[AGG]]* 389 // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 390 // CHECK: store <4 x i32> %0, <4 x i32>* [[T0]], align 391 // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 392 // CHECK: store <4 x i32> %1, <4 x i32>* [[T0]], align 393 // CHECK: ret void 394 // CHECK-LABEL: define void @test_int8() 395 // CHECK: [[TMP1:%.*]] = alloca [[REC]], align 396 // CHECK: [[TMP2:%.*]] = alloca [[REC]], align 397 // CHECK: [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_int8() 398 // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP1]] to [[AGG]]* 399 // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 400 // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0 401 // CHECK: store <4 x i32> [[T1]], <4 x i32>* [[T0]], align 402 // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 403 // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1 404 // CHECK: store <4 x i32> [[T1]], <4 x i32>* [[T0]], align 405 // CHECK: [[V:%.*]] = load [[REC]], [[REC]]* [[TMP1]], align 406 // CHECK: store [[REC]] [[V]], [[REC]]* [[TMP2]], align 407 // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP2]] to [[AGG]]* 408 // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 409 // CHECK: [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align 410 // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 411 // CHECK: [[SECOND:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align 412 // CHECK: call [[SWIFTCC]] void @take_int8(<4 x i32> [[FIRST]], <4 x i32> [[SECOND]]) 413 // CHECK: ret void 414 415 TEST(int5) 416 // CHECK-LABEL: define {{.*}} @return_int5() 417 // CHECK: [[RET:%.*]] = alloca [[REC:<5 x i32>]], align 16 418 // CHECK: [[VAR:%.*]] = alloca [[REC]], align 419 // CHECK: store 420 // CHECK: load 421 // CHECK: store 422 // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[RET]] to [[AGG:{ <4 x i32>, i32 }]]* 423 // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 424 // CHECK: [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align 425 // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 426 // CHECK: [[SECOND:%.*]] = load i32, i32* [[T0]], align 427 // CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ <4 x i32>, i32 }]] undef, <4 x i32> [[FIRST]], 0 428 // CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], i32 [[SECOND]], 1 429 // CHECK: ret [[UAGG]] [[T1]] 430 // CHECK-LABEL: define {{.*}} @take_int5(<4 x i32>, i32) 431 // CHECK: [[V:%.*]] = alloca [[REC]], align 432 // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[V]] to [[AGG]]* 433 // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 434 // CHECK: store <4 x i32> %0, <4 x i32>* [[T0]], align 435 // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 436 // CHECK: store i32 %1, i32* [[T0]], align 437 // CHECK: ret void 438 // CHECK-LABEL: define void @test_int5() 439 // CHECK: [[TMP1:%.*]] = alloca [[REC]], align 440 // CHECK: [[TMP2:%.*]] = alloca [[REC]], align 441 // CHECK: [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_int5() 442 // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP1]] to [[AGG]]* 443 // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 444 // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0 445 // CHECK: store <4 x i32> [[T1]], <4 x i32>* [[T0]], align 446 // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 447 // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1 448 // CHECK: store i32 [[T1]], i32* [[T0]], align 449 // CHECK: [[V:%.*]] = load [[REC]], [[REC]]* [[TMP1]], align 450 // CHECK: store [[REC]] [[V]], [[REC]]* [[TMP2]], align 451 // CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP2]] to [[AGG]]* 452 // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 453 // CHECK: [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align 454 // CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 455 // CHECK: [[SECOND:%.*]] = load i32, i32* [[T0]], align 456 // CHECK: call [[SWIFTCC]] void @take_int5(<4 x i32> [[FIRST]], i32 [[SECOND]]) 457 // CHECK: ret void 458 459 typedef struct { 460 int x; 461 int3 v __attribute__((packed)); 462 } misaligned_int3; 463 TEST(misaligned_int3) 464 // CHECK-LABEL: define swiftcc void @take_misaligned_int3(i64, i64) 465 466 typedef struct { 467 float f0; 468 } struct_f1; 469 TEST(struct_f1) 470 // CHECK-LABEL: define swiftcc float @return_struct_f1() 471 // CHECK-LABEL: define swiftcc void @take_struct_f1(float) 472 473 typedef struct { 474 float f0; 475 float f1; 476 } struct_f2; 477 TEST(struct_f2) 478 // CHECK-LABEL: define swiftcc i64 @return_struct_f2() 479 // CHECK-LABEL: define swiftcc void @take_struct_f2(i64) 480 481 typedef struct { 482 float f0; 483 float f1; 484 float f2; 485 } struct_f3; 486 TEST(struct_f3) 487 // CHECK-LABEL: define swiftcc { i64, float } @return_struct_f3() 488 // CHECK-LABEL: define swiftcc void @take_struct_f3(i64, float) 489 490 typedef struct { 491 float f0; 492 float f1; 493 float f2; 494 float f3; 495 } struct_f4; 496 TEST(struct_f4) 497 // CHECK-LABEL: define swiftcc { i64, i64 } @return_struct_f4() 498 // CHECK-LABEL: define swiftcc void @take_struct_f4(i64, i64) 499 500 501 typedef struct { 502 double d0; 503 } struct_d1; 504 TEST(struct_d1) 505 // CHECK-LABEL: define swiftcc double @return_struct_d1() 506 // CHECK-LABEL: define swiftcc void @take_struct_d1(double) 507 508 typedef struct { 509 double d0; 510 double d1; 511 } struct_d2; 512 TEST(struct_d2) 513 514 // CHECK-LABEL: define swiftcc { double, double } @return_struct_d2() 515 // CHECK-LABEL: define swiftcc void @take_struct_d2(double, double) 516 typedef struct { 517 double d0; 518 double d1; 519 double d2; 520 } struct_d3; 521 TEST(struct_d3) 522 // CHECK-LABEL: define swiftcc { double, double, double } @return_struct_d3() 523 // CHECK-LABEL: define swiftcc void @take_struct_d3(double, double, double) 524 525 typedef struct { 526 double d0; 527 double d1; 528 double d2; 529 double d3; 530 } struct_d4; 531 TEST(struct_d4) 532 // CHECK-LABEL: define swiftcc { double, double, double, double } @return_struct_d4() 533 // CHECK-LABEL: define swiftcc void @take_struct_d4(double, double, double, double) 534 535 typedef struct { 536 double d0; 537 double d1; 538 double d2; 539 double d3; 540 double d4; 541 } struct_d5; 542 TEST(struct_d5) 543 // CHECK: define swiftcc void @return_struct_d5([[STRUCT5:%.*]]* noalias sret 544 // CHECK: define swiftcc void @take_struct_d5([[STRUCT5]] 545 546 typedef struct { 547 char c0; 548 } struct_c1; 549 TEST(struct_c1) 550 // CHECK-LABEL: define swiftcc i8 @return_struct_c1() 551 // CHECK-LABEL: define swiftcc void @take_struct_c1(i8) 552 553 typedef struct { 554 char c0; 555 char c1; 556 } struct_c2; 557 TEST(struct_c2) 558 // CHECK-LABEL: define swiftcc i16 @return_struct_c2() 559 // CHECK-LABEL: define swiftcc void @take_struct_c2(i16) 560 // 561 562 typedef struct { 563 char c0; 564 char c1; 565 char c2; 566 } struct_c3; 567 TEST(struct_c3) 568 // CHECK-LABEL: define swiftcc i32 @return_struct_c3() 569 // CHECK-LABEL: define swiftcc void @take_struct_c3(i32) 570 571 typedef struct { 572 char c0; 573 char c1; 574 char c2; 575 char c3; 576 } struct_c4; 577 TEST(struct_c4) 578 // CHECK-LABEL: define swiftcc i32 @return_struct_c4() 579 // CHECK-LABEL: define swiftcc void @take_struct_c4(i32) 580 581 typedef struct { 582 char c0; 583 char c1; 584 char c2; 585 char c3; 586 char c4; 587 } struct_c5; 588 TEST(struct_c5) 589 // CHECK-LABEL: define swiftcc i64 @return_struct_c5() 590 // CHECK-LABEL: define swiftcc void @take_struct_c5(i64) 591 // 592 typedef struct { 593 char c0; 594 char c1; 595 char c2; 596 char c3; 597 char c4; 598 char c5; 599 char c6; 600 char c7; 601 char c8; 602 } struct_c9; 603 TEST(struct_c9) 604 // CHECK-LABEL: define swiftcc { i64, i8 } @return_struct_c9() 605 // CHECK-LABEL: define swiftcc void @take_struct_c9(i64, i8) 606 607 typedef struct { 608 short s0; 609 } struct_s1; 610 TEST(struct_s1) 611 // CHECK-LABEL: define swiftcc i16 @return_struct_s1() 612 // CHECK-LABEL: define swiftcc void @take_struct_s1(i16) 613 614 typedef struct { 615 short s0; 616 short s1; 617 } struct_s2; 618 TEST(struct_s2) 619 // CHECK-LABEL: define swiftcc i32 @return_struct_s2() 620 // CHECK-LABEL: define swiftcc void @take_struct_s2(i32) 621 // 622 623 typedef struct { 624 short s0; 625 short s1; 626 short s2; 627 } struct_s3; 628 TEST(struct_s3) 629 // CHECK-LABEL: define swiftcc i64 @return_struct_s3() 630 // CHECK-LABEL: define swiftcc void @take_struct_s3(i64) 631 632 typedef struct { 633 short s0; 634 short s1; 635 short s2; 636 short s3; 637 } struct_s4; 638 TEST(struct_s4) 639 // CHECK-LABEL: define swiftcc i64 @return_struct_s4() 640 // CHECK-LABEL: define swiftcc void @take_struct_s4(i64) 641 642 typedef struct { 643 short s0; 644 short s1; 645 short s2; 646 short s3; 647 short s4; 648 } struct_s5; 649 TEST(struct_s5) 650 // CHECK-LABEL: define swiftcc { i64, i16 } @return_struct_s5() 651 // CHECK-LABEL: define swiftcc void @take_struct_s5(i64, i16) 652 653 654 typedef struct { 655 int i0; 656 } struct_i1; 657 TEST(struct_i1) 658 // CHECK-LABEL: define swiftcc i32 @return_struct_i1() 659 // CHECK-LABEL: define swiftcc void @take_struct_i1(i32) 660 661 typedef struct { 662 int i0; 663 int i1; 664 } struct_i2; 665 TEST(struct_i2) 666 // CHECK-LABEL: define swiftcc i64 @return_struct_i2() 667 // CHECK-LABEL: define swiftcc void @take_struct_i2(i64) 668 669 typedef struct { 670 int i0; 671 int i1; 672 int i2; 673 } struct_i3; 674 TEST(struct_i3) 675 // CHECK-LABEL: define swiftcc { i64, i32 } @return_struct_i3() 676 // CHECK-LABEL: define swiftcc void @take_struct_i3(i64, i32) 677 678 typedef struct { 679 int i0; 680 int i1; 681 int i2; 682 int i3; 683 } struct_i4; 684 TEST(struct_i4) 685 // CHECK-LABEL: define swiftcc { i64, i64 } @return_struct_i4() 686 // CHECK-LABEL: define swiftcc void @take_struct_i4(i64, i64) 687 688 typedef struct { 689 long long l0; 690 } struct_l1; 691 TEST(struct_l1) 692 // CHECK-LABEL: define swiftcc i64 @return_struct_l1() 693 // CHECK-LABEL: define swiftcc void @take_struct_l1(i64) 694 695 typedef struct { 696 long long l0; 697 long long l1; 698 } struct_l2; 699 TEST(struct_l2) 700 // CHECK-LABEL: define swiftcc { i64, i64 } @return_struct_l2() 701 // CHECK-LABEL: define swiftcc void @take_struct_l2(i64, i64) 702 703 typedef struct { 704 long long l0; 705 long long l1; 706 long long l2; 707 } struct_l3; 708 TEST(struct_l3) 709 // CHECK-LABEL: define swiftcc { i64, i64, i64 } @return_struct_l3() 710 // CHECK-LABEL: define swiftcc void @take_struct_l3(i64, i64, i64) 711 712 typedef struct { 713 long long l0; 714 long long l1; 715 long long l2; 716 long long l3; 717 } struct_l4; 718 TEST(struct_l4) 719 // CHECK-LABEL: define swiftcc { i64, i64, i64, i64 } @return_struct_l4() 720 // CHECK-LABEL: define swiftcc void @take_struct_l4(i64, i64, i64, i64) 721 722 typedef struct { 723 long long l0; 724 long long l1; 725 long long l2; 726 long long l3; 727 long long l4; 728 } struct_l5; 729 TEST(struct_l5) 730 // CHECK: define swiftcc void @return_struct_l5([[STRUCT5:%.*]]* noalias sret 731 // CHECK: define swiftcc void @take_struct_l5([[STRUCT5]]* 732 733 typedef struct { 734 char16 c0; 735 } struct_vc1; 736 TEST(struct_vc1) 737 // CHECK-LABEL: define swiftcc <16 x i8> @return_struct_vc1() 738 // CHECK-LABEL: define swiftcc void @take_struct_vc1(<16 x i8>) 739 740 typedef struct { 741 char16 c0; 742 char16 c1; 743 } struct_vc2; 744 TEST(struct_vc2) 745 // CHECK-LABEL: define swiftcc { <16 x i8>, <16 x i8> } @return_struct_vc2() 746 // CHECK-LABEL: define swiftcc void @take_struct_vc2(<16 x i8>, <16 x i8>) 747 748 typedef struct { 749 char16 c0; 750 char16 c1; 751 char16 c2; 752 } struct_vc3; 753 TEST(struct_vc3) 754 // CHECK-LABEL: define swiftcc { <16 x i8>, <16 x i8>, <16 x i8> } @return_struct_vc3() 755 // CHECK-LABEL: define swiftcc void @take_struct_vc3(<16 x i8>, <16 x i8>, <16 x i8>) 756 757 typedef struct { 758 char16 c0; 759 char16 c1; 760 char16 c2; 761 char16 c3; 762 } struct_vc4; 763 TEST(struct_vc4) 764 // CHECK-LABEL: define swiftcc { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } @return_struct_vc4() 765 // CHECK-LABEL: define swiftcc void @take_struct_vc4(<16 x i8>, <16 x i8>, <16 x i8>, <16 x i8>) 766 767 typedef struct { 768 char16 c0; 769 char16 c1; 770 char16 c2; 771 char16 c3; 772 char16 c4; 773 } struct_vc5; 774 TEST(struct_vc5) 775 // CHECK: define swiftcc void @return_struct_vc5([[STRUCT:%.*]]* noalias sret 776 // CHECK: define swiftcc void @take_struct_vc5([[STRUCT]] 777 778 typedef struct { 779 short8 c0; 780 } struct_vs1; 781 TEST(struct_vs1) 782 // CHECK-LABEL: define swiftcc <8 x i16> @return_struct_vs1() 783 // CHECK-LABEL: define swiftcc void @take_struct_vs1(<8 x i16>) 784 785 typedef struct { 786 short8 c0; 787 short8 c1; 788 } struct_vs2; 789 TEST(struct_vs2) 790 // CHECK-LABEL: define swiftcc { <8 x i16>, <8 x i16> } @return_struct_vs2() 791 // CHECK-LABEL: define swiftcc void @take_struct_vs2(<8 x i16>, <8 x i16>) 792 793 typedef struct { 794 short8 c0; 795 short8 c1; 796 short8 c2; 797 } struct_vs3; 798 TEST(struct_vs3) 799 // CHECK-LABEL: define swiftcc { <8 x i16>, <8 x i16>, <8 x i16> } @return_struct_vs3() 800 // CHECK-LABEL: define swiftcc void @take_struct_vs3(<8 x i16>, <8 x i16>, <8 x i16>) 801 802 typedef struct { 803 short8 c0; 804 short8 c1; 805 short8 c2; 806 short8 c3; 807 } struct_vs4; 808 TEST(struct_vs4) 809 // CHECK-LABEL: define swiftcc { <8 x i16>, <8 x i16>, <8 x i16>, <8 x i16> } @return_struct_vs4() 810 // CHECK-LABEL: define swiftcc void @take_struct_vs4(<8 x i16>, <8 x i16>, <8 x i16>, <8 x i16>) 811 812 typedef struct { 813 short8 c0; 814 short8 c1; 815 short8 c2; 816 short8 c3; 817 short8 c4; 818 } struct_vs5; 819 TEST(struct_vs5) 820 // CHECK: define swiftcc void @return_struct_vs5([[STRUCT:%.*]]* noalias sret 821 // CHECK: define swiftcc void @take_struct_vs5([[STRUCT]] 822 823 typedef struct { 824 int4 c0; 825 } struct_vi1; 826 TEST(struct_vi1) 827 // CHECK-LABEL: define swiftcc <4 x i32> @return_struct_vi1() 828 // CHECK-LABEL: define swiftcc void @take_struct_vi1(<4 x i32>) 829 830 typedef struct { 831 int4 c0; 832 int4 c1; 833 } struct_vi2; 834 TEST(struct_vi2) 835 // CHECK-LABEL: define swiftcc { <4 x i32>, <4 x i32> } @return_struct_vi2() 836 // CHECK-LABEL: define swiftcc void @take_struct_vi2(<4 x i32>, <4 x i32>) 837 838 typedef struct { 839 int4 c0; 840 int4 c1; 841 int4 c2; 842 } struct_vi3; 843 TEST(struct_vi3) 844 // CHECK-LABEL: define swiftcc { <4 x i32>, <4 x i32>, <4 x i32> } @return_struct_vi3() 845 // CHECK-LABEL: define swiftcc void @take_struct_vi3(<4 x i32>, <4 x i32>, <4 x i32>) 846 847 typedef struct { 848 int4 c0; 849 int4 c1; 850 int4 c2; 851 int4 c3; 852 } struct_vi4; 853 TEST(struct_vi4) 854 // CHECK-LABEL: define swiftcc { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } @return_struct_vi4() 855 // CHECK-LABEL: define swiftcc void @take_struct_vi4(<4 x i32>, <4 x i32>, <4 x i32>, <4 x i32>) 856 857 typedef struct { 858 int4 c0; 859 int4 c1; 860 int4 c2; 861 int4 c3; 862 int4 c4; 863 } struct_vi5; 864 TEST(struct_vi5) 865 // CHECK: define swiftcc void @return_struct_vi5([[STRUCT:%.*]]* noalias sret 866 // CHECK: define swiftcc void @take_struct_vi5([[STRUCT]] 867 868 typedef struct { 869 long2 c0; 870 } struct_vl1; 871 TEST(struct_vl1) 872 // CHECK-LABEL: define swiftcc <2 x i64> @return_struct_vl1() 873 // CHECK-LABEL: define swiftcc void @take_struct_vl1(<2 x i64>) 874 875 typedef struct { 876 long2 c0; 877 long2 c1; 878 long2 c2; 879 long2 c3; 880 } struct_vl4; 881 TEST(struct_vl4) 882 // CHECK-LABEL: define swiftcc { <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @return_struct_vl4() 883 // CHECK-LABEL: define swiftcc void @take_struct_vl4(<2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>) 884 885 typedef struct { 886 long2 c0; 887 long2 c1; 888 long2 c2; 889 long2 c3; 890 long2 c4; 891 } struct_vl5; 892 TEST(struct_vl5) 893 // CHECK: define swiftcc void @return_struct_vl5([[STRUCT:%.*]]* noalias sret 894 // CHECK: define swiftcc void @take_struct_vl5([[STRUCT]] 895 896 typedef struct { 897 double2 c0; 898 } struct_vd1; 899 TEST(struct_vd1) 900 // CHECK-LABEL: define swiftcc <2 x double> @return_struct_vd1() 901 // CHECK-LABEL: define swiftcc void @take_struct_vd1(<2 x double>) 902 903 typedef struct { 904 double2 c0; 905 double2 c1; 906 double2 c2; 907 double2 c3; 908 } struct_vd4; 909 TEST(struct_vd4) 910 // CHECK-LABEL: define swiftcc { <2 x double>, <2 x double>, <2 x double>, <2 x double> } @return_struct_vd4() 911 // CHECK-LABEL: define swiftcc void @take_struct_vd4(<2 x double>, <2 x double>, <2 x double>, <2 x double>) 912 913 typedef struct { 914 double2 c0; 915 double2 c1; 916 double2 c2; 917 double2 c3; 918 double2 c4; 919 } struct_vd5; 920 TEST(struct_vd5) 921 // CHECK: define swiftcc void @return_struct_vd5([[STRUCT:%.*]]* noalias sret 922 // CHECK: define swiftcc void @take_struct_vd5([[STRUCT]] 923 924 typedef struct { 925 double4 c0; 926 } struct_vd41; 927 TEST(struct_vd41) 928 // CHECK-LABEL: define swiftcc { <2 x double>, <2 x double> } @return_struct_vd41() 929 // CHECK-LABEL: define swiftcc void @take_struct_vd41(<2 x double>, <2 x double>) 930 931 typedef struct { 932 double4 c0; 933 double4 c1; 934 } struct_vd42; 935 TEST(struct_vd42) 936 // CHECK-LABEL: define swiftcc { <2 x double>, <2 x double>, <2 x double>, <2 x double> } @return_struct_vd42() 937 // CHECK-LABEL: define swiftcc void @take_struct_vd42(<2 x double>, <2 x double>, <2 x double>, <2 x double>) 938 939 typedef struct { 940 double4 c0; 941 double4 c1; 942 double4 c2; 943 } struct_vd43; 944 TEST(struct_vd43) 945 // CHECK: define swiftcc void @return_struct_vd43([[STRUCT:%.*]]* noalias sret 946 // CHECK: define swiftcc void @take_struct_vd43([[STRUCT]] 947 948 typedef struct { 949 float4 c0; 950 } struct_vf1; 951 TEST(struct_vf1) 952 // CHECK-LABEL: define swiftcc <4 x float> @return_struct_vf1() 953 // CHECK-LABEL: define swiftcc void @take_struct_vf1(<4 x float>) 954 955 typedef struct { 956 float4 c0; 957 float4 c1; 958 } struct_vf2; 959 TEST(struct_vf2) 960 // CHECK-LABEL: define swiftcc { <4 x float>, <4 x float> } @return_struct_vf2() 961 // CHECK-LABEL: define swiftcc void @take_struct_vf2(<4 x float>, <4 x float>) 962 963 typedef struct { 964 float4 c0; 965 float4 c1; 966 float4 c2; 967 float4 c3; 968 } struct_vf4; 969 TEST(struct_vf4) 970 // CHECK-LABEL: define swiftcc { <4 x float>, <4 x float>, <4 x float>, <4 x float> } @return_struct_vf4() 971 // CHECK-LABEL: define swiftcc void @take_struct_vf4(<4 x float>, <4 x float>, <4 x float>, <4 x float>) 972 973 typedef struct { 974 float4 c0; 975 float4 c1; 976 float4 c2; 977 float4 c3; 978 float4 c4; 979 } struct_vf5; 980 TEST(struct_vf5) 981 // CHECK: define swiftcc void @return_struct_vf5([[STRUCT:%.*]]* noalias sret 982 // CHECK: define swiftcc void @take_struct_vf5([[STRUCT]] 983 984 typedef struct { 985 float8 c0; 986 } struct_vf81; 987 TEST(struct_vf81) 988 // CHECK-LABEL: define swiftcc { <4 x float>, <4 x float> } @return_struct_vf81() 989 // CHECK-LABEL: define swiftcc void @take_struct_vf81(<4 x float>, <4 x float>) 990 991 // Don't crash. 992 typedef union { 993 int4 v[2]; 994 struct { 995 int LSW; 996 int d7; 997 int d6; 998 int d5; 999 int d4; 1000 int d3; 1001 int d2; 1002 int MSW; 1003 } s; 1004 } union_het_vecint; 1005 TEST(union_het_vecint) 1006 // CHECK: define swiftcc void @return_union_het_vecint([[UNION:%.*]]* noalias sret 1007 // CHECK: define swiftcc void @take_union_het_vecint([[UNION]]* 1008