Sink the collection of return instructions until after *all*
authorChandler Carruth <chandlerc@gmail.com>
Fri, 6 Apr 2012 17:21:31 +0000 (17:21 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Fri, 6 Apr 2012 17:21:31 +0000 (17:21 +0000)
simplification has been performed. This is a bit less efficient
(requires another ilist walk of the basic blocks) but shouldn't matter
in practice. More importantly, it's just too much work to keep track of
all the various ways the return instructions can be mutated while
simplifying them. This fixes yet another crasher, reported by Daniel
Dunbar.

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

lib/Transforms/Utils/CloneFunction.cpp
test/Transforms/Inline/inline_cleanup.ll

index 423f47d22bf067503f65639e34eb3de69c162e2a..20052a412277979dd62220c74a209e3824009a68 100644 (file)
@@ -532,13 +532,6 @@ void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
     // and we still want to prune the dead code as early as possible.
     ConstantFoldTerminator(I);
 
-    // Track all of the newly-inserted returns.
-    if (ReturnInst *RI = dyn_cast<ReturnInst>(I->getTerminator())) {
-      Returns.push_back(RI);
-      ++I;
-      continue;
-    }
-
     BranchInst *BI = dyn_cast<BranchInst>(I->getTerminator());
     if (!BI || BI->isConditional()) { ++I; continue; }
     
@@ -566,4 +559,13 @@ void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
     
     // Do not increment I, iteratively merge all things this block branches to.
   }
+
+  // Make a final pass over the basic blocks from theh old function to gather
+  // any return instructions which survived folding. We have to do this here
+  // because we can iteratively remove and merge returns above.
+  for (Function::iterator I = cast<BasicBlock>(VMap[&OldFunc->getEntryBlock()]),
+                          E = NewFunc->end();
+       I != E; ++I)
+    if (ReturnInst *RI = dyn_cast<ReturnInst>(I->getTerminator()))
+      Returns.push_back(RI);
 }
index ee73b0e30305f537e21928fe226e61a25f8a09c4..3898aa7044ac0a0e85406c435cccc10448d47a6f 100644 (file)
@@ -174,3 +174,40 @@ entry:
   call void @PR12470_inner(i16 signext 1)
   ret void
 }
+
+define void @crasher_inner() nounwind uwtable {
+entry:
+  br i1 false, label %for.end28, label %for.body6
+
+for.body6:
+  br i1 undef, label %for.body6, label %for.cond12.for.inc26_crit_edge
+
+for.cond12.for.inc26_crit_edge:
+  br label %for.body6.1
+
+for.end28:
+  ret void
+
+for.body6.1:
+  br i1 undef, label %for.body6.1, label %for.cond12.for.inc26_crit_edge.1
+
+for.cond12.for.inc26_crit_edge.1:
+  br label %for.body6.2
+
+for.body6.2:
+  br i1 undef, label %for.body6.2, label %for.cond12.for.inc26_crit_edge.2
+
+for.cond12.for.inc26_crit_edge.2:
+  br label %for.end28
+}
+
+define void @crasher_outer() {
+; CHECK: @crasher_outer
+; CHECK-NOT: call
+; CHECK: ret void
+; CHECK-NOT: ret
+; CHECK: }
+entry:
+  tail call void @crasher_inner()
+  ret void
+}