From d90e5063ca85ecd282389e8be07ae07f2c320f7c Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Tue, 13 Jan 2015 22:59:41 +0000 Subject: [PATCH] R600/SI: Add pattern for bitcasting fp immediates to integers The backend now assumes that all immediates are integers. This allows us to simplify immediate handling code, becasue we no longer need to handle fp and integer immediates differently. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225844 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/R600/AMDGPUMCInstLower.cpp | 12 --------- lib/Target/R600/SIFoldOperands.cpp | 9 ++----- lib/Target/R600/SIISelLowering.cpp | 10 ++++---- lib/Target/R600/SIInstrInfo.cpp | 32 +++++++++++------------- lib/Target/R600/SIInstrInfo.td | 12 +++++++++ lib/Target/R600/SIInstructions.td | 6 ++--- lib/Target/R600/SILowerControlFlow.cpp | 5 ++-- lib/Target/R600/SIShrinkInstructions.cpp | 9 +------ 8 files changed, 39 insertions(+), 56 deletions(-) diff --git a/lib/Target/R600/AMDGPUMCInstLower.cpp b/lib/Target/R600/AMDGPUMCInstLower.cpp index 84ee7842a72..1995ef2b0c9 100644 --- a/lib/Target/R600/AMDGPUMCInstLower.cpp +++ b/lib/Target/R600/AMDGPUMCInstLower.cpp @@ -68,18 +68,6 @@ void AMDGPUMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const { switch (MO.getType()) { default: llvm_unreachable("unknown operand type"); - case MachineOperand::MO_FPImmediate: { - const APFloat &FloatValue = MO.getFPImm()->getValueAPF(); - - if (&FloatValue.getSemantics() == &APFloat::IEEEsingle) - MCOp = MCOperand::CreateFPImm(FloatValue.convertToFloat()); - else if (&FloatValue.getSemantics() == &APFloat::IEEEdouble) - MCOp = MCOperand::CreateFPImm(FloatValue.convertToDouble()); - else - llvm_unreachable("Unhandled floating point type"); - - break; - } case MachineOperand::MO_Immediate: MCOp = MCOperand::CreateImm(MO.getImm()); break; diff --git a/lib/Target/R600/SIFoldOperands.cpp b/lib/Target/R600/SIFoldOperands.cpp index 655b3aaaa2b..d8ffa4f7550 100644 --- a/lib/Target/R600/SIFoldOperands.cpp +++ b/lib/Target/R600/SIFoldOperands.cpp @@ -173,7 +173,7 @@ bool SIFoldOperands::runOnMachineFunction(MachineFunction &MF) { continue; MachineOperand &OpToFold = MI.getOperand(1); - bool FoldingImm = OpToFold.isImm() || OpToFold.isFPImm(); + bool FoldingImm = OpToFold.isImm(); // FIXME: We could also be folding things like FrameIndexes and // TargetIndexes. @@ -210,12 +210,7 @@ bool SIFoldOperands::runOnMachineFunction(MachineFunction &MF) { if (FoldingImm) { const TargetRegisterClass *UseRC = MRI.getRegClass(UseOp.getReg()); - - if (OpToFold.isFPImm()) { - Imm = OpToFold.getFPImm()->getValueAPF().bitcastToAPInt(); - } else { - Imm = APInt(64, OpToFold.getImm()); - } + Imm = APInt(64, OpToFold.getImm()); // Split 64-bit constants into 32-bits for folding. if (UseOp.getSubReg()) { diff --git a/lib/Target/R600/SIISelLowering.cpp b/lib/Target/R600/SIISelLowering.cpp index 2c961ff3efd..12a356b4907 100644 --- a/lib/Target/R600/SIISelLowering.cpp +++ b/lib/Target/R600/SIISelLowering.cpp @@ -1077,7 +1077,7 @@ SDValue SITargetLowering::LowerFDIV32(SDValue Op, SelectionDAG &DAG) const { const APFloat K1Val(BitsToFloat(0x2f800000)); const SDValue K1 = DAG.getConstantFP(K1Val, MVT::f32); - const SDValue One = DAG.getTargetConstantFP(1.0, MVT::f32); + const SDValue One = DAG.getConstantFP(1.0, MVT::f32); EVT SetCCVT = getSetCCResultType(*DAG.getContext(), MVT::f32); @@ -1549,7 +1549,7 @@ SDValue SITargetLowering::PerformDAGCombine(SDNode *N, if (LHS.getOpcode() == ISD::FADD) { SDValue A = LHS.getOperand(0); if (A == LHS.getOperand(1)) { - const SDValue Two = DAG.getTargetConstantFP(2.0, MVT::f32); + const SDValue Two = DAG.getConstantFP(2.0, MVT::f32); return DAG.getNode(AMDGPUISD::MAD, DL, VT, Two, A, RHS); } } @@ -1558,7 +1558,7 @@ SDValue SITargetLowering::PerformDAGCombine(SDNode *N, if (RHS.getOpcode() == ISD::FADD) { SDValue A = RHS.getOperand(0); if (A == RHS.getOperand(1)) { - const SDValue Two = DAG.getTargetConstantFP(2.0, MVT::f32); + const SDValue Two = DAG.getConstantFP(2.0, MVT::f32); return DAG.getNode(AMDGPUISD::MAD, DL, VT, Two, A, LHS); } } @@ -1602,7 +1602,7 @@ SDValue SITargetLowering::PerformDAGCombine(SDNode *N, SDValue A = LHS.getOperand(0); if (A == LHS.getOperand(1)) { - const SDValue Two = DAG.getTargetConstantFP(2.0, MVT::f32); + const SDValue Two = DAG.getConstantFP(2.0, MVT::f32); SDValue NegRHS = DAG.getNode(ISD::FNEG, DL, VT, RHS); return DAG.getNode(AMDGPUISD::MAD, DL, VT, Two, A, NegRHS); @@ -1614,7 +1614,7 @@ SDValue SITargetLowering::PerformDAGCombine(SDNode *N, SDValue A = RHS.getOperand(0); if (A == RHS.getOperand(1)) { - const SDValue NegTwo = DAG.getTargetConstantFP(-2.0, MVT::f32); + const SDValue NegTwo = DAG.getConstantFP(-2.0, MVT::f32); return DAG.getNode(AMDGPUISD::MAD, DL, VT, NegTwo, A, LHS); } } diff --git a/lib/Target/R600/SIInstrInfo.cpp b/lib/Target/R600/SIInstrInfo.cpp index 6454ad5110a..b911d418680 100644 --- a/lib/Target/R600/SIInstrInfo.cpp +++ b/lib/Target/R600/SIInstrInfo.cpp @@ -736,8 +736,8 @@ MachineInstr *SIInstrInfo::commuteInstruction(MachineInstr *MI, } if (!Src1.isReg()) { - // Allow commuting instructions with Imm or FPImm operands. - if (NewMI || (!Src1.isImm() && !Src1.isFPImm()) || + // Allow commuting instructions with Imm operands. + if (NewMI || !Src1.isImm() || (!isVOP2(MI->getOpcode()) && !isVOP3(MI->getOpcode()))) { return nullptr; } @@ -765,8 +765,6 @@ MachineInstr *SIInstrInfo::commuteInstruction(MachineInstr *MI, unsigned SubReg = Src0.getSubReg(); if (Src1.isImm()) Src0.ChangeToImmediate(Src1.getImm()); - else if (Src1.isFPImm()) - Src0.ChangeToFPImmediate(Src1.getFPImm()); else llvm_unreachable("Should only have immediates"); @@ -981,16 +979,11 @@ 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 { - return (MO.isImm() || MO.isFPImm()) && !isInlineConstant(MO); + return MO.isImm() && !isInlineConstant(MO); } static bool compareMachineOp(const MachineOperand &Op0, @@ -1003,8 +996,6 @@ static bool compareMachineOp(const MachineOperand &Op0, return Op0.getReg() == Op1.getReg(); case MachineOperand::MO_Immediate: return Op0.getImm() == Op1.getImm(); - case MachineOperand::MO_FPImmediate: - return Op0.getFPImm() == Op1.getFPImm(); default: llvm_unreachable("Didn't expect to be comparing these operand types"); } @@ -1014,7 +1005,7 @@ bool SIInstrInfo::isImmOperandLegal(const MachineInstr *MI, unsigned OpNo, const MachineOperand &MO) const { const MCOperandInfo &OpInfo = get(MI->getOpcode()).OpInfo[OpNo]; - assert(MO.isImm() || MO.isFPImm() || MO.isTargetIndex() || MO.isFI()); + assert(MO.isImm() || MO.isTargetIndex() || MO.isFI()); if (OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE) return true; @@ -1121,9 +1112,15 @@ bool SIInstrInfo::verifyInstruction(const MachineInstr *MI, // Make sure the register classes are correct for (int i = 0, e = Desc.getNumOperands(); i != e; ++i) { + if (MI->getOperand(i).isFPImm()) { + ErrInfo = "FPImm Machine Operands are not supported. ISel should bitcast " + "all fp values to integers."; + return false; + } + switch (Desc.OpInfo[i].OperandType) { case MCOI::OPERAND_REGISTER: { - if ((MI->getOperand(i).isImm() || MI->getOperand(i).isFPImm()) && + if (MI->getOperand(i).isImm() && !isImmOperandLegal(MI, i, MI->getOperand(i))) { ErrInfo = "Illegal immediate value for operand."; return false; @@ -1134,8 +1131,7 @@ bool SIInstrInfo::verifyInstruction(const MachineInstr *MI, // Check if this operand is an immediate. // FrameIndex operands will be replaced by immediates, so they are // allowed. - if (!MI->getOperand(i).isImm() && !MI->getOperand(i).isFPImm() && - !MI->getOperand(i).isFI()) { + if (!MI->getOperand(i).isImm() && !MI->getOperand(i).isFI()) { ErrInfo = "Expected immediate, but got non-immediate"; return false; } @@ -1195,7 +1191,7 @@ bool SIInstrInfo::verifyInstruction(const MachineInstr *MI, // Verify SRC1 for VOP2 and VOPC if (Src1Idx != -1 && (isVOP2(Opcode) || isVOPC(Opcode))) { const MachineOperand &Src1 = MI->getOperand(Src1Idx); - if (Src1.isImm() || Src1.isFPImm()) { + if (Src1.isImm()) { ErrInfo = "VOP[2C] src1 cannot be an immediate."; return false; } @@ -1479,7 +1475,7 @@ bool SIInstrInfo::isOperandLegal(const MachineInstr *MI, unsigned OpIdx, // Handle non-register types that are treated like immediates. - assert(MO->isImm() || MO->isFPImm() || MO->isTargetIndex() || MO->isFI()); + assert(MO->isImm() || MO->isTargetIndex() || MO->isFI()); if (!DefinedRC) { // This operand expects an immediate. diff --git a/lib/Target/R600/SIInstrInfo.td b/lib/Target/R600/SIInstrInfo.td index dd1449dc6d2..6235de33fa7 100644 --- a/lib/Target/R600/SIInstrInfo.td +++ b/lib/Target/R600/SIInstrInfo.td @@ -159,6 +159,18 @@ def as_i64imm: SDNodeXFormgetTargetConstant(N->getSExtValue(), MVT::i64); }]>; +// Copied from the AArch64 backend: +def bitcast_fpimm_to_i32 : SDNodeXFormgetTargetConstant( + N->getValueAPF().bitcastToAPInt().getZExtValue(), MVT::i32); +}]>; + +// Copied from the AArch64 backend: +def bitcast_fpimm_to_i64 : SDNodeXFormgetTargetConstant( + N->getValueAPF().bitcastToAPInt().getZExtValue(), MVT::i64); +}]>; + def IMM8bit : PatLeaf <(imm), [{return isUInt<8>(N->getZExtValue());}] >; diff --git a/lib/Target/R600/SIInstructions.td b/lib/Target/R600/SIInstructions.td index 4fa3bcd4397..980dba79bb8 100644 --- a/lib/Target/R600/SIInstructions.td +++ b/lib/Target/R600/SIInstructions.td @@ -2552,7 +2552,7 @@ def : Pat < def : Pat < (SGPRImm<(f32 fpimm)>:$imm), - (S_MOV_B32 fpimm:$imm) + (S_MOV_B32 (f32 (bitcast_fpimm_to_i32 $imm))) >; def : Pat < @@ -2562,7 +2562,7 @@ def : Pat < def : Pat < (f32 fpimm:$imm), - (V_MOV_B32_e32 fpimm:$imm) + (V_MOV_B32_e32 (f32 (bitcast_fpimm_to_i32 $imm))) >; def : Pat < @@ -2580,7 +2580,7 @@ def : Pat < def : Pat < (f64 InlineFPImm:$imm), - (S_MOV_B64 InlineFPImm:$imm) + (S_MOV_B64 (f64 (bitcast_fpimm_to_i64 InlineFPImm:$imm))) >; /********** ===================== **********/ diff --git a/lib/Target/R600/SILowerControlFlow.cpp b/lib/Target/R600/SILowerControlFlow.cpp index 90174d7b30a..068b22f3770 100644 --- a/lib/Target/R600/SILowerControlFlow.cpp +++ b/lib/Target/R600/SILowerControlFlow.cpp @@ -308,10 +308,9 @@ void SILowerControlFlowPass::Kill(MachineInstr &MI) { #endif // Clear this thread from the exec mask if the operand is negative - if ((Op.isImm() || Op.isFPImm())) { + if ((Op.isImm())) { // Constant operand: Set exec mask to 0 or do nothing - if (Op.isImm() ? (Op.getImm() & 0x80000000) : - Op.getFPImm()->isNegative()) { + if (Op.getImm() & 0x80000000) { BuildMI(MBB, &MI, DL, TII->get(AMDGPU::S_MOV_B64), AMDGPU::EXEC) .addImm(0); } diff --git a/lib/Target/R600/SIShrinkInstructions.cpp b/lib/Target/R600/SIShrinkInstructions.cpp index e97f9344187..f91d1177bba 100644 --- a/lib/Target/R600/SIShrinkInstructions.cpp +++ b/lib/Target/R600/SIShrinkInstructions.cpp @@ -130,7 +130,7 @@ static void foldImmediates(MachineInstr &MI, const SIInstrInfo *TII, // Only one literal constant is allowed per instruction, so if src0 is a // literal constant then we can't do any folding. - if ((Src0->isImm() || Src0->isFPImm()) && TII->isLiteralConstant(*Src0)) + if (Src0->isImm() && TII->isLiteralConstant(*Src0)) return; @@ -151,12 +151,6 @@ static void foldImmediates(MachineInstr &MI, const SIInstrInfo *TII, if (MovSrc.isImm() && isUInt<32>(MovSrc.getImm())) { Src0->ChangeToImmediate(MovSrc.getImm()); ConstantFolded = true; - } else if (MovSrc.isFPImm()) { - const ConstantFP *CFP = MovSrc.getFPImm(); - if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEsingle) { - Src0->ChangeToFPImmediate(CFP); - ConstantFolded = true; - } } if (ConstantFolded) { if (MRI.use_empty(Reg)) @@ -193,7 +187,6 @@ bool SIShrinkInstructions::runOnMachineFunction(MachineFunction &MF) { if (MI.getOpcode() == AMDGPU::S_MOV_B32) { const MachineOperand &Src = MI.getOperand(1); - // TODO: Handle FPImm? if (Src.isImm()) { if (isInt<16>(Src.getImm()) && !TII->isInlineConstant(Src)) MI.setDesc(TII->get(AMDGPU::S_MOVK_I32)); -- 2.34.1