Skip to content

[CodeGen][ARM64EC] Use MCSymbolRefExpr::VK_None for function aliases. #92100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 16, 2024

Conversation

cjacek
Copy link
Contributor

@cjacek cjacek commented May 14, 2024

VK_WEAKREF is meant for .weakref assembly expressions, but we use a regular .set here.

@llvmbot
Copy link
Member

llvmbot commented May 14, 2024

@llvm/pr-subscribers-backend-aarch64

Author: Jacek Caban (cjacek)

Changes

Depends on #92099.

VK_WEAKREF is meant for .weakref assembly expressions, but we use a regular .set here.


Full diff: https://github.com/llvm/llvm-project/pull/92100.diff

2 Files Affected:

  • (modified) llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp (+36-39)
  • (added) llvm/test/CodeGen/AArch64/arm64ec-symbols.ll (+25)
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index ee39c6355c298..8ce7f87abca00 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -1161,52 +1161,49 @@ void AArch64AsmPrinter::emitFunctionEntryLabel() {
     TS->emitDirectiveVariantPCS(CurrentFnSym);
   }
 
+  AsmPrinter::emitFunctionEntryLabel();
+
   if (TM.getTargetTriple().isWindowsArm64EC() &&
       !MF->getFunction().hasLocalLinkage()) {
     // For ARM64EC targets, a function definition's name is mangled differently
-    // from the normal symbol. We emit the alias from the unmangled symbol to
-    // mangled symbol name here.
-    if (MDNode *Unmangled =
-            MF->getFunction().getMetadata("arm64ec_unmangled_name")) {
-      AsmPrinter::emitFunctionEntryLabel();
-
-      if (MDNode *ECMangled =
-              MF->getFunction().getMetadata("arm64ec_ecmangled_name")) {
-        StringRef UnmangledStr =
-            cast<MDString>(Unmangled->getOperand(0))->getString();
-        MCSymbol *UnmangledSym =
-            MMI->getContext().getOrCreateSymbol(UnmangledStr);
-        StringRef ECMangledStr =
-            cast<MDString>(ECMangled->getOperand(0))->getString();
-        MCSymbol *ECMangledSym =
-            MMI->getContext().getOrCreateSymbol(ECMangledStr);
-        OutStreamer->emitSymbolAttribute(UnmangledSym, MCSA_WeakAntiDep);
-        OutStreamer->emitAssignment(
-            UnmangledSym,
-            MCSymbolRefExpr::create(ECMangledSym, MCSymbolRefExpr::VK_WEAKREF,
-                                    MMI->getContext()));
-        OutStreamer->emitSymbolAttribute(ECMangledSym, MCSA_WeakAntiDep);
-        OutStreamer->emitAssignment(
-            ECMangledSym,
-            MCSymbolRefExpr::create(CurrentFnSym, MCSymbolRefExpr::VK_WEAKREF,
-                                    MMI->getContext()));
-        return;
+    // from the normal symbol, emit required aliases here.
+    auto emitFunctionAlias = [&](MCSymbol *Src, MCSymbol *Dst) {
+      OutStreamer->beginCOFFSymbolDef(Src);
+      OutStreamer->emitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
+                                      << COFF::SCT_COMPLEX_TYPE_SHIFT);
+      OutStreamer->endCOFFSymbolDef();
+      OutStreamer->emitSymbolAttribute(Src, MCSA_WeakAntiDep);
+      OutStreamer->emitAssignment(
+          Src, MCSymbolRefExpr::create(Dst, MCSymbolRefExpr::VK_None,
+                                       MMI->getContext()));
+    };
+
+    auto getSymbolFromMetadata = [&](StringRef Name) {
+      MCSymbol *Sym = nullptr;
+      if (MDNode *Node = MF->getFunction().getMetadata(Name)) {
+        StringRef NameStr = cast<MDString>(Node->getOperand(0))->getString();
+        Sym = MMI->getContext().getOrCreateSymbol(NameStr);
+      }
+      return Sym;
+    };
+
+    if (MCSymbol *UnmangledSym =
+            getSymbolFromMetadata("arm64ec_unmangled_name")) {
+      MCSymbol *ECMangledSym = getSymbolFromMetadata("arm64ec_ecmangled_name");
+
+      if (ECMangledSym) {
+        // An external function, emit the alias from the unmangled symbol to
+        // mangled symbol name and the alias from the mangled symbol to guest
+        // exit thunk.
+        emitFunctionAlias(UnmangledSym, ECMangledSym);
+        emitFunctionAlias(ECMangledSym, CurrentFnSym);
       } else {
-        StringRef UnmangledStr =
-            cast<MDString>(Unmangled->getOperand(0))->getString();
-        MCSymbol *UnmangledSym =
-            MMI->getContext().getOrCreateSymbol(UnmangledStr);
-        OutStreamer->emitSymbolAttribute(UnmangledSym, MCSA_WeakAntiDep);
-        OutStreamer->emitAssignment(
-            UnmangledSym,
-            MCSymbolRefExpr::create(CurrentFnSym, MCSymbolRefExpr::VK_WEAKREF,
-                                    MMI->getContext()));
-        return;
+        // A function implementation, emit the alias from the unmangled symbol
+        // to mangled symbol name.
+        emitFunctionAlias(UnmangledSym, CurrentFnSym);
       }
     }
   }
-
-  return AsmPrinter::emitFunctionEntryLabel();
 }
 
 /// Small jump tables contain an unsigned byte or half, representing the offset
