From 4065ed4eb083b51f984c6815bd2867e80e0b1eb8 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Mon, 31 Mar 2014 19:54:27 +0000 Subject: [PATCH] R600/SI: Implement shouldConvertConstantLoadToIntImm git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205244 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/R600/SIISelLowering.cpp | 7 ++++++ lib/Target/R600/SIISelLowering.h | 3 +++ lib/Target/R600/SIInstrInfo.cpp | 44 ++++++++++++++++++++++---------------- lib/Target/R600/SIInstrInfo.h | 1 + 4 files changed, 37 insertions(+), 18 deletions(-) diff --git a/lib/Target/R600/SIISelLowering.cpp b/lib/Target/R600/SIISelLowering.cpp index d4978cc66c6..35bbd82af34 100644 --- a/lib/Target/R600/SIISelLowering.cpp +++ b/lib/Target/R600/SIISelLowering.cpp @@ -215,6 +215,13 @@ bool SITargetLowering::shouldSplitVectorElementType(EVT VT) const { return VT.bitsLE(MVT::i16); } +bool SITargetLowering::shouldConvertConstantLoadToIntImm(const APInt &Imm, + Type *Ty) const { + const SIInstrInfo *TII = + static_cast(getTargetMachine().getInstrInfo()); + return TII->isInlineConstant(Imm); +} + SDValue SITargetLowering::LowerParameter(SelectionDAG &DAG, EVT VT, EVT MemVT, SDLoc DL, SDValue Chain, unsigned Offset) const { diff --git a/lib/Target/R600/SIISelLowering.h b/lib/Target/R600/SIISelLowering.h index 025f23869af..9d53ba5259d 100644 --- a/lib/Target/R600/SIISelLowering.h +++ b/lib/Target/R600/SIISelLowering.h @@ -52,6 +52,9 @@ public: bool allowsUnalignedMemoryAccesses(EVT VT, unsigned AS, bool *IsFast) const; virtual bool shouldSplitVectorElementType(EVT VT) const; + virtual bool shouldConvertConstantLoadToIntImm(const APInt &Imm, + Type *Ty) const override; + SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl &Ins, diff --git a/lib/Target/R600/SIInstrInfo.cpp b/lib/Target/R600/SIInstrInfo.cpp index c39b1dbb141..ab2fe093172 100644 --- a/lib/Target/R600/SIInstrInfo.cpp +++ b/lib/Target/R600/SIInstrInfo.cpp @@ -360,20 +360,10 @@ bool SIInstrInfo::isSALUInstr(const MachineInstr &MI) const { return get(MI.getOpcode()).TSFlags & SIInstrFlags::SALU; } -bool SIInstrInfo::isInlineConstant(const MachineOperand &MO) const { - - union { - int32_t I; - float F; - } Imm; - - if (MO.isImm()) { - Imm.I = MO.getImm(); - } else if (MO.isFPImm()) { - Imm.F = MO.getFPImm()->getValueAPF().convertToFloat(); - } else { - return false; - } +bool SIInstrInfo::isInlineConstant(const APInt &Imm) const { + int32_t Val = Imm.getSExtValue(); + if (Val >= -16 && Val <= 64) + return true; // The actual type of the operand does not seem to matter as long // as the bits match one of the inline immediate values. For example: @@ -383,10 +373,28 @@ bool SIInstrInfo::isInlineConstant(const MachineOperand &MO) const { // // 1065353216 has the hexadecimal encoding 0x3f800000 which is 1.0f in // floating-point, so it is a legal inline immediate. - return (Imm.I >= -16 && Imm.I <= 64) || - Imm.F == 0.0f || Imm.F == 0.5f || Imm.F == -0.5f || Imm.F == 1.0f || - Imm.F == -1.0f || Imm.F == 2.0f || Imm.F == -2.0f || Imm.F == 4.0f || - Imm.F == -4.0f; + + return (APInt::floatToBits(0.0f) == Imm) || + (APInt::floatToBits(1.0f) == Imm) || + (APInt::floatToBits(-1.0f) == Imm) || + (APInt::floatToBits(0.5f) == Imm) || + (APInt::floatToBits(-0.5f) == Imm) || + (APInt::floatToBits(2.0f) == Imm) || + (APInt::floatToBits(-2.0f) == Imm) || + (APInt::floatToBits(4.0f) == Imm) || + (APInt::floatToBits(-4.0f) == Imm); +} + +bool SIInstrInfo::isInlineConstant(const MachineOperand &MO) const { + if (MO.isImm()) + return isInlineConstant(APInt(32, MO.getImm(), true)); + + if (MO.isFPImm()) { + APFloat FpImm = MO.getFPImm()->getValueAPF(); + return isInlineConstant(FpImm.bitcastToAPInt()); + } + + return false; } bool SIInstrInfo::isLiteralConstant(const MachineOperand &MO) const { diff --git a/lib/Target/R600/SIInstrInfo.h b/lib/Target/R600/SIInstrInfo.h index d143b8a5106..c537038ffbd 100644 --- a/lib/Target/R600/SIInstrInfo.h +++ b/lib/Target/R600/SIInstrInfo.h @@ -97,6 +97,7 @@ public: bool isVOP2(uint16_t Opcode) const; bool isVOP3(uint16_t Opcode) const; bool isVOPC(uint16_t Opcode) const; + bool isInlineConstant(const APInt &Imm) const; bool isInlineConstant(const MachineOperand &MO) const; bool isLiteralConstant(const MachineOperand &MO) const; -- 2.11.0