forked from OSchip/llvm-project
[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:
parent
5e20cd6568
commit
4119da2f7c
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue