diff options
-rw-r--r-- | lib/Transforms/Utils/CloneFunction.cpp | 16 | ||||
-rw-r--r-- | test/Transforms/Inline/inline_cleanup.ll | 37 |
2 files changed, 46 insertions, 7 deletions
diff --git a/lib/Transforms/Utils/CloneFunction.cpp b/lib/Transforms/Utils/CloneFunction.cpp index 423f47d22b..20052a4122 100644 --- a/lib/Transforms/Utils/CloneFunction.cpp +++ b/lib/Transforms/Utils/CloneFunction.cpp @@ -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); } diff --git a/test/Transforms/Inline/inline_cleanup.ll b/test/Transforms/Inline/inline_cleanup.ll index ee73b0e303..3898aa7044 100644 --- a/test/Transforms/Inline/inline_cleanup.ll +++ b/test/Transforms/Inline/inline_cleanup.ll @@ -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 +} |