diff options
| author | Andrea Di Biagio <Andrea_DiBiagio@sn.scee.net> | 2015-02-17 23:40:58 +0000 |
|---|---|---|
| committer | Andrea Di Biagio <Andrea_DiBiagio@sn.scee.net> | 2015-02-17 23:40:58 +0000 |
| commit | e7b58ee555251600e4d5cf61ec7123073890ca7f (patch) | |
| tree | 663d9d994d5843074279e6c1e8a0a0ddafb47ce4 /llvm/lib | |
| parent | 891f88c1ac4e4eff65f12300042edce3ccf3aa53 (diff) | |
| download | bcm5719-llvm-e7b58ee555251600e4d5cf61ec7123073890ca7f.tar.gz bcm5719-llvm-e7b58ee555251600e4d5cf61ec7123073890ca7f.zip | |
[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
llvm-svn: 229589
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/X86/X86FastISel.cpp | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp index 92381085c0e..f63c395fae9 100644 --- a/llvm/lib/Target/X86/X86FastISel.cpp +++ b/llvm/lib/Target/X86/X86FastISel.cpp @@ -129,6 +129,7 @@ private: bool X86SelectFPExt(const Instruction *I); bool X86SelectFPTrunc(const Instruction *I); + bool X86SelectSIToFP(const Instruction *I); const X86InstrInfo *getInstrInfo() const { return Subtarget->getInstrInfo(); @@ -2005,6 +2006,51 @@ bool X86FastISel::X86SelectSelect(const Instruction *I) { return false; } +bool X86FastISel::X86SelectSIToFP(const Instruction *I) { + if (!I->getOperand(0)->getType()->isIntegerTy(32)) + return false; + + // Select integer to float/double conversion. + unsigned OpReg = getRegForValue(I->getOperand(0)); + if (OpReg == 0) + return false; + + bool HasAVX = Subtarget->hasAVX(); + const TargetRegisterClass *RC = nullptr; + unsigned Opcode; + + if (I->getType()->isDoubleTy() && X86ScalarSSEf64) { + // sitofp int -> double + Opcode = HasAVX ? X86::VCVTSI2SDrr : X86::CVTSI2SDrr; + RC = &X86::FR64RegClass; + } else if (I->getType()->isFloatTy() && X86ScalarSSEf32) { + // sitofp int -> float + Opcode = HasAVX ? X86::VCVTSI2SSrr : X86::CVTSI2SSrr; + RC = &X86::FR32RegClass; + } else + return false; + + + unsigned ImplicitDefReg = 0; + if (HasAVX) { + ImplicitDefReg = createResultReg(RC); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, + TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg); + } + + const MCInstrDesc &II = TII.get(Opcode); + OpReg = constrainOperandRegClass(II, OpReg, (HasAVX ? 2 : 1)); + + unsigned ResultReg = createResultReg(RC); + MachineInstrBuilder MIB; + MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, ResultReg); + if (ImplicitDefReg) + MIB.addReg(ImplicitDefReg, RegState::Kill); + MIB.addReg(OpReg); + updateValueMap(I, ResultReg); + return true; +} + // Helper method used by X86SelectFPExt and X86SelectFPTrunc. bool X86FastISel::X86SelectFPExtOrFPTrunc(const Instruction *I, unsigned TargetOpc, @@ -3055,6 +3101,8 @@ X86FastISel::fastSelectInstruction(const Instruction *I) { return X86SelectFPExt(I); case Instruction::FPTrunc: return X86SelectFPTrunc(I); + case Instruction::SIToFP: + return X86SelectSIToFP(I); case Instruction::IntToPtr: // Deliberate fall-through. case Instruction::PtrToInt: { EVT SrcVT = TLI.getValueType(I->getOperand(0)->getType()); |

