[llvm] [PowerPC][AIX] Emit weak_definition symbols as weak externals (PR #156072)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 8 07:42:18 PDT 2026
https://github.com/aabhinavg1 updated https://github.com/llvm/llvm-project/pull/156072
>From 43fbfa2074f6631b65fcce8dd5e8cee513004e79 Mon Sep 17 00:00:00 2001
From: aabhinavg1 <tiwariabhinavak at gmail.com>
Date: Fri, 29 Aug 2025 22:50:27 +0530
Subject: [PATCH 1/2] [PowerPC][AIX] Emit weak_definition symbols as weak
externals
- On AIX, the assembler does not recognize '.weak_definition'.
- Emit MCSA_WeakDefinition symbols using the standard weak directive (.weak)
and set storage class to C_WEAKEXT in XCOFF.
- Added test llvm/test/MC/PowerPC/aix-weak-definition.s
---
llvm/lib/MC/MCAsmStreamer.cpp | 14 +++++++++++---
llvm/lib/MC/MCXCOFFStreamer.cpp | 7 +++++++
llvm/test/MC/PowerPC/aix-weak-definition.s | 13 +++++++++++++
3 files changed, 31 insertions(+), 3 deletions(-)
create mode 100644 llvm/test/MC/PowerPC/aix-weak-definition.s
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index be8c022f39ad1..7b1a1878915bc 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -764,10 +764,18 @@ bool MCAsmStreamer::emitSymbolAttribute(MCSymbol *Symbol,
OS << "\t.extern\t";
break;
case MCSA_Weak: OS << MAI->getWeakDirective(); break;
- case MCSA_WeakDefinition:
- OS << "\t.weak_definition\t";
+ case MCSA_WeakDefinition: {
+ // AIX, use the standard weak directive (.weak) instead of
+ //'.weak_definition' because the AIX assembler does not
+ // recognize the '.weak_definition' directive.
+ const llvm::Triple &TT = getContext().getTargetTriple();
+ if (TT.isOSAIX())
+ OS << MAI->getWeakDirective();
+ else
+ OS << "\t.weak_definition\t";
break;
- // .weak_reference
+ }
+ // .weak_reference
case MCSA_WeakReference: OS << MAI->getWeakRefDirective(); break;
case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
case MCSA_Cold:
diff --git a/llvm/lib/MC/MCXCOFFStreamer.cpp b/llvm/lib/MC/MCXCOFFStreamer.cpp
index 4bf14c11068cb..cd5398dc7bc3b 100644
--- a/llvm/lib/MC/MCXCOFFStreamer.cpp
+++ b/llvm/lib/MC/MCXCOFFStreamer.cpp
@@ -72,6 +72,13 @@ bool MCXCOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
Symbol->setStorageClass(XCOFF::C_WEAKEXT);
Symbol->setExternal(true);
break;
+ case llvm::MCSA_WeakDefinition:
+ // On AIX/XCOFF, a weak definition symbol should be emitted
+ // as an external weak symbol (C_WEAKEXT), since the assembler
+ // does not support '.weak_definition' directly.
+ Symbol->setStorageClass(XCOFF::C_WEAKEXT);
+ Symbol->setExternal(true);
+ break;
case llvm::MCSA_Hidden:
Symbol->setVisibilityType(XCOFF::SYM_V_HIDDEN);
break;
diff --git a/llvm/test/MC/PowerPC/aix-weak-definition.s b/llvm/test/MC/PowerPC/aix-weak-definition.s
new file mode 100644
index 0000000000000..6bab51b91c63d
--- /dev/null
+++ b/llvm/test/MC/PowerPC/aix-weak-definition.s
@@ -0,0 +1,13 @@
+## Check that weak_definition symbols are emitted as weak externals.
+# Note: On AIX, .weak_definition is mapped to .weak by LLVM's backend.
+# RUN: llvm-mc -triple powerpc-ibm-aix-xcoff %s -filetype=obj -o - | \
+# RUN: llvm-objdump --syms - | FileCheck %s
+
+ .weak_definition foo # LLVM IR WeakDefinition → .weak on AIX
+foo:
+ blr
+
+# CHECK: SYMBOL TABLE:
+# CHECK-NEXT: 00000000 df *DEBUG* 00000000 .file
+# CHECK-NEXT: 00000000 l .text 00000004
+# CHECK-NEXT: 00000000 w F .text (csect: ) 00000000 foo
>From ccafe8855493653181a322a14972652cd5a6d03e Mon Sep 17 00:00:00 2001
From: aabhinavg1 <tiwariabhinavak at gmail.com>
Date: Sat, 8 Aug 2026 20:11:48 +0530
Subject: [PATCH 2/2] [PowerPC][AIX] Emit weak_definition symbols as weak
externals
Address review feedback: map .weak_definition to MCSA_Weak in the
generic AsmParser when assembling for XCOFF instead of special-casing
MCSA_WeakDefinition in the streamers, and revert the AIX-specific
streamer changes.
With this mapping, .weak_definition produces the documented .weak
directive in assembler output and a C_WEAKEXT weak external in object
output.
Fixes #130269
---
llvm/lib/MC/MCAsmStreamer.cpp | 14 +++-----------
llvm/lib/MC/MCParser/AsmParser.cpp | 7 ++++++-
llvm/lib/MC/MCXCOFFStreamer.cpp | 7 -------
llvm/test/MC/PowerPC/aix-weak-definition.s | 13 ++++++++++---
4 files changed, 19 insertions(+), 22 deletions(-)
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 7b1a1878915bc..be8c022f39ad1 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -764,18 +764,10 @@ bool MCAsmStreamer::emitSymbolAttribute(MCSymbol *Symbol,
OS << "\t.extern\t";
break;
case MCSA_Weak: OS << MAI->getWeakDirective(); break;
- case MCSA_WeakDefinition: {
- // AIX, use the standard weak directive (.weak) instead of
- //'.weak_definition' because the AIX assembler does not
- // recognize the '.weak_definition' directive.
- const llvm::Triple &TT = getContext().getTargetTriple();
- if (TT.isOSAIX())
- OS << MAI->getWeakDirective();
- else
- OS << "\t.weak_definition\t";
+ case MCSA_WeakDefinition:
+ OS << "\t.weak_definition\t";
break;
- }
- // .weak_reference
+ // .weak_reference
case MCSA_WeakReference: OS << MAI->getWeakRefDirective(); break;
case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
case MCSA_Cold:
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index acea3ab23680a..cf3ac4041f3c7 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -2025,7 +2025,12 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
case DK_REFERENCE:
return parseDirectiveSymbolAttribute(MCSA_Reference);
case DK_WEAK_DEFINITION:
- return parseDirectiveSymbolAttribute(MCSA_WeakDefinition);
+ // XCOFF uses `.weak` for weak definitions; emit MCSA_Weak instead of
+ // the Mach-O-specific `.weak_definition` directive.
+ return parseDirectiveSymbolAttribute(getContext().getObjectFileType() ==
+ MCContext::IsXCOFF
+ ? MCSA_Weak
+ : MCSA_WeakDefinition);
case DK_WEAK_REFERENCE:
return parseDirectiveSymbolAttribute(MCSA_WeakReference);
case DK_WEAK_DEF_CAN_BE_HIDDEN:
diff --git a/llvm/lib/MC/MCXCOFFStreamer.cpp b/llvm/lib/MC/MCXCOFFStreamer.cpp
index cd5398dc7bc3b..4bf14c11068cb 100644
--- a/llvm/lib/MC/MCXCOFFStreamer.cpp
+++ b/llvm/lib/MC/MCXCOFFStreamer.cpp
@@ -72,13 +72,6 @@ bool MCXCOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
Symbol->setStorageClass(XCOFF::C_WEAKEXT);
Symbol->setExternal(true);
break;
- case llvm::MCSA_WeakDefinition:
- // On AIX/XCOFF, a weak definition symbol should be emitted
- // as an external weak symbol (C_WEAKEXT), since the assembler
- // does not support '.weak_definition' directly.
- Symbol->setStorageClass(XCOFF::C_WEAKEXT);
- Symbol->setExternal(true);
- break;
case llvm::MCSA_Hidden:
Symbol->setVisibilityType(XCOFF::SYM_V_HIDDEN);
break;
diff --git a/llvm/test/MC/PowerPC/aix-weak-definition.s b/llvm/test/MC/PowerPC/aix-weak-definition.s
index 6bab51b91c63d..cf4c8db3074d1 100644
--- a/llvm/test/MC/PowerPC/aix-weak-definition.s
+++ b/llvm/test/MC/PowerPC/aix-weak-definition.s
@@ -1,9 +1,14 @@
-## Check that weak_definition symbols are emitted as weak externals.
-# Note: On AIX, .weak_definition is mapped to .weak by LLVM's backend.
+# Check that .weak_definition marks symbols as weak externals on AIX/XCOFF.
+#
+# .weak_definition is not a documented AIX directive; LLVM emits the
+# documented .weak directive instead.
+#
# RUN: llvm-mc -triple powerpc-ibm-aix-xcoff %s -filetype=obj -o - | \
# RUN: llvm-objdump --syms - | FileCheck %s
+# RUN: llvm-mc -triple powerpc-ibm-aix-xcoff %s -filetype=asm -o - | \
+# RUN: FileCheck %s --check-prefix=ASM
- .weak_definition foo # LLVM IR WeakDefinition → .weak on AIX
+ .weak_definition foo
foo:
blr
@@ -11,3 +16,5 @@ foo:
# CHECK-NEXT: 00000000 df *DEBUG* 00000000 .file
# CHECK-NEXT: 00000000 l .text 00000004
# CHECK-NEXT: 00000000 w F .text (csect: ) 00000000 foo
+
+# ASM: .weak foo
More information about the llvm-commits
mailing list