diff options
author | Davide Italiano <davide@freebsd.org> | 2017-12-23 15:06:30 +0000 |
---|---|---|
committer | Davide Italiano <davide@freebsd.org> | 2017-12-23 15:06:30 +0000 |
commit | 55b663431eb024a008f0d4d3fe438d212cf8a168 (patch) | |
tree | 8ba3db38fbbd8012407801e90f423f2f053ea269 /llvm/lib/Transforms/Scalar/SCCP.cpp | |
parent | 730cbc8f8eb93f5d63dd0f67d8bf05511fbbfabf (diff) | |
download | bcm5719-llvm-55b663431eb024a008f0d4d3fe438d212cf8a168.tar.gz bcm5719-llvm-55b663431eb024a008f0d4d3fe438d212cf8a168.zip |
[SCCP] Manually fold branches on undef.
This code was originally removed and replace with an assertion
because believed unnecessary. It turns out there was simply
no test coverage for this case, and the constant folder doesn't
yet know about patterns like `br undef %label1, %label2`.
Presumably at some point the constant folder might learn about
these patterns, but it's a broader change.
A testcase will be added to make sure this doesn't regress again
in the future.
Fixes PR35723.
llvm-svn: 321402
Diffstat (limited to 'llvm/lib/Transforms/Scalar/SCCP.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/SCCP.cpp | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp index e5866b4718d..66608ec631f 100644 --- a/llvm/lib/Transforms/Scalar/SCCP.cpp +++ b/llvm/lib/Transforms/Scalar/SCCP.cpp @@ -1929,9 +1929,32 @@ static bool runIPSCCP(Module &M, const DataLayout &DL, if (!I) continue; bool Folded = ConstantFoldTerminator(I->getParent()); - assert(Folded && - "Expect TermInst on constantint or blockaddress to be folded"); - (void) Folded; + if (!Folded) { + // The constant folder may not have been able to fold the terminator + // if this is a branch or switch on undef. Fold it manually as a + // branch to the first successor. +#ifndef NDEBUG + if (auto *BI = dyn_cast<BranchInst>(I)) { + assert(BI->isConditional() && isa<UndefValue>(BI->getCondition()) && + "Branch should be foldable!"); + } else if (auto *SI = dyn_cast<SwitchInst>(I)) { + assert(isa<UndefValue>(SI->getCondition()) && "Switch should fold"); + } else { + llvm_unreachable("Didn't fold away reference to block!"); + } +#endif + + // Make this an uncond branch to the first successor. + TerminatorInst *TI = I->getParent()->getTerminator(); + BranchInst::Create(TI->getSuccessor(0), TI); + + // Remove entries in successor phi nodes to remove edges. + for (unsigned i = 1, e = TI->getNumSuccessors(); i != e; ++i) + TI->getSuccessor(i)->removePredecessor(TI->getParent()); + + // Remove the old terminator. + TI->eraseFromParent(); + } } // Finally, delete the basic block. |