diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 9 | ||||
-rw-r--r-- | lib/Transforms/Scalar/TailRecursionElimination.cpp | 9 |
2 files changed, 11 insertions, 7 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 495418d999..3a25714f07 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -4205,8 +4205,13 @@ isInTailCallPosition(CallSite CS, Attributes CalleeRetAttr, const ReturnInst *Ret = dyn_cast<ReturnInst>(Term); const Function *F = ExitBB->getParent(); - // The block must end in a return statement or an unreachable. - if (!Ret && !isa<UnreachableInst>(Term)) return false; + // The block must end in a return statement. + // FIXME: Disallow tailcall if the block ends in an unreachable for now. + // The way tailcall optimization is currently implemented means it will + // add an epilogue followed by a jump. That is not profitable. Also, if + // the callee is a special function (e.g. longjmp on x86), it can end up + // causing miscompilation that has not been fully understood. + if (!Ret) return false; // Unless we are explicitly forcing tailcall optimization do not tailcall if // the called function is bitcast'ed. The analysis may not be entirely diff --git a/lib/Transforms/Scalar/TailRecursionElimination.cpp b/lib/Transforms/Scalar/TailRecursionElimination.cpp index 913dd73cc1..162d902cfa 100644 --- a/lib/Transforms/Scalar/TailRecursionElimination.cpp +++ b/lib/Transforms/Scalar/TailRecursionElimination.cpp @@ -184,11 +184,10 @@ bool TailCallElim::runOnFunction(Function &F) { if (!FunctionContainsEscapingAllocas) for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) - if (CallInst *CI = dyn_cast<CallInst>(I)) - if (!CI->doesNotReturn()) { - CI->setTailCall(); - MadeChange = true; - } + if (CallInst *CI = dyn_cast<CallInst>(I)) { + CI->setTailCall(); + MadeChange = true; + } return MadeChange; } |