[llvm] r371868 - [AArch64][GlobalISel] Add support for sibcalling callees with varargs

Jessica Paquette via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 13 09:10:19 PDT 2019


Author: paquette
Date: Fri Sep 13 09:10:19 2019
New Revision: 371868

URL: http://llvm.org/viewvc/llvm-project?rev=371868&view=rev
Log:
[AArch64][GlobalISel] Add support for sibcalling callees with varargs

This adds support for tail calling callees with varargs, equivalent to how it
is done in AArch64ISelLowering.

This only works for sibling calls, and does not add the necessary support for
musttail with varargs. (See r345641 for equivalent ISelLowering support.) This
should be implemented when we stop falling back on musttail.

Update call-translator-tail-call.ll to show that we can now tail call varargs.

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

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

Modified: llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp?rev=371868&r1=371867&r2=371868&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp Fri Sep 13 09:10:19 2019
@@ -514,8 +514,20 @@ bool AArch64CallLowering::areCalleeOutgo
   for (unsigned i = 0; i < OutLocs.size(); ++i) {
     auto &ArgLoc = OutLocs[i];
     // If it's not a register, it's fine.
-    if (!ArgLoc.isRegLoc())
+    if (!ArgLoc.isRegLoc()) {
+      if (Info.IsVarArg) {
+        // Be conservative and disallow variadic memory operands to match SDAG's
+        // behaviour.
+        // FIXME: If the caller's calling convention is C, then we can
+        // potentially use its argument area. However, for cases like fastcc,
+        // we can't do anything.
+        LLVM_DEBUG(
+            dbgs()
+            << "... Cannot tail call vararg function with stack arguments\n");
+        return false;
+      }
       continue;
+    }
 
     Register Reg = ArgLoc.getLocReg();
 
@@ -583,11 +595,6 @@ bool AArch64CallLowering::isEligibleForT
     return false;
   }
 
-  if (Info.IsVarArg) {
-    LLVM_DEBUG(dbgs() << "... Tail calling varargs not supported yet.\n");
-    return false;
-  }
-
   // Byval parameters hand the function a pointer directly into the stack area
   // we want to reuse during a tail call. Working around this *is* possible (see
   // X86).
@@ -641,6 +648,12 @@ bool AArch64CallLowering::isEligibleForT
   assert((!Info.IsVarArg || CalleeCC == CallingConv::C) &&
          "Unexpected variadic calling convention");
 
+  // 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!");
+
   // Verify that the incoming and outgoing arguments from the callee are
   // safe to tail call.
   if (!doCallerAndCalleePassArgsTheSameWay(Info, MF, InArgs)) {

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=371868&r1=371867&r2=371868&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 Fri Sep 13 09:10:19 2019
@@ -75,22 +75,33 @@ define i32 @test_nonvoid_ret() {
   ret i32 %call
 }
 
-; Right now, this should not be tail called.
-; TODO: Support this.
 declare void @varargs(i32, double, i64, ...)
 define void @test_varargs() {
-  ; COMMON-LABEL: name: test_varargs
-  ; COMMON: bb.1 (%ir-block.0):
-  ; COMMON:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
-  ; COMMON:   [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
-  ; COMMON:   [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
-  ; COMMON:   ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
-  ; COMMON:   $w0 = COPY [[C]](s32)
-  ; COMMON:   $d0 = COPY [[C1]](s64)
-  ; COMMON:   $x1 = COPY [[C2]](s64)
-  ; COMMON:   BL @varargs, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $w0, implicit $d0, implicit $x1
-  ; COMMON:   ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
-  ; COMMON:   RET_ReallyLR
+  ; On Darwin, everything is passed on the stack. Since the caller has no stack,
+  ; we don't tail call.
+  ; DARWIN-LABEL: name: test_varargs
+  ; DARWIN: bb.1 (%ir-block.0):
+  ; DARWIN:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
+  ; DARWIN:   [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
+  ; DARWIN:   [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
+  ; DARWIN:   ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
+  ; DARWIN:   $w0 = COPY [[C]](s32)
+  ; DARWIN:   $d0 = COPY [[C1]](s64)
+  ; DARWIN:   $x1 = COPY [[C2]](s64)
+  ; DARWIN:   BL @varargs, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $w0, implicit $d0, implicit $x1
+  ; DARWIN:   ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
+  ; DARWIN:   RET_ReallyLR
+
+  ; Windows uses registers, so we don't need to worry about using the stack.
+  ; WINDOWS-LABEL: name: test_varargs
+  ; WINDOWS: bb.1 (%ir-block.0):
+  ; WINDOWS:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
+  ; WINDOWS:   [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
+  ; WINDOWS:   [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
+  ; WINDOWS:   $w0 = COPY [[C]](s32)
+  ; WINDOWS:   $d0 = COPY [[C1]](s64)
+  ; WINDOWS:   $x1 = COPY [[C2]](s64)
+  ; WINDOWS:   TCRETURNdi @varargs, 0, csr_aarch64_aapcs, implicit $sp, implicit $w0, implicit $d0, implicit $x1
   tail call void(i32, double, i64, ...) @varargs(i32 42, double 1.0, i64 12)
   ret void
 }




More information about the llvm-commits mailing list