[llvm] [AArch64] Fix extern_weak function calls on Windows (PR #219202)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 27 05:45:08 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-aarch64
Author: cqwrteur (trcrsired)
<details>
<summary>Changes</summary>
On aarch64-windows-gnu/msvc, calls to extern_weak functions were incorrectly going through a GOT/COFFSTUB load (adrp/ldr/blr) instead of using a direct BL instruction. This happened because classifyGlobalFunctionReference delegated to ClassifyGlobalReference for Windows, which returned MO_GOT | MO_COFFSTUB for extern_weak symbols.
The fix adds an early return of MO_NO_FLAG for extern_weak function references on Windows, allowing a direct call. The linker handles extern_weak by resolving to either the real symbol or null, so a direct BL is correct (matching ELF behavior).
issue: #<!-- -->218899
---
Full diff: https://github.com/llvm/llvm-project/pull/219202.diff
2 Files Affected:
- (modified) llvm/lib/Target/AArch64/AArch64Subtarget.cpp (+6)
- (modified) llvm/test/CodeGen/AArch64/windows-extern-weak.ll (+23-4)
``````````diff
diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.cpp b/llvm/lib/Target/AArch64/AArch64Subtarget.cpp
index 4fef12ab37ad8..19486ebc36cae 100644
--- a/llvm/lib/Target/AArch64/AArch64Subtarget.cpp
+++ b/llvm/lib/Target/AArch64/AArch64Subtarget.cpp
@@ -503,6 +503,12 @@ unsigned AArch64Subtarget::classifyGlobalFunctionReference(
}
}
+ // extern_weak function references on Windows should not go through
+ // GOT/COFFSTUB. The linker resolves extern_weak to either the real
+ // symbol or null, so a direct call is correct.
+ if (GV->hasExternalWeakLinkage())
+ return AArch64II::MO_NO_FLAG;
+
// Use ClassifyGlobalReference for setting MO_DLLIMPORT/MO_COFFSTUB.
return ClassifyGlobalReference(GV, TM);
}
diff --git a/llvm/test/CodeGen/AArch64/windows-extern-weak.ll b/llvm/test/CodeGen/AArch64/windows-extern-weak.ll
index ecdb802222935..edc5874c4ff39 100644
--- a/llvm/test/CodeGen/AArch64/windows-extern-weak.ll
+++ b/llvm/test/CodeGen/AArch64/windows-extern-weak.ll
@@ -11,7 +11,7 @@ define void @func() nounwind {
; CHECK-NEXT: ldr x8, [x8, :lo12:.refptr.weakfunc]
; CHECK-NEXT: cbz x8, .LBB0_2
; CHECK-NEXT: // %bb.1:
-; CHECK-NEXT: blr x8
+; CHECK-NEXT: bl weakfunc
; CHECK-NEXT: .LBB0_2:
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
; CHECK-NEXT: ret
@@ -23,9 +23,7 @@ define void @func() nounwind {
; FISEL-NEXT: ldr x8, [x8, :lo12:.refptr.weakfunc]
; FISEL-NEXT: cbz x8, .LBB0_2
; FISEL-NEXT: // %bb.1:
-; FISEL-NEXT: adrp x8, .refptr.weakfunc
-; FISEL-NEXT: ldr x8, [x8, :lo12:.refptr.weakfunc]
-; FISEL-NEXT: blr x8
+; FISEL-NEXT: bl weakfunc
; FISEL-NEXT: .LBB0_2:
; FISEL-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
; FISEL-NEXT: ret
@@ -41,3 +39,24 @@ define void @func() nounwind {
}
declare extern_weak void @weakfunc()
+
+define ptr @use() {
+; CHECK-LABEL: use:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
+; CHECK: bl foo
+; CHECK: ldr x30, [sp], #16 // 8-byte Folded Reload
+; CHECK: ret
+;
+; FISEL-LABEL: use:
+; FISEL: // %bb.0: // %entry
+; FISEL-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
+; FISEL: bl foo
+; FISEL: ldr x30, [sp], #16 // 8-byte Folded Reload
+; FISEL: ret
+entry:
+ %r = call ptr @foo()
+ ret ptr %r
+}
+
+declare extern_weak dso_local ptr @foo()
``````````
</details>
https://github.com/llvm/llvm-project/pull/219202
More information about the llvm-commits
mailing list