[llvm] r372273 - [AArch64][GlobalISel] Support lowering musttail calls

Jessica Paquette via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 18 15:42:25 PDT 2019


Author: paquette
Date: Wed Sep 18 15:42:25 2019
New Revision: 372273

URL: http://llvm.org/viewvc/llvm-project?rev=372273&view=rev
Log:
[AArch64][GlobalISel] Support lowering musttail calls

Since we now lower most tail calls, it makes sense to support musttail.

Instead of always falling back to SelectionDAG, only fall back when a musttail
call was not able to be emitted as a tail call. Once we can handle most
incoming and outgoing arguments, we can change this to a `report_fatal_error`
like in ISelLowering.

Remove the assert that we don't have varargs and a musttail, and replace it
with a return false. Implementing this requires that we implement
`saveVarArgRegisters` from AArch64ISelLowering, which is an entirely different
patch.

Add GlobalISel lines to vararg-tallcall.ll to make sure that we produce correct
code. Right now we only fall back, but eventually this will be relevant.

Differential Revision: https://reviews.llvm.org/D67681

Modified:
    llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp
    llvm/trunk/test/CodeGen/AArch64/GlobalISel/call-translator-musttail.ll
    llvm/trunk/test/CodeGen/AArch64/GlobalISel/call-translator-tail-call.ll
    llvm/trunk/test/CodeGen/AArch64/vararg-tallcall.ll

