[llvm] Workaround MSVC Linker Issue when Cross-Compiling for ARM64EC (PR #143659)
Jiachen Yuan via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 10 23:25:52 PDT 2025
https://github.com/JiachenYuan created https://github.com/llvm/llvm-project/pull/143659
This MR presents a temporary workaround for the issue described at https://github.com/llvm/llvm-project/issues/143575. While an [upstream MSVC bug](https://developercommunity.visualstudio.com/t/MSVC-Linker-Issue-When-Cross-Compiling-L/10920141) is reported, it makes sense to apply a workaround in LLVM code to quickly unblock anyone affected.
>From 7b87c4c9313db84642820a9b435a1739ba667159 Mon Sep 17 00:00:00 2001
From: Jiachen Yuan <jiacheny at nvidia.com>
Date: Tue, 10 Jun 2025 22:58:45 -0700
Subject: [PATCH] Workaround MSVC Linker Issue for ARM64EC
---
llvm/include/llvm/IR/Mangler.h | 11 ++++++++++-
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 7 ++++---
.../lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp | 6 ++++--
3 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/llvm/include/llvm/IR/Mangler.h b/llvm/include/llvm/IR/Mangler.h
index e3dfe1eac6189..508d85631edf9 100644
--- a/llvm/include/llvm/IR/Mangler.h
+++ b/llvm/include/llvm/IR/Mangler.h
@@ -26,7 +26,16 @@ class Triple;
class Twine;
class raw_ostream;
-constexpr std::string_view HybridPatchableTargetSuffix = "$hp_target";
+// TODO: There is a linker failure that is only hit when compiling llvm for
+// arm64ec on windows. While it is not clear what the root cause is, removing
+// the dollar sign from the following variable and re-concatenating the string
+// at its uses is a **temporary** workaround to help eliminate the linker
+// failure. The description and context of the issue is at
+// https://github.com/llvm/llvm-project/issues/143575#issuecomment-2960369418.
+// The upstream MSVC bug is filed at
+// https://developercommunity.visualstudio.com/t/MSVC-Linker-Issue-When-Cross-
+// Compiling-L/10920141.
+constexpr std::string_view HybridPatchableTargetSuffix = "hp_target";
class Mangler {
/// We need to give global values the same name every time they are mangled.
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index e13e92378d4aa..a449b1cd7521f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -4729,6 +4729,8 @@ AsmPrinter::getCodeViewJumpTableInfo(int JTI, const MachineInstr *BranchInstr,
codeview::JumpTableEntrySize::Int32);
}
+static const std::string HPSuffix = ("$" + HybridPatchableTargetSuffix).str();
+
void AsmPrinter::emitCOFFReplaceableFunctionData(Module &M) {
const Triple &TT = TM.getTargetTriple();
assert(TT.isOSBinFormatCOFF());
@@ -4749,9 +4751,8 @@ void AsmPrinter::emitCOFFReplaceableFunctionData(Module &M) {
// For hybrid-patchable targets, strip the prefix so that we can mark
// the real function as replaceable.
- if (IsTargetArm64EC && Name.ends_with(HybridPatchableTargetSuffix)) {
- Name = Name.drop_back(HybridPatchableTargetSuffix.size());
- }
+ if (IsTargetArm64EC && Name.ends_with(HPSuffix))
+ Name = Name.drop_back(HPSuffix.size());
MCSymbol *FuncOverrideSymbol =
MMI->getContext().getOrCreateSymbol(Name + "_$fo$");
diff --git a/llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp b/llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp
index 509cbb092705d..af1c4528990b7 100644
--- a/llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp
@@ -760,6 +760,8 @@ void AArch64Arm64ECCallLowering::lowerCall(CallBase *CB) {
CB->setCalledOperand(GuardCheck);
}
+static const std::string HPSuffix = ("$" + HybridPatchableTargetSuffix).str();
+
bool AArch64Arm64ECCallLowering::runOnModule(Module &Mod) {
if (!GenerateThunks)
return false;
@@ -815,7 +817,7 @@ bool AArch64Arm64ECCallLowering::runOnModule(Module &Mod) {
if (!F.hasFnAttribute(Attribute::HybridPatchable) || F.isDeclaration() ||
F.hasLocalLinkage() ||
- F.getName().ends_with(HybridPatchableTargetSuffix))
+ F.getName().ends_with(HPSuffix))
continue;
// Rename hybrid patchable functions and change callers to use a global
@@ -823,7 +825,7 @@ bool AArch64Arm64ECCallLowering::runOnModule(Module &Mod) {
if (std::optional<std::string> MangledName =
getArm64ECMangledFunctionName(F.getName().str())) {
std::string OrigName(F.getName());
- F.setName(MangledName.value() + HybridPatchableTargetSuffix);
+ F.setName(MangledName.value() + HPSuffix);
// The unmangled symbol is a weak alias to an undefined symbol with the
// "EXP+" prefix. This undefined symbol is resolved by the linker by
More information about the llvm-commits
mailing list