diff options
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 26 | ||||
-rw-r--r-- | test/CodeGen/X86/tailcall2.ll | 24 |
2 files changed, 44 insertions, 6 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index c0ebade2dc..e27d93cf7c 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -2252,10 +2252,26 @@ X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Callee, // If -tailcallopt is specified, make fastcc functions tail-callable. const Function *CallerF = DAG.getMachineFunction().getFunction(); - if (PerformTailCallOpt && - CalleeCC == CallingConv::Fast && - CallerF->getCallingConv() == CalleeCC) - return true; + if (PerformTailCallOpt) { + if (CalleeCC == CallingConv::Fast && + CallerF->getCallingConv() == CalleeCC) + return true; + return false; + } + + // Do not tail call optimize vararg calls for now. + if (isVarArg) + return false; + + // Don't tail call optimize recursive call. + GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee); + const Function *CalleeF = G ? cast<Function>(G->getGlobal()) : 0; + if (CallerF == CalleeF) + return false; + // If it's an indirect call, conversatively return false if the caller's + // address is taken. + if (!isa<ExternalSymbolSDNode>(Callee) && CallerF->hasAddressTaken()) + return false; // Look for obvious safe cases to perform tail call optimization. // If the callee takes no arguments then go on to check the results of the @@ -2279,9 +2295,7 @@ X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Callee, return true; // If the return types match, then it's safe. - GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee); if (!G) return false; // FIXME: common external symbols? - Function *CalleeF = cast<Function>(G->getGlobal()); const Type *CalleeRetTy = CalleeF->getReturnType(); return CallerRetTy == CalleeRetTy; } diff --git a/test/CodeGen/X86/tailcall2.ll b/test/CodeGen/X86/tailcall2.ll index 6b0916fc67..e78e213d64 100644 --- a/test/CodeGen/X86/tailcall2.ll +++ b/test/CodeGen/X86/tailcall2.ll @@ -65,3 +65,27 @@ entry: tail call void %x() nounwind ret void } + +define i32 @t6(i32 %x) nounwind ssp { +entry: +; 32: t6: +; 32: call {{_?}}t6 +; 32: call {{_?}}bar + +; 64: t6: +; 64: callq {{_?}}t6 +; 64: jmp {{_?}}bar + %0 = icmp slt i32 %x, 10 + br i1 %0, label %bb, label %bb1 + +bb: + %1 = add nsw i32 %x, -1 + %2 = tail call i32 @t6(i32 %1) nounwind ssp + ret i32 %2 + +bb1: + %3 = tail call i32 @bar(i32 %x) nounwind + ret i32 %3 +} + +declare i32 @bar(i32) |