aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/Transforms/Utils/SimplifyCFG.cpp4
-rw-r--r--test/Transforms/SimplifyCFG/2011-03-08-UnreachableUse.ll31
2 files changed, 34 insertions, 1 deletions
diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp
index 72fa468db6..09f4fb2e13 100644
--- a/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -2168,7 +2168,9 @@ bool SimplifyCFGOpt::SimplifyUnreachable(UnreachableInst *UI) {
if (LI->isVolatile())
break;
- // Delete this instruction
+ // Delete this instruction (any uses are guaranteed to be dead)
+ if (!BBI->use_empty())
+ BBI->replaceAllUsesWith(UndefValue::get(BBI->getType()));
BBI->eraseFromParent();
Changed = true;
}
diff --git a/test/Transforms/SimplifyCFG/2011-03-08-UnreachableUse.ll b/test/Transforms/SimplifyCFG/2011-03-08-UnreachableUse.ll
new file mode 100644
index 0000000000..329774e224
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/2011-03-08-UnreachableUse.ll
@@ -0,0 +1,31 @@
+; RUN: opt < %s -simplifycfg -S | FileCheck %s
+; PR9420
+
+; Note that the crash in PR9420 test is sensitive to the ordering of
+; the transformations done by SimplifyCFG, so this test is likely to rot
+; quickly.
+
+define noalias i8* @func_29() nounwind {
+; CHECK: entry:
+; CHECK-NEXT: unreachable
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc38, %entry
+ %p_34.addr.0 = phi i16 [ 1, %entry ], [ %conv40, %for.inc38 ]
+ br label %for.cond1
+
+for.cond1: ; preds = %for.inc29, %for.cond
+ %p_32.addr.0 = phi i1 [ true, %for.cond ], [ true, %for.inc29 ]
+ br i1 %p_32.addr.0, label %for.body8, label %for.inc38
+
+for.body8: ; preds = %for.cond1
+ unreachable
+
+for.inc29: ; preds = %for.cond17
+ br label %for.cond1
+
+for.inc38: ; preds = %for.end32
+ %conv40 = add i16 %p_34.addr.0, 1
+ br label %for.cond
+}