Index: lib/Transforms/Scalar/SCCP.cpp =================================================================== --- lib/Transforms/Scalar/SCCP.cpp +++ lib/Transforms/Scalar/SCCP.cpp @@ -1587,11 +1587,16 @@ } // Otherwise, it is a branch on a symbolic value which is currently - // considered to be undef. Handle this by forcing the input value to the - // branch to false. - markForcedConstant(BI->getCondition(), - ConstantInt::getFalse(TI->getContext())); - return true; + // considered to be undef. Make sure some edge is executable, so a + // branch on "undef" always flows somewhere. + // FIXME: Distinguish between dead code and an LLVM "undef" value. + BasicBlock *DefaultSuccessor = TI->getSuccessor(1); + if (!KnownFeasibleEdges.count({&BB, DefaultSuccessor})) { + markEdgeExecutable(&BB, DefaultSuccessor); + return true; + } + + continue; } if (auto *IBR = dyn_cast(TI)) { @@ -1612,11 +1617,17 @@ } // Otherwise, it is a branch on a symbolic value which is currently - // considered to be undef. Handle this by forcing the input value to the - // branch to the first successor. - markForcedConstant(IBR->getAddress(), - BlockAddress::get(IBR->getSuccessor(0))); - return true; + // considered to be undef. Make sure some edge is executable, so a + // branch on "undef" always flows somewhere. + // FIXME: IndirectBr on "undef" doesn't actually need to go anywhere: + // we can assume the branch has undefined behavior instead. + BasicBlock *DefaultSuccessor = IBR->getSuccessor(0); + if (!KnownFeasibleEdges.count({&BB, DefaultSuccessor})) { + markEdgeExecutable(&BB, DefaultSuccessor); + return true; + } + + continue; } if (auto *SI = dyn_cast(TI)) { @@ -1631,8 +1642,17 @@ return true; } - markForcedConstant(SI->getCondition(), SI->case_begin()->getCaseValue()); - return true; + // Otherwise, it is a branch on a symbolic value which is currently + // considered to be undef. Make sure some edge is executable, so a + // branch on "undef" always flows somewhere. + // FIXME: Distinguish between dead code and an LLVM "undef" value. + BasicBlock *DefaultSuccessor = SI->case_begin()->getCaseSuccessor(); + if (!KnownFeasibleEdges.count({&BB, DefaultSuccessor})) { + markEdgeExecutable(&BB, DefaultSuccessor); + return true; + } + + continue; } } @@ -1958,6 +1978,23 @@ if (!I) continue; bool Folded = ConstantFoldTerminator(I->getParent()); + if (!Folded) { + // If the branch can't be folded, we must have forced an edge + // for an indeterminate value. Force the terminator to fold + // to that edge. + Constant *C; + if (SwitchInst *SI = dyn_cast(I)) + C = SI->case_begin()->getCaseValue(); + else if (BranchInst *BI = dyn_cast(I)) + C = ConstantInt::getFalse(BI->getContext()); + else if (IndirectBrInst *IBR = dyn_cast(I)) + C = BlockAddress::get(IBR->getSuccessor(0)); + else + llvm_unreachable("Unexpected terminator instruction"); + + I->setOperand(0, C); + Folded = ConstantFoldTerminator(I->getParent()); + } assert(Folded && "Expect TermInst on constantint or blockaddress to be folded"); (void) Folded; Index: test/Transforms/SCCP/ipsccp-phi-one-pred-dead.ll =================================================================== --- test/Transforms/SCCP/ipsccp-phi-one-pred-dead.ll +++ test/Transforms/SCCP/ipsccp-phi-one-pred-dead.ll @@ -7,11 +7,13 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: br label %Flow5.pre ; CHECK: Flow6: -; CHECK-NEXT: br label %end2 +; CHECK-NEXT: br i1 undef, label %end1, label %end2 ; CHECK: Flow5.pre: ; CHECK-NEXT: br label %Flow5 ; CHECK: Flow5: ; CHECK-NEXT: br label %Flow6 +; CHECK: end1: +; CHECK-NEXT: unreachable ; CHECK: end2: ; CHECK-NEXT: unreachable ;