[llvm-commits] [llvm] r72586 - in /llvm/trunk: lib/VMCore/Verifier.cpp test/Verifier/2009-05-29-InvokeResult1.ll test/Verifier/2009-05-29-InvokeResult2.ll test/Verifier/2009-05-29-InvokeResult3.ll
Duncan Sands
baldrick at free.fr
Fri May 29 12:39:37 PDT 2009
Author: baldrick
Date: Fri May 29 14:39:36 2009
New Revision: 72586
URL: http://llvm.org/viewvc/llvm-project?rev=72586&view=rev
Log:
Dan noticed that the verifier wasn't thoroughly checking uses of
invoke results (see the testcases). Tighten up the checking.
Added:
llvm/trunk/test/Verifier/2009-05-29-InvokeResult1.ll
llvm/trunk/test/Verifier/2009-05-29-InvokeResult2.ll
llvm/trunk/test/Verifier/2009-05-29-InvokeResult3.ll
Modified:
llvm/trunk/lib/VMCore/Verifier.cpp
Modified: llvm/trunk/lib/VMCore/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=72586&r1=72585&r2=72586&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Verifier.cpp (original)
+++ llvm/trunk/lib/VMCore/Verifier.cpp Fri May 29 14:39:36 2009
@@ -1244,8 +1244,7 @@
if (!isa<PHINode>(I)) { // Check that non-phi nodes are not self referential
for (Value::use_iterator UI = I.use_begin(), UE = I.use_end();
UI != UE; ++UI)
- Assert1(*UI != (User*)&I ||
- !DT->dominates(&BB->getParent()->getEntryBlock(), BB),
+ Assert1(*UI != (User*)&I || !DT->isReachableFromEntry(BB),
"Only PHI nodes may reference their own value!", &I);
}
@@ -1306,67 +1305,67 @@
BasicBlock *OpBlock = Op->getParent();
// Check that a definition dominates all of its uses.
- if (!isa<PHINode>(I)) {
+ if (InvokeInst *II = dyn_cast<InvokeInst>(Op)) {
// Invoke results are only usable in the normal destination, not in the
// exceptional destination.
- if (InvokeInst *II = dyn_cast<InvokeInst>(Op)) {
- OpBlock = II->getNormalDest();
-
- Assert2(OpBlock != II->getUnwindDest(),
- "No uses of invoke possible due to dominance structure!",
- Op, II);
-
+ BasicBlock *NormalDest = II->getNormalDest();
+
+ Assert2(NormalDest != II->getUnwindDest(),
+ "No uses of invoke possible due to dominance structure!",
+ Op, &I);
+
+ // PHI nodes differ from other nodes because they actually "use" the
+ // value in the predecessor basic blocks they correspond to.
+ BasicBlock *UseBlock = BB;
+ if (isa<PHINode>(I))
+ UseBlock = cast<BasicBlock>(I.getOperand(i+1));
+
+ if (isa<PHINode>(I) && UseBlock == OpBlock) {
+ // Special case of a phi node in the normal destination or the unwind
+ // destination.
+ Assert2(BB == NormalDest || !DT->isReachableFromEntry(UseBlock),
+ "Invoke result not available in the unwind destination!",
+ Op, &I);
+ } else {
+ Assert2(DT->dominates(NormalDest, UseBlock) ||
+ !DT->isReachableFromEntry(UseBlock),
+ "Invoke result does not dominate all uses!", Op, &I);
+
// If the normal successor of an invoke instruction has multiple
- // predecessors, then the normal edge from the invoke is critical, so
- // the invoke value can only be live if the destination block
- // dominates all of it's predecessors (other than the invoke) or if
- // the invoke value is only used by a phi in the successor.
- if (!OpBlock->getSinglePredecessor() &&
- DT->dominates(&BB->getParent()->getEntryBlock(), BB)) {
- // The first case we allow is if the use is a PHI operand in the
- // normal block, and if that PHI operand corresponds to the invoke's
- // block.
- bool Bad = true;
- if (PHINode *PN = dyn_cast<PHINode>(&I))
- if (PN->getParent() == OpBlock &&
- PN->getIncomingBlock(i/2) == Op->getParent())
- Bad = false;
-
+ // predecessors, then the normal edge from the invoke is critical,
+ // so the invoke value can only be live if the destination block
+ // dominates all of it's predecessors (other than the invoke).
+ if (!NormalDest->getSinglePredecessor() &&
+ DT->isReachableFromEntry(UseBlock))
// If it is used by something non-phi, then the other case is that
- // 'OpBlock' dominates all of its predecessors other than the
+ // 'NormalDest' dominates all of its predecessors other than the
// invoke. In this case, the invoke value can still be used.
- if (Bad) {
- Bad = false;
- for (pred_iterator PI = pred_begin(OpBlock),
- E = pred_end(OpBlock); PI != E; ++PI) {
- if (*PI != II->getParent() && !DT->dominates(OpBlock, *PI)) {
- Bad = true;
- break;
- }
+ for (pred_iterator PI = pred_begin(NormalDest),
+ E = pred_end(NormalDest); PI != E; ++PI)
+ if (*PI != II->getParent() && !DT->dominates(NormalDest, *PI) &&
+ DT->isReachableFromEntry(*PI)) {
+ CheckFailed("Invoke result does not dominate all uses!", Op,&I);
+ return;
}
- }
- Assert2(!Bad,
- "Invoke value defined on critical edge but not dead!", &I,
- Op);
- }
- } else if (OpBlock == BB) {
+ }
+ } else if (isa<PHINode>(I)) {
+ // PHI nodes are more difficult than other nodes because they actually
+ // "use" the value in the predecessor basic blocks they correspond to.
+ BasicBlock *PredBB = cast<BasicBlock>(I.getOperand(i+1));
+ Assert2(DT->dominates(OpBlock, PredBB) ||
+ !DT->isReachableFromEntry(PredBB),
+ "Instruction does not dominate all uses!", Op, &I);
+ } else {
+ if (OpBlock == BB) {
// If they are in the same basic block, make sure that the definition
// comes before the use.
- Assert2(InstsInThisBlock.count(Op) ||
- !DT->dominates(&BB->getParent()->getEntryBlock(), BB),
+ Assert2(InstsInThisBlock.count(Op) || !DT->isReachableFromEntry(BB),
"Instruction does not dominate all uses!", Op, &I);
}
// Definition must dominate use unless use is unreachable!
Assert2(InstsInThisBlock.count(Op) || DT->dominates(Op, &I) ||
- !DT->dominates(&BB->getParent()->getEntryBlock(), BB),
- "Instruction does not dominate all uses!", Op, &I);
- } else {
- // PHI nodes are more difficult than other nodes because they actually
- // "use" the value in the predecessor basic blocks they correspond to.
- BasicBlock *PredBB = cast<BasicBlock>(I.getOperand(i+1));
- Assert2(DT->dominates(OpBlock, PredBB) ||
- !DT->dominates(&BB->getParent()->getEntryBlock(), PredBB),
+ !DT->isReachableFromEntry(BB),
"Instruction does not dominate all uses!", Op, &I);
}
} else if (isa<InlineAsm>(I.getOperand(i))) {
Added: llvm/trunk/test/Verifier/2009-05-29-InvokeResult1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/2009-05-29-InvokeResult1.ll?rev=72586&view=auto
==============================================================================
--- llvm/trunk/test/Verifier/2009-05-29-InvokeResult1.ll (added)
+++ llvm/trunk/test/Verifier/2009-05-29-InvokeResult1.ll Fri May 29 14:39:36 2009
@@ -0,0 +1,15 @@
+; RUN: not llvm-as < %s >& /dev/null
+
+declare i32 @v()
+
+define i32 @f() {
+e:
+ %r = invoke i32 @v()
+ to label %c unwind label %u ; <i32> [#uses=2]
+
+c: ; preds = %e
+ ret i32 %r
+
+u: ; preds = %e
+ ret i32 %r
+}
Added: llvm/trunk/test/Verifier/2009-05-29-InvokeResult2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/2009-05-29-InvokeResult2.ll?rev=72586&view=auto
==============================================================================
--- llvm/trunk/test/Verifier/2009-05-29-InvokeResult2.ll (added)
+++ llvm/trunk/test/Verifier/2009-05-29-InvokeResult2.ll Fri May 29 14:39:36 2009
@@ -0,0 +1,16 @@
+; RUN: not llvm-as < %s >& /dev/null
+
+declare i32 @v()
+
+define i32 @g() {
+e:
+ %s = invoke i32 @v()
+ to label %c unwind label %u ; <i32> [#uses=2]
+
+c: ; preds = %e
+ ret i32 %s
+
+u: ; preds = %e
+ %t = phi i32 [ %s, %e ] ; <i32> [#uses=1]
+ ret i32 %t
+}
Added: llvm/trunk/test/Verifier/2009-05-29-InvokeResult3.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/2009-05-29-InvokeResult3.ll?rev=72586&view=auto
==============================================================================
--- llvm/trunk/test/Verifier/2009-05-29-InvokeResult3.ll (added)
+++ llvm/trunk/test/Verifier/2009-05-29-InvokeResult3.ll Fri May 29 14:39:36 2009
@@ -0,0 +1,19 @@
+; RUN: not llvm-as < %s >& /dev/null
+
+declare i32 @v()
+
+define i32 @h() {
+e:
+ %s = invoke i32 @v()
+ to label %c unwind label %u ; <i32> [#uses=2]
+
+c: ; preds = %e
+ br label %d
+
+d: ; preds = %u, %c
+ %p = phi i32 [ %s, %c ], [ %s, %u ] ; <i32> [#uses=1]
+ ret i32 %p
+
+u: ; preds = %e
+ br label %d
+}
More information about the llvm-commits
mailing list