[llvm] [win][arm64ec] Handle `available_externally` functions (PR #151610)

Daniel Paoliello via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 1 10:19:52 PDT 2025


https://github.com/dpaoliello updated https://github.com/llvm/llvm-project/pull/151610

>From 7f0c55c2683eb255e708cb5fcd31a37719124385 Mon Sep 17 00:00:00 2001
From: Daniel Paoliello <danpao at microsoft.com>
Date: Thu, 31 Jul 2025 15:45:35 -0700
Subject: [PATCH] [win][arm64ec] Handle 'externally available' functions

---
 .../AArch64/AArch64Arm64ECCallLowering.cpp    | 11 +++++----
 .../AArch64/arm64ec-available-externally.ll   | 24 +++++++++++++++++++
 2 files changed, 30 insertions(+), 5 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/arm64ec-available-externally.ll

diff --git a/llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp b/llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp
index 509cbb092705d..e8d31612fbb7a 100644
--- a/llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp
@@ -813,8 +813,8 @@ bool AArch64Arm64ECCallLowering::runOnModule(Module &Mod) {
       }
     }
 
-    if (!F.hasFnAttribute(Attribute::HybridPatchable) || F.isDeclaration() ||
-        F.hasLocalLinkage() ||
+    if (!F.hasFnAttribute(Attribute::HybridPatchable) ||
+        F.isDeclarationForLinker() || F.hasLocalLinkage() ||
         F.getName().ends_with(HybridPatchableTargetSuffix))
       continue;
 
@@ -857,7 +857,7 @@ bool AArch64Arm64ECCallLowering::runOnModule(Module &Mod) {
 
   SetVector<GlobalValue *> DirectCalledFns;
   for (Function &F : Mod)
-    if (!F.isDeclaration() &&
+    if (!F.isDeclarationForLinker() &&
         F.getCallingConv() != CallingConv::ARM64EC_Thunk_Native &&
         F.getCallingConv() != CallingConv::ARM64EC_Thunk_X64)
       processFunction(F, DirectCalledFns, FnsMap);
@@ -869,7 +869,8 @@ bool AArch64Arm64ECCallLowering::runOnModule(Module &Mod) {
   };
   SmallVector<ThunkInfo> ThunkMapping;
   for (Function &F : Mod) {
-    if (!F.isDeclaration() && (!F.hasLocalLinkage() || F.hasAddressTaken()) &&
+    if (!F.isDeclarationForLinker() &&
+        (!F.hasLocalLinkage() || F.hasAddressTaken()) &&
         F.getCallingConv() != CallingConv::ARM64EC_Thunk_Native &&
         F.getCallingConv() != CallingConv::ARM64EC_Thunk_X64) {
       if (!F.hasComdat())
@@ -959,7 +960,7 @@ bool AArch64Arm64ECCallLowering::processFunction(
       // unprototyped functions in C)
       if (Function *F = CB->getCalledFunction()) {
         if (!LowerDirectToIndirect || F->hasLocalLinkage() ||
-            F->isIntrinsic() || !F->isDeclaration())
+            F->isIntrinsic() || !F->isDeclarationForLinker())
           continue;
 
         DirectCalledFns.insert(F);
diff --git a/llvm/test/CodeGen/AArch64/arm64ec-available-externally.ll b/llvm/test/CodeGen/AArch64/arm64ec-available-externally.ll
new file mode 100644
index 0000000000000..4a601f13bb81e
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/arm64ec-available-externally.ll
@@ -0,0 +1,24 @@
+; RUN: llc -mtriple arm64ec-windows-msvc -o - %s | FileCheck %s
+
+; Arm64EC Regression Test: The Arm64EC Call Lowering was placing "available
+; externally" items in COMDATs, which is not permitted by the module verifier.
+
+define available_externally float @f() {
+entry:
+  ret float 0x0
+}
+
+define i32 @caller() {
+entry:
+  call float @f()
+  ret i32 0
+}
+
+; Normal function gets an entry thunk, but not an exit thunk.
+; CHECK-DAG:    $ientry_thunk$cdecl$i8$v:
+; CHECK-NOT:    $iexit_thunk$cdecl$i8$v:
+
+; Available Externally function gets an exit thunk, but not an entry thunk.
+; CHECK-DAG:    $iexit_thunk$cdecl$f$v:
+; CHECK-DAG:    "#f$exit_thunk":
+; CHECK-NOT:    $ientry_thunk$cdecl$f$v:



More information about the llvm-commits mailing list