diff options
author | Dan Gohman <gohman@apple.com> | 2010-02-08 20:34:14 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2010-02-08 20:34:14 +0000 |
commit | c2e93b255e120f066ad8c16b0593b05f7e9f3d19 (patch) | |
tree | f41aee4ef660f15060d337608f1a26849f39aec0 | |
parent | 1797ed50f488f2030f9f9a0ac7426262abf5220a (diff) | |
download | external_llvm-c2e93b255e120f066ad8c16b0593b05f7e9f3d19.zip external_llvm-c2e93b255e120f066ad8c16b0593b05f7e9f3d19.tar.gz external_llvm-c2e93b255e120f066ad8c16b0593b05f7e9f3d19.tar.bz2 |
In guaranteed tailcall mode, don't decline the tailcall optimization
for blocks ending in "unreachable".
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95565 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 17 | ||||
-rw-r--r-- | test/CodeGen/X86/tailcall1.ll | 5 |
2 files changed, 14 insertions, 8 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index cf342c7..93ae043 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -4205,13 +4205,16 @@ 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. - // 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; + // The block must end in a return statement or unreachable. + // + // FIXME: Decline tailcall if it's not guaranteed and 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 && + (!GuaranteedTailCallOpt || !isa<UnreachableInst>(Term))) return false; // If I will have a chain, make sure no other instruction that will have a // chain interposes between I and the return. diff --git a/test/CodeGen/X86/tailcall1.ll b/test/CodeGen/X86/tailcall1.ll index d08919e..f7ff5d5 100644 --- a/test/CodeGen/X86/tailcall1.ll +++ b/test/CodeGen/X86/tailcall1.ll @@ -1,4 +1,7 @@ -; RUN: llc < %s -march=x86 -tailcallopt | grep TAILCALL | count 4 +; RUN: llc < %s -march=x86 -tailcallopt | grep TAILCALL | count 5 + +; With -tailcallopt, CodeGen guarantees a tail call optimization +; for all of these. declare fastcc i32 @tailcallee(i32 %a1, i32 %a2, i32 %a3, i32 %a4) |