Skip to content

[AArch64] Allow variadic calls with SVE argument if it is named. #136833

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 24, 2025

Conversation

sdesmalen-arm
Copy link
Collaborator

The following case used to work:

void foo(svint32_t a, ...);
void bar(svint32_t a) { foo(a); }

but 6c9086d introduced a regression that wasn't caught by the existing test sve-varargs.ll because the call in the test wasn't a tail call and therefore skipped the code-path with the report_fatal_error.

The following case used to work:

  void foo(svint32_t a, ...);
  void bar(svint32_t a) { foo(a); }

but 6c9086d introduced a regression
that wasn't caught by the existing test 'sve-varargs.ll' because
it wasn't a tail call and therefore skipped the code-path with
the report_fatal_error.
@llvmbot
Copy link
Member

llvmbot commented Apr 23, 2025

@llvm/pr-subscribers-backend-aarch64

Author: Sander de Smalen (sdesmalen-arm)

Changes

The following case used to work:

void foo(svint32_t a, ...);
void bar(svint32_t a) { foo(a); }

but 6c9086d introduced a regression that wasn't caught by the existing test sve-varargs.ll because the call in the test wasn't a tail call and therefore skipped the code-path with the report_fatal_error.


Full diff: https://github.com/llvm/llvm-project/pull/136833.diff

3 Files Affected:

  • (modified) llvm/lib/Target/AArch64/AArch64ISelLowering.cpp (+4)
  • (modified) llvm/test/CodeGen/AArch64/sve-varargs-caller-broken.ll (+17-4)
  • (modified) llvm/test/CodeGen/AArch64/sve-varargs.ll (+12-2)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index cb8f324b61187..6db2d25017072 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -8595,6 +8595,10 @@ static bool callConvSupportsVarArgs(CallingConv::ID CC) {
   switch (CC) {
   case CallingConv::C:
   case CallingConv::PreserveNone:
+  // SVE vector call is only partially supported, but it should
+  // support named arguments being passed. Any arguments being passed
+  // as varargs, are still unsupported.
+  case CallingConv::AArch64_SVE_VectorCall:
     return true;
   default:
     return false;
diff --git a/llvm/test/CodeGen/AArch64/sve-varargs-caller-broken.ll b/llvm/test/CodeGen/AArch64/sve-varargs-caller-broken.ll
index 1ecdd2ff43781..b90c02fa1c032 100644
--- a/llvm/test/CodeGen/AArch64/sve-varargs-caller-broken.ll
+++ b/llvm/test/CodeGen/AArch64/sve-varargs-caller-broken.ll
@@ -1,11 +1,24 @@
-; RUN: not --crash llc -mtriple aarch64-linux-gnu -mattr=+sve <%s 2>&1 | FileCheck %s
+; RUN: split-file %s %t
 
-declare i32 @sve_printf(ptr, <vscale x 4 x i32>, ...)
+; RUN: not --crash llc -mtriple aarch64-linux-gnu -mattr=+sve < %t/test-non-tailcall.ll 2>&1 | FileCheck %s --check-prefix=CHECKNONTAIL
+; RUN: not --crash llc -mtriple aarch64-linux-gnu -mattr=+sve < %t/test-tailcall.ll 2>&1 | FileCheck %s --check-prefix=CHECKTAIL
 
+;--- test-non-tailcall.ll
+declare i32 @sve_printf(ptr, <vscale x 4 x i32>, ...)
 @.str_1 = internal constant [6 x i8] c"boo!\0A\00"
 
-; CHECK: Passing SVE types to variadic functions is currently not supported
-define void @foo(<vscale x 4 x i32> %x) {
+; CHECKTAIL: Passing SVE types to variadic functions is currently not supported
+define void @foo_nontail(<vscale x 4 x i32> %x) {
   call i32 (ptr, <vscale x 4 x i32>, ...) @sve_printf(ptr @.str_1, <vscale x 4 x i32> %x, <vscale x 4 x i32> %x)
   ret void
 }
+
+;--- test-tailcall.ll
+declare i32 @sve_printf(ptr, <vscale x 4 x i32>, ...)
+@.str_1 = internal constant [6 x i8] c"boo!\0A\00"
+
+; CHECKNONTAIL: Passing SVE types to variadic functions is currently not supported
+define void @foo_tail(<vscale x 4 x i32> %x) {
+  tail call i32 (ptr, <vscale x 4 x i32>, ...) @sve_printf(ptr @.str_1, <vscale x 4 x i32> %x, <vscale x 4 x i32> %x)
+  ret void
+}
diff --git a/llvm/test/CodeGen/AArch64/sve-varargs.ll b/llvm/test/CodeGen/AArch64/sve-varargs.ll
index c63491f445b9c..4ae92f0c8a41b 100644
--- a/llvm/test/CodeGen/AArch64/sve-varargs.ll
+++ b/llvm/test/CodeGen/AArch64/sve-varargs.ll
@@ -5,8 +5,8 @@ declare i32 @sve_printf(ptr, <vscale x 4 x i32>, ...)
 
 @.str_1 = internal constant [6 x i8] c"boo!\0A\00"
 
-define void @foo(<vscale x 4 x i32> %x) uwtable {
-; CHECK-LABEL: foo:
+define void @foo_nontail(<vscale x 4 x i32> %x) uwtable {
+; CHECK-LABEL: foo_nontail:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
@@ -21,3 +21,13 @@ define void @foo(<vscale x 4 x i32> %x) uwtable {
   call i32 (ptr, <vscale x 4 x i32>, ...) @sve_printf(ptr @.str_1, <vscale x 4 x i32> %x)
   ret void
 }
+
+define void @foo_tail(<vscale x 4 x i32> %x) uwtable {
+; CHECK-LABEL: foo_tail:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    adrp x0, .str_1
+; CHECK-NEXT:    add x0, x0, :lo12:.str_1
+; CHECK-NEXT:    b sve_printf
+  tail call i32 (ptr, <vscale x 4 x i32>, ...) @sve_printf(ptr @.str_1, <vscale x 4 x i32> %x)
+  ret void
+}

Copy link
Collaborator

@ostannard ostannard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@sdesmalen-arm sdesmalen-arm merged commit de81b85 into llvm:main Apr 24, 2025
13 checks passed
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…m#136833)

The following case used to work:

  void foo(svint32_t a, ...);
  void bar(svint32_t a) { foo(a); }

but 6c9086d introduced a regression
that wasn't caught by the existing test `sve-varargs.ll` because the
call in the test wasn't a tail call and therefore skipped the code-path
with the `report_fatal_error`.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…m#136833)

The following case used to work:

  void foo(svint32_t a, ...);
  void bar(svint32_t a) { foo(a); }

but 6c9086d introduced a regression
that wasn't caught by the existing test `sve-varargs.ll` because the
call in the test wasn't a tail call and therefore skipped the code-path
with the `report_fatal_error`.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…m#136833)

The following case used to work:

  void foo(svint32_t a, ...);
  void bar(svint32_t a) { foo(a); }

but 6c9086d introduced a regression
that wasn't caught by the existing test `sve-varargs.ll` because the
call in the test wasn't a tail call and therefore skipped the code-path
with the `report_fatal_error`.
Ankur-0429 pushed a commit to Ankur-0429/llvm-project that referenced this pull request May 9, 2025
…m#136833)

The following case used to work:

  void foo(svint32_t a, ...);
  void bar(svint32_t a) { foo(a); }

but 6c9086d introduced a regression
that wasn't caught by the existing test `sve-varargs.ll` because the
call in the test wasn't a tail call and therefore skipped the code-path
with the `report_fatal_error`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants