[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