diff --git a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp --- a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp +++ b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp @@ -2814,7 +2814,7 @@ } else { const MCInstrDesc &InstDesc = I.getDesc(); const MCOperandInfo &OpInfo = InstDesc.OpInfo[OpNo]; - if (TII.isLiteralConstant(Op, OpInfo)) + if (!TII.isInlineConstant(Op, OpInfo)) return true; } } diff --git a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp --- a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp +++ b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp @@ -435,17 +435,12 @@ const MCOperandInfo &OpInfo = InstDesc.OpInfo[OpNo]; // Fine if the operand can be encoded as an inline constant - if (TII->isLiteralConstantLike(*OpToFold, OpInfo)) { - if (!TRI->opCanUseInlineConstant(OpInfo.OperandType) || - !TII->isInlineConstant(*OpToFold, OpInfo)) { - // Otherwise check for another constant - for (unsigned i = 0, e = InstDesc.getNumOperands(); i != e; ++i) { - auto &Op = MI->getOperand(i); - if (OpNo != i && - TII->isLiteralConstantLike(Op, OpInfo)) { - return false; - } - } + if (!OpToFold->isReg() && !TII->isInlineConstant(*OpToFold, OpInfo)) { + // Otherwise check for another constant + for (unsigned i = 0, e = InstDesc.getNumOperands(); i != e; ++i) { + auto &Op = MI->getOperand(i); + if (OpNo != i && !Op.isReg() && !TII->isInlineConstant(Op, OpInfo)) + return false; } } } diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.h b/llvm/lib/Target/AMDGPU/SIInstrInfo.h --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.h +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.h @@ -808,6 +808,13 @@ return isInlineConstant(Imm.bitcastToAPInt()); } + // Returns true if this non-register operand definitely does not need to be + // encoded as a 32-bit literal. Note that this function handles all kinds of + // operands, not just immediates. + // + // Some operands like FrameIndexes could resolve to an inline immediate value + // that will not require an additional 4-bytes; this function assumes that it + // will. bool isInlineConstant(const MachineOperand &MO, uint8_t OperandType) const; bool isInlineConstant(const MachineOperand &MO, @@ -858,23 +865,6 @@ return isInlineConstant(*Parent, Parent->getOperandNo(&MO)); } - bool isLiteralConstant(const MachineOperand &MO, - const MCOperandInfo &OpInfo) const { - return MO.isImm() && !isInlineConstant(MO, OpInfo.OperandType); - } - - bool isLiteralConstant(const MachineInstr &MI, int OpIdx) const { - const MachineOperand &MO = MI.getOperand(OpIdx); - return MO.isImm() && !isInlineConstant(MI, OpIdx); - } - - // Returns true if this operand could potentially require a 32-bit literal - // operand, but not necessarily. A FrameIndex for example could resolve to an - // inline immediate value that will not require an additional 4-bytes; this - // assumes that it will. - bool isLiteralConstantLike(const MachineOperand &MO, - const MCOperandInfo &OpInfo) const; - bool isImmOperandLegal(const MachineInstr &MI, unsigned OpNo, const MachineOperand &MO) const; diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp @@ -1853,7 +1853,8 @@ assert(!SrcOp.isFPImm()); if (ST.hasMovB64()) { MI.setDesc(get(AMDGPU::V_MOV_B64_e32)); - if (!isLiteralConstant(MI, 1) || isUInt<32>(SrcOp.getImm())) + if (SrcOp.isReg() || isInlineConstant(MI, 1) || + isUInt<32>(SrcOp.getImm())) break; } if (SrcOp.isImm()) { @@ -3636,6 +3637,7 @@ bool SIInstrInfo::isInlineConstant(const MachineOperand &MO, uint8_t OperandType) const { + assert(!MO.isReg() && "isInlineConstant called on register operand!"); if (!MO.isImm() || OperandType < AMDGPU::OPERAND_SRC_FIRST || OperandType > AMDGPU::OPERAND_SRC_LAST) @@ -3718,24 +3720,6 @@ } } -bool SIInstrInfo::isLiteralConstantLike(const MachineOperand &MO, - const MCOperandInfo &OpInfo) const { - switch (MO.getType()) { - case MachineOperand::MO_Register: - return false; - case MachineOperand::MO_Immediate: - return !isInlineConstant(MO, OpInfo); - case MachineOperand::MO_FrameIndex: - case MachineOperand::MO_MachineBasicBlock: - case MachineOperand::MO_ExternalSymbol: - case MachineOperand::MO_GlobalAddress: - case MachineOperand::MO_MCSymbol: - return true; - default: - llvm_unreachable("unexpected operand type"); - } -} - static bool compareMachineOp(const MachineOperand &Op0, const MachineOperand &Op1) { if (Op0.getType() != Op1.getType()) @@ -3931,13 +3915,8 @@ const MachineOperand &MO, const MCOperandInfo &OpInfo) const { // Literal constants use the constant bus. - //if (isLiteralConstantLike(MO, OpInfo)) - // return true; - if (MO.isImm()) - return !isInlineConstant(MO, OpInfo); - if (!MO.isReg()) - return true; // Misc other operands like FrameIndex + return !isInlineConstant(MO, OpInfo); if (!MO.isUse()) return false; @@ -4410,8 +4389,8 @@ const MachineOperand &Src1 = MI.getOperand(Src1Idx); if (!Src0.isReg() && !Src1.isReg() && - !isInlineConstant(Src0, Desc.OpInfo[Src0Idx].OperandType) && - !isInlineConstant(Src1, Desc.OpInfo[Src1Idx].OperandType) && + !isInlineConstant(Src0, Desc.OpInfo[Src0Idx]) && + !isInlineConstant(Src1, Desc.OpInfo[Src1Idx]) && !Src0.isIdenticalTo(Src1)) { ErrInfo = "SOP2/SOPC instruction requires too many immediate constants"; return false; @@ -5016,7 +4995,7 @@ int ConstantBusLimit = ST.getConstantBusLimit(MI.getOpcode()); int LiteralLimit = !isVOP3(MI) || ST.hasVOP3Literal() ? 1 : 0; if (isVALU(MI) && usesConstantBus(MRI, *MO, OpInfo)) { - if (isLiteralConstantLike(*MO, OpInfo) && !LiteralLimit--) + if (!MO->isReg() && !isInlineConstant(*MO, OpInfo) && !LiteralLimit--) return false; SmallDenseSet SGPRsUsed; @@ -5037,7 +5016,7 @@ } } else if (InstDesc.OpInfo[i].OperandType == AMDGPU::OPERAND_KIMM32 || (AMDGPU::isSISrcOperand(InstDesc, i) && - isLiteralConstantLike(Op, InstDesc.OpInfo[i]))) { + !isInlineConstant(Op, InstDesc.OpInfo[i]))) { if (!LiteralLimit--) return false; if (--ConstantBusLimit <= 0) @@ -5110,9 +5089,8 @@ // If there is an implicit SGPR use such as VCC use for v_addc_u32/v_subb_u32 // we need to only have one constant bus use before GFX10. bool HasImplicitSGPR = findImplicitSGPRRead(MI); - if (HasImplicitSGPR && ST.getConstantBusLimit(Opc) <= 1 && - Src0.isReg() && (RI.isSGPRReg(MRI, Src0.getReg()) || - isLiteralConstantLike(Src0, InstrDesc.OpInfo[Src0Idx]))) + if (HasImplicitSGPR && ST.getConstantBusLimit(Opc) <= 1 && Src0.isReg() && + RI.isSGPRReg(MRI, Src0.getReg())) legalizeOpWithMove(MI, Src0Idx); // Special case: V_WRITELANE_B32 accepts only immediate or SGPR operands for @@ -5254,7 +5232,7 @@ MachineOperand &MO = MI.getOperand(Idx); if (!MO.isReg()) { - if (!isLiteralConstantLike(MO, get(Opc).OpInfo[Idx])) + if (isInlineConstant(MO, get(Opc).OpInfo[Idx])) continue; if (LiteralLimit > 0 && ConstantBusLimit > 0) { @@ -7531,7 +7509,7 @@ for (int I = 0, E = MI.getNumExplicitOperands(); I != E; ++I) { const MachineOperand &Op = MI.getOperand(I); const MCOperandInfo &OpInfo = Desc.OpInfo[I]; - if (isLiteralConstantLike(Op, OpInfo)) { + if (!Op.isReg() && !isInlineConstant(Op, OpInfo)) { HasLiteral = true; break; }