1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -verify-machineinstrs < %s -mtriple=x86_64-unknown-unknown | FileCheck %s 3; RUN: llc -verify-machineinstrs < %s -mtriple=x86_64-unknown-unknown -O0 | FileCheck --check-prefix=CHECK-O0 %s 4 5@var = dso_local global i32 0 6 7; Test how llvm handles return type of {i16, i8}. The return value will be 8; passed in %eax and %dl. 9define i16 @test(i32 %key) { 10; CHECK-LABEL: test: 11; CHECK: # %bb.0: # %entry 12; CHECK-NEXT: pushq %rax 13; CHECK-NEXT: .cfi_def_cfa_offset 16 14; CHECK-NEXT: movl %edi, {{[0-9]+}}(%rsp) 15; CHECK-NEXT: callq gen@PLT 16; CHECK-NEXT: # kill: def $ax killed $ax def $eax 17; CHECK-NEXT: movsbl %dl, %ecx 18; CHECK-NEXT: addl %ecx, %eax 19; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 20; CHECK-NEXT: popq %rcx 21; CHECK-NEXT: .cfi_def_cfa_offset 8 22; CHECK-NEXT: retq 23; 24; CHECK-O0-LABEL: test: 25; CHECK-O0: # %bb.0: # %entry 26; CHECK-O0-NEXT: pushq %rax 27; CHECK-O0-NEXT: .cfi_def_cfa_offset 16 28; CHECK-O0-NEXT: movl %edi, {{[0-9]+}}(%rsp) 29; CHECK-O0-NEXT: movl {{[0-9]+}}(%rsp), %edi 30; CHECK-O0-NEXT: callq gen@PLT 31; CHECK-O0-NEXT: cwtl 32; CHECK-O0-NEXT: movsbl %dl, %ecx 33; CHECK-O0-NEXT: addl %ecx, %eax 34; CHECK-O0-NEXT: # kill: def $ax killed $ax killed $eax 35; CHECK-O0-NEXT: popq %rcx 36; CHECK-O0-NEXT: .cfi_def_cfa_offset 8 37; CHECK-O0-NEXT: retq 38entry: 39 %key.addr = alloca i32, align 4 40 store i32 %key, i32* %key.addr, align 4 41 %0 = load i32, i32* %key.addr, align 4 42 %call = call swiftcc { i16, i8 } @gen(i32 %0) 43 %v3 = extractvalue { i16, i8 } %call, 0 44 %v1 = sext i16 %v3 to i32 45 %v5 = extractvalue { i16, i8 } %call, 1 46 %v2 = sext i8 %v5 to i32 47 %add = add nsw i32 %v1, %v2 48 %conv = trunc i32 %add to i16 49 ret i16 %conv 50} 51 52declare swiftcc { i16, i8 } @gen(i32) 53 54; If we can't pass every return value in register, we will pass everything 55; in memroy. The caller provides space for the return value and passes 56; the address in %rax. The first input argument will be in %rdi. 57define dso_local i32 @test2(i32 %key) #0 { 58; CHECK-LABEL: test2: 59; CHECK: # %bb.0: # %entry 60; CHECK-NEXT: subq $24, %rsp 61; CHECK-NEXT: .cfi_def_cfa_offset 32 62; CHECK-NEXT: movl %edi, {{[0-9]+}}(%rsp) 63; CHECK-NEXT: movq %rsp, %rax 64; CHECK-NEXT: callq gen2@PLT 65; CHECK-NEXT: movl (%rsp), %eax 66; CHECK-NEXT: addl {{[0-9]+}}(%rsp), %eax 67; CHECK-NEXT: addl {{[0-9]+}}(%rsp), %eax 68; CHECK-NEXT: addl {{[0-9]+}}(%rsp), %eax 69; CHECK-NEXT: addl {{[0-9]+}}(%rsp), %eax 70; CHECK-NEXT: addq $24, %rsp 71; CHECK-NEXT: .cfi_def_cfa_offset 8 72; CHECK-NEXT: retq 73; 74; CHECK-O0-LABEL: test2: 75; CHECK-O0: # %bb.0: # %entry 76; CHECK-O0-NEXT: subq $24, %rsp 77; CHECK-O0-NEXT: .cfi_def_cfa_offset 32 78; CHECK-O0-NEXT: movl %edi, {{[0-9]+}}(%rsp) 79; CHECK-O0-NEXT: movl {{[0-9]+}}(%rsp), %edi 80; CHECK-O0-NEXT: movq %rsp, %rax 81; CHECK-O0-NEXT: callq gen2@PLT 82; CHECK-O0-NEXT: movl {{[0-9]+}}(%rsp), %ecx 83; CHECK-O0-NEXT: movl {{[0-9]+}}(%rsp), %edx 84; CHECK-O0-NEXT: movl {{[0-9]+}}(%rsp), %esi 85; CHECK-O0-NEXT: movl (%rsp), %eax 86; CHECK-O0-NEXT: movl {{[0-9]+}}(%rsp), %edi 87; CHECK-O0-NEXT: addl %edi, %eax 88; CHECK-O0-NEXT: addl %esi, %eax 89; CHECK-O0-NEXT: addl %edx, %eax 90; CHECK-O0-NEXT: addl %ecx, %eax 91; CHECK-O0-NEXT: addq $24, %rsp 92; CHECK-O0-NEXT: .cfi_def_cfa_offset 8 93; CHECK-O0-NEXT: retq 94entry: 95 %key.addr = alloca i32, align 4 96 store i32 %key, i32* %key.addr, align 4 97 %0 = load i32, i32* %key.addr, align 4 98 %call = call swiftcc { i32, i32, i32, i32, i32 } @gen2(i32 %0) 99 100 %v3 = extractvalue { i32, i32, i32, i32, i32 } %call, 0 101 %v5 = extractvalue { i32, i32, i32, i32, i32 } %call, 1 102 %v6 = extractvalue { i32, i32, i32, i32, i32 } %call, 2 103 %v7 = extractvalue { i32, i32, i32, i32, i32 } %call, 3 104 %v8 = extractvalue { i32, i32, i32, i32, i32 } %call, 4 105 106 %add = add nsw i32 %v3, %v5 107 %add1 = add nsw i32 %add, %v6 108 %add2 = add nsw i32 %add1, %v7 109 %add3 = add nsw i32 %add2, %v8 110 ret i32 %add3 111} 112 113; The address of the return value is passed in %rax. 114; On return, we don't keep the address in %rax. 115define swiftcc { i32, i32, i32, i32, i32 } @gen2(i32 %key) { 116; CHECK-LABEL: gen2: 117; CHECK: # %bb.0: 118; CHECK-NEXT: movl %edi, 16(%rax) 119; CHECK-NEXT: movl %edi, 12(%rax) 120; CHECK-NEXT: movl %edi, 8(%rax) 121; CHECK-NEXT: movl %edi, 4(%rax) 122; CHECK-NEXT: movl %edi, (%rax) 123; CHECK-NEXT: retq 124; 125; CHECK-O0-LABEL: gen2: 126; CHECK-O0: # %bb.0: 127; CHECK-O0-NEXT: movl %edi, 16(%rax) 128; CHECK-O0-NEXT: movl %edi, 12(%rax) 129; CHECK-O0-NEXT: movl %edi, 8(%rax) 130; CHECK-O0-NEXT: movl %edi, 4(%rax) 131; CHECK-O0-NEXT: movl %edi, (%rax) 132; CHECK-O0-NEXT: retq 133 %Y = insertvalue { i32, i32, i32, i32, i32 } undef, i32 %key, 0 134 %Z = insertvalue { i32, i32, i32, i32, i32 } %Y, i32 %key, 1 135 %Z2 = insertvalue { i32, i32, i32, i32, i32 } %Z, i32 %key, 2 136 %Z3 = insertvalue { i32, i32, i32, i32, i32 } %Z2, i32 %key, 3 137 %Z4 = insertvalue { i32, i32, i32, i32, i32 } %Z3, i32 %key, 4 138 ret { i32, i32, i32, i32, i32 } %Z4 139} 140 141; The return value {i32, i32, i32, i32} will be returned via registers %eax, 142; %edx, %ecx, %r8d. 143define dso_local i32 @test3(i32 %key) #0 { 144; CHECK-LABEL: test3: 145; CHECK: # %bb.0: # %entry 146; CHECK-NEXT: pushq %rax 147; CHECK-NEXT: .cfi_def_cfa_offset 16 148; CHECK-NEXT: movl %edi, {{[0-9]+}}(%rsp) 149; CHECK-NEXT: callq gen3@PLT 150; CHECK-NEXT: addl %edx, %eax 151; CHECK-NEXT: addl %ecx, %eax 152; CHECK-NEXT: addl %r8d, %eax 153; CHECK-NEXT: popq %rcx 154; CHECK-NEXT: .cfi_def_cfa_offset 8 155; CHECK-NEXT: retq 156; 157; CHECK-O0-LABEL: test3: 158; CHECK-O0: # %bb.0: # %entry 159; CHECK-O0-NEXT: pushq %rax 160; CHECK-O0-NEXT: .cfi_def_cfa_offset 16 161; CHECK-O0-NEXT: movl %edi, {{[0-9]+}}(%rsp) 162; CHECK-O0-NEXT: movl {{[0-9]+}}(%rsp), %edi 163; CHECK-O0-NEXT: callq gen3@PLT 164; CHECK-O0-NEXT: addl %edx, %eax 165; CHECK-O0-NEXT: addl %ecx, %eax 166; CHECK-O0-NEXT: addl %r8d, %eax 167; CHECK-O0-NEXT: popq %rcx 168; CHECK-O0-NEXT: .cfi_def_cfa_offset 8 169; CHECK-O0-NEXT: retq 170entry: 171 %key.addr = alloca i32, align 4 172 store i32 %key, i32* %key.addr, align 4 173 %0 = load i32, i32* %key.addr, align 4 174 %call = call swiftcc { i32, i32, i32, i32 } @gen3(i32 %0) 175 176 %v3 = extractvalue { i32, i32, i32, i32 } %call, 0 177 %v5 = extractvalue { i32, i32, i32, i32 } %call, 1 178 %v6 = extractvalue { i32, i32, i32, i32 } %call, 2 179 %v7 = extractvalue { i32, i32, i32, i32 } %call, 3 180 181 %add = add nsw i32 %v3, %v5 182 %add1 = add nsw i32 %add, %v6 183 %add2 = add nsw i32 %add1, %v7 184 ret i32 %add2 185} 186 187declare swiftcc { i32, i32, i32, i32 } @gen3(i32 %key) 188 189; The return value {float, float, float, float} will be returned via registers 190; %xmm0, %xmm1, %xmm2, %xmm3. 191define dso_local float @test4(float %key) #0 { 192; CHECK-LABEL: test4: 193; CHECK: # %bb.0: # %entry 194; CHECK-NEXT: pushq %rax 195; CHECK-NEXT: .cfi_def_cfa_offset 16 196; CHECK-NEXT: movss %xmm0, {{[0-9]+}}(%rsp) 197; CHECK-NEXT: callq gen4@PLT 198; CHECK-NEXT: addss %xmm1, %xmm0 199; CHECK-NEXT: addss %xmm2, %xmm0 200; CHECK-NEXT: addss %xmm3, %xmm0 201; CHECK-NEXT: popq %rax 202; CHECK-NEXT: .cfi_def_cfa_offset 8 203; CHECK-NEXT: retq 204; 205; CHECK-O0-LABEL: test4: 206; CHECK-O0: # %bb.0: # %entry 207; CHECK-O0-NEXT: pushq %rax 208; CHECK-O0-NEXT: .cfi_def_cfa_offset 16 209; CHECK-O0-NEXT: movss %xmm0, {{[0-9]+}}(%rsp) 210; CHECK-O0-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero 211; CHECK-O0-NEXT: callq gen4@PLT 212; CHECK-O0-NEXT: addss %xmm1, %xmm0 213; CHECK-O0-NEXT: addss %xmm2, %xmm0 214; CHECK-O0-NEXT: addss %xmm3, %xmm0 215; CHECK-O0-NEXT: popq %rax 216; CHECK-O0-NEXT: .cfi_def_cfa_offset 8 217; CHECK-O0-NEXT: retq 218entry: 219 %key.addr = alloca float, align 4 220 store float %key, float* %key.addr, align 4 221 %0 = load float, float* %key.addr, align 4 222 %call = call swiftcc { float, float, float, float } @gen4(float %0) 223 224 %v3 = extractvalue { float, float, float, float } %call, 0 225 %v5 = extractvalue { float, float, float, float } %call, 1 226 %v6 = extractvalue { float, float, float, float } %call, 2 227 %v7 = extractvalue { float, float, float, float } %call, 3 228 229 %add = fadd float %v3, %v5 230 %add1 = fadd float %add, %v6 231 %add2 = fadd float %add1, %v7 232 ret float %add2 233} 234 235declare swiftcc { float, float, float, float } @gen4(float %key) 236 237define dso_local void @consume_i1_ret() { 238; CHECK-LABEL: consume_i1_ret: 239; CHECK: # %bb.0: 240; CHECK-NEXT: pushq %rax 241; CHECK-NEXT: .cfi_def_cfa_offset 16 242; CHECK-NEXT: callq produce_i1_ret@PLT 243; CHECK-NEXT: movzbl %al, %eax 244; CHECK-NEXT: andl $1, %eax 245; CHECK-NEXT: movl %eax, var(%rip) 246; CHECK-NEXT: movzbl %dl, %eax 247; CHECK-NEXT: andl $1, %eax 248; CHECK-NEXT: movl %eax, var(%rip) 249; CHECK-NEXT: movzbl %cl, %eax 250; CHECK-NEXT: andl $1, %eax 251; CHECK-NEXT: movl %eax, var(%rip) 252; CHECK-NEXT: movzbl %r8b, %eax 253; CHECK-NEXT: andl $1, %eax 254; CHECK-NEXT: movl %eax, var(%rip) 255; CHECK-NEXT: popq %rax 256; CHECK-NEXT: .cfi_def_cfa_offset 8 257; CHECK-NEXT: retq 258; 259; CHECK-O0-LABEL: consume_i1_ret: 260; CHECK-O0: # %bb.0: 261; CHECK-O0-NEXT: pushq %rax 262; CHECK-O0-NEXT: .cfi_def_cfa_offset 16 263; CHECK-O0-NEXT: callq produce_i1_ret@PLT 264; CHECK-O0-NEXT: andb $1, %al 265; CHECK-O0-NEXT: movzbl %al, %eax 266; CHECK-O0-NEXT: movl %eax, var 267; CHECK-O0-NEXT: andb $1, %dl 268; CHECK-O0-NEXT: movzbl %dl, %eax 269; CHECK-O0-NEXT: movl %eax, var 270; CHECK-O0-NEXT: andb $1, %cl 271; CHECK-O0-NEXT: movzbl %cl, %eax 272; CHECK-O0-NEXT: movl %eax, var 273; CHECK-O0-NEXT: andb $1, %r8b 274; CHECK-O0-NEXT: movzbl %r8b, %eax 275; CHECK-O0-NEXT: movl %eax, var 276; CHECK-O0-NEXT: popq %rax 277; CHECK-O0-NEXT: .cfi_def_cfa_offset 8 278; CHECK-O0-NEXT: retq 279 %call = call swiftcc { i1, i1, i1, i1 } @produce_i1_ret() 280 %v3 = extractvalue { i1, i1, i1, i1 } %call, 0 281 %v5 = extractvalue { i1, i1, i1, i1 } %call, 1 282 %v6 = extractvalue { i1, i1, i1, i1 } %call, 2 283 %v7 = extractvalue { i1, i1, i1, i1 } %call, 3 284 %val = zext i1 %v3 to i32 285 store volatile i32 %val, i32* @var 286 %val2 = zext i1 %v5 to i32 287 store volatile i32 %val2, i32* @var 288 %val3 = zext i1 %v6 to i32 289 store volatile i32 %val3, i32* @var 290 %val4 = zext i1 %v7 to i32 291 store i32 %val4, i32* @var 292 ret void 293} 294 295declare swiftcc { i1, i1, i1, i1 } @produce_i1_ret() 296 297define swiftcc void @foo(i64* sret(i64) %agg.result, i64 %val) { 298; CHECK-LABEL: foo: 299; CHECK: # %bb.0: 300; CHECK-NEXT: movq %rdi, (%rax) 301; CHECK-NEXT: retq 302; 303; CHECK-O0-LABEL: foo: 304; CHECK-O0: # %bb.0: 305; CHECK-O0-NEXT: movq %rdi, (%rax) 306; CHECK-O0-NEXT: retq 307 store i64 %val, i64* %agg.result 308 ret void 309} 310 311define swiftcc double @test5() #0 { 312; CHECK-LABEL: test5: 313; CHECK: # %bb.0: # %entry 314; CHECK-NEXT: pushq %rax 315; CHECK-NEXT: .cfi_def_cfa_offset 16 316; CHECK-NEXT: callq gen5@PLT 317; CHECK-NEXT: addsd %xmm1, %xmm0 318; CHECK-NEXT: addsd %xmm2, %xmm0 319; CHECK-NEXT: addsd %xmm3, %xmm0 320; CHECK-NEXT: popq %rax 321; CHECK-NEXT: .cfi_def_cfa_offset 8 322; CHECK-NEXT: retq 323; 324; CHECK-O0-LABEL: test5: 325; CHECK-O0: # %bb.0: # %entry 326; CHECK-O0-NEXT: pushq %rax 327; CHECK-O0-NEXT: .cfi_def_cfa_offset 16 328; CHECK-O0-NEXT: callq gen5@PLT 329; CHECK-O0-NEXT: addsd %xmm1, %xmm0 330; CHECK-O0-NEXT: addsd %xmm2, %xmm0 331; CHECK-O0-NEXT: addsd %xmm3, %xmm0 332; CHECK-O0-NEXT: popq %rax 333; CHECK-O0-NEXT: .cfi_def_cfa_offset 8 334; CHECK-O0-NEXT: retq 335entry: 336 %call = call swiftcc { double, double, double, double } @gen5() 337 338 %v3 = extractvalue { double, double, double, double } %call, 0 339 %v5 = extractvalue { double, double, double, double } %call, 1 340 %v6 = extractvalue { double, double, double, double } %call, 2 341 %v7 = extractvalue { double, double, double, double } %call, 3 342 343 %add = fadd double %v3, %v5 344 %add1 = fadd double %add, %v6 345 %add2 = fadd double %add1, %v7 346 ret double %add2 347} 348 349declare swiftcc { double, double, double, double } @gen5() 350 351 352define swiftcc { double, i64 } @test6() #0 { 353; CHECK-LABEL: test6: 354; CHECK: # %bb.0: # %entry 355; CHECK-NEXT: pushq %rax 356; CHECK-NEXT: .cfi_def_cfa_offset 16 357; CHECK-NEXT: callq gen6@PLT 358; CHECK-NEXT: addsd %xmm1, %xmm0 359; CHECK-NEXT: addsd %xmm2, %xmm0 360; CHECK-NEXT: addsd %xmm3, %xmm0 361; CHECK-NEXT: addq %rdx, %rax 362; CHECK-NEXT: addq %rcx, %rax 363; CHECK-NEXT: addq %r8, %rax 364; CHECK-NEXT: popq %rcx 365; CHECK-NEXT: .cfi_def_cfa_offset 8 366; CHECK-NEXT: retq 367; 368; CHECK-O0-LABEL: test6: 369; CHECK-O0: # %bb.0: # %entry 370; CHECK-O0-NEXT: pushq %rax 371; CHECK-O0-NEXT: .cfi_def_cfa_offset 16 372; CHECK-O0-NEXT: callq gen6@PLT 373; CHECK-O0-NEXT: addsd %xmm1, %xmm0 374; CHECK-O0-NEXT: addsd %xmm2, %xmm0 375; CHECK-O0-NEXT: addsd %xmm3, %xmm0 376; CHECK-O0-NEXT: addq %rdx, %rax 377; CHECK-O0-NEXT: addq %rcx, %rax 378; CHECK-O0-NEXT: addq %r8, %rax 379; CHECK-O0-NEXT: popq %rcx 380; CHECK-O0-NEXT: .cfi_def_cfa_offset 8 381; CHECK-O0-NEXT: retq 382entry: 383 %call = call swiftcc { double, double, double, double, i64, i64, i64, i64 } @gen6() 384 385 %v3 = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 0 386 %v5 = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 1 387 %v6 = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 2 388 %v7 = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 3 389 %v3.i = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 4 390 %v5.i = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 5 391 %v6.i = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 6 392 %v7.i = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 7 393 394 %add = fadd double %v3, %v5 395 %add1 = fadd double %add, %v6 396 %add2 = fadd double %add1, %v7 397 398 %add.i = add nsw i64 %v3.i, %v5.i 399 %add1.i = add nsw i64 %add.i, %v6.i 400 %add2.i = add nsw i64 %add1.i, %v7.i 401 402 %Y = insertvalue { double, i64 } undef, double %add2, 0 403 %Z = insertvalue { double, i64 } %Y, i64 %add2.i, 1 404 ret { double, i64} %Z 405} 406 407declare swiftcc { double, double, double, double, i64, i64, i64, i64 } @gen6() 408 409define swiftcc { i32, i32, i32, i32 } @gen7(i32 %key) { 410; CHECK-LABEL: gen7: 411; CHECK: # %bb.0: 412; CHECK-NEXT: movl %edi, %eax 413; CHECK-NEXT: movl %edi, %edx 414; CHECK-NEXT: movl %edi, %ecx 415; CHECK-NEXT: movl %edi, %r8d 416; CHECK-NEXT: retq 417; 418; CHECK-O0-LABEL: gen7: 419; CHECK-O0: # %bb.0: 420; CHECK-O0-NEXT: movl %edi, %r8d 421; CHECK-O0-NEXT: movl %r8d, %eax 422; CHECK-O0-NEXT: movl %r8d, %edx 423; CHECK-O0-NEXT: movl %r8d, %ecx 424; CHECK-O0-NEXT: retq 425 %v0 = insertvalue { i32, i32, i32, i32 } undef, i32 %key, 0 426 %v1 = insertvalue { i32, i32, i32, i32 } %v0, i32 %key, 1 427 %v2 = insertvalue { i32, i32, i32, i32 } %v1, i32 %key, 2 428 %v3 = insertvalue { i32, i32, i32, i32 } %v2, i32 %key, 3 429 ret { i32, i32, i32, i32 } %v3 430} 431 432define swiftcc { i64, i64, i64, i64 } @gen8(i64 %key) { 433; CHECK-LABEL: gen8: 434; CHECK: # %bb.0: 435; CHECK-NEXT: movq %rdi, %rax 436; CHECK-NEXT: movq %rdi, %rdx 437; CHECK-NEXT: movq %rdi, %rcx 438; CHECK-NEXT: movq %rdi, %r8 439; CHECK-NEXT: retq 440; 441; CHECK-O0-LABEL: gen8: 442; CHECK-O0: # %bb.0: 443; CHECK-O0-NEXT: movq %rdi, %r8 444; CHECK-O0-NEXT: movq %r8, %rax 445; CHECK-O0-NEXT: movq %r8, %rdx 446; CHECK-O0-NEXT: movq %r8, %rcx 447; CHECK-O0-NEXT: retq 448 %v0 = insertvalue { i64, i64, i64, i64 } undef, i64 %key, 0 449 %v1 = insertvalue { i64, i64, i64, i64 } %v0, i64 %key, 1 450 %v2 = insertvalue { i64, i64, i64, i64 } %v1, i64 %key, 2 451 %v3 = insertvalue { i64, i64, i64, i64 } %v2, i64 %key, 3 452 ret { i64, i64, i64, i64 } %v3 453} 454 455define swiftcc { i8, i8, i8, i8 } @gen9(i8 %key) { 456; CHECK-LABEL: gen9: 457; CHECK: # %bb.0: 458; CHECK-NEXT: movl %edi, %eax 459; CHECK-NEXT: movl %eax, %edx 460; CHECK-NEXT: movl %eax, %ecx 461; CHECK-NEXT: movl %eax, %r8d 462; CHECK-NEXT: retq 463; 464; CHECK-O0-LABEL: gen9: 465; CHECK-O0: # %bb.0: 466; CHECK-O0-NEXT: movb %dil, %r8b 467; CHECK-O0-NEXT: movb %r8b, %al 468; CHECK-O0-NEXT: movb %r8b, %dl 469; CHECK-O0-NEXT: movb %r8b, %cl 470; CHECK-O0-NEXT: retq 471 %v0 = insertvalue { i8, i8, i8, i8 } undef, i8 %key, 0 472 %v1 = insertvalue { i8, i8, i8, i8 } %v0, i8 %key, 1 473 %v2 = insertvalue { i8, i8, i8, i8 } %v1, i8 %key, 2 474 %v3 = insertvalue { i8, i8, i8, i8 } %v2, i8 %key, 3 475 ret { i8, i8, i8, i8 } %v3 476} 477define swiftcc { double, double, double, double, i64, i64, i64, i64 } @gen10(double %keyd, i64 %keyi) { 478; CHECK-LABEL: gen10: 479; CHECK: # %bb.0: 480; CHECK-NEXT: movq %rdi, %rax 481; CHECK-NEXT: movaps %xmm0, %xmm1 482; CHECK-NEXT: movaps %xmm0, %xmm2 483; CHECK-NEXT: movaps %xmm0, %xmm3 484; CHECK-NEXT: movq %rdi, %rdx 485; CHECK-NEXT: movq %rdi, %rcx 486; CHECK-NEXT: movq %rdi, %r8 487; CHECK-NEXT: retq 488; 489; CHECK-O0-LABEL: gen10: 490; CHECK-O0: # %bb.0: 491; CHECK-O0-NEXT: movq %rdi, %r8 492; CHECK-O0-NEXT: movaps %xmm0, %xmm3 493; CHECK-O0-NEXT: movaps %xmm3, %xmm0 494; CHECK-O0-NEXT: movaps %xmm3, %xmm1 495; CHECK-O0-NEXT: movaps %xmm3, %xmm2 496; CHECK-O0-NEXT: movq %r8, %rax 497; CHECK-O0-NEXT: movq %r8, %rdx 498; CHECK-O0-NEXT: movq %r8, %rcx 499; CHECK-O0-NEXT: retq 500 %v0 = insertvalue { double, double, double, double, i64, i64, i64, i64 } undef, double %keyd, 0 501 %v1 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v0, double %keyd, 1 502 %v2 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v1, double %keyd, 2 503 %v3 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v2, double %keyd, 3 504 %v4 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v3, i64 %keyi, 4 505 %v5 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v4, i64 %keyi, 5 506 %v6 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v5, i64 %keyi, 6 507 %v7 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v6, i64 %keyi, 7 508 ret { double, double, double, double, i64, i64, i64, i64 } %v7 509} 510 511 512define swiftcc <4 x float> @test11() #0 { 513; CHECK-LABEL: test11: 514; CHECK: # %bb.0: # %entry 515; CHECK-NEXT: pushq %rax 516; CHECK-NEXT: .cfi_def_cfa_offset 16 517; CHECK-NEXT: callq gen11@PLT 518; CHECK-NEXT: addps %xmm1, %xmm0 519; CHECK-NEXT: addps %xmm2, %xmm0 520; CHECK-NEXT: addps %xmm3, %xmm0 521; CHECK-NEXT: popq %rax 522; CHECK-NEXT: .cfi_def_cfa_offset 8 523; CHECK-NEXT: retq 524; 525; CHECK-O0-LABEL: test11: 526; CHECK-O0: # %bb.0: # %entry 527; CHECK-O0-NEXT: pushq %rax 528; CHECK-O0-NEXT: .cfi_def_cfa_offset 16 529; CHECK-O0-NEXT: callq gen11@PLT 530; CHECK-O0-NEXT: addps %xmm1, %xmm0 531; CHECK-O0-NEXT: addps %xmm2, %xmm0 532; CHECK-O0-NEXT: addps %xmm3, %xmm0 533; CHECK-O0-NEXT: popq %rax 534; CHECK-O0-NEXT: .cfi_def_cfa_offset 8 535; CHECK-O0-NEXT: retq 536entry: 537 %call = call swiftcc { <4 x float>, <4 x float>, <4 x float>, <4 x float> } @gen11() 538 539 %v3 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 0 540 %v5 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 1 541 %v6 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 2 542 %v7 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 3 543 544 %add = fadd <4 x float> %v3, %v5 545 %add1 = fadd <4 x float> %add, %v6 546 %add2 = fadd <4 x float> %add1, %v7 547 ret <4 x float> %add2 548} 549 550declare swiftcc { <4 x float>, <4 x float>, <4 x float>, <4 x float> } @gen11() 551 552define swiftcc { <4 x float>, float } @test12() #0 { 553; CHECK-LABEL: test12: 554; CHECK: # %bb.0: # %entry 555; CHECK-NEXT: pushq %rax 556; CHECK-NEXT: .cfi_def_cfa_offset 16 557; CHECK-NEXT: callq gen12@PLT 558; CHECK-NEXT: addps %xmm1, %xmm0 559; CHECK-NEXT: addps %xmm2, %xmm0 560; CHECK-NEXT: movaps %xmm3, %xmm1 561; CHECK-NEXT: popq %rax 562; CHECK-NEXT: .cfi_def_cfa_offset 8 563; CHECK-NEXT: retq 564; 565; CHECK-O0-LABEL: test12: 566; CHECK-O0: # %bb.0: # %entry 567; CHECK-O0-NEXT: subq $24, %rsp 568; CHECK-O0-NEXT: .cfi_def_cfa_offset 32 569; CHECK-O0-NEXT: callq gen12@PLT 570; CHECK-O0-NEXT: movaps %xmm1, (%rsp) # 16-byte Spill 571; CHECK-O0-NEXT: movaps %xmm3, %xmm1 572; CHECK-O0-NEXT: movaps (%rsp), %xmm3 # 16-byte Reload 573; CHECK-O0-NEXT: addps %xmm3, %xmm0 574; CHECK-O0-NEXT: addps %xmm2, %xmm0 575; CHECK-O0-NEXT: addq $24, %rsp 576; CHECK-O0-NEXT: .cfi_def_cfa_offset 8 577; CHECK-O0-NEXT: retq 578entry: 579 %call = call swiftcc { <4 x float>, <4 x float>, <4 x float>, float } @gen12() 580 581 %v3 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 0 582 %v5 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 1 583 %v6 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 2 584 %v8 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 3 585 586 %add = fadd <4 x float> %v3, %v5 587 %add1 = fadd <4 x float> %add, %v6 588 %res.0 = insertvalue { <4 x float>, float } undef, <4 x float> %add1, 0 589 %res = insertvalue { <4 x float>, float } %res.0, float %v8, 1 590 ret { <4 x float>, float } %res 591} 592 593declare swiftcc { <4 x float>, <4 x float>, <4 x float>, float } @gen12() 594