diff --git a/llvm/test/CodeGen/AArch64/arm64ec-symbols.ll b/llvm/test/CodeGen/AArch64/arm64ec-symbols.ll
new file mode 100644
index 0000000000000..ab01e1f58fd79
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/arm64ec-symbols.ll
@@ -0,0 +1,25 @@
+; RUN: llc -mtriple=arm64ec-pc-windows-msvc < %s | FileCheck %s
+
+declare void @func() nounwind;
+
+define void @caller() nounwind {
+  call void @func()
+  ret void
+}
+
+; CHECK:      .def    caller;
+; CHECK-NEXT: .type   32;
+; CHECK-NEXT: .endef
+; CHECK-NEXT: .weak_anti_dep  caller
+; CHECK-NEXT: .set caller, "#caller"{{$}}
+
+; CHECK:      .def    func;
+; CHECK-NEXT: .type   32;
+; CHECK-NEXT: .endef
+; CHECK-NEXT: .weak_anti_dep  func
+; CHECK-NEXT: .set func, "#func"{{$}}
+; CHECK-NEXT: .def    "#func";
+; CHECK-NEXT: .type   32;
+; CHECK-NEXT: .endef
+; CHECK-NEXT: .weak_anti_dep  "#func"
+; CHECK-NEXT: .set "#func", "#func$exit_thunk"{{$}}

@efriedma-quic
Copy link
Collaborator

efriedma-quic commented May 14, 2024

Maybe consider pre-committing arm64ec-symbols.ll.

I'd like to see the tests show the effect on the emitted symbols using llvm-objdump, in addition to the asm... from what I recall, the weakref hack was necessary to make the emitted symbols have the right COFF attributes. If that test shows it's not necessary, that's fine, I guess.

@cjacek cjacek force-pushed the arm64ec-ref-kind branch from a3eae1b to 3e39283 Compare May 15, 2024 16:37
@cjacek
Copy link
Contributor Author

cjacek commented May 15, 2024

The new version adds the test in a separate commit. It passes both with and without the second commit. Should I create a separate MR for that?

It seems fine in my testing and things like https://reviews.llvm.org/D157547#4650727 seem to work as expected.

Copy link
Collaborator

@efriedma-quic efriedma-quic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@cjacek cjacek force-pushed the arm64ec-ref-kind branch from 3e39283 to d69f95a Compare May 16, 2024 13:23
@cjacek cjacek merged commit 93c02b7 into llvm:main May 16, 2024
3 of 4 checks passed
@cjacek cjacek deleted the arm64ec-ref-kind branch May 16, 2024 13:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants