994 lines · c
1// RUN: %clang_cc1 -no-enable-noundef-analysis -triple armv7-apple-darwin9 -emit-llvm -o - %s | FileCheck %s2// RUN: %clang_cc1 -no-enable-noundef-analysis -triple armv7s-apple-ios9 -emit-llvm -o - %s | FileCheck %s3// RUN: %clang_cc1 -no-enable-noundef-analysis -triple armv7k-apple-ios9 -emit-llvm -o - %s | FileCheck %s4 5#define SWIFTCALL __attribute__((swiftcall))6#define SWIFTASYNCCALL __attribute__((swiftasynccall))7#define OUT __attribute__((swift_indirect_result))8#define ERROR __attribute__((swift_error_result))9#define CONTEXT __attribute__((swift_context))10#define ASYNC_CONTEXT __attribute__((swift_async_context))11 12/*****************************************************************************/13/****************************** PARAMETER ABIS *******************************/14/*****************************************************************************/15 16SWIFTCALL void indirect_result_1(OUT int *arg0, OUT float *arg1) {}17// CHECK-LABEL: define{{.*}} void @indirect_result_1(ptr noalias sret(ptr) align 4 dereferenceable(4){{.*}}, ptr noalias align 4 dereferenceable(4){{.*}})18 19// TODO: maybe this shouldn't suppress sret.20SWIFTCALL int indirect_result_2(OUT int *arg0, OUT float *arg1) { __builtin_unreachable(); }21// CHECK-LABEL: define{{.*}} i32 @indirect_result_2(ptr noalias align 4 dereferenceable(4){{.*}}, ptr noalias align 4 dereferenceable(4){{.*}})22 23typedef struct { char array[1024]; } struct_reallybig;24SWIFTCALL struct_reallybig indirect_result_3(OUT int *arg0, OUT float *arg1) { __builtin_unreachable(); }25// CHECK-LABEL: define{{.*}} void @indirect_result_3(ptr dead_on_unwind noalias writable sret(%struct.struct_reallybig) {{.*}}, ptr noalias align 4 dereferenceable(4){{.*}}, ptr noalias align 4 dereferenceable(4){{.*}})26 27SWIFTCALL void context_1(CONTEXT void *self) {}28// CHECK-LABEL: define{{.*}} void @context_1(ptr swiftself29 30SWIFTASYNCCALL void async_context_1(ASYNC_CONTEXT void *self) {}31// CHECK-LABEL: define{{.*}} void @async_context_1(ptr swiftasync32 33SWIFTCALL void context_2(void *arg0, CONTEXT void *self) {}34// CHECK-LABEL: define{{.*}} void @context_2(ptr{{.*}}, ptr swiftself35 36SWIFTASYNCCALL void async_context_2(void *arg0, ASYNC_CONTEXT void *self) {}37// CHECK-LABEL: define{{.*}} void @async_context_2(ptr{{.*}}, ptr swiftasync38 39SWIFTCALL void context_error_1(CONTEXT int *self, ERROR float **error) {}40// CHECK-LABEL: define{{.*}} void @context_error_1(ptr swiftself{{.*}}, ptr swifterror %0)41// CHECK: [[TEMP:%.*]] = alloca ptr, align 442// CHECK: [[T0:%.*]] = load ptr, ptr [[ERRORARG:%.*]], align 443// CHECK: store ptr [[T0]], ptr [[TEMP]], align 444// CHECK: [[T0:%.*]] = load ptr, ptr [[TEMP]], align 445// CHECK: store ptr [[T0]], ptr [[ERRORARG]], align 446void test_context_error_1(void) {47 int x;48 float *error;49 context_error_1(&x, &error);50}51// CHECK-LABEL: define{{.*}} void @test_context_error_1()52// CHECK: [[X:%.*]] = alloca i32, align 453// CHECK: [[ERROR:%.*]] = alloca ptr, align 454// CHECK: [[TEMP:%.*]] = alloca swifterror ptr, align 455// CHECK: [[T0:%.*]] = load ptr, ptr [[ERROR]], align 456// CHECK: store ptr [[T0]], ptr [[TEMP]], align 457// CHECK: call [[SWIFTCC:swiftcc]] void @context_error_1(ptr swiftself [[X]], ptr swifterror [[TEMP]])58// CHECK: [[T0:%.*]] = load ptr, ptr [[TEMP]], align 459// CHECK: store ptr [[T0]], ptr [[ERROR]], align 460 61SWIFTCALL void context_error_2(short s, CONTEXT int *self, ERROR float **error) {}62// CHECK-LABEL: define{{.*}} void @context_error_2(i16{{.*}}, ptr swiftself{{.*}}, ptr swifterror %0)63 64/*****************************************************************************/65/********************************** LOWERING *********************************/66/*****************************************************************************/67 68typedef float float3 __attribute__((ext_vector_type(3)));69typedef float float4 __attribute__((ext_vector_type(4)));70typedef float float8 __attribute__((ext_vector_type(8)));71typedef double double2 __attribute__((ext_vector_type(2)));72typedef double double4 __attribute__((ext_vector_type(4)));73typedef int int3 __attribute__((ext_vector_type(3)));74typedef int int4 __attribute__((ext_vector_type(4)));75typedef int int5 __attribute__((ext_vector_type(5)));76typedef int int8 __attribute__((ext_vector_type(8)));77typedef char char16 __attribute__((ext_vector_type(16)));78typedef short short8 __attribute__((ext_vector_type(8)));79typedef long long long2 __attribute__((ext_vector_type(2)));80 81#define TEST(TYPE) \82 SWIFTCALL TYPE return_##TYPE(void) { \83 TYPE result = {}; \84 return result; \85 } \86 SWIFTCALL void take_##TYPE(TYPE v) { \87 } \88 void test_##TYPE(void) { \89 take_##TYPE(return_##TYPE()); \90 }91 92/*****************************************************************************/93/*********************************** STRUCTS *********************************/94/*****************************************************************************/95 96typedef struct {97} struct_empty;98TEST(struct_empty);99// CHECK-LABEL: define{{.*}} @return_struct_empty()100// CHECK: ret void101// CHECK-LABEL: define{{.*}} @take_struct_empty()102// CHECK: ret void103 104typedef struct {105 int x;106 char c0;107 char c1;108 float f0;109 float f1;110} struct_1;111TEST(struct_1);112// CHECK-LABEL: define{{.*}} @return_struct_1()113// CHECK: [[RET:%.*]] = alloca [[REC:%.*]], align 4114// CHECK: @llvm.memset115// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG:{ i32, i16, \[2 x i8\], float, float }]], ptr [[RET]], i32 0, i32 0116// CHECK: [[FIRST:%.*]] = load i32, ptr [[T0]], align 4117// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[RET]], i32 0, i32 1118// CHECK: [[SECOND:%.*]] = load i16, ptr [[T0]], align 4119// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[RET]], i32 0, i32 3120// CHECK: [[THIRD:%.*]] = load float, ptr [[T0]], align121// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[RET]], i32 0, i32 4122// CHECK: [[FOURTH:%.*]] = load float, ptr [[T0]], align123// CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ i32, i16, float, float }]] poison, i32 [[FIRST]], 0124// CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], i16 [[SECOND]], 1125// CHECK: [[T2:%.*]] = insertvalue [[UAGG]] [[T1]], float [[THIRD]], 2126// CHECK: [[T3:%.*]] = insertvalue [[UAGG]] [[T2]], float [[FOURTH]], 3127// CHECK: ret [[UAGG]] [[T3]]128// CHECK-LABEL: define{{.*}} @take_struct_1(i32 %0, i16 %1, float %2, float %3)129// CHECK: [[V:%.*]] = alloca [[REC]], align 4130// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[V]], i32 0, i32 0131// CHECK: store i32 %0, ptr [[T0]], align 4132// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[V]], i32 0, i32 1133// CHECK: store i16 %1, ptr [[T0]], align 4134// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[V]], i32 0, i32 3135// CHECK: store float %2, ptr [[T0]], align 4136// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[V]], i32 0, i32 4137// CHECK: store float %3, ptr [[T0]], align 4138// CHECK: ret void139// CHECK-LABEL: define{{.*}} void @test_struct_1()140// CHECK: [[TMP:%.*]] = alloca [[REC]], align 4141// CHECK: [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_struct_1()142// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 0143// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0144// CHECK: store i32 [[T1]], ptr [[T0]], align 4145// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 1146// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1147// CHECK: store i16 [[T1]], ptr [[T0]], align 4148// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 3149// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 2150// CHECK: store float [[T1]], ptr [[T0]], align 4151// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 4152// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 3153// CHECK: store float [[T1]], ptr [[T0]], align 4154// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 0155// CHECK: [[FIRST:%.*]] = load i32, ptr [[T0]], align 4156// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 1157// CHECK: [[SECOND:%.*]] = load i16, ptr [[T0]], align 4158// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 3159// CHECK: [[THIRD:%.*]] = load float, ptr [[T0]], align 4160// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 4161// CHECK: [[FOURTH:%.*]] = load float, ptr [[T0]], align 4162// CHECK: call [[SWIFTCC]] void @take_struct_1(i32 [[FIRST]], i16 [[SECOND]], float [[THIRD]], float [[FOURTH]])163// CHECK: ret void164 165typedef struct {166 int x;167 char c0;168 __attribute__((aligned(2))) char c1;169 float f0;170 float f1;171} struct_2;172TEST(struct_2);173// CHECK-LABEL: define{{.*}} @return_struct_2()174// CHECK: [[RET:%.*]] = alloca [[REC:%.*]], align 4175// CHECK: @llvm.memset176// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG:{ i32, i32, float, float }]], ptr [[RET]], i32 0, i32 0177// CHECK: [[FIRST:%.*]] = load i32, ptr [[T0]], align 4178// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[RET]], i32 0, i32 1179// CHECK: [[SECOND:%.*]] = load i32, ptr [[T0]], align 4180// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[RET]], i32 0, i32 2181// CHECK: [[THIRD:%.*]] = load float, ptr [[T0]], align182// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[RET]], i32 0, i32 3183// CHECK: [[FOURTH:%.*]] = load float, ptr [[T0]], align184// CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ i32, i32, float, float }]] poison, i32 [[FIRST]], 0185// CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], i32 [[SECOND]], 1186// CHECK: [[T2:%.*]] = insertvalue [[UAGG]] [[T1]], float [[THIRD]], 2187// CHECK: [[T3:%.*]] = insertvalue [[UAGG]] [[T2]], float [[FOURTH]], 3188// CHECK: ret [[UAGG]] [[T3]]189// CHECK-LABEL: define{{.*}} @take_struct_2(i32 %0, i32 %1, float %2, float %3)190// CHECK: [[V:%.*]] = alloca [[REC]], align 4191// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[V]], i32 0, i32 0192// CHECK: store i32 %0, ptr [[T0]], align 4193// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[V]], i32 0, i32 1194// CHECK: store i32 %1, ptr [[T0]], align 4195// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[V]], i32 0, i32 2196// CHECK: store float %2, ptr [[T0]], align 4197// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[V]], i32 0, i32 3198// CHECK: store float %3, ptr [[T0]], align 4199// CHECK: ret void200// CHECK-LABEL: define{{.*}} void @test_struct_2()201// CHECK: [[TMP:%.*]] = alloca [[REC]], align 4202// CHECK: [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_struct_2()203// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 0204// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0205// CHECK: store i32 [[T1]], ptr [[T0]], align 4206// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 1207// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1208// CHECK: store i32 [[T1]], ptr [[T0]], align 4209// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 2210// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 2211// CHECK: store float [[T1]], ptr [[T0]], align 4212// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 3213// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 3214// CHECK: store float [[T1]], ptr [[T0]], align 4215// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 0216// CHECK: [[FIRST:%.*]] = load i32, ptr [[T0]], align 4217// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 1218// CHECK: [[SECOND:%.*]] = load i32, ptr [[T0]], align 4219// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 2220// CHECK: [[THIRD:%.*]] = load float, ptr [[T0]], align 4221// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 3222// CHECK: [[FOURTH:%.*]] = load float, ptr [[T0]], align 4223// CHECK: call [[SWIFTCC]] void @take_struct_2(i32 [[FIRST]], i32 [[SECOND]], float [[THIRD]], float [[FOURTH]])224// CHECK: ret void225 226// There's no way to put a field randomly in the middle of an otherwise227// empty storage unit in C, so that case has to be tested in C++, which228// can use empty structs to introduce arbitrary padding. (In C, they end up229// with size 0 and so don't affect layout.)230 231// Misaligned data rule.232typedef struct {233 char c0;234 __attribute__((packed)) float f;235} struct_misaligned_1;236TEST(struct_misaligned_1)237// CHECK-LABEL: define{{.*}} @return_struct_misaligned_1()238// CHECK: [[RET:%.*]] = alloca [[REC:%.*]], align239// CHECK: @llvm.memset240// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG:{ i32, i8 }]], ptr [[RET]], i32 0, i32 0241// CHECK: [[FIRST:%.*]] = load i32, ptr [[T0]], align242// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[RET]], i32 0, i32 1243// CHECK: [[SECOND:%.*]] = load i8, ptr [[T0]], align244// CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ i32, i8 }]] poison, i32 [[FIRST]], 0245// CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], i8 [[SECOND]], 1246// CHECK: ret [[UAGG]] [[T1]]247// CHECK-LABEL: define{{.*}} @take_struct_misaligned_1(i32 %0, i8 %1)248// CHECK: [[V:%.*]] = alloca [[REC]], align249// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[V]], i32 0, i32 0250// CHECK: store i32 %0, ptr [[T0]], align251// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[V]], i32 0, i32 1252// CHECK: store i8 %1, ptr [[T0]], align253// CHECK: ret void254 255// Too many scalars.256typedef struct {257 int x[5];258} struct_big_1;259TEST(struct_big_1)260 261// CHECK-LABEL: define{{.*}} void @return_struct_big_1({{.*}} dead_on_unwind noalias writable sret({{.*}})262 263// Should not be byval.264// CHECK-LABEL: define{{.*}} void @take_struct_big_1(ptr dead_on_return{{( %.*)?}})265 266/*****************************************************************************/267/********************************* TYPE MERGING ******************************/268/*****************************************************************************/269 270typedef union {271 float f;272 double d;273} union_het_fp;274TEST(union_het_fp)275// CHECK-LABEL: define{{.*}} @return_union_het_fp()276// CHECK: [[RET:%.*]] = alloca [[REC:%.*]], align {{(4|8)}}277// CHECK: @llvm.memset278// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG:{ i32, i32 }]], ptr [[RET]], i32 0, i32 0279// CHECK: [[FIRST:%.*]] = load i32, ptr [[T0]], align {{(4|8)}}280// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[RET]], i32 0, i32 1281// CHECK: [[SECOND:%.*]] = load i32, ptr [[T0]], align {{(4|8)}}282// CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ i32, i32 }]] poison, i32 [[FIRST]], 0283// CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], i32 [[SECOND]], 1284// CHECK: ret [[UAGG]] [[T1]]285// CHECK-LABEL: define{{.*}} @take_union_het_fp(i32 %0, i32 %1)286// CHECK: [[V:%.*]] = alloca [[REC]], align {{(4|8)}}287// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[V]], i32 0, i32 0288// CHECK: store i32 %0, ptr [[T0]], align {{(4|8)}}289// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[V]], i32 0, i32 1290// CHECK: store i32 %1, ptr [[T0]], align {{(4|8)}}291// CHECK: ret void292// CHECK-LABEL: define{{.*}} void @test_union_het_fp()293// CHECK: [[TMP:%.*]] = alloca [[REC]], align {{(4|8)}}294// CHECK: [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_union_het_fp()295// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 0296// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0297// CHECK: store i32 [[T1]], ptr [[T0]], align {{(4|8)}}298// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 1299// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1300// CHECK: store i32 [[T1]], ptr [[T0]], align {{(4|8)}}301// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 0302// CHECK: [[FIRST:%.*]] = load i32, ptr [[T0]], align {{(4|8)}}303// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 1304// CHECK: [[SECOND:%.*]] = load i32, ptr [[T0]], align {{(4|8)}}305// CHECK: call [[SWIFTCC]] void @take_union_het_fp(i32 [[FIRST]], i32 [[SECOND]])306// CHECK: ret void307 308 309typedef union {310 float f1;311 float f2;312} union_hom_fp;313TEST(union_hom_fp)314// CHECK-LABEL: define{{.*}} void @test_union_hom_fp()315// CHECK: [[TMP:%.*]] = alloca [[REC:%.*]], align 4316// CHECK: [[CALL:%.*]] = call [[SWIFTCC]] float @return_union_hom_fp()317// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG:{ float }]], ptr [[TMP]], i32 0, i32 0318// CHECK: store float [[CALL]], ptr [[T0]], align 4319// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 0320// CHECK: [[FIRST:%.*]] = load float, ptr [[T0]], align 4321// CHECK: call [[SWIFTCC]] void @take_union_hom_fp(float [[FIRST]])322// CHECK: ret void323 324typedef union {325 float f1;326 float4 fv2;327} union_hom_fp_partial;328TEST(union_hom_fp_partial)329// CHECK-LABEL: define{{.*}} void @test_union_hom_fp_partial()330// CHECK: [[TMP:%.*]] = alloca [[REC:%.*]], align 16331// CHECK: [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG:{ float, float, float, float }]] @return_union_hom_fp_partial()332// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG:{ float, float, float, float }]], ptr [[TMP]], i32 0, i32 0333// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0334// CHECK: store float [[T1]], ptr [[T0]], align335// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 1336// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1337// CHECK: store float [[T1]], ptr [[T0]], align338// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 2339// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 2340// CHECK: store float [[T1]], ptr [[T0]], align341// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 3342// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 3343// CHECK: store float [[T1]], ptr [[T0]], align344// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 0345// CHECK: [[FIRST:%.*]] = load float, ptr [[T0]], align346// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 1347// CHECK: [[SECOND:%.*]] = load float, ptr [[T0]], align348// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 2349// CHECK: [[THIRD:%.*]] = load float, ptr [[T0]], align350// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 3351// CHECK: [[FOURTH:%.*]] = load float, ptr [[T0]], align352// CHECK: call [[SWIFTCC]] void @take_union_hom_fp_partial(float [[FIRST]], float [[SECOND]], float [[THIRD]], float [[FOURTH]])353// CHECK: ret void354 355typedef union {356 struct { int x, y; } f1;357 float4 fv2;358} union_het_fpv_partial;359TEST(union_het_fpv_partial)360// CHECK-LABEL: define{{.*}} void @test_union_het_fpv_partial()361// CHECK: [[TMP:%.*]] = alloca [[REC:%.*]], align 16362// CHECK: [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG:{ i32, i32, float, float }]] @return_union_het_fpv_partial()363// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG:{ i32, i32, float, float }]], ptr [[TMP]], i32 0, i32 0364// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0365// CHECK: store i32 [[T1]], ptr [[T0]], align366// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 1367// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1368// CHECK: store i32 [[T1]], ptr [[T0]], align369// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 2370// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 2371// CHECK: store float [[T1]], ptr [[T0]], align372// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 3373// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 3374// CHECK: store float [[T1]], ptr [[T0]], align375// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 0376// CHECK: [[FIRST:%.*]] = load i32, ptr [[T0]], align377// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 1378// CHECK: [[SECOND:%.*]] = load i32, ptr [[T0]], align379// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 2380// CHECK: [[THIRD:%.*]] = load float, ptr [[T0]], align381// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP]], i32 0, i32 3382// CHECK: [[FOURTH:%.*]] = load float, ptr [[T0]], align383// CHECK: call [[SWIFTCC]] void @take_union_het_fpv_partial(i32 [[FIRST]], i32 [[SECOND]], float [[THIRD]], float [[FOURTH]])384// CHECK: ret void385 386/*****************************************************************************/387/****************************** VECTOR LEGALIZATION **************************/388/*****************************************************************************/389 390TEST(int4)391// CHECK-LABEL: define{{.*}} <4 x i32> @return_int4()392// CHECK-LABEL: define{{.*}} @take_int4(<4 x i32>393 394TEST(int8)395// CHECK-LABEL: define{{.*}} @return_int8()396// CHECK: [[RET:%.*]] = alloca [[REC:<8 x i32>]], align 32397// CHECK: store398// CHECK: load399// CHECK: store400// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG:{ <4 x i32>, <4 x i32> }]], ptr [[RET]], i32 0, i32 0401// CHECK: [[FIRST:%.*]] = load <4 x i32>, ptr [[T0]], align402// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[RET]], i32 0, i32 1403// CHECK: [[SECOND:%.*]] = load <4 x i32>, ptr [[T0]], align404// CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ <4 x i32>, <4 x i32> }]] poison, <4 x i32> [[FIRST]], 0405// CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], <4 x i32> [[SECOND]], 1406// CHECK: ret [[UAGG]] [[T1]]407// CHECK-LABEL: define{{.*}} @take_int8(<4 x i32> %0, <4 x i32> %1)408// CHECK: [[V:%.*]] = alloca [[REC]], align409// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[V]], i32 0, i32 0410// CHECK: store <4 x i32> %0, ptr [[T0]], align411// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[V]], i32 0, i32 1412// CHECK: store <4 x i32> %1, ptr [[T0]], align413// CHECK: ret void414// CHECK-LABEL: define{{.*}} void @test_int8()415// CHECK: [[TMP1:%.*]] = alloca [[REC]], align416// CHECK: [[TMP2:%.*]] = alloca [[REC]], align417// CHECK: [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_int8()418// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP1]], i32 0, i32 0419// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0420// CHECK: store <4 x i32> [[T1]], ptr [[T0]], align421// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP1]], i32 0, i32 1422// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1423// CHECK: store <4 x i32> [[T1]], ptr [[T0]], align424// CHECK: [[V:%.*]] = load [[REC]], ptr [[TMP1]], align425// CHECK: store [[REC]] [[V]], ptr [[TMP2]], align426// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP2]], i32 0, i32 0427// CHECK: [[FIRST:%.*]] = load <4 x i32>, ptr [[T0]], align428// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP2]], i32 0, i32 1429// CHECK: [[SECOND:%.*]] = load <4 x i32>, ptr [[T0]], align430// CHECK: call [[SWIFTCC]] void @take_int8(<4 x i32> [[FIRST]], <4 x i32> [[SECOND]])431// CHECK: ret void432 433TEST(int5)434// CHECK-LABEL: define{{.*}} @return_int5()435// CHECK: [[RET:%.*]] = alloca [[REC:<5 x i32>]], align 32436// CHECK: store437// CHECK: load438// CHECK: store439// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG:{ <4 x i32>, i32 }]], ptr [[RET]], i32 0, i32 0440// CHECK: [[FIRST:%.*]] = load <4 x i32>, ptr [[T0]], align441// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[RET]], i32 0, i32 1442// CHECK: [[SECOND:%.*]] = load i32, ptr [[T0]], align443// CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ <4 x i32>, i32 }]] poison, <4 x i32> [[FIRST]], 0444// CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], i32 [[SECOND]], 1445// CHECK: ret [[UAGG]] [[T1]]446// CHECK-LABEL: define{{.*}} @take_int5(<4 x i32> %0, i32 %1)447// CHECK: [[V:%.*]] = alloca [[REC]], align448// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[V]], i32 0, i32 0449// CHECK: store <4 x i32> %0, ptr [[T0]], align450// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[V]], i32 0, i32 1451// CHECK: store i32 %1, ptr [[T0]], align452// CHECK: ret void453// CHECK-LABEL: define{{.*}} void @test_int5()454// CHECK: [[TMP1:%.*]] = alloca [[REC]], align455// CHECK: [[TMP2:%.*]] = alloca [[REC]], align456// CHECK: [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_int5()457// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP1]], i32 0, i32 0458// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0459// CHECK: store <4 x i32> [[T1]], ptr [[T0]], align460// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP1]], i32 0, i32 1461// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1462// CHECK: store i32 [[T1]], ptr [[T0]], align463// CHECK: [[V:%.*]] = load [[REC]], ptr [[TMP1]], align464// CHECK: store [[REC]] [[V]], ptr [[TMP2]], align465// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP2]], i32 0, i32 0466// CHECK: [[FIRST:%.*]] = load <4 x i32>, ptr [[T0]], align467// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[AGG]], ptr [[TMP2]], i32 0, i32 1468// CHECK: [[SECOND:%.*]] = load i32, ptr [[T0]], align469// CHECK: call [[SWIFTCC]] void @take_int5(<4 x i32> [[FIRST]], i32 [[SECOND]])470// CHECK: ret void471 472typedef struct {473 int x;474 int3 v __attribute__((packed));475} misaligned_int3;476TEST(misaligned_int3)477// CHECK-LABEL: define{{.*}} @take_misaligned_int3(i32 %0, i32 %1, i32 %2, i32 %3)478 479typedef struct {480 float f0;481} struct_f1;482TEST(struct_f1)483// CHECK-LABEL: define{{.*}} swiftcc float @return_struct_f1()484// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_f1(float %0)485 486typedef struct {487 float f0;488 float f1;489} struct_f2;490TEST(struct_f2)491// CHECK-LABEL: define{{.*}} swiftcc { float, float } @return_struct_f2()492// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_f2(float %0, float %1)493 494typedef struct {495 float f0;496 float f1;497 float f2;498} struct_f3;499TEST(struct_f3)500// CHECK-LABEL: define{{.*}} swiftcc { float, float, float } @return_struct_f3()501// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_f3(float %0, float %1, float %2)502 503typedef struct {504 float f0;505 float f1;506 float f2;507 float f3;508} struct_f4;509TEST(struct_f4)510// CHECK-LABEL: define{{.*}} swiftcc { float, float, float, float } @return_struct_f4()511// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_f4(float %0, float %1, float %2, float %3)512 513 514typedef struct {515 double d0;516} struct_d1;517TEST(struct_d1)518// CHECK-LABEL: define{{.*}} swiftcc double @return_struct_d1()519// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_d1(double %0)520 521typedef struct {522 double d0;523 double d1;524} struct_d2;525TEST(struct_d2)526// CHECK-LABEL: define{{.*}} swiftcc { double, double } @return_struct_d2()527// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_d2(double %0, double %1)528 529typedef struct {530 double d0;531 double d1;532 double d2;533} struct_d3;534TEST(struct_d3)535// CHECK-LABEL: define{{.*}} swiftcc { double, double, double } @return_struct_d3()536// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_d3(double %0, double %1, double %2)537 538typedef struct {539 double d0;540 double d1;541 double d2;542 double d3;543} struct_d4;544TEST(struct_d4)545// CHECK-LABEL: define{{.*}} swiftcc { double, double, double, double } @return_struct_d4()546// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_d4(double %0, double %1, double %2, double %3)547 548typedef struct {549 double d0;550 double d1;551 double d2;552 double d3;553 double d4;554} struct_d5;555TEST(struct_d5)556// CHECK: define{{.*}} swiftcc void @return_struct_d5(ptr dead_on_unwind noalias writable sret([[STRUCT5:%.*]])557// CHECK: define{{.*}} swiftcc void @take_struct_d5(ptr558 559typedef struct {560 char c0;561} struct_c1;562TEST(struct_c1)563// CHECK-LABEL: define{{.*}} swiftcc i8 @return_struct_c1()564// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_c1(i8 %0)565 566typedef struct {567 char c0;568 char c1;569} struct_c2;570TEST(struct_c2)571// CHECK-LABEL: define{{.*}} swiftcc i16 @return_struct_c2()572// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_c2(i16 %0)573//574 575typedef struct {576 char c0;577 char c1;578 char c2;579} struct_c3;580TEST(struct_c3)581// CHECK-LABEL: define{{.*}} swiftcc i32 @return_struct_c3()582// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_c3(i32 %0)583 584typedef struct {585 char c0;586 char c1;587 char c2;588 char c3;589} struct_c4;590TEST(struct_c4)591// CHECK-LABEL: define{{.*}} swiftcc i32 @return_struct_c4()592// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_c4(i32 %0)593 594typedef struct {595 char c0;596 char c1;597 char c2;598 char c3;599 char c4;600} struct_c5;601TEST(struct_c5)602// CHECK-LABEL: define{{.*}} swiftcc { i32, i8 } @return_struct_c5()603// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_c5(i32 %0, i8 %1)604 605typedef struct {606 short s0;607} struct_s1;608TEST(struct_s1)609// CHECK-LABEL: define{{.*}} swiftcc i16 @return_struct_s1()610// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_s1(i16 %0)611 612typedef struct {613 short s0;614 short s1;615} struct_s2;616TEST(struct_s2)617// CHECK-LABEL: define{{.*}} swiftcc i32 @return_struct_s2()618// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_s2(i32 %0)619 620typedef struct {621 short s0;622 short s1;623 short s2;624} struct_s3;625TEST(struct_s3)626// CHECK-LABEL: define{{.*}} swiftcc { i32, i16 } @return_struct_s3()627// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_s3(i32 %0, i16 %1)628 629typedef struct {630 short s0;631 short s1;632 short s2;633 short s3;634} struct_s4;635TEST(struct_s4)636// CHECK-LABEL: define{{.*}} swiftcc { i32, i32 } @return_struct_s4()637// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_s4(i32 %0, i32 %1)638 639typedef struct {640 short s0;641 short s1;642 short s2;643 short s3;644 short s4;645} struct_s5;646TEST(struct_s5)647// CHECK-LABEL: define{{.*}} swiftcc { i32, i32, i16 } @return_struct_s5()648// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_s5(i32 %0, i32 %1, i16 %2)649 650 651typedef struct {652 int i0;653} struct_i1;654TEST(struct_i1)655// CHECK-LABEL: define{{.*}} swiftcc i32 @return_struct_i1()656// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_i1(i32 %0)657 658typedef struct {659 int i0;660 int i1;661} struct_i2;662TEST(struct_i2)663// CHECK-LABEL: define{{.*}} swiftcc { i32, i32 } @return_struct_i2()664// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_i2(i32 %0, i32 %1)665 666typedef struct {667 int i0;668 int i1;669 int i2;670} struct_i3;671TEST(struct_i3)672// CHECK-LABEL: define{{.*}} swiftcc { i32, i32, i32 } @return_struct_i3()673// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_i3(i32 %0, i32 %1, i32 %2)674 675typedef struct {676 int i0;677 int i1;678 int i2;679 int i3;680} struct_i4;681TEST(struct_i4)682// CHECK-LABEL: define{{.*}} swiftcc { i32, i32, i32, i32 } @return_struct_i4()683// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_i4(i32 %0, i32 %1, i32 %2, i32 %3)684 685typedef struct {686 long long l0;687} struct_l1;688TEST(struct_l1)689// CHECK-LABEL: define{{.*}} swiftcc i64 @return_struct_l1()690// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_l1(i64 %0)691 692typedef struct {693 long long l0;694 long long l1;695} struct_l2;696TEST(struct_l2)697// CHECK-LABEL: define{{.*}} swiftcc { i64, i64 } @return_struct_l2()698// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_l2(i64 %0, i64 %1)699 700typedef struct {701 long long l0;702 long long l1;703 long long l2;704} struct_l3;705TEST(struct_l3)706// CHECK: define{{.*}} swiftcc void @return_struct_l3(ptr dead_on_unwind noalias writable sret([[STRUCT:%.*]])707// CHECK: define{{.*}} swiftcc void @take_struct_l3(ptr708 709typedef struct {710 long long l0;711 long long l1;712 long long l2;713 long long l3;714} struct_l4;715TEST(struct_l4)716// CHECK: define{{.*}} swiftcc void @return_struct_l4(ptr dead_on_unwind noalias writable sret([[STRUCT:%.*]])717// CHECK: define{{.*}} swiftcc void @take_struct_l4(ptr718 719typedef struct {720 long long l0;721 long long l1;722 long long l2;723 long long l3;724 long long l4;725} struct_l5;726TEST(struct_l5)727// CHECK: define{{.*}} swiftcc void @return_struct_l5(ptr dead_on_unwind noalias writable sret([[STRUCT5:%.*]])728// CHECK: define{{.*}} swiftcc void @take_struct_l5(ptr729 730typedef struct {731 char16 c0;732} struct_vc1;733TEST(struct_vc1)734// CHECK-LABEL: define{{.*}} swiftcc <16 x i8> @return_struct_vc1()735// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_vc1(<16 x i8> %0)736 737typedef struct {738 char16 c0;739 char16 c1;740} struct_vc2;741TEST(struct_vc2)742// CHECK-LABEL: define{{.*}} swiftcc { <16 x i8>, <16 x i8> } @return_struct_vc2()743// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_vc2(<16 x i8> %0, <16 x i8> %1)744 745typedef struct {746 char16 c0;747 char16 c1;748 char16 c2;749} struct_vc3;750TEST(struct_vc3)751// CHECK-LABEL: define{{.*}} swiftcc { <16 x i8>, <16 x i8>, <16 x i8> } @return_struct_vc3()752// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_vc3(<16 x i8> %0, <16 x i8> %1, <16 x i8> %2)753 754typedef struct {755 char16 c0;756 char16 c1;757 char16 c2;758 char16 c3;759} struct_vc4;760TEST(struct_vc4)761// CHECK-LABEL: define{{.*}} swiftcc { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } @return_struct_vc4()762// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_vc4(<16 x i8> %0, <16 x i8> %1, <16 x i8> %2, <16 x i8> %3)763 764typedef struct {765 char16 c0;766 char16 c1;767 char16 c2;768 char16 c3;769 char16 c4;770} struct_vc5;771TEST(struct_vc5)772// CHECK: define{{.*}} swiftcc void @return_struct_vc5(ptr dead_on_unwind noalias writable sret([[STRUCT:%.*]])773// CHECK: define{{.*}} swiftcc void @take_struct_vc5(ptr774 775typedef struct {776 short8 c0;777} struct_vs1;778TEST(struct_vs1)779// CHECK-LABEL: define{{.*}} swiftcc <8 x i16> @return_struct_vs1()780// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_vs1(<8 x i16> %0)781 782typedef struct {783 short8 c0;784 short8 c1;785} struct_vs2;786TEST(struct_vs2)787// CHECK-LABEL: define{{.*}} swiftcc { <8 x i16>, <8 x i16> } @return_struct_vs2()788// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_vs2(<8 x i16> %0, <8 x i16> %1)789 790typedef struct {791 short8 c0;792 short8 c1;793 short8 c2;794} struct_vs3;795TEST(struct_vs3)796// CHECK-LABEL: define{{.*}} swiftcc { <8 x i16>, <8 x i16>, <8 x i16> } @return_struct_vs3()797// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_vs3(<8 x i16> %0, <8 x i16> %1, <8 x i16> %2)798 799typedef struct {800 short8 c0;801 short8 c1;802 short8 c2;803 short8 c3;804} struct_vs4;805TEST(struct_vs4)806// CHECK-LABEL: define{{.*}} swiftcc { <8 x i16>, <8 x i16>, <8 x i16>, <8 x i16> } @return_struct_vs4()807// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_vs4(<8 x i16> %0, <8 x i16> %1, <8 x i16> %2, <8 x i16> %3)808 809typedef struct {810 short8 c0;811 short8 c1;812 short8 c2;813 short8 c3;814 short8 c4;815} struct_vs5;816TEST(struct_vs5)817// CHECK: define{{.*}} swiftcc void @return_struct_vs5(ptr dead_on_unwind noalias writable sret([[STRUCT:%.*]])818// CHECK: define{{.*}} swiftcc void @take_struct_vs5(ptr819 820typedef struct {821 int4 c0;822} struct_vi1;823TEST(struct_vi1)824// CHECK-LABEL: define{{.*}} swiftcc <4 x i32> @return_struct_vi1()825// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_vi1(<4 x i32> %0)826 827typedef struct {828 int4 c0;829 int4 c1;830} struct_vi2;831TEST(struct_vi2)832// CHECK-LABEL: define{{.*}} swiftcc { <4 x i32>, <4 x i32> } @return_struct_vi2()833// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_vi2(<4 x i32> %0, <4 x i32> %1)834 835typedef struct {836 int4 c0;837 int4 c1;838 int4 c2;839} struct_vi3;840TEST(struct_vi3)841// CHECK-LABEL: define{{.*}} swiftcc { <4 x i32>, <4 x i32>, <4 x i32> } @return_struct_vi3()842// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_vi3(<4 x i32> %0, <4 x i32> %1, <4 x i32> %2)843 844typedef struct {845 int4 c0;846 int4 c1;847 int4 c2;848 int4 c3;849} struct_vi4;850TEST(struct_vi4)851// CHECK-LABEL: define{{.*}} swiftcc { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } @return_struct_vi4()852// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_vi4(<4 x i32> %0, <4 x i32> %1, <4 x i32> %2, <4 x i32> %3)853 854typedef struct {855 int4 c0;856 int4 c1;857 int4 c2;858 int4 c3;859 int4 c4;860} struct_vi5;861TEST(struct_vi5)862// CHECK: define{{.*}} swiftcc void @return_struct_vi5(ptr dead_on_unwind noalias writable sret([[STRUCT:%.*]])863// CHECK: define{{.*}} swiftcc void @take_struct_vi5(ptr864 865typedef struct {866 long2 c0;867} struct_vl1;868TEST(struct_vl1)869// CHECK-LABEL: define{{.*}} swiftcc <2 x i64> @return_struct_vl1()870// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_vl1(<2 x i64> %0)871 872typedef struct {873 long2 c0;874 long2 c1;875 long2 c2;876 long2 c3;877} struct_vl4;878TEST(struct_vl4)879// CHECK-LABEL: define{{.*}} swiftcc { <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @return_struct_vl4()880// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_vl4(<2 x i64> %0, <2 x i64> %1, <2 x i64> %2, <2 x i64> %3)881 882typedef struct {883 long2 c0;884 long2 c1;885 long2 c2;886 long2 c3;887 long2 c4;888} struct_vl5;889TEST(struct_vl5)890// CHECK: define{{.*}} swiftcc void @return_struct_vl5(ptr dead_on_unwind noalias writable sret([[STRUCT:%.*]])891// CHECK: define{{.*}} swiftcc void @take_struct_vl5(ptr892 893typedef struct {894 double2 c0;895} struct_vd1;896TEST(struct_vd1)897// CHECK-LABEL: define{{.*}} swiftcc <2 x double> @return_struct_vd1()898// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_vd1(<2 x double> %0)899 900typedef struct {901 double2 c0;902 double2 c1;903 double2 c2;904 double2 c3;905} struct_vd4;906TEST(struct_vd4)907// CHECK-LABEL: define{{.*}} swiftcc { <2 x double>, <2 x double>, <2 x double>, <2 x double> } @return_struct_vd4()908// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_vd4(<2 x double> %0, <2 x double> %1, <2 x double> %2, <2 x double> %3)909 910typedef struct {911 double2 c0;912 double2 c1;913 double2 c2;914 double2 c3;915 double2 c4;916} struct_vd5;917TEST(struct_vd5)918// CHECK: define{{.*}} swiftcc void @return_struct_vd5(ptr dead_on_unwind noalias writable sret([[STRUCT:%.*]])919// CHECK: define{{.*}} swiftcc void @take_struct_vd5(ptr920 921typedef struct {922 double4 c0;923} struct_vd41;924TEST(struct_vd41)925// CHECK-LABEL: define{{.*}} swiftcc { <2 x double>, <2 x double> } @return_struct_vd41()926// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_vd41(<2 x double> %0, <2 x double> %1)927 928typedef struct {929 double4 c0;930 double4 c1;931} struct_vd42;932TEST(struct_vd42)933// CHECK-LABEL: define{{.*}} swiftcc { <2 x double>, <2 x double>, <2 x double>, <2 x double> } @return_struct_vd42()934// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_vd42(<2 x double> %0, <2 x double> %1, <2 x double> %2, <2 x double> %3)935 936typedef struct {937 double4 c0;938 double4 c1;939 double4 c2;940} struct_vd43;941TEST(struct_vd43)942// CHECK: define{{.*}} swiftcc void @return_struct_vd43(ptr dead_on_unwind noalias writable sret([[STRUCT:%.*]])943// CHECK: define{{.*}} swiftcc void @take_struct_vd43(ptr944 945typedef struct {946 float4 c0;947} struct_vf1;948TEST(struct_vf1)949// CHECK-LABEL: define{{.*}} swiftcc <4 x float> @return_struct_vf1()950// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_vf1(<4 x float> %0)951 952typedef struct {953 float4 c0;954 float4 c1;955} struct_vf2;956TEST(struct_vf2)957// CHECK-LABEL: define{{.*}} swiftcc { <4 x float>, <4 x float> } @return_struct_vf2()958// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_vf2(<4 x float> %0, <4 x float> %1)959 960typedef struct {961 float4 c0;962 float4 c1;963 float4 c2;964 float4 c3;965} struct_vf4;966TEST(struct_vf4)967// CHECK-LABEL: define{{.*}} swiftcc { <4 x float>, <4 x float>, <4 x float>, <4 x float> } @return_struct_vf4()968// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_vf4(<4 x float> %0, <4 x float> %1, <4 x float> %2, <4 x float> %3)969 970typedef struct {971 float4 c0;972 float4 c1;973 float4 c2;974 float4 c3;975 float4 c4;976} struct_vf5;977TEST(struct_vf5)978// CHECK: define{{.*}} swiftcc void @return_struct_vf5(ptr dead_on_unwind noalias writable sret([[STRUCT:%.*]])979// CHECK: define{{.*}} swiftcc void @take_struct_vf5(ptr980 981typedef struct {982 float8 c0;983} struct_vf81;984TEST(struct_vf81)985// CHECK-LABEL: define{{.*}} swiftcc { <4 x float>, <4 x float> } @return_struct_vf81()986// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_vf81(<4 x float> %0, <4 x float> %1)987 988typedef struct {989 float3 f3;990} struct_v1f3;991TEST(struct_v1f3)992// CHECK-LABEL: define{{.*}} swiftcc { <2 x float>, float } @return_struct_v1f3()993// CHECK-LABEL: define{{.*}} swiftcc void @take_struct_v1f3(<2 x float> %0, float %1)994