diff options
Diffstat (limited to 'llvm/lib/Target/R600/SIInstrInfo.cpp')
| -rw-r--r-- | llvm/lib/Target/R600/SIInstrInfo.cpp | 62 |
1 files changed, 41 insertions, 21 deletions
diff --git a/llvm/lib/Target/R600/SIInstrInfo.cpp b/llvm/lib/Target/R600/SIInstrInfo.cpp index 88a6677e7b2..7762b6eccf8 100644 --- a/llvm/lib/Target/R600/SIInstrInfo.cpp +++ b/llvm/lib/Target/R600/SIInstrInfo.cpp @@ -977,15 +977,25 @@ bool SIInstrInfo::isInlineConstant(const APInt &Imm) const { (FloatToBits(-4.0f) == Val); } -bool SIInstrInfo::isInlineConstant(const MachineOperand &MO) const { - if (MO.isImm()) - return isInlineConstant(APInt(32, MO.getImm(), true)); +bool SIInstrInfo::isInlineConstant(const MachineOperand &MO, + unsigned OpSize) const { + if (MO.isImm()) { + // MachineOperand provides no way to tell the true operand size, since it + // only records a 64-bit value. We need to know the size to determine if a + // 32-bit floating point immediate bit pattern is legal for an integer + // immediate. It would be for any 32-bit integer operand, but would not be + // for a 64-bit one. + + unsigned BitSize = 8 * OpSize; + return isInlineConstant(APInt(BitSize, MO.getImm(), true)); + } return false; } -bool SIInstrInfo::isLiteralConstant(const MachineOperand &MO) const { - return MO.isImm() && !isInlineConstant(MO); +bool SIInstrInfo::isLiteralConstant(const MachineOperand &MO, + unsigned OpSize) const { + return MO.isImm() && !isInlineConstant(MO, OpSize); } static bool compareMachineOp(const MachineOperand &Op0, @@ -1015,7 +1025,8 @@ bool SIInstrInfo::isImmOperandLegal(const MachineInstr *MI, unsigned OpNo, if (OpInfo.RegClass < 0) return false; - if (isLiteralConstant(MO)) + unsigned OpSize = RI.getRegClass(OpInfo.RegClass)->getSize(); + if (isLiteralConstant(MO, OpSize)) return RI.opCanUseLiteralConstant(OpInfo.OperandType); return RI.opCanUseInlineConstant(OpInfo.OperandType); @@ -1070,9 +1081,10 @@ bool SIInstrInfo::hasModifiersSet(const MachineInstr &MI, } bool SIInstrInfo::usesConstantBus(const MachineRegisterInfo &MRI, - const MachineOperand &MO) const { + const MachineOperand &MO, + unsigned OpSize) const { // Literal constants use the constant bus. - if (isLiteralConstant(MO)) + if (isLiteralConstant(MO, OpSize)) return true; if (!MO.isReg() || !MO.isUse()) @@ -1134,9 +1146,13 @@ bool SIInstrInfo::verifyInstruction(const MachineInstr *MI, case AMDGPU::OPERAND_REG_IMM32: break; case AMDGPU::OPERAND_REG_INLINE_C: - if (MI->getOperand(i).isImm() && !isInlineConstant(MI->getOperand(i))) { - ErrInfo = "Illegal immediate value for operand."; - return false; + if (MI->getOperand(i).isImm()) { + int RegClass = Desc.OpInfo[i].RegClass; + const TargetRegisterClass *RC = RI.getRegClass(RegClass); + if (!isInlineConstant(MI->getOperand(i), RC->getSize())) { + ErrInfo = "Illegal immediate value for operand."; + return false; + } } break; case MCOI::OPERAND_IMMEDIATE: @@ -1182,9 +1198,8 @@ bool SIInstrInfo::verifyInstruction(const MachineInstr *MI, for (int OpIdx : OpIndices) { if (OpIdx == -1) break; - const MachineOperand &MO = MI->getOperand(OpIdx); - if (usesConstantBus(MRI, MO)) { + if (usesConstantBus(MRI, MO, getOpSize(Opcode, OpIdx))) { if (MO.isReg()) { if (MO.getReg() != SGPRUsed) ++ConstantBusCount; @@ -1211,15 +1226,18 @@ bool SIInstrInfo::verifyInstruction(const MachineInstr *MI, // Verify VOP3 if (isVOP3(Opcode)) { - if (Src0Idx != -1 && isLiteralConstant(MI->getOperand(Src0Idx))) { + if (Src0Idx != -1 && + isLiteralConstant(MI->getOperand(Src0Idx), getOpSize(Opcode, Src0Idx))) { ErrInfo = "VOP3 src0 cannot be a literal constant."; return false; } - if (Src1Idx != -1 && isLiteralConstant(MI->getOperand(Src1Idx))) { + if (Src1Idx != -1 && + isLiteralConstant(MI->getOperand(Src1Idx), getOpSize(Opcode, Src1Idx))) { ErrInfo = "VOP3 src1 cannot be a literal constant."; return false; } - if (Src2Idx != -1 && isLiteralConstant(MI->getOperand(Src2Idx))) { + if (Src2Idx != -1 && + isLiteralConstant(MI->getOperand(Src2Idx), getOpSize(Opcode, Src2Idx))) { ErrInfo = "VOP3 src2 cannot be a literal constant."; return false; } @@ -1312,7 +1330,7 @@ const TargetRegisterClass *SIInstrInfo::getOpRegClass(const MachineInstr &MI, if (TargetRegisterInfo::isVirtualRegister(Reg)) return MRI.getRegClass(Reg); - return RI.getRegClass(Reg); + return RI.getPhysRegClass(Reg); } unsigned RCID = Desc.OpInfo[OpNo].RegClass; @@ -1456,14 +1474,16 @@ bool SIInstrInfo::isOperandLegal(const MachineInstr *MI, unsigned OpIdx, if (!MO) MO = &MI->getOperand(OpIdx); - if (isVALU(InstDesc.Opcode) && usesConstantBus(MRI, *MO)) { + if (isVALU(InstDesc.Opcode) && + usesConstantBus(MRI, *MO, DefinedRC->getSize())) { unsigned SGPRUsed = MO->isReg() ? MO->getReg() : (unsigned)AMDGPU::NoRegister; for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { if (i == OpIdx) continue; - if (usesConstantBus(MRI, MI->getOperand(i)) && - MI->getOperand(i).isReg() && MI->getOperand(i).getReg() != SGPRUsed) { + const MachineOperand &Op = MI->getOperand(i); + if (Op.isReg() && Op.getReg() != SGPRUsed && + usesConstantBus(MRI, Op, getOpSize(*MI, i))) { return false; } } @@ -1556,7 +1576,7 @@ void SIInstrInfo::legalizeOperands(MachineInstr *MI) const { // We can use one SGPR in each VOP3 instruction. continue; } - } else if (!isLiteralConstant(MO)) { + } else if (!isLiteralConstant(MO, getOpSize(MI->getOpcode(), Idx))) { // If it is not a register and not a literal constant, then it must be // an inline constant which is always legal. continue; |

