llvm.org GIT mirror llvm / b3ff6a8
[X86][FastIsel] Teach how to select scalar integer to float/double conversions. This patch teaches fast-isel how to select a (V)CVTSI2SSrr for an integer to float conversion, and how to select a (V)CVTSI2SDrr for an integer to double conversion. Added test 'fast-isel-int-float-conversion.ll'. Differential Revision: http://reviews.llvm.org/D7698 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229589 91177308-0d34-0410-b5e6-96231b3b80d8 Andrea Di Biagio 5 years ago
2 changed file(s) with 93 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
128128
129129 bool X86SelectFPExt(const Instruction *I);
130130 bool X86SelectFPTrunc(const Instruction *I);
131 bool X86SelectSIToFP(const Instruction *I);
131132
132133 const X86InstrInfo *getInstrInfo() const {
133134 return Subtarget->getInstrInfo();
20042005 return false;
20052006 }
20062007
2008 bool X86FastISel::X86SelectSIToFP(const Instruction *I) {
2009 if (!I->getOperand(0)->getType()->isIntegerTy(32))
2010 return false;
2011
2012 // Select integer to float/double conversion.
2013 unsigned OpReg = getRegForValue(I->getOperand(0));
2014 if (OpReg == 0)
2015 return false;
2016
2017 bool HasAVX = Subtarget->hasAVX();
2018 const TargetRegisterClass *RC = nullptr;
2019 unsigned Opcode;
2020
2021 if (I->getType()->isDoubleTy() && X86ScalarSSEf64) {
2022 // sitofp int -> double
2023 Opcode = HasAVX ? X86::VCVTSI2SDrr : X86::CVTSI2SDrr;
2024 RC = &X86::FR64RegClass;
2025 } else if (I->getType()->isFloatTy() && X86ScalarSSEf32) {
2026 // sitofp int -> float
2027 Opcode = HasAVX ? X86::VCVTSI2SSrr : X86::CVTSI2SSrr;
2028 RC = &X86::FR32RegClass;
2029 } else
2030 return false;
2031
2032
2033 unsigned ImplicitDefReg = 0;
2034 if (HasAVX) {
2035 ImplicitDefReg = createResultReg(RC);
2036 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2037 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2038 }
2039
2040 const MCInstrDesc &II = TII.get(Opcode);
2041 OpReg = constrainOperandRegClass(II, OpReg, (HasAVX ? 2 : 1));
2042
2043 unsigned ResultReg = createResultReg(RC);
2044 MachineInstrBuilder MIB;
2045 MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, ResultReg);
2046 if (ImplicitDefReg)
2047 MIB.addReg(ImplicitDefReg, RegState::Kill);
2048 MIB.addReg(OpReg);
2049 updateValueMap(I, ResultReg);
2050 return true;
2051 }
2052
20072053 // Helper method used by X86SelectFPExt and X86SelectFPTrunc.
20082054 bool X86FastISel::X86SelectFPExtOrFPTrunc(const Instruction *I,
20092055 unsigned TargetOpc,
30543100 return X86SelectFPExt(I);
30553101 case Instruction::FPTrunc:
30563102 return X86SelectFPTrunc(I);
3103 case Instruction::SIToFP:
3104 return X86SelectSIToFP(I);
30573105 case Instruction::IntToPtr: // Deliberate fall-through.
30583106 case Instruction::PtrToInt: {
30593107 EVT SrcVT = TLI.getValueType(I->getOperand(0)->getType());
0 ; RUN: llc -mtriple=x86_64-unknown-unknown -mcpu=generic -mattr=+sse2 -O0 --fast-isel-abort < %s | FileCheck %s --check-prefix=ALL --check-prefix=SSE2
1 ; RUN: llc -mtriple=x86_64-unknown-unknown -mcpu=generic -mattr=+avx -O0 --fast-isel-abort < %s | FileCheck %s --check-prefix=ALL --check-prefix=AVX
2
3
4 define double @int_to_double_rr(i32 %a) {
5 ; ALL-LABEL: int_to_double_rr:
6 ; SSE2: cvtsi2sdl %edi, %xmm0
7 ; AVX: vcvtsi2sdl %edi, %xmm0, %xmm0
8 ; ALL-NEXT: ret
9 entry:
10 %0 = sitofp i32 %a to double
11 ret double %0
12 }
13
14 define double @int_to_double_rm(i32* %a) {
15 ; ALL-LABEL: int_to_double_rm:
16 ; SSE2: cvtsi2sdl (%rdi), %xmm0
17 ; AVX: vcvtsi2sdl (%rdi), %xmm0, %xmm0
18 ; ALL-NEXT: ret
19 entry:
20 %0 = load i32* %a
21 %1 = sitofp i32 %0 to double
22 ret double %1
23 }
24
25 define float @int_to_float_rr(i32 %a) {
26 ; ALL-LABEL: int_to_float_rr:
27 ; SSE2: cvtsi2ssl %edi, %xmm0
28 ; AVX: vcvtsi2ssl %edi, %xmm0, %xmm0
29 ; ALL-NEXT: ret
30 entry:
31 %0 = sitofp i32 %a to float
32 ret float %0
33 }
34
35 define float @int_to_float_rm(i32* %a) {
36 ; ALL-LABEL: int_to_float_rm:
37 ; SSE2: cvtsi2ssl (%rdi), %xmm0
38 ; AVX: vcvtsi2ssl (%rdi), %xmm0, %xmm0
39 ; ALL-NEXT: ret
40 entry:
41 %0 = load i32* %a
42 %1 = sitofp i32 %0 to float
43 ret float %1
44 }