Skip to content

Commit

Permalink
[IR] Use EXPORTAS for ARM64EC mangled symbols with dllexport attribut…
Browse files Browse the repository at this point in the history
…e. (#81940)

We currently just use mangled name. This works fine, because linker
should detect that and demangle it for the export table. However, on
MSVC, the compiler is more specific and passes demangled name as well,
with EXPORTAS. This PR aims to match that. MSVC doesn't use quotes in
this case, so I added '#' to the list of characters that don't need it.
  • Loading branch information
cjacek committed Mar 30, 2024
1 parent 37c175a commit 799e1d6
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
14 changes: 13 additions & 1 deletion llvm/lib/IR/Mangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/Object/COFF.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Triple.h"

using namespace llvm;

namespace {
Expand Down Expand Up @@ -192,7 +194,7 @@ void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,

// Check if the name needs quotes to be safe for the linker to interpret.
static bool canBeUnquotedInDirective(char C) {
return isAlnum(C) || C == '_' || C == '@';
return isAlnum(C) || C == '_' || C == '@' || C == '#';
}

static bool canBeUnquotedInDirective(StringRef Name) {
Expand Down Expand Up @@ -233,6 +235,16 @@ void llvm::emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV,
} else {
Mangler.getNameWithPrefix(OS, GV, false);
}
if (TT.isWindowsArm64EC()) {
// Use EXPORTAS for mangled ARM64EC symbols.
// FIXME: During LTO, we're invoked prior to the EC lowering pass,
// so symbols are not yet mangled. Emitting the unmangled name
// typically functions correctly; the linker can resolve the export
// with the demangled alias.
if (std::optional<std::string> demangledName =
object::getArm64ECDemangledFunctionName(GV->getName()))
OS << ",EXPORTAS," << *demangledName;
}
if (NeedQuotes)
OS << "\"";

Expand Down
39 changes: 39 additions & 0 deletions llvm/test/CodeGen/AArch64/dllexport.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
; RUN: llc -mtriple aarch64-windows-gnu -filetype asm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-GNU
; RUN: llc -mtriple aarch64-windows-msvc -filetype asm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-MSVC
; RUN: llc -mtriple arm64ec-windows-gnu -filetype asm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-GNU-EC
; RUN: llc -mtriple arm64ec-windows-msvc -filetype asm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-MSVC-EC

define void @f() {
ret void
Expand Down Expand Up @@ -71,3 +73,40 @@ define weak_odr dllexport void @l() {
; CHECK-MSVC: .ascii " /EXPORT:s"
; CHECK-MSVC: .ascii " /EXPORT:t"
; CHECK-MSVC: .ascii " /EXPORT:u"

; CHECK-GNU-EC-NOT: -export:f
; CHECK-GNU-EC-NOT: -export:#f,EXPORTAS,f
; CHECK-GNU-EC: .ascii " -export:#g,EXPORTAS,g
; CHECK-GNU-EC: .ascii " -export:#h,EXPORTAS,h
; CHECK-GNU-EC-NOT: -export:i
; CHECK-GNU-EC-NOT: -export:#i,EXPORTAS,i
; CHECK-GNU-EC: .ascii " -export:#j,EXPORTAS,j"
; CHECK-GNU-EC: .ascii " -export:#k,EXPORTAS,k"
; CHECK-GNU-EC: .ascii " -export:#l,EXPORTAS,l"
; CHECK-GNU-EC: .ascii " -export:m,data"
; CHECK-GNU-EC: .ascii " -export:n,data"
; CHECK-GNU-EC: .ascii " -export:o,data"
; CHECK-GNU-EC: .ascii " -export:p,data"
; CHECK-GNU-EC: .ascii " -export:q,data"
; CHECK-GNU-EC: .ascii " -export:r"
; CHECK-GNU-EC: .ascii " -export:s"
; CHECK-GNU-EC: .ascii " -export:t"
; CHECK-GNU-EC: .ascii " -export:u"
; CHECK-MSVC-EC-NOT: /EXPORT:f
; CHECK-MSVC-EC-NOT: /EXPORT:#f,EXPORTAS,f
; CHECK-MSVC-EC: .ascii " /EXPORT:#g,EXPORTAS,g"
; CHECK-MSVC-EC: .ascii " /EXPORT:#h,EXPORTAS,h"
; CHECK-MSVC-EC-NOT: /EXPORT:i
; CHECK-MSVC-EC-NOT: /EXPORT:#i,EXPORTAS,i
; CHECK-MSVC-EC: .ascii " /EXPORT:#j,EXPORTAS,j"
; CHECK-MSVC-EC: .ascii " /EXPORT:#k,EXPORTAS,k"
; CHECK-MSVC-EC: .ascii " /EXPORT:#l,EXPORTAS,l"
; CHECK-MSVC-EC: .ascii " /EXPORT:m,DATA"
; CHECK-MSVC-EC: .ascii " /EXPORT:n,DATA"
; CHECK-MSVC-EC: .ascii " /EXPORT:o,DATA"
; CHECK-MSVC-EC: .ascii " /EXPORT:p,DATA"
; CHECK-MSVC-EC: .ascii " /EXPORT:q,DATA"
; CHECK-MSVC-EC: .ascii " /EXPORT:r"
; CHECK-MSVC-EC: .ascii " /EXPORT:s"
; CHECK-MSVC-EC: .ascii " /EXPORT:t"
; CHECK-MSVC-EC: .ascii " /EXPORT:u"

0 comments on commit 799e1d6

Please sign in to comment.