From 4119da2f7c5fd21c03f6d50aa1d2af3527a9e90f Mon Sep 17 00:00:00 2001 From: Jay Foad Date: Tue, 26 Oct 2021 17:17:19 +0100 Subject: [PATCH] [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 --- llvm/lib/CodeGen/MachineVerifier.cpp | 99 ++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 49 deletions(-) diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp index 8ac913d..d6bb3e7 100644 --- a/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/llvm/lib/CodeGen/MachineVerifier.cpp @@ -2217,6 +2217,19 @@ void MachineVerifier::checkLivenessAtDef(const MachineOperand *MO, void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) { const MachineInstr *MI = MO->getParent(); 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. 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 // which case we have already checked that LiveVars knows any kills on the // bundle header instead). - if (LiveVars && Register::isVirtualRegister(Reg) && MO->isKill() && + if (LiveVars && Reg.isVirtual() && MO->isKill() && !MI->isBundledWithPred()) { LiveVariables::VarInfo &VI = LiveVars->getVarInfo(Reg); if (!is_contained(VI.Kills, MI)) @@ -2247,42 +2260,36 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) { } } - if (Register::isVirtualRegister(Reg)) { - if (LiveInts->hasInterval(Reg)) { - // This is a virtual register interval. - const LiveInterval &LI = LiveInts->getInterval(Reg); - checkLivenessAtUse(MO, MONum, UseIdx, LI, Reg); - - if (LI.hasSubRanges() && !MO->isDef()) { - unsigned SubRegIdx = MO->getSubReg(); - LaneBitmask MOMask = SubRegIdx != 0 - ? TRI->getSubRegIndexLaneMask(SubRegIdx) - : MRI->getMaxLaneMaskForVReg(Reg); - LaneBitmask LiveInMask; - for (const LiveInterval::SubRange &SR : LI.subranges()) { - if ((MOMask & SR.LaneMask).none()) - continue; - checkLivenessAtUse(MO, MONum, UseIdx, SR, Reg, SR.LaneMask); - LiveQueryResult LRQ = SR.Query(UseIdx); - if (LRQ.valueIn()) - LiveInMask |= SR.LaneMask; - } - // At least parts of the register has to be live at the use. - if ((LiveInMask & MOMask).none()) { - report("No live subrange at use", MO, MONum); - report_context(LI); - report_context(UseIdx); - } + if (Reg.isVirtual()) { + // This is a virtual register interval. + checkLivenessAtUse(MO, MONum, UseIdx, *LI, Reg); + + if (LI->hasSubRanges() && !MO->isDef()) { + LaneBitmask MOMask = SubRegIdx != 0 + ? TRI->getSubRegIndexLaneMask(SubRegIdx) + : MRI->getMaxLaneMaskForVReg(Reg); + LaneBitmask LiveInMask; + for (const LiveInterval::SubRange &SR : LI->subranges()) { + if ((MOMask & SR.LaneMask).none()) + continue; + checkLivenessAtUse(MO, MONum, UseIdx, SR, Reg, SR.LaneMask); + LiveQueryResult LRQ = SR.Query(UseIdx); + if (LRQ.valueIn()) + LiveInMask |= SR.LaneMask; + } + // At least parts of the register has to be live at the use. + if ((LiveInMask & MOMask).none()) { + report("No live subrange at use", MO, MONum); + report_context(*LI); + report_context(UseIdx); } - } else { - report("Virtual register has no live interval", MO, MONum); } } } // Use of a dead register. if (!regsLive.count(Reg)) { - if (Register::isPhysicalRegister(Reg)) { + if (Reg.isPhysical()) { // Reserved registers may be used even when 'dead'. bool Bad = !isReserved(Reg); // 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()) continue; - if (!Register::isPhysicalRegister(MOP.getReg())) + if (!MOP.getReg().isPhysical()) continue; if (llvm::is_contained(TRI->subregs(MOP.getReg()), Reg)) @@ -2337,7 +2344,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) { addRegWithSubRegs(regsDefined, Reg); // Verify SSA form. - if (MRI->isSSA() && Register::isVirtualRegister(Reg) && + if (MRI->isSSA() && Reg.isVirtual() && std::next(MRI->def_begin(Reg)) != MRI->def_end()) 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); DefIdx = DefIdx.getRegSlot(MO->isEarlyClobber()); - if (Register::isVirtualRegister(Reg)) { - if (LiveInts->hasInterval(Reg)) { - const LiveInterval &LI = LiveInts->getInterval(Reg); - checkLivenessAtDef(MO, MONum, DefIdx, LI, Reg); - - if (LI.hasSubRanges()) { - unsigned SubRegIdx = MO->getSubReg(); - LaneBitmask MOMask = SubRegIdx != 0 - ? TRI->getSubRegIndexLaneMask(SubRegIdx) - : MRI->getMaxLaneMaskForVReg(Reg); - for (const LiveInterval::SubRange &SR : LI.subranges()) { - if ((SR.LaneMask & MOMask).none()) - continue; - checkLivenessAtDef(MO, MONum, DefIdx, SR, Reg, true, SR.LaneMask); - } + if (Reg.isVirtual()) { + checkLivenessAtDef(MO, MONum, DefIdx, *LI, Reg); + + if (LI->hasSubRanges()) { + LaneBitmask MOMask = SubRegIdx != 0 + ? TRI->getSubRegIndexLaneMask(SubRegIdx) + : MRI->getMaxLaneMaskForVReg(Reg); + for (const LiveInterval::SubRange &SR : LI->subranges()) { + if ((SR.LaneMask & MOMask).none()) + continue; + checkLivenessAtDef(MO, MONum, DefIdx, SR, Reg, true, SR.LaneMask); } - } else { - report("Virtual register has no Live interval", MO, MONum); } } } -- 2.7.4