1 // RUN: %clang_cc1 -triple x86_64-unknown-windows -emit-llvm -target-cpu core2 -o - %s | FileCheck %s 2 3 #define SWIFTCALL __attribute__((swiftcall)) 4 #define OUT __attribute__((swift_indirect_result)) 5 #define ERROR __attribute__((swift_error_result)) 6 #define CONTEXT __attribute__((swift_context)) 7 8 /*****************************************************************************/ 9 /****************************** PARAMETER ABIS *******************************/ 10 /*****************************************************************************/ 11 12 SWIFTCALL void indirect_result_1(OUT int *arg0, OUT float *arg1) {} 13 // CHECK-LABEL: define {{.*}} void @indirect_result_1(ptr noalias noundef sret(ptr) align 4 dereferenceable(4){{.*}}, ptr noalias noundef align 4 dereferenceable(4){{.*}}) 14 15 // TODO: maybe this shouldn't suppress sret. 16 SWIFTCALL int indirect_result_2(OUT int *arg0, OUT float *arg1) { __builtin_unreachable(); } 17 // CHECK-LABEL: define {{.*}} i32 @indirect_result_2(ptr noalias noundef align 4 dereferenceable(4){{.*}}, ptr noalias noundef align 4 dereferenceable(4){{.*}}) 18 19 typedef struct { char array[1024]; } struct_reallybig; 20 SWIFTCALL struct_reallybig indirect_result_3(OUT int *arg0, OUT float *arg1) { __builtin_unreachable(); } 21 // CHECK-LABEL: define {{.*}} void @indirect_result_3(ptr dead_on_unwind noalias writable sret({{.*}}) {{.*}}, ptr noalias noundef align 4 dereferenceable(4){{.*}}, ptr noalias noundef align 4 dereferenceable(4){{.*}}) 22 23 SWIFTCALL void context_1(CONTEXT void *self) {} 24 // CHECK-LABEL: define {{.*}} void @context_1(ptr noundef swiftself 25 26 SWIFTCALL void context_2(void *arg0, CONTEXT void *self) {} 27 // CHECK-LABEL: define {{.*}} void @context_2(ptr{{.*}}, ptr noundef swiftself 28 29 SWIFTCALL void context_error_1(CONTEXT int *self, ERROR float **error) {} 30 // CHECK-LABEL: define {{.*}} void @context_error_1(ptr noundef swiftself{{.*}}, ptr noundef swifterror %0) 31 // CHECK: [[TEMP:%.*]] = alloca ptr, align 8 32 // CHECK: [[T0:%.*]] = load ptr, ptr [[ERRORARG:%.*]], align 8 33 // CHECK: store ptr [[T0]], ptr [[TEMP]], align 8 34 // CHECK: [[T0:%.*]] = load ptr, ptr [[TEMP]], align 8 35 // CHECK: store ptr [[T0]], ptr [[ERRORARG]], align 8 36 void test_context_error_1(void) { 37 int x; 38 float *error; 39 context_error_1(&x, &error); 40 } 41 // CHECK-LABEL: define dso_local void @test_context_error_1() 42 // CHECK: [[X:%.*]] = alloca i32, align 4 43 // CHECK: [[ERROR:%.*]] = alloca ptr, align 8 44 // CHECK: [[TEMP:%.*]] = alloca swifterror ptr, align 8 45 // CHECK: [[T0:%.*]] = load ptr, ptr [[ERROR]], align 8 46 // CHECK: store ptr [[T0]], ptr [[TEMP]], align 8 47 // CHECK: call [[SWIFTCC:swiftcc]] void @context_error_1(ptr noundef swiftself [[X]], ptr noundef swifterror [[TEMP]]) 48 // CHECK: [[T0:%.*]] = load ptr, ptr [[TEMP]], align 8 49 // CHECK: store ptr [[T0]], ptr [[ERROR]], align 8 50 51 SWIFTCALL void context_error_2(short s, CONTEXT int *self, ERROR float **error) {} 52 // CHECK-LABEL: define {{.*}} void @context_error_2(i16{{.*}}, ptr noundef swiftself{{.*}}, ptr noundef swifterror %0) 53 54 /*****************************************************************************/ 55 /********************************** LOWERING *********************************/ 56 /*****************************************************************************/ 57 58 typedef float float4 __attribute__((ext_vector_type(4))); 59 typedef float float8 __attribute__((ext_vector_type(8))); 60 typedef double double2 __attribute__((ext_vector_type(2))); 61 typedef double double4 __attribute__((ext_vector_type(4))); 62 typedef int int3 __attribute__((ext_vector_type(3))); 63 typedef int int4 __attribute__((ext_vector_type(4))); 64 typedef int int5 __attribute__((ext_vector_type(5))); 65 typedef int int8 __attribute__((ext_vector_type(8))); 66 67 #define TEST(TYPE) \ 68 SWIFTCALL TYPE return_##TYPE(void) { \ 69 TYPE result = {}; \ 70 return result; \ 71 } \ 72 SWIFTCALL void take_##TYPE(TYPE v) { \ 73 } \ 74 void test_##TYPE(void) { \ 75 take_##TYPE(return_##TYPE()); \ 76 } 77 78 /*****************************************************************************/ 79 /*********************************** STRUCTS *********************************/ 80 /*****************************************************************************/ 81 82 typedef struct { 83 } struct_empty; 84 TEST(struct_empty); 85 // CHECK-LABEL: define {{.*}} @return_struct_empty() 86 // CHECK: ret void 87 // CHECK-LABEL: define {{.*}} @take_struct_empty() 88 // CHECK: ret void 89 90 typedef struct { 91 int x; 92 char c0; 93 char c1; 94 int f0; 95 int f1; 96 } struct_1; 97 TEST(struct_1); 98 // CHECK-LABEL: define dso_local swiftcc { i64, i64 } @return_struct_1() {{.*}}{ 99 // CHECK: [[RET:%.*]] = alloca [[STRUCT1:%.*]], align 4 100 // CHECK: call void @llvm.memset 101 // CHECK: [[GEP0:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr %retval, i32 0, i32 0 102 // CHECK: [[T0:%.*]] = load i64, ptr [[GEP0]], align 4 103 // CHECK: [[GEP1:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr %retval, i32 0, i32 1 104 // CHECK: [[T1:%.*]] = load i64, ptr [[GEP1]], align 4 105 // CHECK: [[R0:%.*]] = insertvalue { i64, i64 } poison, i64 [[T0]], 0 106 // CHECK: [[R1:%.*]] = insertvalue { i64, i64 } [[R0]], i64 [[T1]], 1 107 // CHECK: ret { i64, i64 } [[R1]] 108 // CHECK: } 109 // CHECK-LABEL: define dso_local swiftcc void @take_struct_1(i64 %0, i64 %1) {{.*}}{ 110 // CHECK: [[V:%.*]] = alloca [[STRUCT1:%.*]], align 4 111 // CHECK: [[GEP0:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[V]], i32 0, i32 0 112 // CHECK: store i64 %0, ptr [[GEP0]], align 4 113 // CHECK: [[GEP1:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[V]], i32 0, i32 1 114 // CHECK: store i64 %1, ptr [[GEP1]], align 4 115 // CHECK: ret void 116 // CHECK: } 117 // CHECK-LABEL: define dso_local void @test_struct_1() {{.*}}{ 118 // CHECK: [[AGG:%.*]] = alloca [[STRUCT1:%.*]], align 4 119 // CHECK: [[RET:%.*]] = call swiftcc { i64, i64 } @return_struct_1() 120 // CHECK: [[GEP0:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[AGG]], i32 0, i32 0 121 // CHECK: [[E0:%.*]] = extractvalue { i64, i64 } [[RET]], 0 122 // CHECK: store i64 [[E0]], ptr [[GEP0]], align 4 123 // CHECK: [[GEP1:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[AGG]], i32 0, i32 1 124 // CHECK: [[E1:%.*]] = extractvalue { i64, i64 } [[RET]], 1 125 // CHECK: store i64 [[E1]], ptr [[GEP1]], align 4 126 // CHECK: [[GEP2:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[AGG]], i32 0, i32 0 127 // CHECK: [[V0:%.*]] = load i64, ptr [[GEP2]], align 4 128 // CHECK: [[GEP3:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[AGG]], i32 0, i32 1 129 // CHECK: [[V1:%.*]] = load i64, ptr [[GEP3]], align 4 130 // CHECK: call swiftcc void @take_struct_1(i64 [[V0]], i64 [[V1]]) 131 // CHECK: ret void 132 // CHECK: } 133 134 typedef struct { 135 int x; 136 char c0; 137 __attribute__((aligned(2))) char c1; 138 int f0; 139 int f1; 140 } struct_2; 141 TEST(struct_2); 142 // CHECK-LABEL: define dso_local swiftcc { i64, i64 } @return_struct_2() {{.*}}{ 143 // CHECK: [[RET:%.*]] = alloca [[STRUCT2:%.*]], align 4 144 // CHECK: call void @llvm.memset 145 // CHECK: [[GEP0:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[RET]], i32 0, i32 0 146 // CHECK: [[T0:%.*]] = load i64, ptr [[GEP0]], align 4 147 // CHECK: [[GEP1:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[RET]], i32 0, i32 1 148 // CHECK: [[T1:%.*]] = load i64, ptr [[GEP1]], align 4 149 // CHECK: [[R0:%.*]] = insertvalue { i64, i64 } poison, i64 [[T0]], 0 150 // CHECK: [[R1:%.*]] = insertvalue { i64, i64 } [[R0]], i64 [[T1]], 1 151 // CHECK: ret { i64, i64 } [[R1]] 152 // CHECK: } 153 // CHECK-LABEL: define dso_local swiftcc void @take_struct_2(i64 %0, i64 %1) {{.*}}{ 154 // CHECK: [[V:%.*]] = alloca [[STRUCT2]], align 4 155 // CHECK: [[GEP0:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[V]], i32 0, i32 0 156 // CHECK: store i64 %0, ptr [[GEP0]], align 4 157 // CHECK: [[GEP1:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[V]], i32 0, i32 1 158 // CHECK: store i64 %1, ptr [[GEP1]], align 4 159 // CHECK: ret void 160 // CHECK: } 161 // CHECK-LABEL: define dso_local void @test_struct_2() {{.*}} { 162 // CHECK: [[TMP:%.*]] = alloca [[STRUCT2]], align 4 163 // CHECK: [[CALL:%.*]] = call swiftcc { i64, i64 } @return_struct_2() 164 // CHECK: [[GEP:%.*]] = getelementptr inbounds nuw {{.*}} [[TMP]], i32 0, i32 0 165 // CHECK: [[T0:%.*]] = extractvalue { i64, i64 } [[CALL]], 0 166 // CHECK: store i64 [[T0]], ptr [[GEP]], align 4 167 // CHECK: [[GEP:%.*]] = getelementptr inbounds nuw {{.*}} [[TMP]], i32 0, i32 1 168 // CHECK: [[T0:%.*]] = extractvalue { i64, i64 } [[CALL]], 1 169 // CHECK: store i64 [[T0]], ptr [[GEP]], align 4 170 // CHECK: [[GEP:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[TMP]], i32 0, i32 0 171 // CHECK: [[R0:%.*]] = load i64, ptr [[GEP]], align 4 172 // CHECK: [[GEP:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[TMP]], i32 0, i32 1 173 // CHECK: [[R1:%.*]] = load i64, ptr [[GEP]], align 4 174 // CHECK: call swiftcc void @take_struct_2(i64 [[R0]], i64 [[R1]]) 175 // CHECK: ret void 176 // CHECK: } 177 178 // There's no way to put a field randomly in the middle of an otherwise 179 // empty storage unit in C, so that case has to be tested in C++, which 180 // can use empty structs to introduce arbitrary padding. (In C, they end up 181 // with size 0 and so don't affect layout.) 182 183 // Misaligned data rule. 184 typedef struct { 185 char c0; 186 __attribute__((packed)) float f; 187 } struct_misaligned_1; 188 TEST(struct_misaligned_1) 189 // CHECK-LABEL: define dso_local swiftcc i64 @return_struct_misaligned_1() 190 // CHECK: [[RET:%.*]] = alloca [[STRUCT:%.*]], align 1 191 // CHECK: call void @llvm.memset{{.*}}(ptr align 1 [[RET]], i8 0, i64 5 192 // CHECK: [[GEP:%.*]] = getelementptr inbounds nuw { i64 }, ptr [[RET]], i32 0, i32 0 193 // CHECK: [[R0:%.*]] = load i64, ptr [[GEP]], align 1 194 // CHECK: ret i64 [[R0]] 195 // CHECK:} 196 // CHECK-LABEL: define dso_local swiftcc void @take_struct_misaligned_1(i64 %0) {{.*}}{ 197 // CHECK: [[V:%.*]] = alloca [[STRUCT:%.*]], align 1 198 // CHECK: [[GEP:%.*]] = getelementptr inbounds nuw { i64 }, ptr [[V]], i32 0, i32 0 199 // CHECK: store i64 %0, ptr [[GEP]], align 1 200 // CHECK: ret void 201 // CHECK: } 202 // CHECK: define dso_local void @test_struct_misaligned_1() {{.*}}{ 203 // CHECK: [[AGG:%.*]] = alloca [[STRUCT:%.*]], align 1 204 // CHECK: [[CALL:%.*]] = call swiftcc i64 @return_struct_misaligned_1() 205 // CHECK: [[T1:%.*]] = getelementptr inbounds nuw { i64 }, ptr [[AGG]], i32 0, i32 0 206 // CHECK: store i64 [[CALL]], ptr [[T1]], align 1 207 // CHECK: [[T1:%.*]] = getelementptr inbounds nuw { i64 }, ptr [[AGG]], i32 0, i32 0 208 // CHECK: [[P:%.*]] = load i64, ptr [[T1]], align 1 209 // CHECK: call swiftcc void @take_struct_misaligned_1(i64 [[P]]) 210 // CHECK: ret void 211 // CHECK: } 212 213 // Too many scalars. 214 typedef struct { 215 long long x[5]; 216 } struct_big_1; 217 TEST(struct_big_1) 218 219 // CHECK-LABEL: define {{.*}} void @return_struct_big_1({{.*}} dead_on_unwind noalias writable sret 220 221 // Should not be byval. 222 // CHECK-LABEL: define {{.*}} void @take_struct_big_1(ptr noundef{{( %.*)?}}) 223 224 /*****************************************************************************/ 225 /********************************* TYPE MERGING ******************************/ 226 /*****************************************************************************/ 227 228 typedef union { 229 float f; 230 double d; 231 } union_het_fp; 232 TEST(union_het_fp) 233 // CHECK-LABEL: define dso_local swiftcc i64 @return_union_het_fp() 234 // CHECK: [[RET:%.*]] = alloca [[UNION:%.*]], align 8 235 // CHECK: call void @llvm.memset{{.*}}(ptr align {{[0-9]+}} [[RET]] 236 // CHECK: [[GEP:%.*]] = getelementptr inbounds nuw { i64 }, ptr [[RET]], i32 0, i32 0 237 // CHECK: [[R0:%.*]] = load i64, ptr [[GEP]], align 8 238 // CHECK: ret i64 [[R0]] 239 // CHECK-LABEL: define dso_local swiftcc void @take_union_het_fp(i64 %0) {{.*}}{ 240 // CHECK: [[V:%.*]] = alloca [[UNION:%.*]], align 8 241 // CHECK: [[GEP:%.*]] = getelementptr inbounds nuw { i64 }, ptr [[V]], i32 0, i32 0 242 // CHECK: store i64 %0, ptr [[GEP]], align 8 243 // CHECK: ret void 244 // CHECK: } 245 // CHECK-LABEL: define dso_local void @test_union_het_fp() {{.*}}{ 246 // CHECK: [[AGG:%.*]] = alloca [[UNION:%.*]], align 8 247 // CHECK: [[CALL:%.*]] = call swiftcc i64 @return_union_het_fp() 248 // CHECK: [[T1:%.*]] = getelementptr inbounds nuw { i64 }, ptr [[AGG]], i32 0, i32 0 249 // CHECK: store i64 [[CALL]], ptr [[T1]], align 8 250 // CHECK: [[T1:%.*]] = getelementptr inbounds nuw { i64 }, ptr [[AGG]], i32 0, i32 0 251 // CHECK: [[V0:%.*]] = load i64, ptr [[T1]], align 8 252 // CHECK: call swiftcc void @take_union_het_fp(i64 [[V0]]) 253 // CHECK: ret void 254 // CHECK: } 255 256 257 typedef union { 258 float f1; 259 float f2; 260 } union_hom_fp; 261 TEST(union_hom_fp) 262 // CHECK-LABEL: define dso_local void @test_union_hom_fp() 263 // CHECK: [[TMP:%.*]] = alloca [[REC:%.*]], align 4 264 // CHECK: [[CALL:%.*]] = call [[SWIFTCC]] float @return_union_hom_fp() 265 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG:{ float }]], ptr [[TMP]], i32 0, i32 0 266 // CHECK: store float [[CALL]], ptr [[T0]], align 4 267 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 0 268 // CHECK: [[FIRST:%.*]] = load float, ptr [[T0]], align 4 269 // CHECK: call [[SWIFTCC]] void @take_union_hom_fp(float [[FIRST]]) 270 // CHECK: ret void 271 272 typedef union { 273 float f1; 274 float4 fv2; 275 } union_hom_fp_partial; 276 TEST(union_hom_fp_partial) 277 // CHECK: define dso_local void @test_union_hom_fp_partial() 278 // CHECK: [[AGG:%.*]] = alloca [[UNION:%.*]], align 16 279 // CHECK: [[CALL:%.*]] = call swiftcc { float, float, float, float } @return_union_hom_fp_partial() 280 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw { float, float, float, float }, ptr [[AGG]], i32 0, i32 0 281 // CHECK: [[T1:%.*]] = extractvalue { float, float, float, float } [[CALL]], 0 282 // CHECK: store float [[T1]], ptr [[T0]], align 16 283 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw { float, float, float, float }, ptr [[AGG]], i32 0, i32 1 284 // CHECK: [[T1:%.*]] = extractvalue { float, float, float, float } [[CALL]], 1 285 // CHECK: store float [[T1]], ptr [[T0]], align 4 286 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw { float, float, float, float }, ptr [[AGG]], i32 0, i32 2 287 // CHECK: [[T1:%.*]] = extractvalue { float, float, float, float } [[CALL]], 2 288 // CHECK: store float [[T1]], ptr [[T0]], align 8 289 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw { float, float, float, float }, ptr [[AGG]], i32 0, i32 3 290 // CHECK: [[T1:%.*]] = extractvalue { float, float, float, float } [[CALL]], 3 291 // CHECK: store float [[T1]], ptr [[T0]], align 4 292 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw { float, float, float, float }, ptr [[AGG]], i32 0, i32 0 293 // CHECK: [[V0:%.*]] = load float, ptr [[T0]], align 16 294 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw { float, float, float, float }, ptr [[AGG]], i32 0, i32 1 295 // CHECK: [[V1:%.*]] = load float, ptr [[T0]], align 4 296 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw { float, float, float, float }, ptr [[AGG]], i32 0, i32 2 297 // CHECK: [[V2:%.*]] = load float, ptr [[T0]], align 8 298 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw { float, float, float, float }, ptr [[AGG]], i32 0, i32 3 299 // CHECK: [[V3:%.*]] = load float, ptr [[T0]], align 4 300 // CHECK: call swiftcc void @take_union_hom_fp_partial(float [[V0]], float [[V1]], float [[V2]], float [[V3]]) 301 // CHECK: ret void 302 // CHECK: } 303 304 typedef union { 305 struct { int x, y; } f1; 306 float4 fv2; 307 } union_het_fpv_partial; 308 TEST(union_het_fpv_partial) 309 // CHECK-LABEL: define dso_local void @test_union_het_fpv_partial() 310 // CHECK: [[AGG:%.*]] = alloca [[UNION:%.*]], align 16 311 // CHECK: [[CALL:%.*]] = call swiftcc { i64, float, float } @return_union_het_fpv_partial() 312 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw { i64, float, float }, ptr [[AGG]], i32 0, i32 0 313 // CHECK: [[T1:%.*]] = extractvalue { i64, float, float } [[CALL]], 0 314 // CHECK: store i64 [[T1]], ptr [[T0]], align 16 315 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw { i64, float, float }, ptr [[AGG]], i32 0, i32 1 316 // CHECK: [[T1:%.*]] = extractvalue { i64, float, float } [[CALL]], 1 317 // CHECK: store float [[T1]], ptr [[T0]], align 8 318 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw { i64, float, float }, ptr [[AGG]], i32 0, i32 2 319 // CHECK: [[T1:%.*]] = extractvalue { i64, float, float } [[CALL]], 2 320 // CHECK: store float [[T1]], ptr [[T0]], align 4 321 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw { i64, float, float }, ptr [[AGG]], i32 0, i32 0 322 // CHECK: [[V0:%.*]] = load i64, ptr [[T0]], align 16 323 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw { i64, float, float }, ptr [[AGG]], i32 0, i32 1 324 // CHECK: [[V1:%.*]] = load float, ptr [[T0]], align 8 325 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw { i64, float, float }, ptr [[AGG]], i32 0, i32 2 326 // CHECK: [[V2:%.*]] = load float, ptr [[T0]], align 4 327 // CHECK: call swiftcc void @take_union_het_fpv_partial(i64 [[V0]], float [[V1]], float [[V2]]) 328 // CHECK: ret void 329 // CHECK: } 330 331 /*****************************************************************************/ 332 /****************************** VECTOR LEGALIZATION **************************/ 333 /*****************************************************************************/ 334 335 TEST(int4) 336 // CHECK-LABEL: define {{.*}} <4 x i32> @return_int4() 337 // CHECK-LABEL: define {{.*}} @take_int4(<4 x i32> 338 339 TEST(int8) 340 // CHECK-LABEL: define {{.*}} @return_int8() 341 // CHECK: [[RET:%.*]] = alloca [[REC:<8 x i32>]], align 32 342 // CHECK: [[VAR:%.*]] = alloca [[REC]], align 343 // CHECK: store 344 // CHECK: load 345 // CHECK: store 346 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG:{ <4 x i32>, <4 x i32> }]], ptr [[RET]], i32 0, i32 0 347 // CHECK: [[FIRST:%.*]] = load <4 x i32>, ptr [[T0]], align 348 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[RET]], i32 0, i32 1 349 // CHECK: [[SECOND:%.*]] = load <4 x i32>, ptr [[T0]], align 350 // CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ <4 x i32>, <4 x i32> }]] poison, <4 x i32> [[FIRST]], 0 351 // CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], <4 x i32> [[SECOND]], 1 352 // CHECK: ret [[UAGG]] [[T1]] 353 // CHECK-LABEL: define {{.*}} @take_int8(<4 x i32> noundef %0, <4 x i32> noundef %1) 354 // CHECK: [[V:%.*]] = alloca [[REC]], align 355 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[V]], i32 0, i32 0 356 // CHECK: store <4 x i32> %0, ptr [[T0]], align 357 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[V]], i32 0, i32 1 358 // CHECK: store <4 x i32> %1, ptr [[T0]], align 359 // CHECK: ret void 360 // CHECK-LABEL: define dso_local void @test_int8() 361 // CHECK: [[TMP1:%.*]] = alloca [[REC]], align 362 // CHECK: [[TMP2:%.*]] = alloca [[REC]], align 363 // CHECK: [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_int8() 364 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP1]], i32 0, i32 0 365 // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0 366 // CHECK: store <4 x i32> [[T1]], ptr [[T0]], align 367 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP1]], i32 0, i32 1 368 // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1 369 // CHECK: store <4 x i32> [[T1]], ptr [[T0]], align 370 // CHECK: [[V:%.*]] = load [[REC]], ptr [[TMP1]], align 371 // CHECK: store [[REC]] [[V]], ptr [[TMP2]], align 372 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP2]], i32 0, i32 0 373 // CHECK: [[FIRST:%.*]] = load <4 x i32>, ptr [[T0]], align 374 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP2]], i32 0, i32 1 375 // CHECK: [[SECOND:%.*]] = load <4 x i32>, ptr [[T0]], align 376 // CHECK: call [[SWIFTCC]] void @take_int8(<4 x i32> noundef [[FIRST]], <4 x i32> noundef [[SECOND]]) 377 // CHECK: ret void 378 379 TEST(int5) 380 // CHECK-LABEL: define {{.*}} @return_int5() 381 // CHECK: [[RET:%.*]] = alloca [[REC:<5 x i32>]], align 32 382 // CHECK: [[VAR:%.*]] = alloca [[REC]], align 383 // CHECK: store 384 // CHECK: load 385 // CHECK: store 386 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG:{ <4 x i32>, i32 }]], ptr [[RET]], i32 0, i32 0 387 // CHECK: [[FIRST:%.*]] = load <4 x i32>, ptr [[T0]], align 388 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[RET]], i32 0, i32 1 389 // CHECK: [[SECOND:%.*]] = load i32, ptr [[T0]], align 390 // CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ <4 x i32>, i32 }]] poison, <4 x i32> [[FIRST]], 0 391 // CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], i32 [[SECOND]], 1 392 // CHECK: ret [[UAGG]] [[T1]] 393 // CHECK-LABEL: define {{.*}} @take_int5(<4 x i32> %0, i32 %1) 394 // CHECK: [[V:%.*]] = alloca [[REC]], align 395 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[V]], i32 0, i32 0 396 // CHECK: store <4 x i32> %0, ptr [[T0]], align 397 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[V]], i32 0, i32 1 398 // CHECK: store i32 %1, ptr [[T0]], align 399 // CHECK: ret void 400 // CHECK-LABEL: define dso_local void @test_int5() 401 // CHECK: [[TMP1:%.*]] = alloca [[REC]], align 402 // CHECK: [[TMP2:%.*]] = alloca [[REC]], align 403 // CHECK: [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_int5() 404 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP1]], i32 0, i32 0 405 // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0 406 // CHECK: store <4 x i32> [[T1]], ptr [[T0]], align 407 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP1]], i32 0, i32 1 408 // CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1 409 // CHECK: store i32 [[T1]], ptr [[T0]], align 410 // CHECK: [[V:%.*]] = load [[REC]], ptr [[TMP1]], align 411 // CHECK: store [[REC]] [[V]], ptr [[TMP2]], align 412 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP2]], i32 0, i32 0 413 // CHECK: [[FIRST:%.*]] = load <4 x i32>, ptr [[T0]], align 414 // CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP2]], i32 0, i32 1 415 // CHECK: [[SECOND:%.*]] = load i32, ptr [[T0]], align 416 // CHECK: call [[SWIFTCC]] void @take_int5(<4 x i32> [[FIRST]], i32 [[SECOND]]) 417 // CHECK: ret void 418 419 typedef struct { 420 int x; 421 int3 v __attribute__((packed)); 422 } misaligned_int3; 423 TEST(misaligned_int3) 424 // CHECK-LABEL: define dso_local swiftcc void @take_misaligned_int3(i64 %0, i64 %1) 425