Index: lib/Target/AMDGPU/SIInstrInfo.cpp =================================================================== --- lib/Target/AMDGPU/SIInstrInfo.cpp +++ lib/Target/AMDGPU/SIInstrInfo.cpp @@ -2963,7 +2963,12 @@ usesConstantBus(MRI, Op, InstDesc.OpInfo[i])) { return false; } - } else if (InstDesc.OpInfo[i].OperandType == AMDGPU::OPERAND_KIMM32) { + } else if (InstDesc.OpInfo[i].OperandType == AMDGPU::OPERAND_KIMM32 || + InstDesc.OpInfo[i].OperandType == AMDGPU::OPERAND_KIMM16) { + return false; + } else if (Op.isImm() && !isInlineConstant(Op, OpInfo) && + InstDesc.OpInfo[i].OperandType >= AMDGPU::OPERAND_SRC_FIRST && + InstDesc.OpInfo[i].OperandType <= AMDGPU::OPERAND_SRC_LAST) { return false; } } @@ -3073,13 +3078,12 @@ Src1.setSubReg(Src0SubReg); } -// Legalize VOP3 operands. Because all operand types are supported for any -// operand, and since literal constants are not allowed and should never be -// seen, we only need to worry about inserting copies if we use multiple SGPR -// operands. void SIInstrInfo::legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr &MI) const { unsigned Opc = MI.getOpcode(); + const SIRegisterInfo *TRI = + static_cast(MRI.getTargetRegisterInfo()); + int VOP3Idx[3] = { AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0), @@ -3089,6 +3093,7 @@ // Find the one SGPR operand we are allowed to use. unsigned SGPRReg = findUsedSGPR(MI, VOP3Idx); + bool ConstantBusUsed = (SGPRReg != AMDGPU::NoRegister); for (unsigned i = 0; i < 3; ++i) { int Idx = VOP3Idx[i]; @@ -3096,16 +3101,30 @@ break; MachineOperand &MO = MI.getOperand(Idx); - // We should never see a VOP3 instruction with an illegal immediate operand. + if (MO.isImm()) { + auto OpType = get(Opc).OpInfo[Idx].OperandType; + if (TRI->opCanUseInlineConstant(OpType) && isInlineConstant(MO, OpType)) + continue; + if (ConstantBusUsed) + legalizeOpWithMove(MI, Idx); + ConstantBusUsed = true; + continue; + } + if (!MO.isReg()) continue; if (!RI.isSGPRClass(MRI.getRegClass(MO.getReg()))) continue; // VGPRs are legal - if (SGPRReg == AMDGPU::NoRegister || SGPRReg == MO.getReg()) { + // We can use one SGPR in each VOP3 instruction. + // We can use one SGPR or one immediate in each VOP3P instruction. + if (SGPRReg == MO.getReg()) + continue; + + if (SGPRReg == AMDGPU::NoRegister && !ConstantBusUsed) { SGPRReg = MO.getReg(); - // We can use one SGPR in each VOP3 instruction. + ConstantBusUsed = true; continue; }