https://github.com/phoebewang created https://github.com/llvm/llvm-project/pull/173224
None >From 5d765591ccb28b4323a4616e9a63a6795034d603 Mon Sep 17 00:00:00 2001 From: Phoebe Wang <[email protected]> Date: Mon, 22 Dec 2025 15:36:20 +0800 Subject: [PATCH] [WIP][APX] Allow EGPR registers used as non-volatile registers --- clang/include/clang/Options/Options.td | 2 + clang/lib/Driver/ToolChains/Arch/X86.cpp | 3 + clang/lib/Driver/ToolChains/CommonArgs.cpp | 6 ++ llvm/lib/Target/X86/X86CallingConv.td | 17 ++++++ llvm/lib/Target/X86/X86RegisterInfo.cpp | 65 ++++++++++++++++++++-- 5 files changed, 89 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index 8cd31a3be109a..c98bb969b28d9 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -9330,6 +9330,8 @@ def : CLFlag<"Qscatter-">, Alias<mno_scatter>, // Non-aliases: +def _SLASH_apx_features_egprnv : CLCompileJoined<"apx-features=egpr-nv:">, + HelpText<"Set number of non-volatile registers of APX features">; def _SLASH_arch : CLCompileJoined<"arch:">, HelpText<"Set architecture for code generation">; def _SLASH_vlen : CLFlag<"vlen">, diff --git a/clang/lib/Driver/ToolChains/Arch/X86.cpp b/clang/lib/Driver/ToolChains/Arch/X86.cpp index d6e6657c521f0..e90edd0a203b1 100644 --- a/clang/lib/Driver/ToolChains/Arch/X86.cpp +++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp @@ -277,6 +277,9 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name)); } + if (Args.hasArgNoClaim(options::OPT__SLASH_apx_features_egprnv)) + Features.push_back("+egpr"); + // Enable/disable straight line speculation hardening. if (Arg *A = Args.getLastArg(options::OPT_mharden_sls_EQ)) { StringRef Scope = A->getValue(); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 882283a99d4f1..ce4a199668b60 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -922,6 +922,12 @@ void tools::getTargetFeatures(const Driver &D, const llvm::Triple &Triple, CmdArgs.push_back(IsAux ? "-aux-target-feature" : "-target-feature"); CmdArgs.push_back(Feature.data()); } + + if (Arg *A = Args.getLastArg(options::OPT__SLASH_apx_features_egprnv)) { + StringRef Value = A->getValue(); + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back(Args.MakeArgString("-apx-egpr-csr=" + Value)); + } } llvm::StringRef tools::getLTOParallelism(const ArgList &Args, const Driver &D) { diff --git a/llvm/lib/Target/X86/X86CallingConv.td b/llvm/lib/Target/X86/X86CallingConv.td index f020e0b55141c..e62e5292f6374 100644 --- a/llvm/lib/Target/X86/X86CallingConv.td +++ b/llvm/lib/Target/X86/X86CallingConv.td @@ -1134,6 +1134,23 @@ def CSR_Win64_NoSSE : CalleeSavedRegs<(add RBX, RBP, RDI, RSI, R12, R13, R14, R1 def CSR_Win64 : CalleeSavedRegs<(add CSR_Win64_NoSSE, (sequence "XMM%u", 6, 15))>; +def CSR_Win64_EGPR1 : CalleeSavedRegs<(add CSR_Win64, R31)>; +def CSR_Win64_EGPR2 : CalleeSavedRegs<(add CSR_Win64_EGPR1, R30)>; +def CSR_Win64_EGPR3 : CalleeSavedRegs<(add CSR_Win64_EGPR2, R29)>; +def CSR_Win64_EGPR4 : CalleeSavedRegs<(add CSR_Win64_EGPR3, R28)>; +def CSR_Win64_EGPR5 : CalleeSavedRegs<(add CSR_Win64_EGPR4, R27)>; +def CSR_Win64_EGPR6 : CalleeSavedRegs<(add CSR_Win64_EGPR5, R26)>; +def CSR_Win64_EGPR7 : CalleeSavedRegs<(add CSR_Win64_EGPR6, R25)>; +def CSR_Win64_EGPR8 : CalleeSavedRegs<(add CSR_Win64_EGPR7, R24)>; +def CSR_Win64_EGPR9 : CalleeSavedRegs<(add CSR_Win64_EGPR8, R23)>; +def CSR_Win64_EGPR10 : CalleeSavedRegs<(add CSR_Win64_EGPR9, R22)>; +def CSR_Win64_EGPR11 : CalleeSavedRegs<(add CSR_Win64_EGPR10, R21)>; +def CSR_Win64_EGPR12 : CalleeSavedRegs<(add CSR_Win64_EGPR11, R20)>; +def CSR_Win64_EGPR13 : CalleeSavedRegs<(add CSR_Win64_EGPR12, R19)>; +def CSR_Win64_EGPR14 : CalleeSavedRegs<(add CSR_Win64_EGPR13, R18)>; +def CSR_Win64_EGPR15 : CalleeSavedRegs<(add CSR_Win64_EGPR14, R17)>; +def CSR_Win64_EGPR16 : CalleeSavedRegs<(add CSR_Win64_EGPR15, R16)>; + def CSR_Win64_SwiftError : CalleeSavedRegs<(sub CSR_Win64, R12)>; def CSR_Win64_SwiftTail : CalleeSavedRegs<(sub CSR_Win64, R13, R14)>; diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp index 72f38133e21ff..b22e0ab704786 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.cpp +++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp @@ -52,6 +52,9 @@ static cl::opt<bool> extern cl::opt<bool> X86EnableAPXForRelocation; +static cl::opt<unsigned> ApxEgprCSR("apx-egpr-csr", cl::init(0), + cl::desc("Set N egpr as callee-saved register for APX calling convention")); + X86RegisterInfo::X86RegisterInfo(const Triple &TT) : X86GenRegisterInfo((TT.isX86_64() ? X86::RIP : X86::EIP), X86_MC::getDwarfRegFlavour(TT, false), @@ -245,6 +248,7 @@ X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { bool HasAVX = Subtarget.hasAVX(); bool HasAVX512 = Subtarget.hasAVX512(); bool CallsEHReturn = MF->callsEHReturn(); + bool HasEGPR = Subtarget.hasEGPR(); CallingConv::ID CC = F.getCallingConv(); @@ -258,6 +262,32 @@ X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { if (MF->getFunction().hasFnAttribute("no_callee_saved_registers")) return CSR_NoRegs_SaveList; + auto CSR_Win64_Or_EGPR_SaveList = [HasEGPR]() { + if (!HasEGPR) + return CSR_Win64_SaveList; + + switch (ApxEgprCSR) { + case 0: return CSR_Win64_SaveList; + case 1: return CSR_Win64_EGPR1_SaveList; + case 2: return CSR_Win64_EGPR2_SaveList; + case 3: return CSR_Win64_EGPR3_SaveList; + case 4: return CSR_Win64_EGPR4_SaveList; + case 5: return CSR_Win64_EGPR5_SaveList; + case 6: return CSR_Win64_EGPR6_SaveList; + case 7: return CSR_Win64_EGPR7_SaveList; + case 8: return CSR_Win64_EGPR8_SaveList; + case 9: return CSR_Win64_EGPR9_SaveList; + case 10: return CSR_Win64_EGPR10_SaveList; + case 11: return CSR_Win64_EGPR11_SaveList; + case 12: return CSR_Win64_EGPR12_SaveList; + case 13: return CSR_Win64_EGPR13_SaveList; + case 14: return CSR_Win64_EGPR14_SaveList; + case 15: return CSR_Win64_EGPR15_SaveList; + case 16: return CSR_Win64_EGPR16_SaveList; + default: llvm_unreachable("Invalid reg number!"); + } + }; + switch (CC) { case CallingConv::GHC: case CallingConv::HiPE: @@ -317,7 +347,7 @@ X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { case CallingConv::Win64: if (!HasSSE) return CSR_Win64_NoSSE_SaveList; - return CSR_Win64_SaveList; + return CSR_Win64_Or_EGPR_SaveList(); case CallingConv::SwiftTail: if (!Is64Bit) return CSR_32_SaveList; @@ -356,7 +386,7 @@ X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { : CSR_64_SwiftError_SaveList; if (IsWin64 || IsUEFI64) - return HasSSE ? CSR_Win64_SaveList : CSR_Win64_NoSSE_SaveList; + return HasSSE ? CSR_Win64_Or_EGPR_SaveList() : CSR_Win64_NoSSE_SaveList; if (CallsEHReturn) return CSR_64EHRet_SaveList; return CSR_64_SaveList; @@ -386,6 +416,33 @@ X86RegisterInfo::getCallPreservedMask(const MachineFunction &MF, bool HasSSE = Subtarget.hasSSE1(); bool HasAVX = Subtarget.hasAVX(); bool HasAVX512 = Subtarget.hasAVX512(); + bool HasEGPR = Subtarget.hasEGPR(); + + auto CSR_Win64_Or_EGPR_RegMask = [HasEGPR]() { + if (!HasEGPR) + return CSR_Win64_RegMask; + + switch (ApxEgprCSR) { + case 0: return CSR_Win64_RegMask; + case 1: return CSR_Win64_EGPR1_RegMask; + case 2: return CSR_Win64_EGPR2_RegMask; + case 3: return CSR_Win64_EGPR3_RegMask; + case 4: return CSR_Win64_EGPR4_RegMask; + case 5: return CSR_Win64_EGPR5_RegMask; + case 6: return CSR_Win64_EGPR6_RegMask; + case 7: return CSR_Win64_EGPR7_RegMask; + case 8: return CSR_Win64_EGPR8_RegMask; + case 9: return CSR_Win64_EGPR9_RegMask; + case 10: return CSR_Win64_EGPR10_RegMask; + case 11: return CSR_Win64_EGPR11_RegMask; + case 12: return CSR_Win64_EGPR12_RegMask; + case 13: return CSR_Win64_EGPR13_RegMask; + case 14: return CSR_Win64_EGPR14_RegMask; + case 15: return CSR_Win64_EGPR15_RegMask; + case 16: return CSR_Win64_EGPR16_RegMask; + default: llvm_unreachable("Invalid reg number!"); + } + }; switch (CC) { case CallingConv::GHC: @@ -442,7 +499,7 @@ X86RegisterInfo::getCallPreservedMask(const MachineFunction &MF, return CSR_64_MostRegs_RegMask; break; case CallingConv::Win64: - return CSR_Win64_RegMask; + return CSR_Win64_Or_EGPR_RegMask(); case CallingConv::SwiftTail: if (!Is64Bit) return CSR_32_RegMask; @@ -480,7 +537,7 @@ X86RegisterInfo::getCallPreservedMask(const MachineFunction &MF, if (IsSwiftCC) return IsWin64 ? CSR_Win64_SwiftError_RegMask : CSR_64_SwiftError_RegMask; - return (IsWin64 || IsUEFI64) ? CSR_Win64_RegMask : CSR_64_RegMask; + return (IsWin64 || IsUEFI64) ? CSR_Win64_Or_EGPR_RegMask() : CSR_64_RegMask; } return CSR_32_RegMask; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
