diff --git a/llvm/lib/Target/AArch64/AArch64CallingConvention.td b/llvm/lib/Target/AArch64/AArch64CallingConvention.td index 8e67f0f5c8815f..3a046e16a0982a 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>, + 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>, + + CCIfType<[nxv1i1, nxv2i1, nxv4i1, nxv8i1, nxv16i1, aarch64svcount], + CCAssignToReg<[P0, P1, P2, P3]>>, + CCIfType<[nxv1i1, nxv2i1, nxv4i1, nxv8i1, nxv16i1, aarch64svcount], + CCPassIndirect>, + // 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>, @@ -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 c86c98eed24f08..1bd6172ad6c659 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(); AttributeList Attrs = MF.getFunction().getAttributes(); + AArch64FunctionInfo *AFI = MF.getInfo(); 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 d82fa3924f8363..0b1070b1b25bbc 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()->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 8cb8b1c92fa7e0..0739c6dd3738e6 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 0a45244f12be54..0cf53ebe559a25 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 @sve_signature_ret_vec() nounwind { ret undef } ; CHECK-LABEL: name: sve_signature_ret_pred +; DARWIN-LABEL: name: sve_signature_ret_pred define @sve_signature_ret_pred() nounwind { ret undef } ; CHECK-LABEL: name: sve_signature_arg_vec +; DARWIN-LABEL: name: sve_signature_arg_vec define void @sve_signature_arg_vec( %arg) nounwind { ret void } ; CHECK-LABEL: name: sve_signature_arg_pred +; DARWIN-LABEL: name: sve_signature_arg_pred define void @sve_signature_arg_pred( %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 @sve_signature_ret_vec_caller() nounwind { %res = call @sve_signature_ret_vec() ret %res @@ -49,6 +62,8 @@ define @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 @sve_signature_ret_vec_caller_fastcc() nounwind { %res = call fastcc @sve_signature_ret_vec() ret %res @@ -56,6 +71,8 @@ define @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 @sve_signature_ret_pred_caller() nounwind { %res = call @sve_signature_ret_pred() ret %res @@ -63,6 +80,8 @@ define @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 @sve_signature_ret_pred_caller_fastcc() nounwind { %res = call fastcc @sve_signature_ret_pred() ret %res @@ -70,6 +89,8 @@ define @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( %arg) nounwind { call void @sve_signature_arg_vec( %arg) ret void @@ -77,6 +98,8 @@ define void @sve_signature_arg_vec_caller( %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( %arg) nounwind { call fastcc void @sve_signature_arg_vec( %arg) ret void @@ -84,6 +107,8 @@ define void @sve_signature_arg_vec_caller_fastcc( %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( %arg) nounwind { call void @sve_signature_arg_pred( %arg) ret void @@ -91,6 +116,8 @@ define void @sve_signature_arg_pred_caller( %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( %arg) nounwind { call fastcc void @sve_signature_arg_pred( %arg) ret void @@ -100,6 +127,10 @@ define void @sve_signature_arg_pred_caller_fastcc( %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 @sve_signature_many_arg_vec( %arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8) nounwind { ret %arg8 } @@ -108,6 +139,10 @@ define @sve_signature_many_arg_vec( %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 @sve_signature_many_arg_pred( %arg1, %arg2, %arg3, %arg4) nounwind { ret %arg4 } @@ -116,6 +151,10 @@ define @sve_signature_many_arg_pred( %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 @sve_signature_vec( %arg1, %arg2) nounwind { ret %arg2 } @@ -124,6 +163,10 @@ define @sve_signature_vec( %arg1, @sve_signature_pred( %arg1, %arg2) nounwind { ret %arg2 } @@ -137,6 +180,15 @@ define @sve_signature_pred( %arg1, @sve_signature_vec_caller( %arg1, %arg2) nounwind { %res = call @sve_signature_vec( %arg2, %arg1) ret %res @@ -151,6 +203,15 @@ define @sve_signature_vec_caller( %arg1, @sve_signature_pred_caller( %arg1, %arg2) nounwind { %res = call @sve_signature_pred( %arg2, %arg1) ret %res