[llvm-branch-commits] [llvm] [AArch64] Classify global references on UEFI like Windows COFF (PR #232703)

Prabhu Rajasekaran via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Oct 16 23:26:57 PDT 2026


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

>From 68a0dc44e0d71a2e82836dc4220a2b14d87d053a Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Fri, 16 Oct 2026 04:48:54 -0700
Subject: [PATCH] [AArch64] Classify global references on UEFI like Windows
 COFF

Apply the Windows COFF rules for global references to
aarch64-unknown-uefi, which produces the same PE/COFF images:

* classify dllimport and non-dso-local globals with MO_DLLIMPORT /
  MO_COFFSTUB, so extern_weak symbols are referenced through a stub that
  can be resolved to zero by the linker,
* keep the existing SelectionDAG, FastISel and GlobalISel handling of
  calls and tail calls to extern_weak functions in sync with that,
* default to the PIC relocation model, so jump tables and other
  references stay position independent in relocatable PE images,
* lower ifuncs on UEFI as COFF has no support for them.

The extern weak and jump table tests gain aarch64-unknown-uefi run lines.

Assisted-by: Claude
---
 llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp          | 6 +++---
 llvm/lib/Target/AArch64/AArch64FastISel.cpp           | 2 +-
 llvm/lib/Target/AArch64/AArch64ISelLowering.cpp       | 3 ++-
 llvm/lib/Target/AArch64/AArch64Subtarget.cpp          | 4 ++--
 llvm/lib/Target/AArch64/AArch64TargetMachine.cpp      | 6 +++---
 llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp | 2 +-
 llvm/test/CodeGen/AArch64/win64-jumptable.ll          | 1 +
 llvm/test/CodeGen/AArch64/windows-extern-weak.ll      | 3 +++
 8 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 18f5b1c8149711..1dd32d5ca55e9e 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -3630,7 +3630,7 @@ bool IRTranslatorImpl::translateCall(const User &U,
   // FIXME: support Windows dllimport function calls and calls through
   // weak symbols.
   if (F && (F->hasDLLImportStorageClass() ||
-            (MF->getTarget().getTargetTriple().isOSWindows() &&
+            (MF->getTarget().getTargetTriple().isOSWindowsOrUEFI() &&
              F->hasExternalWeakLinkage())))
     return false;
 
@@ -3850,8 +3850,8 @@ bool IRTranslatorImpl::translateInvoke(const User &U,
   // FIXME: support Windows dllimport function calls and calls through
   // weak symbols.
   if (Fn && (Fn->hasDLLImportStorageClass() ||
-            (MF->getTarget().getTargetTriple().isOSWindows() &&
-             Fn->hasExternalWeakLinkage())))
+             (MF->getTarget().getTargetTriple().isOSWindowsOrUEFI() &&
+              Fn->hasExternalWeakLinkage())))
     return false;
 
   bool LowerInlineAsm = I.isInlineAsm();
diff --git a/llvm/lib/Target/AArch64/AArch64FastISel.cpp b/llvm/lib/Target/AArch64/AArch64FastISel.cpp
index aaa95824bf6030..c0a8bebc000706 100644
--- a/llvm/lib/Target/AArch64/AArch64FastISel.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FastISel.cpp
@@ -3218,7 +3218,7 @@ bool AArch64FastISel::fastLowerCall(CallLoweringInfo &CLI) {
   // The weak function target may be zero; in that case we must use indirect
   // addressing via a stub on windows as it may be out of range for a
   // PC-relative jump.
-  if (Subtarget->isTargetWindows() && Addr.getGlobalValue() &&
+  if (Subtarget->isTargetWindowsOrUEFI() && Addr.getGlobalValue() &&
       Addr.getGlobalValue()->hasExternalWeakLinkage())
     return false;
 
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 42729b32cd7aa6..6d6cd21f25be20 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -10139,7 +10139,8 @@ bool AArch64TargetLowering::isEligibleForTailCallOptimization(
     const GlobalValue *GV = G->getGlobal();
     const Triple &TT = GV->getParent()->getTargetTriple();
     if (GV->hasExternalWeakLinkage() &&
-        (!TT.isOSWindows() || TT.isOSBinFormatELF() || TT.isOSBinFormatMachO()))
+        (!TT.isOSWindowsOrUEFI() || TT.isOSBinFormatELF() ||
+         TT.isOSBinFormatMachO()))
       return false;
   }
 
diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.cpp b/llvm/lib/Target/AArch64/AArch64Subtarget.cpp
index 4950294592a5cd..0adee4dc05611b 100644
--- a/llvm/lib/Target/AArch64/AArch64Subtarget.cpp
+++ b/llvm/lib/Target/AArch64/AArch64Subtarget.cpp
@@ -396,7 +396,7 @@ AArch64Subtarget::ClassifyGlobalReference(const GlobalValue *GV,
     if (GV->hasDLLImportStorageClass()) {
       return AArch64II::MO_GOT | AArch64II::MO_DLLIMPORT;
     }
-    if (getTargetTriple().isOSWindows())
+    if (getTargetTriple().isOSWindowsOrUEFI())
       return AArch64II::MO_GOT | AArch64II::MO_COFFSTUB;
     return AArch64II::MO_GOT;
   }
@@ -432,7 +432,7 @@ unsigned AArch64Subtarget::classifyGlobalFunctionReference(
       F->hasFnAttribute(Attribute::NonLazyBind) && !TM.shouldAssumeDSOLocal(GV))
     return AArch64II::MO_GOT;
 
-  if (getTargetTriple().isOSWindows()) {
+  if (getTargetTriple().isOSWindowsOrUEFI()) {
     if (isWindowsArm64EC() && GV->getValueType()->isFunctionTy()) {
       if (GV->hasDLLImportStorageClass()) {
         // On Arm64EC, if we're calling a symbol from the import table
diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
index db97ad61b274f0..c1014bfd66bef7 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
@@ -152,8 +152,8 @@ static StringRef computeDefaultCPU(const Triple &TT, StringRef CPU) {
 
 static Reloc::Model getEffectiveRelocModel(const Triple &TT,
                                            std::optional<Reloc::Model> RM) {
-  // AArch64 Darwin and Windows are always PIC.
-  if (TT.isOSDarwin() || TT.isOSWindows())
+  // AArch64 Darwin, Windows and UEFI are always PIC.
+  if (TT.isOSDarwin() || TT.isOSWindowsOrUEFI())
     return Reloc::PIC_;
   // On ELF platforms the default static relocation model has a smart enough
   // linker to cope with referencing external symbols defined in a shared
@@ -472,7 +472,7 @@ void AArch64TargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
         if (Level != OptimizationLevel::O0)
           LPM.addPass(LoopIdiomVectorizePass());
       });
-  if (getTargetTriple().isOSWindows())
+  if (getTargetTriple().isOSWindowsOrUEFI())
     PB.registerPipelineEarlySimplificationEPCallback(
         [](ModulePassManager &PM, OptimizationLevel, ThinOrFullLTOPhase) {
           PM.addPass(LowerIFuncPass());
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
index 18a41f98a76341..1cf369608e8074 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
@@ -1099,7 +1099,7 @@ bool AArch64CallLowering::isEligibleForTailCallOptimization(
     const GlobalValue *GV = Info.Callee.getGlobal();
     const Triple &TT = GV->getParent()->getTargetTriple();
     if (GV->hasExternalWeakLinkage() &&
-        (!TT.isOSWindows() || TT.isOSBinFormatELF() ||
+        (!TT.isOSWindowsOrUEFI() || TT.isOSBinFormatELF() ||
          TT.isOSBinFormatMachO())) {
       LLVM_DEBUG(dbgs() << "... Cannot tail call externally-defined function "
                            "with weak linkage for this OS.\n");
diff --git a/llvm/test/CodeGen/AArch64/win64-jumptable.ll b/llvm/test/CodeGen/AArch64/win64-jumptable.ll
index f9f2b0bf0ca5cf..ecd7ac0d0b4fca 100644
--- a/llvm/test/CodeGen/AArch64/win64-jumptable.ll
+++ b/llvm/test/CodeGen/AArch64/win64-jumptable.ll
@@ -1,5 +1,6 @@
 ; RUN: llc -o - %s -mtriple=aarch64-windows -aarch64-min-jump-table-entries=4 -aarch64-enable-compress-jump-tables=0 | FileCheck %s
 ; RUN: llc -o - %s -mtriple=aarch64-windows -aarch64-min-jump-table-entries=4 -aarch64-enable-compress-jump-tables=0 -filetype=obj | llvm-readobj --unwind - | FileCheck %s -check-prefix=UNWIND
+; RUN: llc -o - %s -mtriple=aarch64-unknown-uefi -aarch64-min-jump-table-entries=4 -aarch64-enable-compress-jump-tables=0 | FileCheck %s
 
 define void @f(i32 %x) {
 entry:
diff --git a/llvm/test/CodeGen/AArch64/windows-extern-weak.ll b/llvm/test/CodeGen/AArch64/windows-extern-weak.ll
index ecdb8022229354..934c06ef6f20e3 100644
--- a/llvm/test/CodeGen/AArch64/windows-extern-weak.ll
+++ b/llvm/test/CodeGen/AArch64/windows-extern-weak.ll
@@ -2,6 +2,9 @@
 ; RUN: llc -mtriple aarch64-windows -filetype asm -o - < %s | FileCheck %s
 ; RUN: llc -mtriple aarch64-windows -filetype asm -o - -fast-isel %s | FileCheck %s --check-prefix=FISEL
 ; RUN: llc -mtriple aarch64-windows -filetype asm -o - -global-isel -global-isel-abort=0 %s | FileCheck %s
+; RUN: llc -mtriple aarch64-unknown-uefi -filetype asm -o - < %s | FileCheck %s
+; RUN: llc -mtriple aarch64-unknown-uefi -filetype asm -o - -fast-isel %s | FileCheck %s --check-prefix=FISEL
+; RUN: llc -mtriple aarch64-unknown-uefi -filetype asm -o - -global-isel -global-isel-abort=0 %s | FileCheck %s
 
 define void @func() nounwind {
 ; CHECK-LABEL: func:



More information about the llvm-branch-commits mailing list