llvm-project/llvm/test/CodeGen/X86/isel-int-to-fp.ll
Phoebe Wang 76e14deb4a
[X86][BreakFalseDeps] Using reverse order for undef register selection (#137569)
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.
2025-06-11 22:08:20 +08:00

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
}