aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/MachineVerifier.cpp
diff options
context:
space:
mode:
authorBjorn Pettersson <bjorn.a.pettersson@ericsson.com>2018-09-20 06:59:18 +0000
committerBjorn Pettersson <bjorn.a.pettersson@ericsson.com>2018-09-20 06:59:18 +0000
commitb2154af25f52589360eb43e2b74413dbba461aff (patch)
tree827d8c93d0bc3a41458a81724e2f0036e70502df /llvm/lib/CodeGen/MachineVerifier.cpp
parent1f6020798493b536304dd36b393682b062ef1fbd (diff)
downloadllvm-b2154af25f52589360eb43e2b74413dbba461aff.zip
llvm-b2154af25f52589360eb43e2b74413dbba461aff.tar.gz
llvm-b2154af25f52589360eb43e2b74413dbba461aff.tar.bz2
[MachineVerifier] Relax checkLivenessAtDef regarding dead subreg defs
Summary: Consider an instruction that has multiple defs of the same vreg, but defining different subregs: %7.sub1:rc, dead %7.sub2:rc = inst Calling checkLivenessAtDef for the live interval associated with %7 incorrectly reported "live range continues after a dead def". The live range for %7 has a dead def at the slot index for "inst" even if the live range continues (given that there are later uses of %7.sub1). This patch adjusts MachineVerifier::checkLivenessAtDef to allow dead subregister definitions, unless we are checking a subrange (when tracking subregister liveness). A limitation is that we do not detect the situation when the live range continues past an instruction that defines the full virtual register by multiple dead subreg defines. I also removed some dead code related to physical register in checkLivenessAtDef. Wwe only call that method for virtual registers, so I added an assertion instead. Reviewers: kparzysz Reviewed By: kparzysz Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D52237 llvm-svn: 342618
Diffstat (limited to 'llvm/lib/CodeGen/MachineVerifier.cpp')
-rw-r--r--llvm/lib/CodeGen/MachineVerifier.cpp32
1 files changed, 11 insertions, 21 deletions
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 8b27470..aebfb08 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -262,6 +262,7 @@ namespace {
LaneBitmask LaneMask = LaneBitmask::getNone());
void checkLivenessAtDef(const MachineOperand *MO, unsigned MONum,
SlotIndex DefIdx, const LiveRange &LR, unsigned VRegOrUnit,
+ bool SubRangeCheck = false,
LaneBitmask LaneMask = LaneBitmask::getNone());
void markReachable(const MachineBasicBlock *MBB);
@@ -1396,7 +1397,7 @@ void MachineVerifier::checkLivenessAtUse(const MachineOperand *MO,
void MachineVerifier::checkLivenessAtDef(const MachineOperand *MO,
unsigned MONum, SlotIndex DefIdx, const LiveRange &LR, unsigned VRegOrUnit,
- LaneBitmask LaneMask) {
+ bool SubRangeCheck, LaneBitmask LaneMask) {
if (const VNInfo *VNI = LR.getVNInfoAt(DefIdx)) {
assert(VNI && "NULL valno is not allowed");
if (VNI->def != DefIdx) {
@@ -1420,25 +1421,14 @@ void MachineVerifier::checkLivenessAtDef(const MachineOperand *MO,
if (MO->isDead()) {
LiveQueryResult LRQ = LR.Query(DefIdx);
if (!LRQ.isDeadDef()) {
- // In case of physregs we can have a non-dead definition on another
- // operand.
- bool otherDef = false;
- if (!TargetRegisterInfo::isVirtualRegister(VRegOrUnit)) {
- const MachineInstr &MI = *MO->getParent();
- for (const MachineOperand &MO : MI.operands()) {
- if (!MO.isReg() || !MO.isDef() || MO.isDead())
- continue;
- unsigned Reg = MO.getReg();
- for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) {
- if (*Units == VRegOrUnit) {
- otherDef = true;
- break;
- }
- }
- }
- }
-
- if (!otherDef) {
+ assert(TargetRegisterInfo::isVirtualRegister(VRegOrUnit) &&
+ "Expecting a virtual register.");
+ // A dead subreg def only tells us that the specific subreg is dead. There
+ // could be other non-dead defs of other subregs, or we could have other
+ // parts of the register being live through the instruction. So unless we
+ // are checking liveness for a subrange it is ok for the live range to
+ // continue, given that we have a dead def of a subregister.
+ if (SubRangeCheck || MO->getSubReg() == 0) {
report("Live range continues after dead def flag", MO, MONum);
report_context_liverange(LR);
report_context_vreg_regunit(VRegOrUnit);
@@ -1596,7 +1586,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
for (const LiveInterval::SubRange &SR : LI.subranges()) {
if ((SR.LaneMask & MOMask).none())
continue;
- checkLivenessAtDef(MO, MONum, DefIdx, SR, Reg, SR.LaneMask);
+ checkLivenessAtDef(MO, MONum, DefIdx, SR, Reg, true, SR.LaneMask);
}
}
} else {