mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-28 23:43:50 +00:00
R600/SI: Simplify and fix handling of VOP2 in SIInstrInfo::legalizeOperands
We were incorrectly assuming that all VOP2 instructions can read SGPRs in Src0, but this is not true for instructions that read carry-in from VCC. The old logic has been replaced with new logic which checks the defined register classes of the VOP2 instruction to determine whether or not to legalize the operands. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@214465 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
635fb9fb59
commit
5494792536
@ -472,14 +472,14 @@ bool SIInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
|
||||
MachineInstr *SIInstrInfo::commuteInstruction(MachineInstr *MI,
|
||||
bool NewMI) const {
|
||||
|
||||
MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
|
||||
if (MI->getNumOperands() < 3 || !MI->getOperand(1).isReg())
|
||||
return nullptr;
|
||||
|
||||
// Cannot commute VOP2 if src0 is SGPR.
|
||||
if (isVOP2(MI->getOpcode()) && MI->getOperand(1).isReg() &&
|
||||
RI.isSGPRClass(MRI.getRegClass(MI->getOperand(1).getReg())))
|
||||
return nullptr;
|
||||
// Make sure it s legal to commute operands for VOP2.
|
||||
if (isVOP2(MI->getOpcode()) &&
|
||||
(!isOperandLegal(MI, 1, &MI->getOperand(2)) ||
|
||||
!isOperandLegal(MI, 2, &MI->getOperand(1))))
|
||||
return nullptr;
|
||||
|
||||
if (!MI->getOperand(2).isReg()) {
|
||||
// XXX: Commute instructions with FPImm operands
|
||||
@ -988,8 +988,36 @@ unsigned SIInstrInfo::split64BitImm(SmallVectorImpl<MachineInstr *> &Worklist,
|
||||
return Dst;
|
||||
}
|
||||
|
||||
bool SIInstrInfo::isOperandLegal(const MachineInstr *MI, unsigned OpIdx,
|
||||
const MachineOperand *MO) const {
|
||||
const MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
|
||||
const MCInstrDesc &InstDesc = get(MI->getOpcode());
|
||||
const MCOperandInfo &OpInfo = InstDesc.OpInfo[OpIdx];
|
||||
const TargetRegisterClass *DefinedRC =
|
||||
OpInfo.RegClass != -1 ? RI.getRegClass(OpInfo.RegClass) : nullptr;
|
||||
if (!MO)
|
||||
MO = &MI->getOperand(OpIdx);
|
||||
|
||||
if (MO->isReg()) {
|
||||
assert(DefinedRC);
|
||||
const TargetRegisterClass *RC = MRI.getRegClass(MO->getReg());
|
||||
return RI.getCommonSubClass(RC, RI.getRegClass(OpInfo.RegClass));
|
||||
}
|
||||
|
||||
|
||||
// Handle non-register types that are treated like immediates.
|
||||
assert(MO->isImm() || MO->isFPImm() || MO->isTargetIndex() || MO->isFI());
|
||||
|
||||
if (!DefinedRC)
|
||||
// This opperand expects an immediate
|
||||
return true;
|
||||
|
||||
return RI.regClassCanUseImmediate(DefinedRC);
|
||||
}
|
||||
|
||||
void SIInstrInfo::legalizeOperands(MachineInstr *MI) const {
|
||||
MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
|
||||
|
||||
int Src0Idx = AMDGPU::getNamedOperandIdx(MI->getOpcode(),
|
||||
AMDGPU::OpName::src0);
|
||||
int Src1Idx = AMDGPU::getNamedOperandIdx(MI->getOpcode(),
|
||||
@ -999,34 +1027,26 @@ void SIInstrInfo::legalizeOperands(MachineInstr *MI) const {
|
||||
|
||||
// Legalize VOP2
|
||||
if (isVOP2(MI->getOpcode()) && Src1Idx != -1) {
|
||||
MachineOperand &Src0 = MI->getOperand(Src0Idx);
|
||||
MachineOperand &Src1 = MI->getOperand(Src1Idx);
|
||||
|
||||
// If the instruction implicitly reads VCC, we can't have any SGPR operands,
|
||||
// so move any.
|
||||
bool ReadsVCC = MI->readsRegister(AMDGPU::VCC, &RI);
|
||||
if (ReadsVCC && Src0.isReg() &&
|
||||
RI.isSGPRClass(MRI.getRegClass(Src0.getReg()))) {
|
||||
// Legalize src0
|
||||
if (!isOperandLegal(MI, Src0Idx))
|
||||
legalizeOpWithMove(MI, Src0Idx);
|
||||
|
||||
// Legalize src1
|
||||
if (isOperandLegal(MI, Src1Idx))
|
||||
return;
|
||||
|
||||
// Usually src0 of VOP2 instructions allow more types of inputs
|
||||
// than src1, so try to commute the instruction to decrease our
|
||||
// chances of having to insert a MOV instruction to legalize src1.
|
||||
if (MI->isCommutable()) {
|
||||
if (commuteInstruction(MI))
|
||||
// If we are successful in commuting, then we know MI is legal, so
|
||||
// we are done.
|
||||
return;
|
||||
}
|
||||
|
||||
if (ReadsVCC && Src1.isReg() &&
|
||||
RI.isSGPRClass(MRI.getRegClass(Src1.getReg()))) {
|
||||
legalizeOpWithMove(MI, Src1Idx);
|
||||
return;
|
||||
}
|
||||
|
||||
// Legalize VOP2 instructions where src1 is not a VGPR. An SGPR input must
|
||||
// be the first operand, and there can only be one.
|
||||
if (Src1.isImm() || Src1.isFPImm() ||
|
||||
(Src1.isReg() && RI.isSGPRClass(MRI.getRegClass(Src1.getReg())))) {
|
||||
if (MI->isCommutable()) {
|
||||
if (commuteInstruction(MI))
|
||||
return;
|
||||
}
|
||||
legalizeOpWithMove(MI, Src1Idx);
|
||||
}
|
||||
legalizeOpWithMove(MI, Src1Idx);
|
||||
return;
|
||||
}
|
||||
|
||||
// XXX - Do any VOP3 instructions read VCC?
|
||||
|
@ -150,6 +150,11 @@ public:
|
||||
/// instead of MOV.
|
||||
void legalizeOpWithMove(MachineInstr *MI, unsigned OpIdx) const;
|
||||
|
||||
/// \brief Check if \p MO is a legal operand if it was the \p OpIdx Operand
|
||||
/// for \p MI.
|
||||
bool isOperandLegal(const MachineInstr *MI, unsigned OpIdx,
|
||||
const MachineOperand *MO = nullptr) const;
|
||||
|
||||
/// \brief Legalize all operands in this instruction. This function may
|
||||
/// create new instruction and insert them before \p MI.
|
||||
void legalizeOperands(MachineInstr *MI) const;
|
||||
|
Loading…
Reference in New Issue
Block a user