[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