[llvm] [llvm] X86_64 CC for UEFI (PR #137905)

Prabhu Rajasekaran via llvm-commits llvm-commits at lists.llvm.org
Thu May 1 15:42:47 PDT 2025


https://github.com/Prabhuk updated https://github.com/llvm/llvm-project/pull/137905

>From d9e4c7f897db5b6074d1a728ebbc6dfad9df648f Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Tue, 29 Apr 2025 16:39:03 -0700
Subject: [PATCH 1/3] [llvm] X86_64 CC for UEFI

Select appropriate registers for X86_64 UEFI.
---
 llvm/lib/Target/X86/X86CallingConv.td   | 9 ++++++++-
 llvm/lib/Target/X86/X86RegisterInfo.cpp | 7 ++++---
 llvm/lib/Target/X86/X86RegisterInfo.h   | 4 ++++
 llvm/lib/Target/X86/X86Subtarget.h      | 5 +++++
 4 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/X86/X86CallingConv.td b/llvm/lib/Target/X86/X86CallingConv.td
index 0d087e057a2bd..8103e8c6df51b 100644
--- a/llvm/lib/Target/X86/X86CallingConv.td
+++ b/llvm/lib/Target/X86/X86CallingConv.td
@@ -284,7 +284,8 @@ def RetCC_X86Common : CallingConv<[
 
   // Long double types are always returned in FP0 (even with SSE),
   // except on Win64.
-  CCIfNotSubtarget<"isTargetWin64()", CCIfType<[f80], CCAssignToReg<[FP0, FP1]>>>
+  CCIfNotSubtarget<"isTargetWinOrUEFI64()",
+                    CCIfType<[f80], CCAssignToReg<[FP0, FP1]>>>
 ]>;
 
 // X86-32 C return-value convention.
@@ -495,6 +496,9 @@ def RetCC_X86_64 : CallingConv<[
   // Mingw64 and native Win64 use Win64 CC
   CCIfSubtarget<"isTargetWin64()", CCDelegateTo<RetCC_X86_Win64_C>>,
 
+  // UEFI64 uses Win64 CC
+  CCIfSubtarget<"isTargetUEFI64()", CCDelegateTo<RetCC_X86_Win64_C>>,
+
   // Otherwise, drop to normal X86-64 CC
   CCDelegateTo<RetCC_X86_64_C>
 ]>;
@@ -1085,6 +1089,9 @@ def CC_X86_64 : CallingConv<[
   // Mingw64 and native Win64 use Win64 CC
   CCIfSubtarget<"isTargetWin64()", CCDelegateTo<CC_X86_Win64_C>>,
 
+  // UEFI uses Win64 CC
+  CCIfSubtarget<"isTargetUEFI64()", CCDelegateTo<CC_X86_Win64_C>>,
+
   // Otherwise, drop to normal X86-64 CC
   CCDelegateTo<CC_X86_64_C>
 ]>;
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp
index 29242c7059d5f..ef58c7619b243 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.cpp
+++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp
@@ -60,6 +60,7 @@ X86RegisterInfo::X86RegisterInfo(const Triple &TT)
   // Cache some information.
   Is64Bit = TT.isArch64Bit();
   IsWin64 = Is64Bit && TT.isOSWindows();
+  IsUEFI64 = Is64Bit && TT.isUEFI();
 
   // Use a callee-saved register as the base pointer.  These registers must
   // not conflict with any ABI requirements.  For example, in 32-bit mode PIC
@@ -227,7 +228,7 @@ X86RegisterInfo::getPointerRegClass(const MachineFunction &MF,
 const TargetRegisterClass *
 X86RegisterInfo::getGPRsForTailCall(const MachineFunction &MF) const {
   const Function &F = MF.getFunction();
-  if (IsWin64 || (F.getCallingConv() == CallingConv::Win64))
+  if (IsWin64 || IsUEFI64 || (F.getCallingConv() == CallingConv::Win64))
     return &X86::GR64_TCW64RegClass;
   else if (Is64Bit)
     return &X86::GR64_TCRegClass;
@@ -389,7 +390,7 @@ X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
       return IsWin64 ? CSR_Win64_SwiftError_SaveList
                      : CSR_64_SwiftError_SaveList;
 
-    if (IsWin64)
+    if (IsWin64 || IsUEFI64)
       return HasSSE ? CSR_Win64_SaveList : CSR_Win64_NoSSE_SaveList;
     if (CallsEHReturn)
       return CSR_64EHRet_SaveList;
@@ -514,7 +515,7 @@ X86RegisterInfo::getCallPreservedMask(const MachineFunction &MF,
     if (IsSwiftCC)
       return IsWin64 ? CSR_Win64_SwiftError_RegMask : CSR_64_SwiftError_RegMask;
 
-    return IsWin64 ? CSR_Win64_RegMask : CSR_64_RegMask;
+    return (IsWin64 || IsUEFI64) ? CSR_Win64_RegMask : CSR_64_RegMask;
   }
 
   return CSR_32_RegMask;
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.h b/llvm/lib/Target/X86/X86RegisterInfo.h
index b3c03e8f2bc22..13a5fbf16e981 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.h
+++ b/llvm/lib/Target/X86/X86RegisterInfo.h
@@ -31,6 +31,10 @@ class X86RegisterInfo final : public X86GenRegisterInfo {
   ///
   bool IsWin64;
 
+  /// IsUEFI64 - Is UEFI 64 bit target.
+  ///
+  bool IsUEFI64;
+
   /// SlotSize - Stack slot size in bytes.
   ///
   unsigned SlotSize;
diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h
index e0dd3565605b9..a793595532fb7 100644
--- a/llvm/lib/Target/X86/X86Subtarget.h
+++ b/llvm/lib/Target/X86/X86Subtarget.h
@@ -337,6 +337,10 @@ class X86Subtarget final : public X86GenSubtargetInfo {
 
   bool isTargetWin64() const { return Is64Bit && isOSWindows(); }
 
+  bool isTargetWinOrUEFI64() const {
+    return isTargetWin64() || isTargetUEFI64();
+  }
+
   bool isTargetWin32() const { return !Is64Bit && isOSWindows(); }
 
   bool isPICStyleGOT() const { return PICStyle == PICStyles::Style::GOT; }
@@ -352,6 +356,7 @@ class X86Subtarget final : public X86GenSubtargetInfo {
     switch (CC) {
     // On Win64, all these conventions just use the default convention.
     case CallingConv::C:
+      return isTargetWin64() || isTargetUEFI64();
     case CallingConv::Fast:
     case CallingConv::Tail:
     case CallingConv::Swift:

>From 94a74e7ad9b2e55e7b86d914ef3df0128c34d440 Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Thu, 1 May 2025 22:39:06 +0000
Subject: [PATCH 2/3] Remove isTargetWinOrUEFI64

---
 llvm/lib/Target/X86/X86CallingConv.td | 8 ++++----
 llvm/lib/Target/X86/X86Subtarget.h    | 4 ----
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/X86/X86CallingConv.td b/llvm/lib/Target/X86/X86CallingConv.td
index 8103e8c6df51b..5ae3bb27cb786 100644
--- a/llvm/lib/Target/X86/X86CallingConv.td
+++ b/llvm/lib/Target/X86/X86CallingConv.td
@@ -283,10 +283,10 @@ def RetCC_X86Common : CallingConv<[
             CCAssignToReg<[ZMM0,ZMM1,ZMM2,ZMM3]>>,
 
   // Long double types are always returned in FP0 (even with SSE),
-  // except on Win64.
-  CCIfNotSubtarget<"isTargetWinOrUEFI64()",
-                    CCIfType<[f80], CCAssignToReg<[FP0, FP1]>>>
-]>;
+  // except on Win64 and UEFI64.
+  CCIfNotSubtarget<"isTargetWin64()",
+                    CCIfNotSubtarget<"isTargetUEFI64()",
+                    CCIfType<[f80], CCAssignToReg<[FP0, FP1]>>>>]>;
 
 // X86-32 C return-value convention.
 def RetCC_X86_32_C : CallingConv<[
diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h
index a793595532fb7..a0b182d3f4c9b 100644
--- a/llvm/lib/Target/X86/X86Subtarget.h
+++ b/llvm/lib/Target/X86/X86Subtarget.h
@@ -337,10 +337,6 @@ class X86Subtarget final : public X86GenSubtargetInfo {
 
   bool isTargetWin64() const { return Is64Bit && isOSWindows(); }
 
-  bool isTargetWinOrUEFI64() const {
-    return isTargetWin64() || isTargetUEFI64();
-  }
-
   bool isTargetWin32() const { return !Is64Bit && isOSWindows(); }
 
   bool isPICStyleGOT() const { return PICStyle == PICStyles::Style::GOT; }

>From 1e14acc9a3abb655e5becd3d6adfb6f7f93e51bd Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Thu, 1 May 2025 22:42:33 +0000
Subject: [PATCH 3/3] Fix formatting

---
 llvm/lib/Target/X86/X86CallingConv.td | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/X86/X86CallingConv.td b/llvm/lib/Target/X86/X86CallingConv.td
index 5ae3bb27cb786..215906d9df8b3 100644
--- a/llvm/lib/Target/X86/X86CallingConv.td
+++ b/llvm/lib/Target/X86/X86CallingConv.td
@@ -286,7 +286,8 @@ def RetCC_X86Common : CallingConv<[
   // except on Win64 and UEFI64.
   CCIfNotSubtarget<"isTargetWin64()",
                     CCIfNotSubtarget<"isTargetUEFI64()",
-                    CCIfType<[f80], CCAssignToReg<[FP0, FP1]>>>>]>;
+                    CCIfType<[f80], CCAssignToReg<[FP0, FP1]>>>>
+]>;
 
 // X86-32 C return-value convention.
 def RetCC_X86_32_C : CallingConv<[



More information about the llvm-commits mailing list