[llvm] [AArch64] Basic SVE PCS support for handling scalable vectors on Darwin. (PR #92607)

via llvm-commits llvm-commits at lists.llvm.org
Fri May 17 14:44:18 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-aarch64

Author: Amara Emerson (aemerson)

<details>
<summary>Changes</summary>



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


5 Files Affected:

- (modified) llvm/lib/Target/AArch64/AArch64CallingConvention.td (+17) 
- (modified) llvm/lib/Target/AArch64/AArch64FrameLowering.cpp (+3-1) 
- (modified) llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp (+3-2) 
- (modified) llvm/test/CodeGen/AArch64/sve-calling-convention-byref.ll (+1) 
- (modified) llvm/test/CodeGen/AArch64/sve-calling-convention.ll (+61) 


``````````diff
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

``````````

</details>


https://github.com/llvm/llvm-project/pull/92607


More information about the llvm-commits mailing list