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