summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/SCCP.cpp
diff options
context:
space:
mode:
authorDavide Italiano <davide@freebsd.org>2017-12-23 15:06:30 +0000
committerDavide Italiano <davide@freebsd.org>2017-12-23 15:06:30 +0000
commit55b663431eb024a008f0d4d3fe438d212cf8a168 (patch)
tree8ba3db38fbbd8012407801e90f423f2f053ea269 /llvm/lib/Transforms/Scalar/SCCP.cpp
parent730cbc8f8eb93f5d63dd0f67d8bf05511fbbfabf (diff)
downloadbcm5719-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.cpp29
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.
OpenPOWER on IntegriCloud