mirror of
https://github.com/RPCS3/llvm.git
synced 2026-07-19 15:13:49 -04:00
5fd17c6d29
Trace through multiple COPYs when looking for a physreg source. Add hinting for vregs that will be copied into physregs (we only hinted for vregs getting copied to a physreg previously). Give hinted a register a bonus when deciding which value to spill. This is part of my rewrite regallocfast series. In fact this one doesn't even have an effect unless you also flip the allocation to happen from back to front of a basic block. Nonetheless it helps to split this up to ease review of D52010 Patch by Matthias Braun git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360887 91177308-0d34-0410-b5e6-96231b3b80d8
598 lines
21 KiB
LLVM
598 lines
21 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc -verify-machineinstrs < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
|
|
; RUN: llc -verify-machineinstrs < %s -mtriple=x86_64-unknown-unknown -O0 | FileCheck --check-prefix=CHECK-O0 %s
|
|
|
|
@var = global i32 0
|
|
|
|
; Test how llvm handles return type of {i16, i8}. The return value will be
|
|
; passed in %eax and %dl.
|
|
define i16 @test(i32 %key) {
|
|
; CHECK-LABEL: test:
|
|
; CHECK: # %bb.0: # %entry
|
|
; CHECK-NEXT: pushq %rax
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: movl %edi, {{[0-9]+}}(%rsp)
|
|
; CHECK-NEXT: callq gen
|
|
; CHECK-NEXT: # kill: def $ax killed $ax def $eax
|
|
; CHECK-NEXT: movsbl %dl, %ecx
|
|
; CHECK-NEXT: addl %ecx, %eax
|
|
; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
|
|
; CHECK-NEXT: popq %rcx
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-NEXT: retq
|
|
;
|
|
; CHECK-O0-LABEL: test:
|
|
; CHECK-O0: # %bb.0: # %entry
|
|
; CHECK-O0-NEXT: pushq %rax
|
|
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-O0-NEXT: movl %edi, {{[0-9]+}}(%rsp)
|
|
; CHECK-O0-NEXT: movl {{[0-9]+}}(%rsp), %edi
|
|
; CHECK-O0-NEXT: callq gen
|
|
; CHECK-O0-NEXT: movswl %ax, %ecx
|
|
; CHECK-O0-NEXT: movsbl %dl, %esi
|
|
; CHECK-O0-NEXT: addl %esi, %ecx
|
|
; CHECK-O0-NEXT: # kill: def $cx killed $cx killed $ecx
|
|
; CHECK-O0-NEXT: movw %cx, %ax
|
|
; CHECK-O0-NEXT: popq %rcx
|
|
; CHECK-O0-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-O0-NEXT: retq
|
|
entry:
|
|
%key.addr = alloca i32, align 4
|
|
store i32 %key, i32* %key.addr, align 4
|
|
%0 = load i32, i32* %key.addr, align 4
|
|
%call = call swiftcc { i16, i8 } @gen(i32 %0)
|
|
%v3 = extractvalue { i16, i8 } %call, 0
|
|
%v1 = sext i16 %v3 to i32
|
|
%v5 = extractvalue { i16, i8 } %call, 1
|
|
%v2 = sext i8 %v5 to i32
|
|
%add = add nsw i32 %v1, %v2
|
|
%conv = trunc i32 %add to i16
|
|
ret i16 %conv
|
|
}
|
|
|
|
declare swiftcc { i16, i8 } @gen(i32)
|
|
|
|
; If we can't pass every return value in register, we will pass everything
|
|
; in memroy. The caller provides space for the return value and passes
|
|
; the address in %rax. The first input argument will be in %rdi.
|
|
define i32 @test2(i32 %key) #0 {
|
|
; CHECK-LABEL: test2:
|
|
; CHECK: # %bb.0: # %entry
|
|
; CHECK-NEXT: subq $24, %rsp
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 32
|
|
; CHECK-NEXT: movl %edi, {{[0-9]+}}(%rsp)
|
|
; CHECK-NEXT: movq %rsp, %rax
|
|
; CHECK-NEXT: callq gen2
|
|
; CHECK-NEXT: movl (%rsp), %eax
|
|
; CHECK-NEXT: addl {{[0-9]+}}(%rsp), %eax
|
|
; CHECK-NEXT: addl {{[0-9]+}}(%rsp), %eax
|
|
; CHECK-NEXT: addl {{[0-9]+}}(%rsp), %eax
|
|
; CHECK-NEXT: addl {{[0-9]+}}(%rsp), %eax
|
|
; CHECK-NEXT: addq $24, %rsp
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-NEXT: retq
|
|
;
|
|
; CHECK-O0-LABEL: test2:
|
|
; CHECK-O0: # %bb.0: # %entry
|
|
; CHECK-O0-NEXT: subq $24, %rsp
|
|
; CHECK-O0-NEXT: .cfi_def_cfa_offset 32
|
|
; CHECK-O0-NEXT: movl %edi, {{[0-9]+}}(%rsp)
|
|
; CHECK-O0-NEXT: movl {{[0-9]+}}(%rsp), %edi
|
|
; CHECK-O0-NEXT: movq %rsp, %rax
|
|
; CHECK-O0-NEXT: callq gen2
|
|
; CHECK-O0-NEXT: movl {{[0-9]+}}(%rsp), %ecx
|
|
; CHECK-O0-NEXT: movl {{[0-9]+}}(%rsp), %edx
|
|
; CHECK-O0-NEXT: movl {{[0-9]+}}(%rsp), %esi
|
|
; CHECK-O0-NEXT: movl (%rsp), %edi
|
|
; CHECK-O0-NEXT: movl {{[0-9]+}}(%rsp), %r8d
|
|
; CHECK-O0-NEXT: addl %r8d, %edi
|
|
; CHECK-O0-NEXT: addl %esi, %edi
|
|
; CHECK-O0-NEXT: addl %edx, %edi
|
|
; CHECK-O0-NEXT: addl %ecx, %edi
|
|
; CHECK-O0-NEXT: movl %edi, %eax
|
|
; CHECK-O0-NEXT: addq $24, %rsp
|
|
; CHECK-O0-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-O0-NEXT: retq
|
|
entry:
|
|
%key.addr = alloca i32, align 4
|
|
store i32 %key, i32* %key.addr, align 4
|
|
%0 = load i32, i32* %key.addr, align 4
|
|
%call = call swiftcc { i32, i32, i32, i32, i32 } @gen2(i32 %0)
|
|
|
|
%v3 = extractvalue { i32, i32, i32, i32, i32 } %call, 0
|
|
%v5 = extractvalue { i32, i32, i32, i32, i32 } %call, 1
|
|
%v6 = extractvalue { i32, i32, i32, i32, i32 } %call, 2
|
|
%v7 = extractvalue { i32, i32, i32, i32, i32 } %call, 3
|
|
%v8 = extractvalue { i32, i32, i32, i32, i32 } %call, 4
|
|
|
|
%add = add nsw i32 %v3, %v5
|
|
%add1 = add nsw i32 %add, %v6
|
|
%add2 = add nsw i32 %add1, %v7
|
|
%add3 = add nsw i32 %add2, %v8
|
|
ret i32 %add3
|
|
}
|
|
|
|
; The address of the return value is passed in %rax.
|
|
; On return, we don't keep the address in %rax.
|
|
define swiftcc { i32, i32, i32, i32, i32 } @gen2(i32 %key) {
|
|
; CHECK-LABEL: gen2:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: movl %edi, 16(%rax)
|
|
; CHECK-NEXT: movl %edi, 12(%rax)
|
|
; CHECK-NEXT: movl %edi, 8(%rax)
|
|
; CHECK-NEXT: movl %edi, 4(%rax)
|
|
; CHECK-NEXT: movl %edi, (%rax)
|
|
; CHECK-NEXT: retq
|
|
;
|
|
; CHECK-O0-LABEL: gen2:
|
|
; CHECK-O0: # %bb.0:
|
|
; CHECK-O0-NEXT: movl %edi, 16(%rax)
|
|
; CHECK-O0-NEXT: movl %edi, 12(%rax)
|
|
; CHECK-O0-NEXT: movl %edi, 8(%rax)
|
|
; CHECK-O0-NEXT: movl %edi, 4(%rax)
|
|
; CHECK-O0-NEXT: movl %edi, (%rax)
|
|
; CHECK-O0-NEXT: retq
|
|
%Y = insertvalue { i32, i32, i32, i32, i32 } undef, i32 %key, 0
|
|
%Z = insertvalue { i32, i32, i32, i32, i32 } %Y, i32 %key, 1
|
|
%Z2 = insertvalue { i32, i32, i32, i32, i32 } %Z, i32 %key, 2
|
|
%Z3 = insertvalue { i32, i32, i32, i32, i32 } %Z2, i32 %key, 3
|
|
%Z4 = insertvalue { i32, i32, i32, i32, i32 } %Z3, i32 %key, 4
|
|
ret { i32, i32, i32, i32, i32 } %Z4
|
|
}
|
|
|
|
; The return value {i32, i32, i32, i32} will be returned via registers %eax,
|
|
; %edx, %ecx, %r8d.
|
|
define i32 @test3(i32 %key) #0 {
|
|
; CHECK-LABEL: test3:
|
|
; CHECK: # %bb.0: # %entry
|
|
; CHECK-NEXT: pushq %rax
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: movl %edi, {{[0-9]+}}(%rsp)
|
|
; CHECK-NEXT: callq gen3
|
|
; CHECK-NEXT: addl %edx, %eax
|
|
; CHECK-NEXT: addl %ecx, %eax
|
|
; CHECK-NEXT: addl %r8d, %eax
|
|
; CHECK-NEXT: popq %rcx
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-NEXT: retq
|
|
;
|
|
; CHECK-O0-LABEL: test3:
|
|
; CHECK-O0: # %bb.0: # %entry
|
|
; CHECK-O0-NEXT: pushq %rax
|
|
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-O0-NEXT: movl %edi, {{[0-9]+}}(%rsp)
|
|
; CHECK-O0-NEXT: movl {{[0-9]+}}(%rsp), %edi
|
|
; CHECK-O0-NEXT: callq gen3
|
|
; CHECK-O0-NEXT: addl %edx, %eax
|
|
; CHECK-O0-NEXT: addl %ecx, %eax
|
|
; CHECK-O0-NEXT: addl %r8d, %eax
|
|
; CHECK-O0-NEXT: popq %rcx
|
|
; CHECK-O0-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-O0-NEXT: retq
|
|
entry:
|
|
%key.addr = alloca i32, align 4
|
|
store i32 %key, i32* %key.addr, align 4
|
|
%0 = load i32, i32* %key.addr, align 4
|
|
%call = call swiftcc { i32, i32, i32, i32 } @gen3(i32 %0)
|
|
|
|
%v3 = extractvalue { i32, i32, i32, i32 } %call, 0
|
|
%v5 = extractvalue { i32, i32, i32, i32 } %call, 1
|
|
%v6 = extractvalue { i32, i32, i32, i32 } %call, 2
|
|
%v7 = extractvalue { i32, i32, i32, i32 } %call, 3
|
|
|
|
%add = add nsw i32 %v3, %v5
|
|
%add1 = add nsw i32 %add, %v6
|
|
%add2 = add nsw i32 %add1, %v7
|
|
ret i32 %add2
|
|
}
|
|
|
|
declare swiftcc { i32, i32, i32, i32 } @gen3(i32 %key)
|
|
|
|
; The return value {float, float, float, float} will be returned via registers
|
|
; %xmm0, %xmm1, %xmm2, %xmm3.
|
|
define float @test4(float %key) #0 {
|
|
; CHECK-LABEL: test4:
|
|
; CHECK: # %bb.0: # %entry
|
|
; CHECK-NEXT: pushq %rax
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: movss %xmm0, {{[0-9]+}}(%rsp)
|
|
; CHECK-NEXT: callq gen4
|
|
; CHECK-NEXT: addss %xmm1, %xmm0
|
|
; CHECK-NEXT: addss %xmm2, %xmm0
|
|
; CHECK-NEXT: addss %xmm3, %xmm0
|
|
; CHECK-NEXT: popq %rax
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-NEXT: retq
|
|
;
|
|
; CHECK-O0-LABEL: test4:
|
|
; CHECK-O0: # %bb.0: # %entry
|
|
; CHECK-O0-NEXT: pushq %rax
|
|
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-O0-NEXT: movss %xmm0, {{[0-9]+}}(%rsp)
|
|
; CHECK-O0-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
|
|
; CHECK-O0-NEXT: callq gen4
|
|
; CHECK-O0-NEXT: addss %xmm1, %xmm0
|
|
; CHECK-O0-NEXT: addss %xmm2, %xmm0
|
|
; CHECK-O0-NEXT: addss %xmm3, %xmm0
|
|
; CHECK-O0-NEXT: popq %rax
|
|
; CHECK-O0-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-O0-NEXT: retq
|
|
entry:
|
|
%key.addr = alloca float, align 4
|
|
store float %key, float* %key.addr, align 4
|
|
%0 = load float, float* %key.addr, align 4
|
|
%call = call swiftcc { float, float, float, float } @gen4(float %0)
|
|
|
|
%v3 = extractvalue { float, float, float, float } %call, 0
|
|
%v5 = extractvalue { float, float, float, float } %call, 1
|
|
%v6 = extractvalue { float, float, float, float } %call, 2
|
|
%v7 = extractvalue { float, float, float, float } %call, 3
|
|
|
|
%add = fadd float %v3, %v5
|
|
%add1 = fadd float %add, %v6
|
|
%add2 = fadd float %add1, %v7
|
|
ret float %add2
|
|
}
|
|
|
|
declare swiftcc { float, float, float, float } @gen4(float %key)
|
|
|
|
define void @consume_i1_ret() {
|
|
; CHECK-LABEL: consume_i1_ret:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: pushq %rax
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: callq produce_i1_ret
|
|
; CHECK-NEXT: movzbl %al, %eax
|
|
; CHECK-NEXT: andl $1, %eax
|
|
; CHECK-NEXT: movl %eax, {{.*}}(%rip)
|
|
; CHECK-NEXT: movzbl %dl, %eax
|
|
; CHECK-NEXT: andl $1, %eax
|
|
; CHECK-NEXT: movl %eax, {{.*}}(%rip)
|
|
; CHECK-NEXT: movzbl %cl, %eax
|
|
; CHECK-NEXT: andl $1, %eax
|
|
; CHECK-NEXT: movl %eax, {{.*}}(%rip)
|
|
; CHECK-NEXT: movzbl %r8b, %eax
|
|
; CHECK-NEXT: andl $1, %eax
|
|
; CHECK-NEXT: movl %eax, {{.*}}(%rip)
|
|
; CHECK-NEXT: popq %rax
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-NEXT: retq
|
|
;
|
|
; CHECK-O0-LABEL: consume_i1_ret:
|
|
; CHECK-O0: # %bb.0:
|
|
; CHECK-O0-NEXT: pushq %rax
|
|
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-O0-NEXT: callq produce_i1_ret
|
|
; CHECK-O0-NEXT: andb $1, %al
|
|
; CHECK-O0-NEXT: movzbl %al, %esi
|
|
; CHECK-O0-NEXT: movl %esi, var
|
|
; CHECK-O0-NEXT: andb $1, %dl
|
|
; CHECK-O0-NEXT: movzbl %dl, %esi
|
|
; CHECK-O0-NEXT: movl %esi, var
|
|
; CHECK-O0-NEXT: andb $1, %cl
|
|
; CHECK-O0-NEXT: movzbl %cl, %esi
|
|
; CHECK-O0-NEXT: movl %esi, var
|
|
; CHECK-O0-NEXT: andb $1, %r8b
|
|
; CHECK-O0-NEXT: movzbl %r8b, %esi
|
|
; CHECK-O0-NEXT: movl %esi, var
|
|
; CHECK-O0-NEXT: popq %rax
|
|
; CHECK-O0-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-O0-NEXT: retq
|
|
%call = call swiftcc { i1, i1, i1, i1 } @produce_i1_ret()
|
|
%v3 = extractvalue { i1, i1, i1, i1 } %call, 0
|
|
%v5 = extractvalue { i1, i1, i1, i1 } %call, 1
|
|
%v6 = extractvalue { i1, i1, i1, i1 } %call, 2
|
|
%v7 = extractvalue { i1, i1, i1, i1 } %call, 3
|
|
%val = zext i1 %v3 to i32
|
|
store volatile i32 %val, i32* @var
|
|
%val2 = zext i1 %v5 to i32
|
|
store volatile i32 %val2, i32* @var
|
|
%val3 = zext i1 %v6 to i32
|
|
store volatile i32 %val3, i32* @var
|
|
%val4 = zext i1 %v7 to i32
|
|
store i32 %val4, i32* @var
|
|
ret void
|
|
}
|
|
|
|
declare swiftcc { i1, i1, i1, i1 } @produce_i1_ret()
|
|
|
|
define swiftcc void @foo(i64* sret %agg.result, i64 %val) {
|
|
; CHECK-LABEL: foo:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: movq %rdi, (%rax)
|
|
; CHECK-NEXT: retq
|
|
;
|
|
; CHECK-O0-LABEL: foo:
|
|
; CHECK-O0: # %bb.0:
|
|
; CHECK-O0-NEXT: movq %rdi, (%rax)
|
|
; CHECK-O0-NEXT: retq
|
|
store i64 %val, i64* %agg.result
|
|
ret void
|
|
}
|
|
|
|
define swiftcc double @test5() #0 {
|
|
; CHECK-LABEL: test5:
|
|
; CHECK: # %bb.0: # %entry
|
|
; CHECK-NEXT: pushq %rax
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: callq gen5
|
|
; CHECK-NEXT: addsd %xmm1, %xmm0
|
|
; CHECK-NEXT: addsd %xmm2, %xmm0
|
|
; CHECK-NEXT: addsd %xmm3, %xmm0
|
|
; CHECK-NEXT: popq %rax
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-NEXT: retq
|
|
;
|
|
; CHECK-O0-LABEL: test5:
|
|
; CHECK-O0: # %bb.0: # %entry
|
|
; CHECK-O0-NEXT: pushq %rax
|
|
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-O0-NEXT: callq gen5
|
|
; CHECK-O0-NEXT: addsd %xmm1, %xmm0
|
|
; CHECK-O0-NEXT: addsd %xmm2, %xmm0
|
|
; CHECK-O0-NEXT: addsd %xmm3, %xmm0
|
|
; CHECK-O0-NEXT: popq %rax
|
|
; CHECK-O0-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-O0-NEXT: retq
|
|
entry:
|
|
%call = call swiftcc { double, double, double, double } @gen5()
|
|
|
|
%v3 = extractvalue { double, double, double, double } %call, 0
|
|
%v5 = extractvalue { double, double, double, double } %call, 1
|
|
%v6 = extractvalue { double, double, double, double } %call, 2
|
|
%v7 = extractvalue { double, double, double, double } %call, 3
|
|
|
|
%add = fadd double %v3, %v5
|
|
%add1 = fadd double %add, %v6
|
|
%add2 = fadd double %add1, %v7
|
|
ret double %add2
|
|
}
|
|
|
|
declare swiftcc { double, double, double, double } @gen5()
|
|
|
|
|
|
define swiftcc { double, i64 } @test6() #0 {
|
|
; CHECK-LABEL: test6:
|
|
; CHECK: # %bb.0: # %entry
|
|
; CHECK-NEXT: pushq %rax
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: callq gen6
|
|
; CHECK-NEXT: addsd %xmm1, %xmm0
|
|
; CHECK-NEXT: addsd %xmm2, %xmm0
|
|
; CHECK-NEXT: addsd %xmm3, %xmm0
|
|
; CHECK-NEXT: addq %rdx, %rax
|
|
; CHECK-NEXT: addq %rcx, %rax
|
|
; CHECK-NEXT: addq %r8, %rax
|
|
; CHECK-NEXT: popq %rcx
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-NEXT: retq
|
|
;
|
|
; CHECK-O0-LABEL: test6:
|
|
; CHECK-O0: # %bb.0: # %entry
|
|
; CHECK-O0-NEXT: pushq %rax
|
|
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-O0-NEXT: callq gen6
|
|
; CHECK-O0-NEXT: addsd %xmm1, %xmm0
|
|
; CHECK-O0-NEXT: addsd %xmm2, %xmm0
|
|
; CHECK-O0-NEXT: addsd %xmm3, %xmm0
|
|
; CHECK-O0-NEXT: addq %rdx, %rax
|
|
; CHECK-O0-NEXT: addq %rcx, %rax
|
|
; CHECK-O0-NEXT: addq %r8, %rax
|
|
; CHECK-O0-NEXT: popq %rcx
|
|
; CHECK-O0-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-O0-NEXT: retq
|
|
entry:
|
|
%call = call swiftcc { double, double, double, double, i64, i64, i64, i64 } @gen6()
|
|
|
|
%v3 = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 0
|
|
%v5 = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 1
|
|
%v6 = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 2
|
|
%v7 = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 3
|
|
%v3.i = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 4
|
|
%v5.i = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 5
|
|
%v6.i = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 6
|
|
%v7.i = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 7
|
|
|
|
%add = fadd double %v3, %v5
|
|
%add1 = fadd double %add, %v6
|
|
%add2 = fadd double %add1, %v7
|
|
|
|
%add.i = add nsw i64 %v3.i, %v5.i
|
|
%add1.i = add nsw i64 %add.i, %v6.i
|
|
%add2.i = add nsw i64 %add1.i, %v7.i
|
|
|
|
%Y = insertvalue { double, i64 } undef, double %add2, 0
|
|
%Z = insertvalue { double, i64 } %Y, i64 %add2.i, 1
|
|
ret { double, i64} %Z
|
|
}
|
|
|
|
declare swiftcc { double, double, double, double, i64, i64, i64, i64 } @gen6()
|
|
|
|
define swiftcc { i32, i32, i32, i32 } @gen7(i32 %key) {
|
|
; CHECK-LABEL: gen7:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: movl %edi, %eax
|
|
; CHECK-NEXT: movl %edi, %edx
|
|
; CHECK-NEXT: movl %edi, %ecx
|
|
; CHECK-NEXT: movl %edi, %r8d
|
|
; CHECK-NEXT: retq
|
|
;
|
|
; CHECK-O0-LABEL: gen7:
|
|
; CHECK-O0: # %bb.0:
|
|
; CHECK-O0-NEXT: movl %edi, %eax
|
|
; CHECK-O0-NEXT: movl %edi, %edx
|
|
; CHECK-O0-NEXT: movl %edi, %ecx
|
|
; CHECK-O0-NEXT: movl %edi, %r8d
|
|
; CHECK-O0-NEXT: retq
|
|
%v0 = insertvalue { i32, i32, i32, i32 } undef, i32 %key, 0
|
|
%v1 = insertvalue { i32, i32, i32, i32 } %v0, i32 %key, 1
|
|
%v2 = insertvalue { i32, i32, i32, i32 } %v1, i32 %key, 2
|
|
%v3 = insertvalue { i32, i32, i32, i32 } %v2, i32 %key, 3
|
|
ret { i32, i32, i32, i32 } %v3
|
|
}
|
|
|
|
define swiftcc { i64, i64, i64, i64 } @gen8(i64 %key) {
|
|
; CHECK-LABEL: gen8:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: movq %rdi, %rax
|
|
; CHECK-NEXT: movq %rdi, %rdx
|
|
; CHECK-NEXT: movq %rdi, %rcx
|
|
; CHECK-NEXT: movq %rdi, %r8
|
|
; CHECK-NEXT: retq
|
|
;
|
|
; CHECK-O0-LABEL: gen8:
|
|
; CHECK-O0: # %bb.0:
|
|
; CHECK-O0-NEXT: movq %rdi, %rax
|
|
; CHECK-O0-NEXT: movq %rdi, %rdx
|
|
; CHECK-O0-NEXT: movq %rdi, %rcx
|
|
; CHECK-O0-NEXT: movq %rdi, %r8
|
|
; CHECK-O0-NEXT: retq
|
|
%v0 = insertvalue { i64, i64, i64, i64 } undef, i64 %key, 0
|
|
%v1 = insertvalue { i64, i64, i64, i64 } %v0, i64 %key, 1
|
|
%v2 = insertvalue { i64, i64, i64, i64 } %v1, i64 %key, 2
|
|
%v3 = insertvalue { i64, i64, i64, i64 } %v2, i64 %key, 3
|
|
ret { i64, i64, i64, i64 } %v3
|
|
}
|
|
|
|
define swiftcc { i8, i8, i8, i8 } @gen9(i8 %key) {
|
|
; CHECK-LABEL: gen9:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: movl %edi, %eax
|
|
; CHECK-NEXT: movl %eax, %edx
|
|
; CHECK-NEXT: movl %eax, %ecx
|
|
; CHECK-NEXT: movl %eax, %r8d
|
|
; CHECK-NEXT: retq
|
|
;
|
|
; CHECK-O0-LABEL: gen9:
|
|
; CHECK-O0: # %bb.0:
|
|
; CHECK-O0-NEXT: # kill: def $dil killed $dil killed $edi
|
|
; CHECK-O0-NEXT: movb %dil, %al
|
|
; CHECK-O0-NEXT: movb %dil, %dl
|
|
; CHECK-O0-NEXT: movb %dil, %cl
|
|
; CHECK-O0-NEXT: movb %dil, %r8b
|
|
; CHECK-O0-NEXT: retq
|
|
%v0 = insertvalue { i8, i8, i8, i8 } undef, i8 %key, 0
|
|
%v1 = insertvalue { i8, i8, i8, i8 } %v0, i8 %key, 1
|
|
%v2 = insertvalue { i8, i8, i8, i8 } %v1, i8 %key, 2
|
|
%v3 = insertvalue { i8, i8, i8, i8 } %v2, i8 %key, 3
|
|
ret { i8, i8, i8, i8 } %v3
|
|
}
|
|
define swiftcc { double, double, double, double, i64, i64, i64, i64 } @gen10(double %keyd, i64 %keyi) {
|
|
; CHECK-LABEL: gen10:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: movq %rdi, %rax
|
|
; CHECK-NEXT: movaps %xmm0, %xmm1
|
|
; CHECK-NEXT: movaps %xmm0, %xmm2
|
|
; CHECK-NEXT: movaps %xmm0, %xmm3
|
|
; CHECK-NEXT: movq %rdi, %rdx
|
|
; CHECK-NEXT: movq %rdi, %rcx
|
|
; CHECK-NEXT: movq %rdi, %r8
|
|
; CHECK-NEXT: retq
|
|
;
|
|
; CHECK-O0-LABEL: gen10:
|
|
; CHECK-O0: # %bb.0:
|
|
; CHECK-O0-NEXT: movsd %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
|
|
; CHECK-O0-NEXT: movsd {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 8-byte Reload
|
|
; CHECK-O0-NEXT: # xmm1 = mem[0],zero
|
|
; CHECK-O0-NEXT: movsd {{[-0-9]+}}(%r{{[sb]}}p), %xmm2 # 8-byte Reload
|
|
; CHECK-O0-NEXT: # xmm2 = mem[0],zero
|
|
; CHECK-O0-NEXT: movsd {{[-0-9]+}}(%r{{[sb]}}p), %xmm3 # 8-byte Reload
|
|
; CHECK-O0-NEXT: # xmm3 = mem[0],zero
|
|
; CHECK-O0-NEXT: movq %rdi, %rax
|
|
; CHECK-O0-NEXT: movq %rdi, %rdx
|
|
; CHECK-O0-NEXT: movq %rdi, %rcx
|
|
; CHECK-O0-NEXT: movq %rdi, %r8
|
|
; CHECK-O0-NEXT: retq
|
|
%v0 = insertvalue { double, double, double, double, i64, i64, i64, i64 } undef, double %keyd, 0
|
|
%v1 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v0, double %keyd, 1
|
|
%v2 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v1, double %keyd, 2
|
|
%v3 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v2, double %keyd, 3
|
|
%v4 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v3, i64 %keyi, 4
|
|
%v5 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v4, i64 %keyi, 5
|
|
%v6 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v5, i64 %keyi, 6
|
|
%v7 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v6, i64 %keyi, 7
|
|
ret { double, double, double, double, i64, i64, i64, i64 } %v7
|
|
}
|
|
|
|
|
|
define swiftcc <4 x float> @test11() #0 {
|
|
; CHECK-LABEL: test11:
|
|
; CHECK: # %bb.0: # %entry
|
|
; CHECK-NEXT: pushq %rax
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: callq gen11
|
|
; CHECK-NEXT: addps %xmm1, %xmm0
|
|
; CHECK-NEXT: addps %xmm2, %xmm0
|
|
; CHECK-NEXT: addps %xmm3, %xmm0
|
|
; CHECK-NEXT: popq %rax
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-NEXT: retq
|
|
;
|
|
; CHECK-O0-LABEL: test11:
|
|
; CHECK-O0: # %bb.0: # %entry
|
|
; CHECK-O0-NEXT: pushq %rax
|
|
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-O0-NEXT: callq gen11
|
|
; CHECK-O0-NEXT: addps %xmm1, %xmm0
|
|
; CHECK-O0-NEXT: addps %xmm2, %xmm0
|
|
; CHECK-O0-NEXT: addps %xmm3, %xmm0
|
|
; CHECK-O0-NEXT: popq %rax
|
|
; CHECK-O0-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-O0-NEXT: retq
|
|
entry:
|
|
%call = call swiftcc { <4 x float>, <4 x float>, <4 x float>, <4 x float> } @gen11()
|
|
|
|
%v3 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 0
|
|
%v5 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 1
|
|
%v6 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 2
|
|
%v7 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 3
|
|
|
|
%add = fadd <4 x float> %v3, %v5
|
|
%add1 = fadd <4 x float> %add, %v6
|
|
%add2 = fadd <4 x float> %add1, %v7
|
|
ret <4 x float> %add2
|
|
}
|
|
|
|
declare swiftcc { <4 x float>, <4 x float>, <4 x float>, <4 x float> } @gen11()
|
|
|
|
define swiftcc { <4 x float>, float } @test12() #0 {
|
|
; CHECK-LABEL: test12:
|
|
; CHECK: # %bb.0: # %entry
|
|
; CHECK-NEXT: pushq %rax
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: callq gen12
|
|
; CHECK-NEXT: addps %xmm1, %xmm0
|
|
; CHECK-NEXT: addps %xmm2, %xmm0
|
|
; CHECK-NEXT: movaps %xmm3, %xmm1
|
|
; CHECK-NEXT: popq %rax
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-NEXT: retq
|
|
;
|
|
; CHECK-O0-LABEL: test12:
|
|
; CHECK-O0: # %bb.0: # %entry
|
|
; CHECK-O0-NEXT: pushq %rax
|
|
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-O0-NEXT: callq gen12
|
|
; CHECK-O0-NEXT: addps %xmm1, %xmm0
|
|
; CHECK-O0-NEXT: addps %xmm2, %xmm0
|
|
; CHECK-O0-NEXT: movaps %xmm3, %xmm1
|
|
; CHECK-O0-NEXT: popq %rax
|
|
; CHECK-O0-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-O0-NEXT: retq
|
|
entry:
|
|
%call = call swiftcc { <4 x float>, <4 x float>, <4 x float>, float } @gen12()
|
|
|
|
%v3 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 0
|
|
%v5 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 1
|
|
%v6 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 2
|
|
%v8 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 3
|
|
|
|
%add = fadd <4 x float> %v3, %v5
|
|
%add1 = fadd <4 x float> %add, %v6
|
|
%res.0 = insertvalue { <4 x float>, float } undef, <4 x float> %add1, 0
|
|
%res = insertvalue { <4 x float>, float } %res.0, float %v8, 1
|
|
ret { <4 x float>, float } %res
|
|
}
|
|
|
|
declare swiftcc { <4 x float>, <4 x float>, <4 x float>, float } @gen12()
|