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 15 SWIFTCALL 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. 19 SWIFTCALL 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 22 typedef struct { char array[1024]; } struct_reallybig; 23 SWIFTCALL 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 26 SWIFTCALL void context_1(CONTEXT void *self) {} 27 // CHECK-LABEL: define {{.*}} void @context_1(i8* swiftself 28 29 SWIFTCALL void context_2(void *arg0, CONTEXT void *self) {} 30 // CHECK-LABEL: define {{.*}} void @context_2(i8*{{.*}}, i8* swiftself 31 32 SWIFTCALL 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 39 void 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 54 SWIFTCALL 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 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 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 85 typedef struct { 86 } struct_empty; 87 TEST(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 93 typedef struct { 94 int x; 95 char c0; 96 char c1; 97 float f0; 98 float f1; 99 } struct_1; 100 TEST(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 160 typedef struct { 161 int x; 162 char c0; 163 __attribute__((aligned(2))) char c1; 164 float f0; 165 float f1; 166 } struct_2; 167 TEST(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. 233 typedef struct { 234 char c0; 235 __attribute__((packed)) float f; 236 } struct_misaligned_1; 237 TEST(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. 261 typedef struct { 262 int x[5]; 263 } struct_big_1; 264 TEST(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 275 typedef union { 276 float f; 277 double d; 278 } union_het_fp; 279 TEST(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 320 typedef union { 321 float f1; 322 float f2; 323 } union_hom_fp; 324 TEST(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 337 typedef union { 338 float f1; 339 float4 fv2; 340 } union_hom_fp_partial; 341 TEST(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 370 typedef union { 371 struct { int x, y; } f1; 372 float4 fv2; 373 } union_het_fpv_partial; 374 TEST(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 407 TEST(int4) 408 // CHECK-LABEL: define {{.*}} <4 x i32> @return_int4() 409 // CHECK-LABEL: define {{.*}} @take_int4(<4 x i32> 410 411 TEST(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 455 TEST(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 499 typedef struct { 500 int x; 501 int3 v __attribute__((packed)); 502 } misaligned_int3; 503 TEST(misaligned_int3) 504 // CHECK-LABEL: define {{.*}} @take_misaligned_int3(i32, i32, i32, i32) 505