Fix PR2029
authorChris Lattner <sabre@nondot.org>
Thu, 14 Feb 2008 19:18:13 +0000 (19:18 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 14 Feb 2008 19:18:13 +0000 (19:18 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47129 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Utils/LowerInvoke.cpp
test/Transforms/LowerInvoke/2008-02-14-CritEdgePhiCrash.ll [new file with mode: 0644]

index 39738a09ba70556f85610c471b351a8ab3d957ca..920a0286ead2f6dd5ff5b694368ec50261410aa7 100644 (file)
@@ -256,6 +256,17 @@ void LowerInvoke::rewriteExpensiveInvoke(InvokeInst *II, unsigned InvokeNo,
                                          SwitchInst *CatchSwitch) {
   ConstantInt *InvokeNoC = ConstantInt::get(Type::Int32Ty, InvokeNo);
 
+  // If the unwind edge has phi nodes, split the edge.
+  if (isa<PHINode>(II->getUnwindDest()->begin())) {
+    SplitCriticalEdge(II, 1, this);
+   
+    // If there are any phi nodes left, they must have a single predecessor.
+    while (PHINode *PN = dyn_cast<PHINode>(II->getUnwindDest()->begin())) {
+      PN->replaceAllUsesWith(PN->getIncomingValue(0));
+      PN->eraseFromParent();
+    }
+  }
+  
   // Insert a store of the invoke num before the invoke and store zero into the
   // location afterward.
   new StoreInst(InvokeNoC, InvokeNum, true, II);  // volatile
diff --git a/test/Transforms/LowerInvoke/2008-02-14-CritEdgePhiCrash.ll b/test/Transforms/LowerInvoke/2008-02-14-CritEdgePhiCrash.ll
new file mode 100644 (file)
index 0000000..fa82539
--- /dev/null
@@ -0,0 +1,14 @@
+; RUN: llvm-as < %s | opt -lowerinvoke -enable-correct-eh-support -disable-output
+; PR2029
+define i32 @main(i32 %argc, i8** %argv) {
+bb470:
+        invoke i32 @main(i32 0, i8** null) to label %invcont474 unwind label
+%lpad902
+
+invcont474:             ; preds = %bb470
+        ret i32 0
+
+lpad902:                ; preds = %bb470
+        %tmp471.lcssa = phi i8* [ null, %bb470 ]                ; <i8*>
+        ret i32 0
+}