[llvm] r321402 - [SCCP] Manually fold branches on undef.

Davide Italiano via llvm-commits llvm-commits at lists.llvm.org
Sat Dec 23 07:06:30 PST 2017


Author: davide
Date: Sat Dec 23 07:06:30 2017
New Revision: 321402

URL: http://llvm.org/viewvc/llvm-project?rev=321402&view=rev
Log:
[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.

Modified:
    llvm/trunk/lib/Transforms/Scalar/SCCP.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=321402&r1=321401&r2=321402&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Sat Dec 23 07:06:30 2017
@@ -1929,9 +1929,32 @@ static bool runIPSCCP(Module &M, const D
         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.




More information about the llvm-commits mailing list