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