TRE: Just erase dead BBs and tweak the iteration loop not to increment the deleted...
authorBenjamin Kramer <benny.kra@googlemail.com>
Sat, 28 Feb 2015 16:47:27 +0000 (16:47 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Sat, 28 Feb 2015 16:47:27 +0000 (16:47 +0000)
Leaving empty blocks around just opens up a can of bugs like PR22704. Deleting
them early also slightly simplifies code.

Thanks to Sanjay for the IR test case.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@230856 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/TailRecursionElimination.cpp
test/Transforms/TailCallElim/inf-recursion.ll

index 92d94876304c59ff81abd46494ce0de2b8c524e4..79a96b512bfd1b2d11f0876aaa449a8146150ba4 100644 (file)
@@ -403,28 +403,19 @@ bool TailCallElim::runTRE(Function &F) {
   // alloca' is changed from being a static alloca to being a dynamic alloca.
   // Until this is resolved, disable this transformation if that would ever
   // happen.  This bug is PR962.
-  SmallVector<BasicBlock*, 8> BBToErase;
-  for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
+  for (Function::iterator BBI = F.begin(), E = F.end(); BBI != E; /*in loop*/) {
+    BasicBlock *BB = BBI++; // FoldReturnAndProcessPred may delete BB.
     if (ReturnInst *Ret = dyn_cast<ReturnInst>(BB->getTerminator())) {
       bool Change = ProcessReturningBlock(Ret, OldEntry, TailCallsAreMarkedTail,
                                           ArgumentPHIs, !CanTRETailMarkedCall);
-      if (!Change && BB->getFirstNonPHIOrDbg() == Ret) {
+      if (!Change && BB->getFirstNonPHIOrDbg() == Ret)
         Change = FoldReturnAndProcessPred(BB, Ret, OldEntry,
                                           TailCallsAreMarkedTail, ArgumentPHIs,
                                           !CanTRETailMarkedCall);
-        // FoldReturnAndProcessPred may have emptied some BB. Remember to
-        // erase them.
-        if (Change && BB->empty())
-          BBToErase.push_back(BB);
-
-      }
       MadeChange |= Change;
     }
   }
 
-  for (auto BB: BBToErase)
-    BB->eraseFromParent();
-
   // If we eliminated any tail recursions, it's possible that we inserted some
   // silly PHI nodes which just merge an initial value (the incoming operand)
   // with themselves.  Check to see if we did and clean up our mess if so.  This
@@ -831,14 +822,11 @@ bool TailCallElim::FoldReturnAndProcessPred(BasicBlock *BB,
       ReturnInst *RI = FoldReturnIntoUncondBranch(Ret, BB, Pred);
 
       // Cleanup: if all predecessors of BB have been eliminated by
-      // FoldReturnIntoUncondBranch, we would like to delete it, but we
-      // can not just nuke it as it is being used as an iterator by our caller.
-      // Just empty it, and the caller will erase it when it is safe to do so.
-      // It is important to empty it, because the ret instruction in there is
-      // still using a value which EliminateRecursiveTailCall will attempt
-      // to remove.
+      // FoldReturnIntoUncondBranch, delete it.  It is important to empty it,
+      // because the ret instruction in there is still using a value which
+      // EliminateRecursiveTailCall will attempt to remove.
       if (!BB->hasAddressTaken() && pred_begin(BB) == pred_end(BB))
-        BB->getInstList().clear();
+        BB->eraseFromParent();
 
       EliminateRecursiveTailCall(CI, RI, OldEntry, TailCallsAreMarkedTail,
                                  ArgumentPHIs,
index 157226f93d3f62857561800bca71b353849d39a2..c121c25aee98dfbf2d9e13b087c04e2a70879942 100644 (file)
@@ -31,3 +31,24 @@ define float @fabsf(float %f) {
 }
 
 declare x86_fp80 @fabsl(x86_fp80 %f)
+
+; Don't crash while transforming a function with infinite recursion.
+define i32 @PR22704(i1 %bool) {
+entry:
+  br i1 %bool, label %t, label %f
+
+t:
+  %call1 = call i32 @PR22704(i1 1)
+  br label %return
+
+f:
+  %call = call i32 @PR22704(i1 1)
+  br label %return
+
+return:
+  ret i32 0
+
+; CHECK-LABEL: @PR22704(
+; CHECK:       %bool.tr = phi i1 [ %bool, %entry ], [ true, %t ], [ true, %f ]
+; CHECK:       br i1 %bool.tr, label %t, label %f
+}