From 042c860eefa1328f351656190ac5efbb0f01a751 Mon Sep 17 00:00:00 2001 From: Sander de Smalen Date: Wed, 23 Apr 2025 08:42:54 +0000 Subject: [PATCH] [AArch64] Allow variadic calls with SVE argument if it is named. The following case used to work: void foo(svint32_t a, ...); void bar(svint32_t a) { foo(a); } but 6c9086d13fa7e1069e75ed2d139aae30ee3863c8 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. --- .../Target/AArch64/AArch64ISelLowering.cpp | 4 ++++ .../AArch64/sve-varargs-caller-broken.ll | 21 +++++++++++++++---- llvm/test/CodeGen/AArch64/sve-varargs.ll | 14 +++++++++++-- 3 files changed, 33 insertions(+), 6 deletions(-) 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, , ...) +; 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, , ...) @.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( %x) { +; CHECKTAIL: Passing SVE types to variadic functions is currently not supported +define void @foo_nontail( %x) { call i32 (ptr, , ...) @sve_printf(ptr @.str_1, %x, %x) ret void } + +;--- test-tailcall.ll +declare i32 @sve_printf(ptr, , ...) +@.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( %x) { + tail call i32 (ptr, , ...) @sve_printf(ptr @.str_1, %x, %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, , ...) @.str_1 = internal constant [6 x i8] c"boo!\0A\00" -define void @foo( %x) uwtable { -; CHECK-LABEL: foo: +define void @foo_nontail( %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( %x) uwtable { call i32 (ptr, , ...) @sve_printf(ptr @.str_1, %x) ret void } + +define void @foo_tail( %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, , ...) @sve_printf(ptr @.str_1, %x) + ret void +}