[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