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

Reply via email to