Modified: llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp?rev=372273&r1=372272&r2=372273&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp Wed Sep 18 15:42:25 2019
@@ -596,6 +596,11 @@ bool AArch64CallLowering::isEligibleForT
     MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info,
     SmallVectorImpl<ArgInfo> &InArgs,
     SmallVectorImpl<ArgInfo> &OutArgs) const {
+
+  // Must pass all target-independent checks in order to tail call optimize.
+  if (!Info.IsTailCall)
+    return false;
+
   CallingConv::ID CalleeCC = Info.CallConv;
   MachineFunction &MF = MIRBuilder.getMF();
   const Function &CallerF = MF.getFunction();
@@ -675,8 +680,12 @@ bool AArch64CallLowering::isEligibleForT
   // Before we can musttail varargs, we need to forward parameters like in
   // r345641. Make sure that we don't enable musttail with varargs without
   // addressing that!
-  assert(!(Info.IsVarArg && Info.IsMustTailCall) &&
-         "musttail support for varargs not implemented yet!");
+  if (Info.IsVarArg && Info.IsMustTailCall) {
+    LLVM_DEBUG(
+        dbgs()
+        << "... Cannot handle vararg musttail functions yet.\n");
+    return false;
+  }
 
   // Verify that the incoming and outgoing arguments from the callee are
   // safe to tail call.
@@ -841,12 +850,6 @@ bool AArch64CallLowering::lowerCall(Mach
   auto &DL = F.getParent()->getDataLayout();
   const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
 
-  if (Info.IsMustTailCall) {
-    // TODO: Until we lower all tail calls, we should fall back on this.
-    LLVM_DEBUG(dbgs() << "Cannot lower musttail calls yet.\n");
-    return false;
-  }
-
   SmallVector<ArgInfo, 8> OutArgs;
   for (auto &OrigArg : Info.OrigArgs) {
     splitToValueTypes(OrigArg, OutArgs, DL, MRI, Info.CallConv);
@@ -860,8 +863,19 @@ bool AArch64CallLowering::lowerCall(Mach
     splitToValueTypes(Info.OrigRet, InArgs, DL, MRI, F.getCallingConv());
 
   // If we can lower as a tail call, do that instead.
-  if (Info.IsTailCall &&
-      isEligibleForTailCallOptimization(MIRBuilder, Info, InArgs, OutArgs))
+  bool CanTailCallOpt =
+      isEligibleForTailCallOptimization(MIRBuilder, Info, InArgs, OutArgs);
+
+  // We must emit a tail call if we have musttail.
+  if (Info.IsMustTailCall && !CanTailCallOpt) {
+    // There are types of incoming/outgoing arguments we can't handle yet, so
+    // it doesn't make sense to actually die here like in ISelLowering. Instead,
+    // fall back to SelectionDAG and let it try to handle this.
+    LLVM_DEBUG(dbgs() << "Failed to lower musttail call as tail call\n");
+    return false;
+  }
+
+  if (CanTailCallOpt)
     return lowerTailCall(MIRBuilder, Info, OutArgs);
 
   // Find out which ABI gets to decide where things go.

Modified: llvm/trunk/test/CodeGen/AArch64/GlobalISel/call-translator-musttail.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/call-translator-musttail.ll?rev=372273&r1=372272&r2=372273&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/call-translator-musttail.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/call-translator-musttail.ll Wed Sep 18 15:42:25 2019
@@ -1,10 +1,13 @@
-; RUN: not llc %s -mtriple aarch64-unknown-unknown -debug-only=aarch64-call-lowering -global-isel -o - 2>&1 | FileCheck %s
+; RUN: not llc %s -mtriple aarch64-apple-darwin -debug-only=aarch64-call-lowering -global-isel -global-isel-abort=2 -o - 2>&1 | FileCheck %s
 ; REQUIRES: asserts
 
-; CHECK: Cannot lower musttail calls yet.
-; CHECK-NEXT: LLVM ERROR: unable to translate instruction: call (in function: foo)
-declare void @must_callee(i8*)
-define void @foo(i32*) {
-  musttail call void @must_callee(i8* null)
+; Verify that we fall back to SelectionDAG, and error out when we can't tail call musttail functions
+; CHECK: ... Cannot tail call externally-defined function with weak linkage for this OS.
+; CHECK-NEXT: Failed to lower musttail call as tail call
+; CHECK-NEXT: warning: Instruction selection used fallback path for caller_weak
+; CHECK-NEXT: LLVM ERROR: failed to perform tail call elimination on a call site marked musttail
+declare extern_weak void @callee_weak()
+define void @caller_weak() {
+  musttail call void @callee_weak()
   ret void
 }

Modified: llvm/trunk/test/CodeGen/AArch64/GlobalISel/call-translator-tail-call.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/call-translator-tail-call.ll?rev=372273&r1=372272&r2=372273&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/call-translator-tail-call.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/call-translator-tail-call.ll Wed Sep 18 15:42:25 2019
@@ -224,3 +224,18 @@ define hidden swiftcc i64 @swiftself_ind
   %tmp2 = tail call swiftcc i64 %tmp1(i64* swiftself %arg)
   ret i64 %tmp2
 }
+
+; Verify that we can tail call musttail callees.
+declare void @must_callee(i8*)
+define void @foo(i32*) {
+  ; COMMON-LABEL: name: foo
+  ; COMMON: bb.1 (%ir-block.1):
+  ; COMMON:   liveins: $x0
+  ; COMMON:   [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+  ; COMMON:   [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+  ; COMMON:   [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[C]](s64)
+  ; COMMON:   $x0 = COPY [[INTTOPTR]](p0)
+  ; COMMON:   TCRETURNdi @must_callee, 0, csr_aarch64_aapcs, implicit $sp, implicit $x0
+  musttail call void @must_callee(i8* null)
+  ret void
+}

Modified: llvm/trunk/test/CodeGen/AArch64/vararg-tallcall.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/vararg-tallcall.ll?rev=372273&r1=372272&r2=372273&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/vararg-tallcall.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/vararg-tallcall.ll Wed Sep 18 15:42:25 2019
@@ -1,5 +1,7 @@
 ; RUN: llc -mtriple=aarch64-windows-msvc %s -o - | FileCheck %s
 ; RUN: llc -mtriple=aarch64-linux-gnu %s -o - | FileCheck %s
+; RUN: llc -global-isel -global-isel-abort=2 -verify-machineinstrs -mtriple=aarch64-windows-msvc %s -o - | FileCheck %s
+; RUN: llc -global-isel -global-isel-abort=2 -verify-machineinstrs -mtriple=aarch64-linux-gnu %s -o - | FileCheck %s
 
 target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128"
 




More information about the llvm-commits mailing list