summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCISelLowering.cpp')
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelLowering.cpp11
1 files changed, 10 insertions, 1 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index f895b06ac68..09887c3e4d1 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -4695,7 +4695,9 @@ PPCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
ImmutableCallSite *CS = CLI.CS;
if (isTailCall) {
- if (Subtarget.isSVR4ABI() && Subtarget.isPPC64())
+ if (Subtarget.useLongCalls() && !(CS && CS->isMustTailCall()))
+ isTailCall = false;
+ else if (Subtarget.isSVR4ABI() && Subtarget.isPPC64())
isTailCall =
IsEligibleForTailCallOptimization_64SVR4(Callee, CallConv, CS,
isVarArg, Outs, Ins, DAG);
@@ -4725,6 +4727,13 @@ PPCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
report_fatal_error("failed to perform tail call elimination on a call "
"site marked musttail");
+ // When long calls (i.e. indirect calls) are always used, calls are always
+ // made via function pointer. If we have a function name, first translate it
+ // into a pointer.
+ if (Subtarget.useLongCalls() && isa<GlobalAddressSDNode>(Callee) &&
+ !isTailCall)
+ Callee = LowerGlobalAddress(Callee, DAG);
+
if (Subtarget.isSVR4ABI()) {
if (Subtarget.isPPC64())
return LowerCall_64SVR4(Chain, Callee, CallConv, isVarArg,
OpenPOWER on IntegriCloud