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