diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index d5c98fc4955..07e70099769 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -1313,15 +1313,30 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) { continue; } - // If the edge to the first successor isn't thought to be feasible yet, mark - // it so now. - if (KnownFeasibleEdges.count(Edge(BB, TI->getSuccessor(0)))) + // If the edge to the second successor isn't thought to be feasible yet, + // mark it so now. We pick the second one so that this goes to some + // enumerated value in a switch instead of going to the default destination. + if (KnownFeasibleEdges.count(Edge(BB, TI->getSuccessor(1)))) continue; // Otherwise, it isn't already thought to be feasible. Mark it as such now // and return. This will make other blocks reachable, which will allow new // values to be discovered and existing ones to be moved in the lattice. - markEdgeExecutable(BB, TI->getSuccessor(0)); + markEdgeExecutable(BB, TI->getSuccessor(1)); + + // This must be a conditional branch of switch on undef. At this point, + // force the old terminator to branch to the first successor. This is + // required because we are now influencing the dataflow of the function with + // the assumption that this edge is taken. If we leave the branch condition + // as undef, then further analysis could think the undef went another way + // leading to an inconsistent set of conclusions. + if (BranchInst *BI = dyn_cast(TI)) { + BI->setCondition(ConstantInt::getFalse()); + } else { + SwitchInst *SI = cast(TI); + SI->setCondition(SI->getCaseValue(1)); + } + return true; } diff --git a/test/Transforms/SCCP/2008-01-27-UndefCorrelate.ll b/test/Transforms/SCCP/2008-01-27-UndefCorrelate.ll new file mode 100644 index 00000000000..18ab5e8cdc5 --- /dev/null +++ b/test/Transforms/SCCP/2008-01-27-UndefCorrelate.ll @@ -0,0 +1,36 @@ +; RUN: llvm-as < %s | opt -sccp | llvm-dis | grep undef | count 1 +; PR1938 + +define i32 @main() { +entry: + br label %bb + +bb: + %indvar = phi i32 [ 0, %entry ], [ %k, %bb.backedge ] + %k = add i32 %indvar, 1 + br i1 undef, label %cond_true, label %cond_false + +cond_true: + %tmp97 = icmp slt i32 %k, 10 + br i1 %tmp97, label %bb.backedge, label %bb12 + +bb.backedge: + br label %bb + +cond_false: + %tmp9 = icmp slt i32 %k, 10 + br i1 %tmp9, label %bb.backedge, label %bb12 + +bb12: + %tmp14 = icmp eq i32 %k, 10 + br i1 %tmp14, label %cond_next18, label %cond_true17 + +cond_true17: + tail call void @abort( ) + unreachable + +cond_next18: + ret i32 0 +} + +declare void @abort()