1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

[GISel]: Fix one more CSE Non determinism

https://reviews.llvm.org/D86676

Sometimes we can have the following code

 x:gpr(s32) = G_OP

Say we build G_OP2 to the same x and then delete the previous instruction. Using something like

 Register X = ...;
 auto NewMIB = CSEBuilder.buildOp2(X, ... args);

Currently there's a mismatch in how NewMIB is profiled and inserted into the CSEMap (ie it doesn't consider register bank/register class along with type).Unify the profiling by refactoring and calling the common method.

This was found by turning on the CSEInfo::verify in at the end of each of our GISel passes which turns inconsistent state/non determinism in CSEing into crashes which likely usually indicates missing calls to Observer on mutations (the most common case). Here non determinism usually means not cseing sometimes, but almost never about producing incorrect code.
Also this patch adds this verification at the end of the combiners as well.
This commit is contained in:
Aditya Nandakumar 2020-08-27 08:54:33 -07:00
parent 4265553ed8
commit 46055bcec5
4 changed files with 27 additions and 10 deletions

View File

@ -182,6 +182,8 @@ public:
const GISelInstProfileBuilder &addNodeIDRegNum(Register Reg) const;
const GISelInstProfileBuilder &addNodeIDReg(Register Reg) const;
const GISelInstProfileBuilder &addNodeIDImmediate(int64_t Imm) const;
const GISelInstProfileBuilder &
addNodeIDMBB(const MachineBasicBlock *MBB) const;

View File

@ -367,23 +367,30 @@ GISelInstProfileBuilder::addNodeIDFlag(unsigned Flag) const {
return *this;
}
const GISelInstProfileBuilder &
GISelInstProfileBuilder::addNodeIDReg(Register Reg) const {
LLT Ty = MRI.getType(Reg);
if (Ty.isValid())
addNodeIDRegType(Ty);
if (const RegClassOrRegBank &RCOrRB = MRI.getRegClassOrRegBank(Reg)) {
if (const auto *RB = RCOrRB.dyn_cast<const RegisterBank *>())
addNodeIDRegType(RB);
else if (const auto *RC = RCOrRB.dyn_cast<const TargetRegisterClass *>())
addNodeIDRegType(RC);
}
return *this;
}
const GISelInstProfileBuilder &GISelInstProfileBuilder::addNodeIDMachineOperand(
const MachineOperand &MO) const {
if (MO.isReg()) {
Register Reg = MO.getReg();
if (!MO.isDef())
addNodeIDRegNum(Reg);
LLT Ty = MRI.getType(Reg);
if (Ty.isValid())
addNodeIDRegType(Ty);
if (const RegClassOrRegBank &RCOrRB = MRI.getRegClassOrRegBank(Reg)) {
if (const auto *RB = RCOrRB.dyn_cast<const RegisterBank *>())
addNodeIDRegType(RB);
else if (const auto *RC = RCOrRB.dyn_cast<const TargetRegisterClass *>())
addNodeIDRegType(RC);
}
// Profile the register properties.
addNodeIDReg(Reg);
assert(!MO.isImplicit() && "Unhandled case");
} else if (MO.isImm())
ID.AddInteger(MO.getImm());

View File

@ -62,6 +62,11 @@ void CSEMIRBuilder::profileDstOp(const DstOp &Op,
case DstOp::DstType::Ty_RC:
B.addNodeIDRegType(Op.getRegClass());
break;
case DstOp::DstType::Ty_Reg: {
// Regs can have LLT&(RB|RC). If those exist, profile them as well.
B.addNodeIDReg(Op.getReg());
break;
}
default:
B.addNodeIDRegType(Op.getLLTTy(*getMRI()));
break;

View File

@ -153,5 +153,8 @@ bool Combiner::combineMachineInstrs(MachineFunction &MF,
MFChanged |= Changed;
} while (Changed);
assert(!CSEInfo || !errorToBool(CSEInfo->verify()) &&
"CSEInfo is not consistent. Likely missing calls to "
"observer on mutations");
return MFChanged;
}