
BreakFalseDeps picks the best register for undef operands if instructions have false dependency. The problem is if the instruction is close to the beginning of the function, ReachingDefAnalysis is over optimism to the unused registers, which results in collision with registers just defined in the caller. This patch changes the selection of undef register in an reverse order, which reduces the probability of register collisions between caller and callee. It brings improvement in some of our internal benchmarks with negligible effect on other benchmarks.
396 lines
11 KiB
LLVM
396 lines
11 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
|
|
; RUN: llc < %s -mtriple=x86_64-- -verify-machineinstrs | FileCheck %s --check-prefixes X64,SDAG-X64
|
|
; RUN: llc < %s -global-isel -global-isel-abort=1 -mtriple=x86_64-- -verify-machineinstrs | FileCheck %s --check-prefixes X64,GISEL-X64
|
|
; RUN: llc < %s -mattr=+avx512f -mtriple=x86_64-- -verify-machineinstrs | FileCheck %s --check-prefixes AVX512,SDAG-AVX512
|
|
; RUN: llc < %s -global-isel -global-isel-abort=1 -mattr=+avx512f -mtriple=x86_64-- -verify-machineinstrs | FileCheck %s --check-prefixes AVX512,GISEL-AVX512
|
|
|
|
define double @test_ui64_to_double(i64 %x) {
|
|
; SDAG-X64-LABEL: test_ui64_to_double:
|
|
; SDAG-X64: # %bb.0: # %entry
|
|
; SDAG-X64-NEXT: movq %rdi, %xmm1
|
|
; SDAG-X64-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
|
|
; SDAG-X64-NEXT: subpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
|
|
; SDAG-X64-NEXT: movapd %xmm1, %xmm0
|
|
; SDAG-X64-NEXT: unpckhpd {{.*#+}} xmm0 = xmm0[1],xmm1[1]
|
|
; SDAG-X64-NEXT: addsd %xmm1, %xmm0
|
|
; SDAG-X64-NEXT: retq
|
|
;
|
|
; GISEL-X64-LABEL: test_ui64_to_double:
|
|
; GISEL-X64: # %bb.0: # %entry
|
|
; GISEL-X64-NEXT: movabsq $4841369599423283200, %rax # imm = 0x4330000000000000
|
|
; GISEL-X64-NEXT: movabsq $4985484787499139072, %rcx # imm = 0x4530000000000000
|
|
; GISEL-X64-NEXT: movsd {{.*#+}} xmm0 = [1.9342813118337666E+25,0.0E+0]
|
|
; GISEL-X64-NEXT: movl $4294967295, %edx # imm = 0xFFFFFFFF
|
|
; GISEL-X64-NEXT: andq %rdi, %rdx
|
|
; GISEL-X64-NEXT: orq %rax, %rdx
|
|
; GISEL-X64-NEXT: shrq $32, %rdi
|
|
; GISEL-X64-NEXT: orq %rdi, %rcx
|
|
; GISEL-X64-NEXT: movq %rcx, %xmm1
|
|
; GISEL-X64-NEXT: subsd %xmm0, %xmm1
|
|
; GISEL-X64-NEXT: movq %rdx, %xmm0
|
|
; GISEL-X64-NEXT: addsd %xmm1, %xmm0
|
|
; GISEL-X64-NEXT: retq
|
|
;
|
|
; AVX512-LABEL: test_ui64_to_double:
|
|
; AVX512: # %bb.0: # %entry
|
|
; AVX512-NEXT: vcvtusi2sd %rdi, %xmm15, %xmm0
|
|
; AVX512-NEXT: retq
|
|
entry:
|
|
%conv = uitofp i64 %x to double
|
|
ret double %conv
|
|
}
|
|
|
|
define double @test_ui32_to_double(i32 %x) {
|
|
; X64-LABEL: test_ui32_to_double:
|
|
; X64: # %bb.0: # %entry
|
|
; X64-NEXT: movl %edi, %eax
|
|
; X64-NEXT: cvtsi2sd %rax, %xmm0
|
|
; X64-NEXT: retq
|
|
;
|
|
; AVX512-LABEL: test_ui32_to_double:
|
|
; AVX512: # %bb.0: # %entry
|
|
; AVX512-NEXT: vcvtusi2sd %edi, %xmm15, %xmm0
|
|
; AVX512-NEXT: retq
|
|
entry:
|
|
%conv = uitofp i32 %x to double
|
|
ret double %conv
|
|
}
|
|
|
|
define double @test_ui16_to_double(i16 zeroext %x) {
|
|
; X64-LABEL: test_ui16_to_double:
|
|
; X64: # %bb.0: # %entry
|
|
; X64-NEXT: cvtsi2sd %edi, %xmm0
|
|
; X64-NEXT: retq
|
|
;
|
|
; SDAG-AVX512-LABEL: test_ui16_to_double:
|
|
; SDAG-AVX512: # %bb.0: # %entry
|
|
; SDAG-AVX512-NEXT: vcvtsi2sd %edi, %xmm15, %xmm0
|
|
; SDAG-AVX512-NEXT: retq
|
|
;
|
|
; GISEL-AVX512-LABEL: test_ui16_to_double:
|
|
; GISEL-AVX512: # %bb.0: # %entry
|
|
; GISEL-AVX512-NEXT: vcvtusi2sd %edi, %xmm15, %xmm0
|
|
; GISEL-AVX512-NEXT: retq
|
|
entry:
|
|
%conv = uitofp i16 %x to double
|
|
ret double %conv
|
|
}
|
|
|
|
define double @test_ui8_to_double(i8 zeroext %x) {
|
|
; X64-LABEL: test_ui8_to_double:
|
|
; X64: # %bb.0: # %entry
|
|
; X64-NEXT: cvtsi2sd %edi, %xmm0
|
|
; X64-NEXT: retq
|
|
;
|
|
; SDAG-AVX512-LABEL: test_ui8_to_double:
|
|
; SDAG-AVX512: # %bb.0: # %entry
|
|
; SDAG-AVX512-NEXT: vcvtsi2sd %edi, %xmm15, %xmm0
|
|
; SDAG-AVX512-NEXT: retq
|
|
;
|
|
; GISEL-AVX512-LABEL: test_ui8_to_double:
|
|
; GISEL-AVX512: # %bb.0: # %entry
|
|
; GISEL-AVX512-NEXT: vcvtusi2sd %edi, %xmm15, %xmm0
|
|
; GISEL-AVX512-NEXT: retq
|
|
entry:
|
|
%conv = uitofp i8 %x to double
|
|
ret double %conv
|
|
}
|
|
|
|
define float @test_ui64_to_float(i64 %x) {
|
|
; SDAG-X64-LABEL: test_ui64_to_float:
|
|
; SDAG-X64: # %bb.0: # %entry
|
|
; SDAG-X64-NEXT: testq %rdi, %rdi
|
|
; SDAG-X64-NEXT: js .LBB4_1
|
|
; SDAG-X64-NEXT: # %bb.2: # %entry
|
|
; SDAG-X64-NEXT: cvtsi2ss %rdi, %xmm0
|
|
; SDAG-X64-NEXT: retq
|
|
; SDAG-X64-NEXT: .LBB4_1:
|
|
; SDAG-X64-NEXT: movq %rdi, %rax
|
|
; SDAG-X64-NEXT: shrq %rax
|
|
; SDAG-X64-NEXT: andl $1, %edi
|
|
; SDAG-X64-NEXT: orq %rax, %rdi
|
|
; SDAG-X64-NEXT: cvtsi2ss %rdi, %xmm0
|
|
; SDAG-X64-NEXT: addss %xmm0, %xmm0
|
|
; SDAG-X64-NEXT: retq
|
|
;
|
|
; GISEL-X64-LABEL: test_ui64_to_float:
|
|
; GISEL-X64: # %bb.0: # %entry
|
|
; GISEL-X64-NEXT: cvtsi2ss %rdi, %xmm0
|
|
; GISEL-X64-NEXT: movq %rdi, %rax
|
|
; GISEL-X64-NEXT: shrq %rax
|
|
; GISEL-X64-NEXT: movq %rdi, %rcx
|
|
; GISEL-X64-NEXT: andq $1, %rcx
|
|
; GISEL-X64-NEXT: orq %rax, %rcx
|
|
; GISEL-X64-NEXT: cvtsi2ss %rcx, %xmm1
|
|
; GISEL-X64-NEXT: addss %xmm1, %xmm1
|
|
; GISEL-X64-NEXT: xorl %eax, %eax
|
|
; GISEL-X64-NEXT: cmpq $0, %rdi
|
|
; GISEL-X64-NEXT: setl %al
|
|
; GISEL-X64-NEXT: andl $1, %eax
|
|
; GISEL-X64-NEXT: movd %xmm1, %eax
|
|
; GISEL-X64-NEXT: movd %xmm0, %ecx
|
|
; GISEL-X64-NEXT: cmovnel %eax, %ecx
|
|
; GISEL-X64-NEXT: movd %ecx, %xmm0
|
|
; GISEL-X64-NEXT: retq
|
|
;
|
|
; AVX512-LABEL: test_ui64_to_float:
|
|
; AVX512: # %bb.0: # %entry
|
|
; AVX512-NEXT: vcvtusi2ss %rdi, %xmm15, %xmm0
|
|
; AVX512-NEXT: retq
|
|
entry:
|
|
%conv = uitofp i64 %x to float
|
|
ret float %conv
|
|
}
|
|
|
|
define float @test_ui32_to_float(i32 %x) {
|
|
; X64-LABEL: test_ui32_to_float:
|
|
; X64: # %bb.0: # %entry
|
|
; X64-NEXT: movl %edi, %eax
|
|
; X64-NEXT: cvtsi2ss %rax, %xmm0
|
|
; X64-NEXT: retq
|
|
;
|
|
; AVX512-LABEL: test_ui32_to_float:
|
|
; AVX512: # %bb.0: # %entry
|
|
; AVX512-NEXT: vcvtusi2ss %edi, %xmm15, %xmm0
|
|
; AVX512-NEXT: retq
|
|
entry:
|
|
%conv = uitofp i32 %x to float
|
|
ret float %conv
|
|
}
|
|
|
|
define float @test_ui16_to_float(i16 zeroext %x) {
|
|
; X64-LABEL: test_ui16_to_float:
|
|
; X64: # %bb.0: # %entry
|
|
; X64-NEXT: cvtsi2ss %edi, %xmm0
|
|
; X64-NEXT: retq
|
|
;
|
|
; SDAG-AVX512-LABEL: test_ui16_to_float:
|
|
; SDAG-AVX512: # %bb.0: # %entry
|
|
; SDAG-AVX512-NEXT: vcvtsi2ss %edi, %xmm15, %xmm0
|
|
; SDAG-AVX512-NEXT: retq
|
|
;
|
|
; GISEL-AVX512-LABEL: test_ui16_to_float:
|
|
; GISEL-AVX512: # %bb.0: # %entry
|
|
; GISEL-AVX512-NEXT: vcvtusi2ss %edi, %xmm15, %xmm0
|
|
; GISEL-AVX512-NEXT: retq
|
|
entry:
|
|
%conv = uitofp i16 %x to float
|
|
ret float %conv
|
|
}
|
|
|
|
define float @test_ui8_to_float(i8 zeroext %x) {
|
|
; X64-LABEL: test_ui8_to_float:
|
|
; X64: # %bb.0: # %entry
|
|
; X64-NEXT: cvtsi2ss %edi, %xmm0
|
|
; X64-NEXT: retq
|
|
;
|
|
; SDAG-AVX512-LABEL: test_ui8_to_float:
|
|
; SDAG-AVX512: # %bb.0: # %entry
|
|
; SDAG-AVX512-NEXT: vcvtsi2ss %edi, %xmm15, %xmm0
|
|
; SDAG-AVX512-NEXT: retq
|
|
;
|
|
; GISEL-AVX512-LABEL: test_ui8_to_float:
|
|
; GISEL-AVX512: # %bb.0: # %entry
|
|
; GISEL-AVX512-NEXT: vcvtusi2ss %edi, %xmm15, %xmm0
|
|
; GISEL-AVX512-NEXT: retq
|
|
entry:
|
|
%conv = uitofp i8 %x to float
|
|
ret float %conv
|
|
}
|
|
|
|
define double @test_si64_to_double(i64 %x) {
|
|
; X64-LABEL: test_si64_to_double:
|
|
; X64: # %bb.0: # %entry
|
|
; X64-NEXT: cvtsi2sd %rdi, %xmm0
|
|
; X64-NEXT: retq
|
|
;
|
|
; AVX512-LABEL: test_si64_to_double:
|
|
; AVX512: # %bb.0: # %entry
|
|
; AVX512-NEXT: vcvtsi2sd %rdi, %xmm15, %xmm0
|
|
; AVX512-NEXT: retq
|
|
entry:
|
|
%conv = sitofp i64 %x to double
|
|
ret double %conv
|
|
}
|
|
|
|
define double @test_si32_to_double(i32 %x) {
|
|
; X64-LABEL: test_si32_to_double:
|
|
; X64: # %bb.0: # %entry
|
|
; X64-NEXT: cvtsi2sd %edi, %xmm0
|
|
; X64-NEXT: retq
|
|
;
|
|
; AVX512-LABEL: test_si32_to_double:
|
|
; AVX512: # %bb.0: # %entry
|
|
; AVX512-NEXT: vcvtsi2sd %edi, %xmm15, %xmm0
|
|
; AVX512-NEXT: retq
|
|
entry:
|
|
%conv = sitofp i32 %x to double
|
|
ret double %conv
|
|
}
|
|
|
|
define double @test_si16_to_double(i16 signext %x) {
|
|
; X64-LABEL: test_si16_to_double:
|
|
; X64: # %bb.0: # %entry
|
|
; X64-NEXT: cvtsi2sd %edi, %xmm0
|
|
; X64-NEXT: retq
|
|
;
|
|
; AVX512-LABEL: test_si16_to_double:
|
|
; AVX512: # %bb.0: # %entry
|
|
; AVX512-NEXT: vcvtsi2sd %edi, %xmm15, %xmm0
|
|
; AVX512-NEXT: retq
|
|
entry:
|
|
%conv = sitofp i16 %x to double
|
|
ret double %conv
|
|
}
|
|
|
|
define double @test_si8_to_double(i8 signext %x) {
|
|
; X64-LABEL: test_si8_to_double:
|
|
; X64: # %bb.0: # %entry
|
|
; X64-NEXT: cvtsi2sd %edi, %xmm0
|
|
; X64-NEXT: retq
|
|
;
|
|
; AVX512-LABEL: test_si8_to_double:
|
|
; AVX512: # %bb.0: # %entry
|
|
; AVX512-NEXT: vcvtsi2sd %edi, %xmm15, %xmm0
|
|
; AVX512-NEXT: retq
|
|
entry:
|
|
%conv = sitofp i8 %x to double
|
|
ret double %conv
|
|
}
|
|
|
|
define double @test_si31_to_double(i31 %x) {
|
|
; X64-LABEL: test_si31_to_double:
|
|
; X64: # %bb.0: # %entry
|
|
; X64-NEXT: addl %edi, %edi
|
|
; X64-NEXT: sarl %edi
|
|
; X64-NEXT: cvtsi2sd %edi, %xmm0
|
|
; X64-NEXT: retq
|
|
;
|
|
; AVX512-LABEL: test_si31_to_double:
|
|
; AVX512: # %bb.0: # %entry
|
|
; AVX512-NEXT: addl %edi, %edi
|
|
; AVX512-NEXT: sarl %edi
|
|
; AVX512-NEXT: vcvtsi2sd %edi, %xmm15, %xmm0
|
|
; AVX512-NEXT: retq
|
|
entry:
|
|
%conv = sitofp i31 %x to double
|
|
ret double %conv
|
|
}
|
|
|
|
define double @test_si33_to_double(i33 %x) {
|
|
; X64-LABEL: test_si33_to_double:
|
|
; X64: # %bb.0: # %entry
|
|
; X64-NEXT: shlq $31, %rdi
|
|
; X64-NEXT: sarq $31, %rdi
|
|
; X64-NEXT: cvtsi2sd %rdi, %xmm0
|
|
; X64-NEXT: retq
|
|
;
|
|
; AVX512-LABEL: test_si33_to_double:
|
|
; AVX512: # %bb.0: # %entry
|
|
; AVX512-NEXT: shlq $31, %rdi
|
|
; AVX512-NEXT: sarq $31, %rdi
|
|
; AVX512-NEXT: vcvtsi2sd %rdi, %xmm15, %xmm0
|
|
; AVX512-NEXT: retq
|
|
entry:
|
|
%conv = sitofp i33 %x to double
|
|
ret double %conv
|
|
}
|
|
|
|
define float @test_si64_to_float(i64 %x) {
|
|
; X64-LABEL: test_si64_to_float:
|
|
; X64: # %bb.0: # %entry
|
|
; X64-NEXT: cvtsi2ss %rdi, %xmm0
|
|
; X64-NEXT: retq
|
|
;
|
|
; AVX512-LABEL: test_si64_to_float:
|
|
; AVX512: # %bb.0: # %entry
|
|
; AVX512-NEXT: vcvtsi2ss %rdi, %xmm15, %xmm0
|
|
; AVX512-NEXT: retq
|
|
entry:
|
|
%conv = sitofp i64 %x to float
|
|
ret float %conv
|
|
}
|
|
|
|
define float @test_si32_to_float(i32 %x) {
|
|
; X64-LABEL: test_si32_to_float:
|
|
; X64: # %bb.0: # %entry
|
|
; X64-NEXT: cvtsi2ss %edi, %xmm0
|
|
; X64-NEXT: retq
|
|
;
|
|
; AVX512-LABEL: test_si32_to_float:
|
|
; AVX512: # %bb.0: # %entry
|
|
; AVX512-NEXT: vcvtsi2ss %edi, %xmm15, %xmm0
|
|
; AVX512-NEXT: retq
|
|
entry:
|
|
%conv = sitofp i32 %x to float
|
|
ret float %conv
|
|
}
|
|
|
|
define float @test_si16_to_float(i16 signext %x) {
|
|
; X64-LABEL: test_si16_to_float:
|
|
; X64: # %bb.0: # %entry
|
|
; X64-NEXT: cvtsi2ss %edi, %xmm0
|
|
; X64-NEXT: retq
|
|
;
|
|
; AVX512-LABEL: test_si16_to_float:
|
|
; AVX512: # %bb.0: # %entry
|
|
; AVX512-NEXT: vcvtsi2ss %edi, %xmm15, %xmm0
|
|
; AVX512-NEXT: retq
|
|
entry:
|
|
%conv = sitofp i16 %x to float
|
|
ret float %conv
|
|
}
|
|
|
|
define float @test_si8_to_float(i8 signext %x) {
|
|
; X64-LABEL: test_si8_to_float:
|
|
; X64: # %bb.0: # %entry
|
|
; X64-NEXT: cvtsi2ss %edi, %xmm0
|
|
; X64-NEXT: retq
|
|
;
|
|
; AVX512-LABEL: test_si8_to_float:
|
|
; AVX512: # %bb.0: # %entry
|
|
; AVX512-NEXT: vcvtsi2ss %edi, %xmm15, %xmm0
|
|
; AVX512-NEXT: retq
|
|
entry:
|
|
%conv = sitofp i8 %x to float
|
|
ret float %conv
|
|
}
|
|
|
|
define float @test_si31_to_float(i31 %x) {
|
|
; X64-LABEL: test_si31_to_float:
|
|
; X64: # %bb.0: # %entry
|
|
; X64-NEXT: addl %edi, %edi
|
|
; X64-NEXT: sarl %edi
|
|
; X64-NEXT: cvtsi2ss %edi, %xmm0
|
|
; X64-NEXT: retq
|
|
;
|
|
; AVX512-LABEL: test_si31_to_float:
|
|
; AVX512: # %bb.0: # %entry
|
|
; AVX512-NEXT: addl %edi, %edi
|
|
; AVX512-NEXT: sarl %edi
|
|
; AVX512-NEXT: vcvtsi2ss %edi, %xmm15, %xmm0
|
|
; AVX512-NEXT: retq
|
|
entry:
|
|
%conv = sitofp i31 %x to float
|
|
ret float %conv
|
|
}
|
|
|
|
define float @test_si33_to_float(i33 %x) {
|
|
; X64-LABEL: test_si33_to_float:
|
|
; X64: # %bb.0: # %entry
|
|
; X64-NEXT: shlq $31, %rdi
|
|
; X64-NEXT: sarq $31, %rdi
|
|
; X64-NEXT: cvtsi2ss %rdi, %xmm0
|
|
; X64-NEXT: retq
|
|
;
|
|
; AVX512-LABEL: test_si33_to_float:
|
|
; AVX512: # %bb.0: # %entry
|
|
; AVX512-NEXT: shlq $31, %rdi
|
|
; AVX512-NEXT: sarq $31, %rdi
|
|
; AVX512-NEXT: vcvtsi2ss %rdi, %xmm15, %xmm0
|
|
; AVX512-NEXT: retq
|
|
entry:
|
|
%conv = sitofp i33 %x to float
|
|
ret float %conv
|
|
}
|