diff options
-rw-r--r-- | lib/Transforms/Utils/SimplifyCFG.cpp | 4 | ||||
-rw-r--r-- | test/Transforms/SimplifyCFG/2011-03-08-UnreachableUse.ll | 31 |
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 +} |