diff options
-rw-r--r-- | lib/Transforms/Scalar/CorrelatedValuePropagation.cpp | 5 | ||||
-rw-r--r-- | test/Transforms/CorrelatedValuePropagation/crash.ll | 25 |
2 files changed, 30 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp index 9b0aadb..3ec6f3d 100644 --- a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -235,6 +235,11 @@ bool CorrelatedValuePropagation::processSwitch(SwitchInst *SI) { // This case never fires - remove it. CI.getCaseSuccessor()->removePredecessor(BB); SI->removeCase(CI); // Does not invalidate the iterator. + + // The condition can be modified by removePredecessor's PHI simplification + // logic. + Cond = SI->getCondition(); + ++NumDeadCases; Changed = true; } else if (State == LazyValueInfo::True) { diff --git a/test/Transforms/CorrelatedValuePropagation/crash.ll b/test/Transforms/CorrelatedValuePropagation/crash.ll index 80c43d0..9723d18 100644 --- a/test/Transforms/CorrelatedValuePropagation/crash.ll +++ b/test/Transforms/CorrelatedValuePropagation/crash.ll @@ -35,3 +35,28 @@ srf.exit.i: func_29.exit: ret void } + +; PR13972 +define void @test3() nounwind { +for.body: + br label %return + +for.cond.i: ; preds = %if.else.i, %for.body.i + %e.2.i = phi i32 [ %e.2.i, %if.else.i ], [ -8, %for.body.i ] + br i1 undef, label %return, label %for.body.i + +for.body.i: ; preds = %for.cond.i + switch i32 %e.2.i, label %for.cond3.i [ + i32 -3, label %if.else.i + i32 0, label %for.cond.i + ] + +for.cond3.i: ; preds = %for.cond3.i, %for.body.i + br label %for.cond3.i + +if.else.i: ; preds = %for.body.i + br label %for.cond.i + +return: ; preds = %for.cond.i, %for.body + ret void +} |