Skip to content

Commit a6d5374

Browse files
committedNov 28, 2017
MachineVerifier: Improve PHI operand checking
Additional checks for phi operands: - first operand should be a virtual register def. It should not be tied, implicit, internalread, earlyclobber or a read. - The other operands should be register/mbb operands next to each other - The register operands should not be implicit, internalread, earlyclobber, debug or tied. - We can perform most of the PHI checks even for unreachable blocks. llvm-svn: 319140
1 parent adf7582 commit a6d5374

File tree

1 file changed

+54
-28
lines changed

1 file changed

+54
-28
lines changed
 

‎llvm/lib/CodeGen/MachineVerifier.cpp

+54-28
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ namespace {
264264

265265
void markReachable(const MachineBasicBlock *MBB);
266266
void calcRegsPassed();
267-
void checkPHIOps(const MachineBasicBlock *MBB);
267+
void checkPHIOps(const MachineBasicBlock &MBB);
268268

269269
void calcRegsRequired();
270270
void verifyLiveVariables();
@@ -1604,32 +1604,65 @@ void MachineVerifier::calcRegsRequired() {
16041604

16051605
// Check PHI instructions at the beginning of MBB. It is assumed that
16061606
// calcRegsPassed has been run so BBInfo::isLiveOut is valid.
1607-
void MachineVerifier::checkPHIOps(const MachineBasicBlock *MBB) {
1607+
void MachineVerifier::checkPHIOps(const MachineBasicBlock &MBB) {
1608+
BBInfo &MInfo = MBBInfoMap[&MBB];
1609+
16081610
SmallPtrSet<const MachineBasicBlock*, 8> seen;
1609-
for (const auto &BBI : *MBB) {
1610-
if (!BBI.isPHI())
1611+
for (const MachineInstr &Phi : MBB) {
1612+
if (!Phi.isPHI())
16111613
break;
16121614
seen.clear();
16131615

1614-
for (unsigned i = 1, e = BBI.getNumOperands(); i != e; i += 2) {
1615-
unsigned Reg = BBI.getOperand(i).getReg();
1616-
const MachineBasicBlock *Pre = BBI.getOperand(i + 1).getMBB();
1617-
if (!Pre->isSuccessor(MBB))
1616+
const MachineOperand &MODef = Phi.getOperand(0);
1617+
if (!MODef.isReg() || !MODef.isDef()) {
1618+
report("Expected first PHI operand to be a register def", &MODef, 0);
1619+
continue;
1620+
}
1621+
if (MODef.isTied() || MODef.isImplicit() || MODef.isInternalRead() ||
1622+
MODef.isEarlyClobber() || MODef.isDebug())
1623+
report("Unexpected flag on PHI operand", &MODef, 0);
1624+
unsigned DefReg = MODef.getReg();
1625+
if (!TargetRegisterInfo::isVirtualRegister(DefReg))
1626+
report("Expected first PHI operand to be a virtual register", &MODef, 0);
1627+
1628+
for (unsigned I = 1, E = Phi.getNumOperands(); I != E; I += 2) {
1629+
const MachineOperand &MO0 = Phi.getOperand(I);
1630+
if (!MO0.isReg()) {
1631+
report("Expected PHI operand to be a register", &MO0, I);
1632+
continue;
1633+
}
1634+
if (MO0.isImplicit() || MO0.isInternalRead() || MO0.isEarlyClobber() ||
1635+
MO0.isDebug() || MO0.isTied())
1636+
report("Unexpected flag on PHI operand", &MO0, I);
1637+
1638+
const MachineOperand &MO1 = Phi.getOperand(I + 1);
1639+
if (!MO1.isMBB()) {
1640+
report("Expected PHI operand to be a basic block", &MO1, I + 1);
16181641
continue;
1619-
seen.insert(Pre);
1620-
BBInfo &PrInfo = MBBInfoMap[Pre];
1621-
if (PrInfo.reachable && !PrInfo.isLiveOut(Reg))
1622-
report("PHI operand is not live-out from predecessor",
1623-
&BBI.getOperand(i), i);
1642+
}
1643+
1644+
const MachineBasicBlock &Pre = *MO1.getMBB();
1645+
if (!Pre.isSuccessor(&MBB)) {
1646+
report("PHI input is not a predecessor block", &MO1, I + 1);
1647+
continue;
1648+
}
1649+
1650+
if (MInfo.reachable) {
1651+
seen.insert(&Pre);
1652+
BBInfo &PrInfo = MBBInfoMap[&Pre];
1653+
if (PrInfo.reachable && !PrInfo.isLiveOut(MO0.getReg()))
1654+
report("PHI operand is not live-out from predecessor", &MO0, I);
1655+
}
16241656
}
16251657

16261658
// Did we see all predecessors?
1627-
for (MachineBasicBlock::const_pred_iterator PrI = MBB->pred_begin(),
1628-
PrE = MBB->pred_end(); PrI != PrE; ++PrI) {
1629-
if (!seen.count(*PrI)) {
1630-
report("Missing PHI operand", &BBI);
1631-
errs() << "BB#" << (*PrI)->getNumber()
1632-
<< " is a predecessor according to the CFG.\n";
1659+
if (MInfo.reachable) {
1660+
for (MachineBasicBlock *Pred : MBB.predecessors()) {
1661+
if (!seen.count(Pred)) {
1662+
report("Missing PHI operand", &Phi);
1663+
errs() << "BB#" << Pred->getNumber()
1664+
<< " is a predecessor according to the CFG.\n";
1665+
}
16331666
}
16341667
}
16351668
}
@@ -1638,15 +1671,8 @@ void MachineVerifier::checkPHIOps(const MachineBasicBlock *MBB) {
16381671
void MachineVerifier::visitMachineFunctionAfter() {
16391672
calcRegsPassed();
16401673

1641-
for (const auto &MBB : *MF) {
1642-
BBInfo &MInfo = MBBInfoMap[&MBB];
1643-
1644-
// Skip unreachable MBBs.
1645-
if (!MInfo.reachable)
1646-
continue;
1647-
1648-
checkPHIOps(&MBB);
1649-
}
1674+
for (const MachineBasicBlock &MBB : *MF)
1675+
checkPHIOps(MBB);
16501676

16511677
// Now check liveness info if available
16521678
calcRegsRequired();

0 commit comments

Comments
 (0)