[llvm] [AArch64] Basic SVE PCS support for handling scalable vectors on Darwin. (PR #92607)
Amara Emerson via llvm-commits
llvm-commits at lists.llvm.org
Fri May 17 14:43:50 PDT 2024
https://github.com/aemerson created https://github.com/llvm/llvm-project/pull/92607
None
>From f033f5572fbbbffbb0339872a5ef3142fdced7be Mon Sep 17 00:00:00 2001
From: Amara Emerson <amara at apple.com>
Date: Fri, 17 May 2024 14:42:25 -0700
Subject: [PATCH] [AArch64] Basic SVE PCS support for handling scalable vectors
on Darwin.
---
.../AArch64/AArch64CallingConvention.td | 17 ++++++
.../Target/AArch64/AArch64FrameLowering.cpp | 4 +-
.../Target/AArch64/AArch64RegisterInfo.cpp | 5 +-
.../AArch64/sve-calling-convention-byref.ll | 1 +
.../CodeGen/AArch64/sve-calling-convention.ll | 61 +++++++++++++++++++
5 files changed, 85 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64CallingConvention.td b/llvm/lib/Target/AArch64/AArch64CallingConvention.td
index 8e67f0f5c8815..3a046e16a0982 100644
--- a/llvm/lib/Target/AArch64/AArch64CallingConvention.td
+++ b/llvm/lib/Target/AArch64/AArch64CallingConvention.td
@@ -371,6 +371,18 @@ def CC_AArch64_DarwinPCS : CallingConv<[
CCIfConsecutiveRegs<CCCustom<"CC_AArch64_Custom_Block">>,
+ CCIfType<[nxv16i8, nxv8i16, nxv4i32, nxv2i64, nxv2f16, nxv4f16, nxv8f16,
+ nxv2bf16, nxv4bf16, nxv8bf16, nxv2f32, nxv4f32, nxv2f64],
+ CCAssignToReg<[Z0, Z1, Z2, Z3, Z4, Z5, Z6, Z7]>>,
+ CCIfType<[nxv16i8, nxv8i16, nxv4i32, nxv2i64, nxv2f16, nxv4f16, nxv8f16,
+ nxv2bf16, nxv4bf16, nxv8bf16, nxv2f32, nxv4f32, nxv2f64],
+ CCPassIndirect<i64>>,
+
+ CCIfType<[nxv1i1, nxv2i1, nxv4i1, nxv8i1, nxv16i1, aarch64svcount],
+ CCAssignToReg<[P0, P1, P2, P3]>>,
+ CCIfType<[nxv1i1, nxv2i1, nxv4i1, nxv8i1, nxv16i1, aarch64svcount],
+ CCPassIndirect<i64>>,
+
// Handle i1, i8, i16, i32, i64, f32, f64 and v2f64 by passing in registers,
// up to eight each of GPR and FPR.
CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
@@ -555,6 +567,11 @@ def CSR_AArch64_SVE_AAPCS : CalleeSavedRegs<(add (sequence "Z%u", 8, 23),
X19, X20, X21, X22, X23, X24,
X25, X26, X27, X28, LR, FP)>;
+def CSR_Darwin_AArch64_SVE_AAPCS : CalleeSavedRegs<(add (sequence "Z%u", 8, 23),
+ (sequence "P%u", 4, 15),
+ LR, FP, X19, X20, X21, X22,
+ X23, X24, X25, X26, X27, X28)>;
+
// SME ABI support routines such as __arm_tpidr2_save/restore preserve most registers.
def CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0
: CalleeSavedRegs<(add (sequence "Z%u", 0, 31),
diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index c86c98eed24f0..1bd6172ad6c65 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -2696,10 +2696,12 @@ static unsigned getPrologueDeath(MachineFunction &MF, unsigned Reg) {
static bool produceCompactUnwindFrame(MachineFunction &MF) {
const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
AttributeList Attrs = MF.getFunction().getAttributes();
+ AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
return Subtarget.isTargetMachO() &&
!(Subtarget.getTargetLowering()->supportSwiftError() &&
Attrs.hasAttrSomewhere(Attribute::SwiftError)) &&
- MF.getFunction().getCallingConv() != CallingConv::SwiftTail;
+ MF.getFunction().getCallingConv() != CallingConv::SwiftTail &&
+ AFI->getSVECalleeSavedStackSize() == 0;
}
static bool invalidateWindowsRegisterPairing(unsigned Reg1, unsigned Reg2,
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
index d82fa3924f836..0b1070b1b25bb 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
@@ -177,6 +177,8 @@ AArch64RegisterInfo::getDarwinCalleeSavedRegs(const MachineFunction *MF) const {
return CSR_Darwin_AArch64_RT_AllRegs_SaveList;
if (MF->getFunction().getCallingConv() == CallingConv::Win64)
return CSR_Darwin_AArch64_AAPCS_Win64_SaveList;
+ if (MF->getInfo<AArch64FunctionInfo>()->isSVECC())
+ return CSR_Darwin_AArch64_SVE_AAPCS_SaveList;
return CSR_Darwin_AArch64_AAPCS_SaveList;
}
@@ -230,8 +232,7 @@ AArch64RegisterInfo::getDarwinCallPreservedMask(const MachineFunction &MF,
if (CC == CallingConv::AArch64_VectorCall)
return CSR_Darwin_AArch64_AAVPCS_RegMask;
if (CC == CallingConv::AArch64_SVE_VectorCall)
- report_fatal_error(
- "Calling convention SVE_VectorCall is unsupported on Darwin.");
+ return CSR_Darwin_AArch64_SVE_AAPCS_RegMask;
if (CC == CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0)
return CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0_RegMask;
if (CC == CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2)
diff --git a/llvm/test/CodeGen/AArch64/sve-calling-convention-byref.ll b/llvm/test/CodeGen/AArch64/sve-calling-convention-byref.ll
index 8cb8b1c92fa7e..0739c6dd3738e 100644
--- a/llvm/test/CodeGen/AArch64/sve-calling-convention-byref.ll
+++ b/llvm/test/CodeGen/AArch64/sve-calling-convention-byref.ll
@@ -1,4 +1,5 @@
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve -stop-after=finalize-isel < %s | FileCheck %s
+; RUN: llc -mtriple=aarch64-apple-darwin -mattr=+sme -stop-after=finalize-isel < %s | FileCheck %s
; Test that z8 and z9, passed in by reference, are correctly loaded from x0 and x1.
; i.e. z0 = %z0
diff --git a/llvm/test/CodeGen/AArch64/sve-calling-convention.ll b/llvm/test/CodeGen/AArch64/sve-calling-convention.ll
index 0a45244f12be5..0cf53ebe559a2 100644
--- a/llvm/test/CodeGen/AArch64/sve-calling-convention.ll
+++ b/llvm/test/CodeGen/AArch64/sve-calling-convention.ll
@@ -1,33 +1,42 @@
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve -stop-after=finalize-isel < %s | FileCheck %s
+; RUN: llc -mtriple=aarch64-apple-darwin -mattr=+sme -stop-after=finalize-isel < %s | FileCheck %s --check-prefix=DARWIN
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve -stop-after=prologepilog < %s | FileCheck %s --check-prefix=CHECKCSR
+; RUN: llc -mtriple=aarch64-apple-darwin -mattr=+sme -stop-after=prologepilog < %s | FileCheck %s --check-prefix=CHECKCSR
; CHECK-LABEL: name: nosve_signature
+; DARWIN-LABEL: name: nosve_signature
define i32 @nosve_signature() nounwind {
ret i32 42
}
; CHECK-LABEL: name: sve_signature_ret_vec
+; DARWIN-LABEL: name: sve_signature_ret_vec
define <vscale x 4 x i32> @sve_signature_ret_vec() nounwind {
ret <vscale x 4 x i32> undef
}
; CHECK-LABEL: name: sve_signature_ret_pred
+; DARWIN-LABEL: name: sve_signature_ret_pred
define <vscale x 4 x i1> @sve_signature_ret_pred() nounwind {
ret <vscale x 4 x i1> undef
}
; CHECK-LABEL: name: sve_signature_arg_vec
+; DARWIN-LABEL: name: sve_signature_arg_vec
define void @sve_signature_arg_vec(<vscale x 4 x i32> %arg) nounwind {
ret void
}
; CHECK-LABEL: name: sve_signature_arg_pred
+; DARWIN-LABEL: name: sve_signature_arg_pred
define void @sve_signature_arg_pred(<vscale x 4 x i1> %arg) nounwind {
ret void
}
; CHECK-LABEL: name: caller_nosve_signature
; CHECK: BL @nosve_signature, csr_aarch64_aapcs
+; DARWIN-LABEL: name: caller_nosve_signature
+; DARWIN: BL @nosve_signature, csr_darwin_aarch64_aapcs
define i32 @caller_nosve_signature() nounwind {
%res = call i32 @nosve_signature()
ret i32 %res
@@ -35,6 +44,8 @@ define i32 @caller_nosve_signature() nounwind {
; CHECK-LABEL: name: caller_nosve_signature_fastcc
; CHECK: BL @nosve_signature, csr_aarch64_aapcs
+; DARWIN-LABEL: name: caller_nosve_signature_fastcc
+; DARWIN: BL @nosve_signature, csr_darwin_aarch64_aapcs
define i32 @caller_nosve_signature_fastcc() nounwind {
%res = call fastcc i32 @nosve_signature()
ret i32 %res
@@ -42,6 +53,8 @@ define i32 @caller_nosve_signature_fastcc() nounwind {
; CHECK-LABEL: name: sve_signature_ret_vec_caller
; CHECK: BL @sve_signature_ret_vec, csr_aarch64_sve_aapcs
+; DARWIN-LABEL: name: sve_signature_ret_vec_caller
+; DARWIN: BL @sve_signature_ret_vec, csr_darwin_aarch64_sve_aapcs
define <vscale x 4 x i32> @sve_signature_ret_vec_caller() nounwind {
%res = call <vscale x 4 x i32> @sve_signature_ret_vec()
ret <vscale x 4 x i32> %res
@@ -49,6 +62,8 @@ define <vscale x 4 x i32> @sve_signature_ret_vec_caller() nounwind {
; CHECK-LABEL: name: sve_signature_ret_vec_caller_fastcc
; CHECK: BL @sve_signature_ret_vec, csr_aarch64_sve_aapcs
+; DARWIN-LABEL: name: sve_signature_ret_vec_caller_fastcc
+; DARWIN: BL @sve_signature_ret_vec, csr_darwin_aarch64_sve_aapcs
define <vscale x 4 x i32> @sve_signature_ret_vec_caller_fastcc() nounwind {
%res = call fastcc <vscale x 4 x i32> @sve_signature_ret_vec()
ret <vscale x 4 x i32> %res
@@ -56,6 +71,8 @@ define <vscale x 4 x i32> @sve_signature_ret_vec_caller_fastcc() nounwind {
; CHECK-LABEL: name: sve_signature_ret_pred_caller
; CHECK: BL @sve_signature_ret_pred, csr_aarch64_sve_aapcs
+; DARWIN-LABEL: name: sve_signature_ret_pred_caller
+; DARWIN: BL @sve_signature_ret_pred, csr_darwin_aarch64_sve_aapcs
define <vscale x 4 x i1> @sve_signature_ret_pred_caller() nounwind {
%res = call <vscale x 4 x i1> @sve_signature_ret_pred()
ret <vscale x 4 x i1> %res
@@ -63,6 +80,8 @@ define <vscale x 4 x i1> @sve_signature_ret_pred_caller() nounwind {
; CHECK-LABEL: name: sve_signature_ret_pred_caller_fastcc
; CHECK: BL @sve_signature_ret_pred, csr_aarch64_sve_aapcs
+; DARWIN-LABEL: name: sve_signature_ret_pred_caller_fastcc
+; DARWIN: BL @sve_signature_ret_pred, csr_darwin_aarch64_sve_aapcs
define <vscale x 4 x i1> @sve_signature_ret_pred_caller_fastcc() nounwind {
%res = call fastcc <vscale x 4 x i1> @sve_signature_ret_pred()
ret <vscale x 4 x i1> %res
@@ -70,6 +89,8 @@ define <vscale x 4 x i1> @sve_signature_ret_pred_caller_fastcc() nounwind {
; CHECK-LABEL: name: sve_signature_arg_vec_caller
; CHECK: BL @sve_signature_arg_vec, csr_aarch64_sve_aapcs
+; DARWIN-LABEL: name: sve_signature_arg_vec_caller
+; DARWIN: BL @sve_signature_arg_vec, csr_darwin_aarch64_sve_aapcs
define void @sve_signature_arg_vec_caller(<vscale x 4 x i32> %arg) nounwind {
call void @sve_signature_arg_vec(<vscale x 4 x i32> %arg)
ret void
@@ -77,6 +98,8 @@ define void @sve_signature_arg_vec_caller(<vscale x 4 x i32> %arg) nounwind {
; CHECK-LABEL: name: sve_signature_arg_vec_caller_fastcc
; CHECK: BL @sve_signature_arg_vec, csr_aarch64_sve_aapcs
+; DARWIN-LABEL: name: sve_signature_arg_vec_caller_fastcc
+; DARWIN: BL @sve_signature_arg_vec, csr_darwin_aarch64_sve_aapcs
define void @sve_signature_arg_vec_caller_fastcc(<vscale x 4 x i32> %arg) nounwind {
call fastcc void @sve_signature_arg_vec(<vscale x 4 x i32> %arg)
ret void
@@ -84,6 +107,8 @@ define void @sve_signature_arg_vec_caller_fastcc(<vscale x 4 x i32> %arg) nounwi
; CHECK-LABEL: name: sve_signature_arg_pred_caller
; CHECK: BL @sve_signature_arg_pred, csr_aarch64_sve_aapcs
+; DARWIN-LABEL: name: sve_signature_arg_pred_caller
+; DARWIN: BL @sve_signature_arg_pred, csr_darwin_aarch64_sve_aapcs
define void @sve_signature_arg_pred_caller(<vscale x 4 x i1> %arg) nounwind {
call void @sve_signature_arg_pred(<vscale x 4 x i1> %arg)
ret void
@@ -91,6 +116,8 @@ define void @sve_signature_arg_pred_caller(<vscale x 4 x i1> %arg) nounwind {
; CHECK-LABEL: name: sve_signature_arg_pred_caller_fastcc
; CHECK: BL @sve_signature_arg_pred, csr_aarch64_sve_aapcs
+; DARWIN-LABEL: name: sve_signature_arg_pred_caller_fastcc
+; DARWIN: BL @sve_signature_arg_pred, csr_darwin_aarch64_sve_aapcs
define void @sve_signature_arg_pred_caller_fastcc(<vscale x 4 x i1> %arg) nounwind {
call fastcc void @sve_signature_arg_pred(<vscale x 4 x i1> %arg)
ret void
@@ -100,6 +127,10 @@ define void @sve_signature_arg_pred_caller_fastcc(<vscale x 4 x i1> %arg) nounwi
; CHECK: [[RES:%[0-9]+]]:zpr = COPY $z7
; CHECK: $z0 = COPY [[RES]]
; CHECK: RET_ReallyLR implicit $z0
+; DARWIN-LABEL: name: sve_signature_many_arg_vec
+; DARWIN: [[RES:%[0-9]+]]:zpr = COPY $z7
+; DARWIN: $z0 = COPY [[RES]]
+; DARWIN: RET_ReallyLR implicit $z0
define <vscale x 4 x i32> @sve_signature_many_arg_vec(<vscale x 4 x i32> %arg1, <vscale x 4 x i32> %arg2, <vscale x 4 x i32> %arg3, <vscale x 4 x i32> %arg4, <vscale x 4 x i32> %arg5, <vscale x 4 x i32> %arg6, <vscale x 4 x i32> %arg7, <vscale x 4 x i32> %arg8) nounwind {
ret <vscale x 4 x i32> %arg8
}
@@ -108,6 +139,10 @@ define <vscale x 4 x i32> @sve_signature_many_arg_vec(<vscale x 4 x i32> %arg1,
; CHECK: [[RES:%[0-9]+]]:ppr = COPY $p3
; CHECK: $p0 = COPY [[RES]]
; CHECK: RET_ReallyLR implicit $p0
+; DARWIN-LABEL: name: sve_signature_many_arg_pred
+; DARWIN: [[RES:%[0-9]+]]:ppr = COPY $p3
+; DARWIN: $p0 = COPY [[RES]]
+; DARWIN: RET_ReallyLR implicit $p0
define <vscale x 4 x i1> @sve_signature_many_arg_pred(<vscale x 4 x i1> %arg1, <vscale x 4 x i1> %arg2, <vscale x 4 x i1> %arg3, <vscale x 4 x i1> %arg4) nounwind {
ret <vscale x 4 x i1> %arg4
}
@@ -116,6 +151,10 @@ define <vscale x 4 x i1> @sve_signature_many_arg_pred(<vscale x 4 x i1> %arg1, <
; CHECK: [[RES:%[0-9]+]]:zpr = COPY $z1
; CHECK: $z0 = COPY [[RES]]
; CHECK: RET_ReallyLR implicit $z0
+; DARWIN-LABEL: name: sve_signature_vec
+; DARWIN: [[RES:%[0-9]+]]:zpr = COPY $z1
+; DARWIN: $z0 = COPY [[RES]]
+; DARWIN: RET_ReallyLR implicit $z0
define <vscale x 4 x i32> @sve_signature_vec(<vscale x 4 x i32> %arg1, <vscale x 4 x i32> %arg2) nounwind {
ret <vscale x 4 x i32> %arg2
}
@@ -124,6 +163,10 @@ define <vscale x 4 x i32> @sve_signature_vec(<vscale x 4 x i32> %arg1, <vscale x
; CHECK: [[RES:%[0-9]+]]:ppr = COPY $p1
; CHECK: $p0 = COPY [[RES]]
; CHECK: RET_ReallyLR implicit $p0
+; DARWIN-LABEL: name: sve_signature_pred
+; DARWIN: [[RES:%[0-9]+]]:ppr = COPY $p1
+; DARWIN: $p0 = COPY [[RES]]
+; DARWIN: RET_ReallyLR implicit $p0
define <vscale x 4 x i1> @sve_signature_pred(<vscale x 4 x i1> %arg1, <vscale x 4 x i1> %arg2) nounwind {
ret <vscale x 4 x i1> %arg2
}
@@ -137,6 +180,15 @@ define <vscale x 4 x i1> @sve_signature_pred(<vscale x 4 x i1> %arg1, <vscale x
; CHECK: [[RES:%[0-9]+]]:zpr = COPY $z0
; CHECK: $z0 = COPY [[RES]]
; CHECK: RET_ReallyLR implicit $z0
+; DARWIN-LABEL: name: sve_signature_vec_caller
+; DARWIN-DAG: [[ARG2:%[0-9]+]]:zpr = COPY $z1
+; DARWIN-DAG: [[ARG1:%[0-9]+]]:zpr = COPY $z0
+; DARWIN-DAG: $z0 = COPY [[ARG2]]
+; DARWIN-DAG: $z1 = COPY [[ARG1]]
+; DARWIN-NEXT: BL @sve_signature_vec, csr_darwin_aarch64_sve_aapcs
+; DARWIN: [[RES:%[0-9]+]]:zpr = COPY $z0
+; DARWIN: $z0 = COPY [[RES]]
+; DARWIN: RET_ReallyLR implicit $z0
define <vscale x 4 x i32> @sve_signature_vec_caller(<vscale x 4 x i32> %arg1, <vscale x 4 x i32> %arg2) nounwind {
%res = call <vscale x 4 x i32> @sve_signature_vec(<vscale x 4 x i32> %arg2, <vscale x 4 x i32> %arg1)
ret <vscale x 4 x i32> %res
@@ -151,6 +203,15 @@ define <vscale x 4 x i32> @sve_signature_vec_caller(<vscale x 4 x i32> %arg1, <v
; CHECK: [[RES:%[0-9]+]]:ppr = COPY $p0
; CHECK: $p0 = COPY [[RES]]
; CHECK: RET_ReallyLR implicit $p0
+; DARWIN-LABEL: name: sve_signature_pred_caller
+; DARWIN-DAG: [[ARG2:%[0-9]+]]:ppr = COPY $p1
+; DARWIN-DAG: [[ARG1:%[0-9]+]]:ppr = COPY $p0
+; DARWIN-DAG: $p0 = COPY [[ARG2]]
+; DARWIN-DAG: $p1 = COPY [[ARG1]]
+; DARWIN-NEXT: BL @sve_signature_pred, csr_darwin_aarch64_sve_aapcs
+; DARWIN: [[RES:%[0-9]+]]:ppr = COPY $p0
+; DARWIN: $p0 = COPY [[RES]]
+; DARWIN: RET_ReallyLR implicit $p0
define <vscale x 4 x i1> @sve_signature_pred_caller(<vscale x 4 x i1> %arg1, <vscale x 4 x i1> %arg2) nounwind {
%res = call <vscale x 4 x i1> @sve_signature_pred(<vscale x 4 x i1> %arg2, <vscale x 4 x i1> %arg1)
ret <vscale x 4 x i1> %res
More information about the llvm-commits
mailing list