[MachineVerifier] Live interval for a subreg must have subranges

MachineVerifier verified the subranges of a live interval if
they existed, but did not complain if they did not exist.

This patch changes the verifier to complain if there are no
subranges in the live interval for a subreg operand (so long
as MachineRegisterInfo says we should be tracking subreg
liveness for that register). This matches the conditions for
LiveIntervalCalc to create subranges in the first place.

Differential Revision: https://reviews.llvm.org/D112556
This commit is contained in:
Jay Foad 2021-10-26 17:17:19 +01:00
parent 5e20cd6568
commit 4119da2f7c
1 changed files with 48 additions and 47 deletions

View File

@ -2217,6 +2217,19 @@ void MachineVerifier::checkLivenessAtDef(const MachineOperand *MO,
void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) { void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
const MachineInstr *MI = MO->getParent(); const MachineInstr *MI = MO->getParent();
const Register Reg = MO->getReg(); const Register Reg = MO->getReg();
const unsigned SubRegIdx = MO->getSubReg();
const LiveInterval *LI = nullptr;
if (LiveInts && Reg.isVirtual()) {
if (LiveInts->hasInterval(Reg)) {
LI = &LiveInts->getInterval(Reg);
if (SubRegIdx != 0 && !LI->empty() && !LI->hasSubRanges() &&
MRI->shouldTrackSubRegLiveness(Reg))
report("Live interval for subreg operand has no subranges", MO, MONum);
} else {
report("Virtual register has no live interval", MO, MONum);
}
}
// Both use and def operands can read a register. // Both use and def operands can read a register.
if (MO->readsReg()) { if (MO->readsReg()) {
@ -2226,7 +2239,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
// Check that LiveVars knows this kill (unless we are inside a bundle, in // Check that LiveVars knows this kill (unless we are inside a bundle, in
// which case we have already checked that LiveVars knows any kills on the // which case we have already checked that LiveVars knows any kills on the
// bundle header instead). // bundle header instead).
if (LiveVars && Register::isVirtualRegister(Reg) && MO->isKill() && if (LiveVars && Reg.isVirtual() && MO->isKill() &&
!MI->isBundledWithPred()) { !MI->isBundledWithPred()) {
LiveVariables::VarInfo &VI = LiveVars->getVarInfo(Reg); LiveVariables::VarInfo &VI = LiveVars->getVarInfo(Reg);
if (!is_contained(VI.Kills, MI)) if (!is_contained(VI.Kills, MI))
@ -2247,42 +2260,36 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
} }
} }
if (Register::isVirtualRegister(Reg)) { if (Reg.isVirtual()) {
if (LiveInts->hasInterval(Reg)) { // This is a virtual register interval.
// This is a virtual register interval. checkLivenessAtUse(MO, MONum, UseIdx, *LI, Reg);
const LiveInterval &LI = LiveInts->getInterval(Reg);
checkLivenessAtUse(MO, MONum, UseIdx, LI, Reg);
if (LI.hasSubRanges() && !MO->isDef()) { if (LI->hasSubRanges() && !MO->isDef()) {
unsigned SubRegIdx = MO->getSubReg(); LaneBitmask MOMask = SubRegIdx != 0
LaneBitmask MOMask = SubRegIdx != 0 ? TRI->getSubRegIndexLaneMask(SubRegIdx)
? TRI->getSubRegIndexLaneMask(SubRegIdx) : MRI->getMaxLaneMaskForVReg(Reg);
: MRI->getMaxLaneMaskForVReg(Reg); LaneBitmask LiveInMask;
LaneBitmask LiveInMask; for (const LiveInterval::SubRange &SR : LI->subranges()) {
for (const LiveInterval::SubRange &SR : LI.subranges()) { if ((MOMask & SR.LaneMask).none())
if ((MOMask & SR.LaneMask).none()) continue;
continue; checkLivenessAtUse(MO, MONum, UseIdx, SR, Reg, SR.LaneMask);
checkLivenessAtUse(MO, MONum, UseIdx, SR, Reg, SR.LaneMask); LiveQueryResult LRQ = SR.Query(UseIdx);
LiveQueryResult LRQ = SR.Query(UseIdx); if (LRQ.valueIn())
if (LRQ.valueIn()) LiveInMask |= SR.LaneMask;
LiveInMask |= SR.LaneMask; }
} // At least parts of the register has to be live at the use.
// At least parts of the register has to be live at the use. if ((LiveInMask & MOMask).none()) {
if ((LiveInMask & MOMask).none()) { report("No live subrange at use", MO, MONum);
report("No live subrange at use", MO, MONum); report_context(*LI);
report_context(LI); report_context(UseIdx);
report_context(UseIdx);
}
} }
} else {
report("Virtual register has no live interval", MO, MONum);
} }
} }
} }
// Use of a dead register. // Use of a dead register.
if (!regsLive.count(Reg)) { if (!regsLive.count(Reg)) {
if (Register::isPhysicalRegister(Reg)) { if (Reg.isPhysical()) {
// Reserved registers may be used even when 'dead'. // Reserved registers may be used even when 'dead'.
bool Bad = !isReserved(Reg); bool Bad = !isReserved(Reg);
// We are fine if just any subregister has a defined value. // We are fine if just any subregister has a defined value.
@ -2304,7 +2311,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
if (!MOP.isReg() || !MOP.isImplicit()) if (!MOP.isReg() || !MOP.isImplicit())
continue; continue;
if (!Register::isPhysicalRegister(MOP.getReg())) if (!MOP.getReg().isPhysical())
continue; continue;
if (llvm::is_contained(TRI->subregs(MOP.getReg()), Reg)) if (llvm::is_contained(TRI->subregs(MOP.getReg()), Reg))
@ -2337,7 +2344,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
addRegWithSubRegs(regsDefined, Reg); addRegWithSubRegs(regsDefined, Reg);
// Verify SSA form. // Verify SSA form.
if (MRI->isSSA() && Register::isVirtualRegister(Reg) && if (MRI->isSSA() && Reg.isVirtual() &&
std::next(MRI->def_begin(Reg)) != MRI->def_end()) std::next(MRI->def_begin(Reg)) != MRI->def_end())
report("Multiple virtual register defs in SSA form", MO, MONum); report("Multiple virtual register defs in SSA form", MO, MONum);
@ -2346,24 +2353,18 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
SlotIndex DefIdx = LiveInts->getInstructionIndex(*MI); SlotIndex DefIdx = LiveInts->getInstructionIndex(*MI);
DefIdx = DefIdx.getRegSlot(MO->isEarlyClobber()); DefIdx = DefIdx.getRegSlot(MO->isEarlyClobber());
if (Register::isVirtualRegister(Reg)) { if (Reg.isVirtual()) {
if (LiveInts->hasInterval(Reg)) { checkLivenessAtDef(MO, MONum, DefIdx, *LI, Reg);
const LiveInterval &LI = LiveInts->getInterval(Reg);
checkLivenessAtDef(MO, MONum, DefIdx, LI, Reg);
if (LI.hasSubRanges()) { if (LI->hasSubRanges()) {
unsigned SubRegIdx = MO->getSubReg(); LaneBitmask MOMask = SubRegIdx != 0
LaneBitmask MOMask = SubRegIdx != 0 ? TRI->getSubRegIndexLaneMask(SubRegIdx)
? TRI->getSubRegIndexLaneMask(SubRegIdx) : MRI->getMaxLaneMaskForVReg(Reg);
: MRI->getMaxLaneMaskForVReg(Reg); for (const LiveInterval::SubRange &SR : LI->subranges()) {
for (const LiveInterval::SubRange &SR : LI.subranges()) { if ((SR.LaneMask & MOMask).none())
if ((SR.LaneMask & MOMask).none()) continue;
continue; checkLivenessAtDef(MO, MONum, DefIdx, SR, Reg, true, SR.LaneMask);
checkLivenessAtDef(MO, MONum, DefIdx, SR, Reg, true, SR.LaneMask);
}
} }
} else {
report("Virtual register has no Live interval", MO, MONum);
} }
} }
} }