[llvm] [SystemZ][GOFF] Reference to external variable needs PR symbol (PR #185742)

Kai Nacke via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 10 08:20:03 PDT 2026


https://github.com/redstar updated https://github.com/llvm/llvm-project/pull/185742

>From 6b34d4c2f21339d5f65a7cdb90f1440eb7173edb Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Tue, 10 Mar 2026 11:31:37 -0400
Subject: [PATCH 1/9] [SystemZ][GOFF] Reference to external variable needs PR
 symbol

Variables are modelled as parts in the GOFF format. Referencing a
variable defined in a different compilation unit requires to use
a PR symbol instead of EXTRN/WEXTRN instruction.
A small issue is that these PR symbols can refer to the same ED
symbols, for which a section needs to be created.
---
 llvm/include/llvm/MC/MCGOFFObjectWriter.h     |  6 ++
 llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp    |  5 +-
 llvm/lib/MC/GOFFObjectWriter.cpp              | 32 +++++--
 llvm/lib/MC/MCGOFFStreamer.cpp                | 17 +++-
 .../MCTargetDesc/SystemZHLASMAsmStreamer.cpp  |  9 +-
 llvm/test/CodeGen/SystemZ/zos-section-1.ll    | 92 ++++++++++---------
 llvm/test/CodeGen/SystemZ/zos-section-2.ll    | 62 +++++++------
 llvm/test/CodeGen/SystemZ/zos-symbol-2.ll     | 24 ++---
 8 files changed, 151 insertions(+), 96 deletions(-)

diff --git a/llvm/include/llvm/MC/MCGOFFObjectWriter.h b/llvm/include/llvm/MC/MCGOFFObjectWriter.h
index 57e152f6a61dc..82ff6fddf6552 100644
--- a/llvm/include/llvm/MC/MCGOFFObjectWriter.h
+++ b/llvm/include/llvm/MC/MCGOFFObjectWriter.h
@@ -83,6 +83,9 @@ class GOFFObjectWriter : public MCObjectWriter {
   // The RootSD section.
   MCSectionGOFF *RootSD = nullptr;
 
+  // The ED section for external data references.
+  MCSectionGOFF *ExternalED = nullptr;
+
   // Saved relocation data.
   std::vector<GOFFRelocationEntry> Relocations;
 
@@ -92,6 +95,9 @@ class GOFFObjectWriter : public MCObjectWriter {
   ~GOFFObjectWriter() override;
 
   void setRootSD(MCSectionGOFF *RootSD) { this->RootSD = RootSD; }
+  void setExternalED(MCSectionGOFF *ExternalED) {
+    this->ExternalED = ExternalED;
+  }
 
   // Implementation of the MCObjectWriter interface.
   void recordRelocation(const MCFragment &F, const MCFixup &Fixup,
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 5fdf88831892f..445117ed37ff4 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -840,8 +840,11 @@ void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
     OutStreamer->emitSymbolAttribute(EmittedSym, MCSA_Memtag);
   }
 
-  if (!GV->hasInitializer())   // External globals require no extra code.
+  if (!GV->hasInitializer()) { // External globals require no extra code.
+    if (TM.getTargetTriple().isOSzOS())
+      OutStreamer->emitSymbolAttribute(EmittedSym, MCSA_ELF_TypeObject);
     return;
+  }
 
   GVSym->redefineIfPossible();
   if (GVSym->isDefined() || GVSym->isVariable())
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 9319a377ca10b..02099e9733b10 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -286,6 +286,7 @@ class GOFFWriter {
   GOFFOstream OS;
   MCAssembler &Asm;
   MCSectionGOFF *RootSD;
+  MCSectionGOFF *ExternalED;
 
   /// Saved relocation data collected in recordRelocations().
   std::vector<GOFFRelocationEntry> &Relocations;
@@ -303,15 +304,16 @@ class GOFFWriter {
 
 public:
   GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm, MCSectionGOFF *RootSD,
-             std::vector<GOFFRelocationEntry> &Relocations);
+             MCSectionGOFF *ExternalED, std::vector<GOFFRelocationEntry> &Relocations);
   uint64_t writeObject();
 };
 } // namespace
 
 GOFFWriter::GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm,
-                       MCSectionGOFF *RootSD,
+                       MCSectionGOFF *RootSD, MCSectionGOFF *ExternalED,
                        std::vector<GOFFRelocationEntry> &Relocations)
-    : OS(OS), Asm(Asm), RootSD(RootSD), Relocations(Relocations) {}
+    : OS(OS), Asm(Asm), RootSD(RootSD), ExternalED(ExternalED),
+      Relocations(Relocations) {}
 
 void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
   if (Section.isSD()) {
@@ -360,12 +362,21 @@ void GOFFWriter::defineLabel(const MCSymbolGOFF &Symbol) {
 }
 
 void GOFFWriter::defineExtern(const MCSymbolGOFF &Symbol) {
-  GOFFSymbol ER(Symbol.getExternalName(), Symbol.getIndex(),
-                RootSD->getOrdinal(),
-                GOFF::ERAttr{Symbol.isIndirect(), Symbol.getCodeData(),
-                             Symbol.getBindingStrength(), Symbol.getLinkage(),
-                             GOFF::ESD_AMODE_64, Symbol.getBindingScope()});
-  writeSymbol(ER);
+  if (Symbol.getCodeData() == GOFF::ESD_EXE_DATA) {
+    GOFFSymbol PR(Symbol.getExternalName(), Symbol.getIndex(),
+                  ExternalED->getOrdinal(), ExternalED->getEDAttributes(),
+                  GOFF::PRAttr{/*IsRenamable*/ false, Symbol.getCodeData(),
+                               Symbol.getLinkage(), Symbol.getBindingScope(),
+                               0});
+    writeSymbol(PR);
+  } else {
+    GOFFSymbol ER(Symbol.getExternalName(), Symbol.getIndex(),
+                  RootSD->getOrdinal(),
+                  GOFF::ERAttr{Symbol.isIndirect(), Symbol.getCodeData(),
+                               Symbol.getBindingStrength(), Symbol.getLinkage(),
+                               GOFF::ESD_AMODE_64, Symbol.getBindingScope()});
+    writeSymbol(ER);
+  }
 }
 
 void GOFFWriter::defineSymbols() {
@@ -791,7 +802,8 @@ void GOFFObjectWriter::recordRelocation(const MCFragment &F,
 }
 
 uint64_t GOFFObjectWriter::writeObject() {
-  uint64_t Size = GOFFWriter(OS, *Asm, RootSD, Relocations).writeObject();
+  uint64_t Size =
+      GOFFWriter(OS, *Asm, RootSD, ExternalED, Relocations).writeObject();
   return Size;
 }
 
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index 7c99fcbc5451c..fca826d828ac9 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -34,9 +34,22 @@ MCGOFFStreamer::MCGOFFStreamer(MCContext &Context,
 MCGOFFStreamer::~MCGOFFStreamer() = default;
 
 void MCGOFFStreamer::finishImpl() {
-  getWriter().setRootSD(static_cast<MCSectionGOFF *>(
+  // The root SD symbol.
+  MCSectionGOFF *RootSD = static_cast<MCSectionGOFF *>(
                             getContext().getObjectFileInfo()->getTextSection())
-                            ->getParent());
+                            ->getParent();
+  // Special ED symbol required for external data references.
+  MCSectionGOFF *ExternalED = getContext().getGOFFSection(
+      SectionKind::getMetadata(), GOFF::CLASS_WSA,
+      GOFF::EDAttr{false, GOFF::ESD_RMODE_64, GOFF::ESD_NS_Parts,
+                   GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
+                   GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_1,
+                   GOFF::ESD_ALIGN_Quadword, 0},
+      RootSD);
+  // Change to this section to register and initialize it.
+  MCObjectStreamer::changeSection(ExternalED, 0);
+  getWriter().setRootSD(RootSD);
+  getWriter().setExternalED(ExternalED);
   MCObjectStreamer::finishImpl();
 }
 
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index 51442a8ca47eb..c2bbbdd7d5a78 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -367,8 +367,13 @@ void SystemZHLASMAsmStreamer::finishImpl() {
     if (Symbol.isTemporary() || !Symbol.isRegistered() || Symbol.isDefined())
       continue;
     auto &Sym = static_cast<MCSymbolGOFF &>(const_cast<MCSymbol &>(Symbol));
-    OS << " " << (Sym.isWeak() ? "WXTRN" : "EXTRN") << " " << Sym.getName();
-    EmitEOL();
+    if (Sym.getCodeData() == GOFF::ESD_EXE_DATA) {
+      OS << "C_WSA64 CATTR PART(" << Sym.getName() << ")";
+      EmitEOL();
+    } else {
+      OS << " " << (Sym.isWeak() ? "WXTRN" : "EXTRN") << " " << Sym.getName();
+      EmitEOL();
+    }
     emitXATTR(OS, Sym.getName(), Sym.getADA(), Sym.isIndirect(),
               Sym.getLinkage(), Sym.getCodeData(), Sym.getBindingScope());
     EmitEOL();
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-1.ll b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
index ac9b6fc362c36..c31af1db3fa91 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-1.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
@@ -96,71 +96,79 @@ entry:
 ; CHECK-NEXT: 0002b0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 10 08
 ; CHECK-NEXT: 0002c0 00 80 03 00 00 00 00 06 c2 6d c9 c4 d9 d3 00 00
 
+; ESD record, type ED.
+; The name is C_WSA64. This is the ED symbol for global data references.
+; CHECK-NEXT: 0002d0 03 00 00 01 [[GLOBAL:00 00 00 08]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 0002e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0002f0 00 00 00 00 00 00 00 00 03 81 00 00 00 00 00 00
+; CHECK-NEXT: 000300 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 00
+; CHECK-NEXT: 000310 00 40 04 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
+
 ; ESD record, type LD.
 ; The name is test#C.
-; CHECK-NEXT: 0002d0 03 00 00 02 [[TESTC:00 00 00 08]] [[C_CODE64]] 00 00 00 00
-; CHECK-NEXT: 0002e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0002f0 00 00 00 00 00 00 00 00 01 00 00 00 [[TESTS]]
-; CHECK-NEXT: 000300 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
-; CHECK-NEXT: 000310 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
+; CHECK-NEXT: 000320 03 00 00 02 [[TESTC:00 00 00 09]] [[C_CODE64]] 00 00 00 00
+; CHECK-NEXT: 000330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000340 00 00 00 00 00 00 00 00 01 00 00 00 [[TESTS]]
+; CHECK-NEXT: 000350 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
+; CHECK-NEXT: 000360 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
 
 ; ESD record, type ER.
 ; The name is CELQSTRT.
-; CHECK-NEXT: 000320 03 00 00 04 [[CELQSTRT:00 00 00 09]] [[ROOTSD]] 00 00 00 00
-; CHECK-NEXT: 000330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000340 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
-; CHECK-NEXT: 000350 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00
-; CHECK-NEXT: 000360 00 04 00 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
+; CHECK-NEXT: 000370 03 00 00 04 [[CELQSTRT:00 00 00 0a]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 000380 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000390 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
+; CHECK-NEXT: 0003a0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00
+; CHECK-NEXT: 0003b0 00 04 00 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
 
 ; ESD record, type LD.
 ; The name is me.
-; CHECK-NEXT: 000370 03 00 00 02 [[ME:00 00 00 0a]] [[C_CODE64]] 00 00 00 00
-; CHECK-NEXT: 000380 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000390 00 00 00 00 00 00 00 00 01 00 00 00 [[TESTS]]
-; CHECK-NEXT: 0003a0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
-; CHECK-NEXT: 0003b0 00 04 20 00 00 00 00 02 94 85 00 00 00 00 00 00
+; CHECK-NEXT: 0003c0 03 00 00 02 [[ME:00 00 00 0b]] [[C_CODE64]] 00 00 00 00
+; CHECK-NEXT: 0003d0 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0003e0 00 00 00 00 00 00 00 00 01 00 00 00 [[TESTS]]
+; CHECK-NEXT: 0003f0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
+; CHECK-NEXT: 000400 00 04 20 00 00 00 00 02 94 85 00 00 00 00 00 00
 
 ; ESD record, type ER.
 ; The name is other.
-; CHECK-NEXT: 0003c0 03 00 00 04 [[OTHER:00 00 00 0b]] [[ROOTSD]] 00 00 00 00
-; CHECK-NEXT: 0003d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0003e0 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
-; CHECK-NEXT: 0003f0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00
-; CHECK-NEXT: 000400 00 04 20 00 00 00 00 05 96 a3 88 85 99 00 00 00
+; CHECK-NEXT: 000410 03 00 00 04 [[OTHER:00 00 00 0c]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 000420 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000430 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
+; CHECK-NEXT: 000440 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00
+; CHECK-NEXT: 000450 00 04 20 00 00 00 00 05 96 a3 88 85 99 00 00 00
 
 ; Text record for the code section C_CODE64.
 ; The regular expression matches the lower byte of the length.
-; CHECK-NEXT: 000410 03 11 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000420 00 00 00 00 00 00 00 {{..}} 00 c3 00 c5 00 c5 00 f1
+; CHECK-NEXT: 000460 03 11 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000470 00 00 00 00 00 00 00 {{..}} 00 c3 00 c5 00 c5 00 f1
 
 ; Text record for the section .&ppa2.
-; CHECK:      0004b0 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0004c0 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK:      000500 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000510 00 00 00 00 00 00 00 {{..}} {{.*}}
 
 ; Text record for the ADA section test#S.
-; CHECK:      000500 03 10 00 00 [[TESTS]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000510 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK:      000550 03 10 00 00 [[TESTS]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000560 00 00 00 00 00 00 00 {{..}} {{.*}}
 
 ; Text record for the section B_IDRL.
-; CHECK:      000550 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000560 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK:      0005a0 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0005b0 00 00 00 00 00 00 00 {{..}} {{.*}}
 
 ; The relocation data directory.
-; CHECK:      0005a0 03 21 00 00 00 5c 00 00 02 00 04 00 00 00 00 00
-; CHECK-NEXT: 0005b0 00 08 00 00 00 02 00 00 00 5a 60 00 00 00 04 00
-; CHECK-NEXT: 0005c0 00 00 00 00 00 09 00 00 00 00 08 00 00 00 00 00
-; CHECK-NEXT: 0005d0 00 08 00 00 00 04 00 00 00 00 60 00 02 00 08 00
-; CHECK-NEXT: 0005e0 00 00 00 00 00 09 20 70 01 00 08 00 00 00 00 00
+; CHECK:      0005f0 03 21 00 00 00 5c 00 00 02 00 04 00 00 00 00 00
+; CHECK-NEXT: 000600 00 09 00 00 00 02 00 00 00 5a 60 00 00 00 04 00
+; CHECK-NEXT: 000610 00 00 00 00 00 0a 00 00 00 00 08 00 00 00 00 00
+; CHECK-NEXT: 000620 00 09 00 00 00 04 00 00 00 00 60 00 02 00 08 00
+; CHECK-NEXT: 000630 00 00 00 00 00 0a 20 70 01 00 08 00 00 00 00 00
 ; Continuation of the relocation data directory.
-; CHECK-NEXT: 0005f0 03 22 00 00 0b 00 00 00 06 c0 00 01 00 08 00 00
-; CHECK-NEXT: 000600 00 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000610 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000620 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000630 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-
-; End record.
-; CHECK:      000640 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000650 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000640 03 22 00 00 0c 00 00 00 06 c0 00 01 00 08 00 00
+; CHECK-NEXT: 000650 00 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00
 ; CHECK-NEXT: 000660 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ; CHECK-NEXT: 000670 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ; CHECK-NEXT: 000680 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+; End record.
+; CHECK:      000690 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0006a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0006b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0006c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0006d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-2.ll b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
index dad9b4866f155..89b27902262c5 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-2.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
@@ -139,51 +139,59 @@ source_filename = "test.ll"
 ; CHECK-NEXT: 000490 00 00 00 00 00 00 00 00 00 00 00 00 00 04 10 08
 ; CHECK-NEXT: 0004a0 00 80 03 00 00 00 00 06 c2 6d c9 c4 d9 d3 00 00
 
+; ESD record, type ED.
+; The name is C_WSA64. This is the ED symbol for global data references.
+; CHECK-NEXT: 0004b0 03 00 00 01 00 00 00 0e [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 0004c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0004d0 00 00 00 00 00 00 00 00 03 81 00 00 00 00 00 00
+; CHECK-NEXT: 0004e0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 00
+; CHECK-NEXT: 0004f0 00 40 04 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
+
 ; ESD record, type LD.
 ; The name is test#C.
-; CHECK-NEXT: 0004b0 03 00 00 02 [[TESTC:00 00 00 0e]] [[C_CODE64]] 00 00 00 00
-; CHECK-NEXT: 0004c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0004d0 00 00 00 00 00 00 00 00 01 00 00 00 [[TESTS]]
-; CHECK-NEXT: 0004e0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
-; CHECK-NEXT: 0004f0 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
+; CHECK-NEXT: 000500 03 00 00 02 [[TESTC:00 00 00 0f]] [[C_CODE64]] 00 00 00 00
+; CHECK-NEXT: 000510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000520 00 00 00 00 00 00 00 00 01 00 00 00 [[TESTS]]
+; CHECK-NEXT: 000530 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
+; CHECK-NEXT: 000540 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
 
 ; ESD record, type ER.
 ; The name is CELQSTRT.
-; CHECK-NEXT: 000500 03 00 00 04 [[CELQSTRT:00 00 00 0f]] [[ROOTSD]] 00 00 00 00
-; CHECK-NEXT: 000510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000520 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
-; CHECK-NEXT: 000530 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00
-; CHECK-NEXT: 000540 00 04 00 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
+; CHECK-NEXT: 000550 03 00 00 04 [[CELQSTRT:00 00 00 10]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 000560 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000570 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
+; CHECK-NEXT: 000580 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00
+; CHECK-NEXT: 000590 00 04 00 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
 
 ; Text record for the code section C_CODE64.
 ; The regular expression matches the lower byte of the length.
-; CHECK-NEXT: 000550 03 10 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000560 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK-NEXT: 0005a0 03 10 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0005b0 00 00 00 00 00 00 00 {{..}} {{.*}}
 
 ; Text record for the section .&ppa2.
-; CHECK:      0005a0 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0005b0 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK:      0005f0 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000600 00 00 00 00 00 00 00 {{..}} {{.*}}
 
 ; Text record for the section data.
 ; Length is 4, and the content is 0x2a = 42.
-; CHECK:      0005f0 03 10 00 00 [[DATA_PR]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000600 00 00 00 00 00 00 00 04 00 00 00 2a 00 00 00 00
+; CHECK:      000640 03 10 00 00 [[DATA_PR]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000650 00 00 00 00 00 00 00 04 00 00 00 2a 00 00 00 00
 
 ; There is no text record for section bss!
 
 ; Text record for the section B_IDRL.
-; CHECK:      000640 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000650 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK:      000690 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0006a0 00 00 00 00 00 00 00 {{..}} {{.*}}
 
 ; The relocation data directory
-; CHECK:      000690 03 20 00 00 00 40 00 00 02 00 04 00 00 00 00 00
-; CHECK-NEXT: 0006a0 00 0e 00 00 00 02 00 00 00 04 60 00 00 00 04 00
-; CHECK-NEXT: 0006b0 00 00 00 00 00 0f 00 00 00 00 08 00 00 00 00 00
-; CHECK-NEXT: 0006c0 00 0e 00 00 00 04 00 00 00 00 60 00 02 00 08 00
-; CHECK-NEXT: 0006d0 00 00 00 00 00 0f 00 00 00 00 00 00 00 00 00 00
+; CHECK:      0006e0 03 20 00 00 00 40 00 00 02 00 04 00 00 00 00 00
+; CHECK-NEXT: 0006f0 00 0f 00 00 00 02 00 00 00 04 60 00 00 00 04 00
+; CHECK-NEXT: 000700 00 00 00 00 00 10 00 00 00 00 08 00 00 00 00 00
+; CHECK-NEXT: 000710 00 0f 00 00 00 04 00 00 00 00 60 00 02 00 08 00
+; CHECK-NEXT: 000720 00 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00
 
 ; End record.
-; CHECK:      0006e0 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0006f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000700 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000710 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK:      000730 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000740 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000750 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000760 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
diff --git a/llvm/test/CodeGen/SystemZ/zos-symbol-2.ll b/llvm/test/CodeGen/SystemZ/zos-symbol-2.ll
index bccbe7c672be7..d785d2488b69a 100644
--- a/llvm/test/CodeGen/SystemZ/zos-symbol-2.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-symbol-2.ll
@@ -28,26 +28,26 @@ entry:
 ; CHECK-NEXT: a XATTR LINKAGE(XPLINK),REFERENCE(DATA),SCOPE(LIBRARY)
 
 ; Check the declaration of the external variable
-; CHECK:       EXTRN b
-; CHECK-NEXT: b XATTR LINKAGE(XPLINK),SCOPE(EXPORT)
+; CHECK:      C_WSA64 CATTR PART(b)
+; CHECK-NEXT: b XATTR LINKAGE(XPLINK),REFERENCE(DATA),SCOPE(EXPORT)
 
 ; Check the relocation data directory.
 ;  03 is prefix byte
 ;  2. is header type (RT_RLD)
 ;  .1 is flag (record is continued)
 ;  00 is version
-; CHECKREL:      000690 03 21 00 00 00 60 00 00 02 00 04 00 00 00 00 00
-; CHECKREL-NEXT: 0006a0 00 0b 00 00 00 02 00 00 00 4e 60 00 00 00 04 00
-; CHECKREL-NEXT: 0006b0 00 00 00 00 00 0c 00 00 00 00 08 00 00 00 00 00
-; CHECKREL-NEXT: 0006c0 00 0b 00 00 00 04 00 00 00 00 60 00 02 00 08 00
-; CHECKREL-NEXT: 0006d0 00 00 00 00 00 0c 20 00 00 00 08 00 00 00 00 00
+; CHECKREL:      0006e0 03 21 00 00 00 60 00 00 02 00 04 00 00 00 00 00
+; CHECKREL-NEXT: 0006f0 00 0c 00 00 00 02 00 00 00 4e 60 00 00 00 04 00
+; CHECKREL-NEXT: 000700 00 00 00 00 00 0d 00 00 00 00 08 00 00 00 00 00
+; CHECKREL-NEXT: 000710 00 0c 00 00 00 04 00 00 00 00 60 00 02 00 08 00
+; CHECKREL-NEXT: 000720 00 00 00 00 00 0d 20 00 00 00 08 00 00 00 00 00
 ; Continuation of relocation data directory.
 ;  03 is prefix byte
 ;  2. is header type (RT_RLD)
 ;  .2 is flag (record is continuation but not continued)
 ;  00 is version
-; CHECKREL-NEXT: 0006e0 03 22 00 00 07 00 00 00 09 40 00 00 00 08 00 00
-; CHECKREL-NEXT: 0006f0 00 00 00 00 0e 00 00 00 08 00 00 00 00 00 00 00
-; CHECKREL-NEXT: 000700 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECKREL-NEXT: 000710 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECKREL-NEXT: 000720 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECKREL-NEXT: 000730 03 22 00 00 07 00 00 00 09 40 00 00 00 08 00 00
+; CHECKREL-NEXT: 000740 00 00 00 00 0f 00 00 00 08 00 00 00 00 00 00 00
+; CHECKREL-NEXT: 000750 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECKREL-NEXT: 000760 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECKREL-NEXT: 000770 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

>From 7d0313d41c69f2ae7f42e64a1325ccb6191493f0 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Tue, 10 Mar 2026 16:44:21 -0400
Subject: [PATCH 2/9] Fix formatting

---
 llvm/lib/MC/GOFFObjectWriter.cpp | 3 ++-
 llvm/lib/MC/MCGOFFStreamer.cpp   | 7 ++++---
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 02099e9733b10..2434b3370c0af 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -304,7 +304,8 @@ class GOFFWriter {
 
 public:
   GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm, MCSectionGOFF *RootSD,
-             MCSectionGOFF *ExternalED, std::vector<GOFFRelocationEntry> &Relocations);
+             MCSectionGOFF *ExternalED,
+             std::vector<GOFFRelocationEntry> &Relocations);
   uint64_t writeObject();
 };
 } // namespace
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index fca826d828ac9..6027a3243f73a 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -35,9 +35,10 @@ MCGOFFStreamer::~MCGOFFStreamer() = default;
 
 void MCGOFFStreamer::finishImpl() {
   // The root SD symbol.
-  MCSectionGOFF *RootSD = static_cast<MCSectionGOFF *>(
-                            getContext().getObjectFileInfo()->getTextSection())
-                            ->getParent();
+  MCSectionGOFF *RootSD =
+      static_cast<MCSectionGOFF *>(
+          getContext().getObjectFileInfo()->getTextSection())
+          ->getParent();
   // Special ED symbol required for external data references.
   MCSectionGOFF *ExternalED = getContext().getGOFFSection(
       SectionKind::getMetadata(), GOFF::CLASS_WSA,

>From 61830b22565b75a0119b08c94cc42c489cd1e634 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Thu, 9 Apr 2026 16:09:05 -0400
Subject: [PATCH 3/9] Use ADA reference of MCSymbolGOFF for externals.

---
 llvm/include/llvm/CodeGen/AsmPrinter.h            |  4 ++++
 llvm/include/llvm/MC/MCGOFFObjectWriter.h         |  6 ------
 llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp        |  7 ++-----
 llvm/lib/MC/GOFFObjectWriter.cpp                  | 15 ++++++---------
 llvm/lib/MC/MCGOFFStreamer.cpp                    | 12 +-----------
 .../MCTargetDesc/SystemZHLASMAsmStreamer.cpp      |  5 +++--
 llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp     | 15 +++++++++++++++
 llvm/lib/Target/SystemZ/SystemZAsmPrinter.h       |  1 +
 8 files changed, 32 insertions(+), 33 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index ec17b54357acd..f7d8249ee87ca 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -673,6 +673,10 @@ class LLVM_ABI AsmPrinter : public MachineFunctionPass {
   virtual bool
   isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const;
 
+  /// Targets can override this if they need to emit additional data after an
+  /// external global variable was emitted.
+  virtual void emitExternalGlobalVariableEnd(MCSymbol *Sym) {}
+
   /// Targets can override this to customize the output of IMPLICIT_DEF
   /// instructions in verbose mode.
   virtual void emitImplicitDef(const MachineInstr *MI) const;
diff --git a/llvm/include/llvm/MC/MCGOFFObjectWriter.h b/llvm/include/llvm/MC/MCGOFFObjectWriter.h
index 82ff6fddf6552..57e152f6a61dc 100644
--- a/llvm/include/llvm/MC/MCGOFFObjectWriter.h
+++ b/llvm/include/llvm/MC/MCGOFFObjectWriter.h
@@ -83,9 +83,6 @@ class GOFFObjectWriter : public MCObjectWriter {
   // The RootSD section.
   MCSectionGOFF *RootSD = nullptr;
 
-  // The ED section for external data references.
-  MCSectionGOFF *ExternalED = nullptr;
-
   // Saved relocation data.
   std::vector<GOFFRelocationEntry> Relocations;
 
@@ -95,9 +92,6 @@ class GOFFObjectWriter : public MCObjectWriter {
   ~GOFFObjectWriter() override;
 
   void setRootSD(MCSectionGOFF *RootSD) { this->RootSD = RootSD; }
-  void setExternalED(MCSectionGOFF *ExternalED) {
-    this->ExternalED = ExternalED;
-  }
 
   // Implementation of the MCObjectWriter interface.
   void recordRelocation(const MCFragment &F, const MCFixup &Fixup,
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 445117ed37ff4..d24605f8e3fe2 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -840,11 +840,8 @@ void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
     OutStreamer->emitSymbolAttribute(EmittedSym, MCSA_Memtag);
   }
 
-  if (!GV->hasInitializer()) { // External globals require no extra code.
-    if (TM.getTargetTriple().isOSzOS())
-      OutStreamer->emitSymbolAttribute(EmittedSym, MCSA_ELF_TypeObject);
-    return;
-  }
+  if (!GV->hasInitializer()) // External globals require no extra code.
+    return emitExternalGlobalVariableEnd(EmittedSym);
 
   GVSym->redefineIfPossible();
   if (GVSym->isDefined() || GVSym->isVariable())
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 2434b3370c0af..001098cbb7a86 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -286,7 +286,6 @@ class GOFFWriter {
   GOFFOstream OS;
   MCAssembler &Asm;
   MCSectionGOFF *RootSD;
-  MCSectionGOFF *ExternalED;
 
   /// Saved relocation data collected in recordRelocations().
   std::vector<GOFFRelocationEntry> &Relocations;
@@ -304,17 +303,15 @@ class GOFFWriter {
 
 public:
   GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm, MCSectionGOFF *RootSD,
-             MCSectionGOFF *ExternalED,
              std::vector<GOFFRelocationEntry> &Relocations);
   uint64_t writeObject();
 };
 } // namespace
 
 GOFFWriter::GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm,
-                       MCSectionGOFF *RootSD, MCSectionGOFF *ExternalED,
+                       MCSectionGOFF *RootSD,
                        std::vector<GOFFRelocationEntry> &Relocations)
-    : OS(OS), Asm(Asm), RootSD(RootSD), ExternalED(ExternalED),
-      Relocations(Relocations) {}
+    : OS(OS), Asm(Asm), RootSD(RootSD), Relocations(Relocations) {}
 
 void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
   if (Section.isSD()) {
@@ -364,8 +361,9 @@ void GOFFWriter::defineLabel(const MCSymbolGOFF &Symbol) {
 
 void GOFFWriter::defineExtern(const MCSymbolGOFF &Symbol) {
   if (Symbol.getCodeData() == GOFF::ESD_EXE_DATA) {
-    GOFFSymbol PR(Symbol.getExternalName(), Symbol.getIndex(),
-                  ExternalED->getOrdinal(), ExternalED->getEDAttributes(),
+    MCSectionGOFF *ED = Symbol.getADA();
+    GOFFSymbol PR(Symbol.getExternalName(), Symbol.getIndex(), ED->getOrdinal(),
+                  ED->getEDAttributes(),
                   GOFF::PRAttr{/*IsRenamable*/ false, Symbol.getCodeData(),
                                Symbol.getLinkage(), Symbol.getBindingScope(),
                                0});
@@ -803,8 +801,7 @@ void GOFFObjectWriter::recordRelocation(const MCFragment &F,
 }
 
 uint64_t GOFFObjectWriter::writeObject() {
-  uint64_t Size =
-      GOFFWriter(OS, *Asm, RootSD, ExternalED, Relocations).writeObject();
+  uint64_t Size = GOFFWriter(OS, *Asm, RootSD, Relocations).writeObject();
   return Size;
 }
 
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index 6027a3243f73a..ad66e7a91e054 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -39,18 +39,8 @@ void MCGOFFStreamer::finishImpl() {
       static_cast<MCSectionGOFF *>(
           getContext().getObjectFileInfo()->getTextSection())
           ->getParent();
-  // Special ED symbol required for external data references.
-  MCSectionGOFF *ExternalED = getContext().getGOFFSection(
-      SectionKind::getMetadata(), GOFF::CLASS_WSA,
-      GOFF::EDAttr{false, GOFF::ESD_RMODE_64, GOFF::ESD_NS_Parts,
-                   GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
-                   GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_1,
-                   GOFF::ESD_ALIGN_Quadword, 0},
-      RootSD);
-  // Change to this section to register and initialize it.
-  MCObjectStreamer::changeSection(ExternalED, 0);
+
   getWriter().setRootSD(RootSD);
-  getWriter().setExternalED(ExternalED);
   MCObjectStreamer::finishImpl();
 }
 
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index c2bbbdd7d5a78..583f24b0f9d03 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -215,7 +215,8 @@ static void emitXATTR(raw_ostream &OS, StringRef Name, MCSectionGOFF *ADA,
 
     OS << ")";
   }
-  if (ADA)
+  // Emit PSECT only for code symbols.
+  if (ADA && Executable != GOFF::ESD_EXE_DATA)
     OS << Sep << "PSECT(" << ADA->getName() << ")";
   if (BindingScope != GOFF::ESD_BSC_Unspecified) {
     OS << Sep << "SCOPE(";
@@ -368,7 +369,7 @@ void SystemZHLASMAsmStreamer::finishImpl() {
       continue;
     auto &Sym = static_cast<MCSymbolGOFF &>(const_cast<MCSymbol &>(Symbol));
     if (Sym.getCodeData() == GOFF::ESD_EXE_DATA) {
-      OS << "C_WSA64 CATTR PART(" << Sym.getName() << ")";
+      OS << Sym.getADA()->getExternalName() << " CATTR PART(" << Sym.getName() << ")";
       EmitEOL();
     } else {
       OS << " " << (Sym.isWeak() ? "WXTRN" : "EXTRN") << " " << Sym.getName();
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index 8be75196f0482..37432ef6ceddd 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -1232,6 +1232,21 @@ void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) {
   emitAttributes(M);
 }
 
+void SystemZAsmPrinter::emitExternalGlobalVariableEnd(MCSymbol *Sym) {
+  auto TT = OutContext.getTargetTriple();
+  if (TT.isOSzOS()) {
+    // On z/OS, we need to associate an external data reference with an ED
+    // symbol, for which we use the the ED of the ADA. We also need to mark the
+    // reference as being to data, otherwise we cannot bind with code generated
+    // by XL.
+    MCSymbolGOFF *EmittedSym = static_cast<MCSymbolGOFF *>(Sym);
+    EmittedSym->setADA(static_cast<MCSectionGOFF *>(
+                           OutContext.getObjectFileInfo()->getADASection())
+                           ->getParent());
+    OutStreamer->emitSymbolAttribute(EmittedSym, MCSA_ELF_TypeObject);
+  }
+}
+
 void SystemZAsmPrinter::emitADASection() {
   OutStreamer->pushSection();
 
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
index 0f87eb0307911..22150f6a78e02 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
@@ -117,6 +117,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter {
   void emitXXStructorList(const DataLayout &DL, const Constant *List,
                           bool IsCtor) override;
   void emitEndOfAsmFile(Module &M) override;
+  void emitExternalGlobalVariableEnd(MCSymbol *Sym) override;
   bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
                        const char *ExtraCode, raw_ostream &OS) override;
   bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,

>From 70406aa1056575f87f3f94aa1aea225612f7ba34 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Thu, 9 Apr 2026 16:13:22 -0400
Subject: [PATCH 4/9] Fix formatting

---
 .../Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp    | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index 583f24b0f9d03..067a42b910404 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -369,7 +369,8 @@ void SystemZHLASMAsmStreamer::finishImpl() {
       continue;
     auto &Sym = static_cast<MCSymbolGOFF &>(const_cast<MCSymbol &>(Symbol));
     if (Sym.getCodeData() == GOFF::ESD_EXE_DATA) {
-      OS << Sym.getADA()->getExternalName() << " CATTR PART(" << Sym.getName() << ")";
+      OS << Sym.getADA()->getExternalName() << " CATTR PART(" << Sym.getName()
+         << ")";
       EmitEOL();
     } else {
       OS << " " << (Sym.isWeak() ? "WXTRN" : "EXTRN") << " " << Sym.getName();

>From a085299cc251ddb2f302d7e323615116bfcbe3b8 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Thu, 9 Apr 2026 16:37:30 -0400
Subject: [PATCH 5/9] Update tests

---
 llvm/test/CodeGen/SystemZ/zos-section-1.ll | 92 ++++++++++------------
 llvm/test/CodeGen/SystemZ/zos-section-2.ll | 62 +++++++--------
 2 files changed, 69 insertions(+), 85 deletions(-)

diff --git a/llvm/test/CodeGen/SystemZ/zos-section-1.ll b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
index c31af1db3fa91..ac9b6fc362c36 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-1.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
@@ -96,79 +96,71 @@ entry:
 ; CHECK-NEXT: 0002b0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 10 08
 ; CHECK-NEXT: 0002c0 00 80 03 00 00 00 00 06 c2 6d c9 c4 d9 d3 00 00
 
-; ESD record, type ED.
-; The name is C_WSA64. This is the ED symbol for global data references.
-; CHECK-NEXT: 0002d0 03 00 00 01 [[GLOBAL:00 00 00 08]] [[ROOTSD]] 00 00 00 00
-; CHECK-NEXT: 0002e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0002f0 00 00 00 00 00 00 00 00 03 81 00 00 00 00 00 00
-; CHECK-NEXT: 000300 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 00
-; CHECK-NEXT: 000310 00 40 04 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
-
 ; ESD record, type LD.
 ; The name is test#C.
-; CHECK-NEXT: 000320 03 00 00 02 [[TESTC:00 00 00 09]] [[C_CODE64]] 00 00 00 00
-; CHECK-NEXT: 000330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000340 00 00 00 00 00 00 00 00 01 00 00 00 [[TESTS]]
-; CHECK-NEXT: 000350 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
-; CHECK-NEXT: 000360 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
+; CHECK-NEXT: 0002d0 03 00 00 02 [[TESTC:00 00 00 08]] [[C_CODE64]] 00 00 00 00
+; CHECK-NEXT: 0002e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0002f0 00 00 00 00 00 00 00 00 01 00 00 00 [[TESTS]]
+; CHECK-NEXT: 000300 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
+; CHECK-NEXT: 000310 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
 
 ; ESD record, type ER.
 ; The name is CELQSTRT.
-; CHECK-NEXT: 000370 03 00 00 04 [[CELQSTRT:00 00 00 0a]] [[ROOTSD]] 00 00 00 00
-; CHECK-NEXT: 000380 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000390 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
-; CHECK-NEXT: 0003a0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00
-; CHECK-NEXT: 0003b0 00 04 00 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
+; CHECK-NEXT: 000320 03 00 00 04 [[CELQSTRT:00 00 00 09]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 000330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000340 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
+; CHECK-NEXT: 000350 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00
+; CHECK-NEXT: 000360 00 04 00 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
 
 ; ESD record, type LD.
 ; The name is me.
-; CHECK-NEXT: 0003c0 03 00 00 02 [[ME:00 00 00 0b]] [[C_CODE64]] 00 00 00 00
-; CHECK-NEXT: 0003d0 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0003e0 00 00 00 00 00 00 00 00 01 00 00 00 [[TESTS]]
-; CHECK-NEXT: 0003f0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
-; CHECK-NEXT: 000400 00 04 20 00 00 00 00 02 94 85 00 00 00 00 00 00
+; CHECK-NEXT: 000370 03 00 00 02 [[ME:00 00 00 0a]] [[C_CODE64]] 00 00 00 00
+; CHECK-NEXT: 000380 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000390 00 00 00 00 00 00 00 00 01 00 00 00 [[TESTS]]
+; CHECK-NEXT: 0003a0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
+; CHECK-NEXT: 0003b0 00 04 20 00 00 00 00 02 94 85 00 00 00 00 00 00
 
 ; ESD record, type ER.
 ; The name is other.
-; CHECK-NEXT: 000410 03 00 00 04 [[OTHER:00 00 00 0c]] [[ROOTSD]] 00 00 00 00
-; CHECK-NEXT: 000420 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000430 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
-; CHECK-NEXT: 000440 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00
-; CHECK-NEXT: 000450 00 04 20 00 00 00 00 05 96 a3 88 85 99 00 00 00
+; CHECK-NEXT: 0003c0 03 00 00 04 [[OTHER:00 00 00 0b]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 0003d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0003e0 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
+; CHECK-NEXT: 0003f0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00
+; CHECK-NEXT: 000400 00 04 20 00 00 00 00 05 96 a3 88 85 99 00 00 00
 
 ; Text record for the code section C_CODE64.
 ; The regular expression matches the lower byte of the length.
-; CHECK-NEXT: 000460 03 11 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000470 00 00 00 00 00 00 00 {{..}} 00 c3 00 c5 00 c5 00 f1
+; CHECK-NEXT: 000410 03 11 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000420 00 00 00 00 00 00 00 {{..}} 00 c3 00 c5 00 c5 00 f1
 
 ; Text record for the section .&ppa2.
-; CHECK:      000500 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000510 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK:      0004b0 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0004c0 00 00 00 00 00 00 00 {{..}} {{.*}}
 
 ; Text record for the ADA section test#S.
-; CHECK:      000550 03 10 00 00 [[TESTS]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000560 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK:      000500 03 10 00 00 [[TESTS]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000510 00 00 00 00 00 00 00 {{..}} {{.*}}
 
 ; Text record for the section B_IDRL.
-; CHECK:      0005a0 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0005b0 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK:      000550 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000560 00 00 00 00 00 00 00 {{..}} {{.*}}
 
 ; The relocation data directory.
-; CHECK:      0005f0 03 21 00 00 00 5c 00 00 02 00 04 00 00 00 00 00
-; CHECK-NEXT: 000600 00 09 00 00 00 02 00 00 00 5a 60 00 00 00 04 00
-; CHECK-NEXT: 000610 00 00 00 00 00 0a 00 00 00 00 08 00 00 00 00 00
-; CHECK-NEXT: 000620 00 09 00 00 00 04 00 00 00 00 60 00 02 00 08 00
-; CHECK-NEXT: 000630 00 00 00 00 00 0a 20 70 01 00 08 00 00 00 00 00
+; CHECK:      0005a0 03 21 00 00 00 5c 00 00 02 00 04 00 00 00 00 00
+; CHECK-NEXT: 0005b0 00 08 00 00 00 02 00 00 00 5a 60 00 00 00 04 00
+; CHECK-NEXT: 0005c0 00 00 00 00 00 09 00 00 00 00 08 00 00 00 00 00
+; CHECK-NEXT: 0005d0 00 08 00 00 00 04 00 00 00 00 60 00 02 00 08 00
+; CHECK-NEXT: 0005e0 00 00 00 00 00 09 20 70 01 00 08 00 00 00 00 00
 ; Continuation of the relocation data directory.
-; CHECK-NEXT: 000640 03 22 00 00 0c 00 00 00 06 c0 00 01 00 08 00 00
-; CHECK-NEXT: 000650 00 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0005f0 03 22 00 00 0b 00 00 00 06 c0 00 01 00 08 00 00
+; CHECK-NEXT: 000600 00 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000610 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000620 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000630 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+; End record.
+; CHECK:      000640 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000650 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ; CHECK-NEXT: 000660 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ; CHECK-NEXT: 000670 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ; CHECK-NEXT: 000680 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-
-; End record.
-; CHECK:      000690 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0006a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0006b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0006c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0006d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-2.ll b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
index 89b27902262c5..dad9b4866f155 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-2.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
@@ -139,59 +139,51 @@ source_filename = "test.ll"
 ; CHECK-NEXT: 000490 00 00 00 00 00 00 00 00 00 00 00 00 00 04 10 08
 ; CHECK-NEXT: 0004a0 00 80 03 00 00 00 00 06 c2 6d c9 c4 d9 d3 00 00
 
-; ESD record, type ED.
-; The name is C_WSA64. This is the ED symbol for global data references.
-; CHECK-NEXT: 0004b0 03 00 00 01 00 00 00 0e [[ROOTSD]] 00 00 00 00
-; CHECK-NEXT: 0004c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0004d0 00 00 00 00 00 00 00 00 03 81 00 00 00 00 00 00
-; CHECK-NEXT: 0004e0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 00
-; CHECK-NEXT: 0004f0 00 40 04 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
-
 ; ESD record, type LD.
 ; The name is test#C.
-; CHECK-NEXT: 000500 03 00 00 02 [[TESTC:00 00 00 0f]] [[C_CODE64]] 00 00 00 00
-; CHECK-NEXT: 000510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000520 00 00 00 00 00 00 00 00 01 00 00 00 [[TESTS]]
-; CHECK-NEXT: 000530 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
-; CHECK-NEXT: 000540 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
+; CHECK-NEXT: 0004b0 03 00 00 02 [[TESTC:00 00 00 0e]] [[C_CODE64]] 00 00 00 00
+; CHECK-NEXT: 0004c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0004d0 00 00 00 00 00 00 00 00 01 00 00 00 [[TESTS]]
+; CHECK-NEXT: 0004e0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
+; CHECK-NEXT: 0004f0 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
 
 ; ESD record, type ER.
 ; The name is CELQSTRT.
-; CHECK-NEXT: 000550 03 00 00 04 [[CELQSTRT:00 00 00 10]] [[ROOTSD]] 00 00 00 00
-; CHECK-NEXT: 000560 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000570 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
-; CHECK-NEXT: 000580 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00
-; CHECK-NEXT: 000590 00 04 00 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
+; CHECK-NEXT: 000500 03 00 00 04 [[CELQSTRT:00 00 00 0f]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 000510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000520 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
+; CHECK-NEXT: 000530 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00
+; CHECK-NEXT: 000540 00 04 00 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
 
 ; Text record for the code section C_CODE64.
 ; The regular expression matches the lower byte of the length.
-; CHECK-NEXT: 0005a0 03 10 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0005b0 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK-NEXT: 000550 03 10 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000560 00 00 00 00 00 00 00 {{..}} {{.*}}
 
 ; Text record for the section .&ppa2.
-; CHECK:      0005f0 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000600 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK:      0005a0 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0005b0 00 00 00 00 00 00 00 {{..}} {{.*}}
 
 ; Text record for the section data.
 ; Length is 4, and the content is 0x2a = 42.
-; CHECK:      000640 03 10 00 00 [[DATA_PR]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000650 00 00 00 00 00 00 00 04 00 00 00 2a 00 00 00 00
+; CHECK:      0005f0 03 10 00 00 [[DATA_PR]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000600 00 00 00 00 00 00 00 04 00 00 00 2a 00 00 00 00
 
 ; There is no text record for section bss!
 
 ; Text record for the section B_IDRL.
-; CHECK:      000690 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0006a0 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK:      000640 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000650 00 00 00 00 00 00 00 {{..}} {{.*}}
 
 ; The relocation data directory
-; CHECK:      0006e0 03 20 00 00 00 40 00 00 02 00 04 00 00 00 00 00
-; CHECK-NEXT: 0006f0 00 0f 00 00 00 02 00 00 00 04 60 00 00 00 04 00
-; CHECK-NEXT: 000700 00 00 00 00 00 10 00 00 00 00 08 00 00 00 00 00
-; CHECK-NEXT: 000710 00 0f 00 00 00 04 00 00 00 00 60 00 02 00 08 00
-; CHECK-NEXT: 000720 00 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00
+; CHECK:      000690 03 20 00 00 00 40 00 00 02 00 04 00 00 00 00 00
+; CHECK-NEXT: 0006a0 00 0e 00 00 00 02 00 00 00 04 60 00 00 00 04 00
+; CHECK-NEXT: 0006b0 00 00 00 00 00 0f 00 00 00 00 08 00 00 00 00 00
+; CHECK-NEXT: 0006c0 00 0e 00 00 00 04 00 00 00 00 60 00 02 00 08 00
+; CHECK-NEXT: 0006d0 00 00 00 00 00 0f 00 00 00 00 00 00 00 00 00 00
 
 ; End record.
-; CHECK:      000730 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000740 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000750 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000760 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK:      0006e0 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0006f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000700 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000710 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

>From 3c5e03b4e9c5cc254d6165c4a2b57ad8095ba2db Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Thu, 9 Apr 2026 16:58:13 -0400
Subject: [PATCH 6/9] Extend test

---
 llvm/test/CodeGen/SystemZ/zos-symbol-2.ll | 34 ++++++++++++++++-------
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/llvm/test/CodeGen/SystemZ/zos-symbol-2.ll b/llvm/test/CodeGen/SystemZ/zos-symbol-2.ll
index d785d2488b69a..72fba7bbd4732 100644
--- a/llvm/test/CodeGen/SystemZ/zos-symbol-2.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-symbol-2.ll
@@ -31,23 +31,37 @@ entry:
 ; CHECK:      C_WSA64 CATTR PART(b)
 ; CHECK-NEXT: b XATTR LINKAGE(XPLINK),REFERENCE(DATA),SCOPE(EXPORT)
 
+; Check the C_WSA64
+; CHECKREL:      0002d0 03 00 00 01 [[C_WSA64:00 00 00 08]] 00 00 00 01 00 00 00 00
+; CHECKREL-NEXT: 0002e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECKREL-NEXT: 0002f0 00 00 00 00 00 00 00 00 03 81 00 00 00 00 00 00
+; CHECKREL-NEXT: 000300 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 00
+; CHECKREL-NEXT: 000310 00 40 04 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
+
+; Check the PR symbol for b
+; CHECKREL:      0004b0 03 00 00 03 00 00 00 0e [[C_WSA64]] 00 00 00 00
+; CHECKREL-NEXT: 0004c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECKREL-NEXT: 0004d0 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
+; CHECKREL-NEXT: 0004e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
+; CHECKREL-NEXT: 0004f0 00 04 24 00 00 00 00 01 82 00 00 00 00 00 00 00
+
 ; Check the relocation data directory.
 ;  03 is prefix byte
 ;  2. is header type (RT_RLD)
 ;  .1 is flag (record is continued)
 ;  00 is version
-; CHECKREL:      0006e0 03 21 00 00 00 60 00 00 02 00 04 00 00 00 00 00
-; CHECKREL-NEXT: 0006f0 00 0c 00 00 00 02 00 00 00 4e 60 00 00 00 04 00
-; CHECKREL-NEXT: 000700 00 00 00 00 00 0d 00 00 00 00 08 00 00 00 00 00
-; CHECKREL-NEXT: 000710 00 0c 00 00 00 04 00 00 00 00 60 00 02 00 08 00
-; CHECKREL-NEXT: 000720 00 00 00 00 00 0d 20 00 00 00 08 00 00 00 00 00
+; CHECKREL:      000690 03 21 00 00 00 60 00 00 02 00 04 00 00 00 00 00
+; CHECKREL-NEXT: 0006a0 00 0b 00 00 00 02 00 00 00 4e 60 00 00 00 04 00
+; CHECKREL-NEXT: 0006b0 00 00 00 00 00 0c 00 00 00 00 08 00 00 00 00 00
+; CHECKREL-NEXT: 0006c0 00 0b 00 00 00 04 00 00 00 00 60 00 02 00 08 00
+; CHECKREL-NEXT: 0006d0 00 00 00 00 00 0c 20 00 00 00 08 00 00 00 00 00
 ; Continuation of relocation data directory.
 ;  03 is prefix byte
 ;  2. is header type (RT_RLD)
 ;  .2 is flag (record is continuation but not continued)
 ;  00 is version
-; CHECKREL-NEXT: 000730 03 22 00 00 07 00 00 00 09 40 00 00 00 08 00 00
-; CHECKREL-NEXT: 000740 00 00 00 00 0f 00 00 00 08 00 00 00 00 00 00 00
-; CHECKREL-NEXT: 000750 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECKREL-NEXT: 000760 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECKREL-NEXT: 000770 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECKREL-NEXT: 0006e0 03 22 00 00 07 00 00 00 09 40 00 00 00 08 00 00
+; CHECKREL-NEXT: 0006f0 00 00 00 00 0e 00 00 00 08 00 00 00 00 00 00 00
+; CHECKREL-NEXT: 000700 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECKREL-NEXT: 000710 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECKREL-NEXT: 000720 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

>From 81bf4daab579943877e82a38af50f1cdd00de73c Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 10 Apr 2026 09:10:11 -0400
Subject: [PATCH 7/9] Remove unintended change of code.

---
 llvm/lib/MC/MCGOFFStreamer.cpp | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index ad66e7a91e054..7c99fcbc5451c 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -34,13 +34,9 @@ MCGOFFStreamer::MCGOFFStreamer(MCContext &Context,
 MCGOFFStreamer::~MCGOFFStreamer() = default;
 
 void MCGOFFStreamer::finishImpl() {
-  // The root SD symbol.
-  MCSectionGOFF *RootSD =
-      static_cast<MCSectionGOFF *>(
-          getContext().getObjectFileInfo()->getTextSection())
-          ->getParent();
-
-  getWriter().setRootSD(RootSD);
+  getWriter().setRootSD(static_cast<MCSectionGOFF *>(
+                            getContext().getObjectFileInfo()->getTextSection())
+                            ->getParent());
   MCObjectStreamer::finishImpl();
 }
 

>From 5ddd299ecc612f8d3fd97982cbac5198ce8e260d Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 10 Apr 2026 11:01:06 -0400
Subject: [PATCH 8/9] Use reference to ADA and use emitADA.

Also update the reference in the GOFF writer.
---
 llvm/lib/MC/GOFFObjectWriter.cpp              | 2 +-
 llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 8 +++-----
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 001098cbb7a86..c5719df24e204 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -361,7 +361,7 @@ void GOFFWriter::defineLabel(const MCSymbolGOFF &Symbol) {
 
 void GOFFWriter::defineExtern(const MCSymbolGOFF &Symbol) {
   if (Symbol.getCodeData() == GOFF::ESD_EXE_DATA) {
-    MCSectionGOFF *ED = Symbol.getADA();
+    MCSectionGOFF *ED = Symbol.getADA()->getParent();
     GOFFSymbol PR(Symbol.getExternalName(), Symbol.getIndex(), ED->getOrdinal(),
                   ED->getEDAttributes(),
                   GOFF::PRAttr{/*IsRenamable*/ false, Symbol.getCodeData(),
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index 37432ef6ceddd..00dba408ec1cb 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -24,6 +24,7 @@
 #include "llvm/BinaryFormat/GOFF.h"
 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
+#include "llvm/IR/GlobalVariable.h"
 #include "llvm/IR/Mangler.h"
 #include "llvm/IR/Module.h"
 #include "llvm/MC/MCDirectives.h"
@@ -1239,11 +1240,8 @@ void SystemZAsmPrinter::emitExternalGlobalVariableEnd(MCSymbol *Sym) {
     // symbol, for which we use the the ED of the ADA. We also need to mark the
     // reference as being to data, otherwise we cannot bind with code generated
     // by XL.
-    MCSymbolGOFF *EmittedSym = static_cast<MCSymbolGOFF *>(Sym);
-    EmittedSym->setADA(static_cast<MCSectionGOFF *>(
-                           OutContext.getObjectFileInfo()->getADASection())
-                           ->getParent());
-    OutStreamer->emitSymbolAttribute(EmittedSym, MCSA_ELF_TypeObject);
+    getTargetStreamer()->emitADA(Sym, OutContext.getObjectFileInfo()->getADASection());
+    OutStreamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeObject);
   }
 }
 

>From f3249890736209bab09c183ad9ab65594e8a560a Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 10 Apr 2026 11:19:26 -0400
Subject: [PATCH 9/9] Remove changes to AsmPrinter.

---
 llvm/include/llvm/CodeGen/AsmPrinter.h        |  4 ----
 llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp    |  4 ++--
 .../MCTargetDesc/SystemZHLASMAsmStreamer.cpp  |  4 ++--
 llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 20 ++++++++++---------
 llvm/lib/Target/SystemZ/SystemZAsmPrinter.h   |  1 -
 5 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index f7d8249ee87ca..ec17b54357acd 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -673,10 +673,6 @@ class LLVM_ABI AsmPrinter : public MachineFunctionPass {
   virtual bool
   isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const;
 
-  /// Targets can override this if they need to emit additional data after an
-  /// external global variable was emitted.
-  virtual void emitExternalGlobalVariableEnd(MCSymbol *Sym) {}
-
   /// Targets can override this to customize the output of IMPLICIT_DEF
   /// instructions in verbose mode.
   virtual void emitImplicitDef(const MachineInstr *MI) const;
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index d24605f8e3fe2..5fdf88831892f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -840,8 +840,8 @@ void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
     OutStreamer->emitSymbolAttribute(EmittedSym, MCSA_Memtag);
   }
 
-  if (!GV->hasInitializer()) // External globals require no extra code.
-    return emitExternalGlobalVariableEnd(EmittedSym);
+  if (!GV->hasInitializer())   // External globals require no extra code.
+    return;
 
   GVSym->redefineIfPossible();
   if (GVSym->isDefined() || GVSym->isVariable())
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index 067a42b910404..b38bbb09fb8fa 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -369,8 +369,8 @@ void SystemZHLASMAsmStreamer::finishImpl() {
       continue;
     auto &Sym = static_cast<MCSymbolGOFF &>(const_cast<MCSymbol &>(Symbol));
     if (Sym.getCodeData() == GOFF::ESD_EXE_DATA) {
-      OS << Sym.getADA()->getExternalName() << " CATTR PART(" << Sym.getName()
-         << ")";
+      OS << Sym.getADA()->getParent()->getExternalName() << " CATTR PART("
+         << Sym.getName() << ")";
       EmitEOL();
     } else {
       OS << " " << (Sym.isWeak() ? "WXTRN" : "EXTRN") << " " << Sym.getName();
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index 00dba408ec1cb..7df3d33cfcc35 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -1229,20 +1229,22 @@ void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) {
   if (TT.isOSzOS()) {
     emitADASection();
     emitIDRLSection(M);
-  }
-  emitAttributes(M);
-}
-
-void SystemZAsmPrinter::emitExternalGlobalVariableEnd(MCSymbol *Sym) {
-  auto TT = OutContext.getTargetTriple();
-  if (TT.isOSzOS()) {
     // On z/OS, we need to associate an external data reference with an ED
     // symbol, for which we use the the ED of the ADA. We also need to mark the
     // reference as being to data, otherwise we cannot bind with code generated
     // by XL.
-    getTargetStreamer()->emitADA(Sym, OutContext.getObjectFileInfo()->getADASection());
-    OutStreamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeObject);
+    for (auto &GO : M.global_objects()) {
+      if (auto *GV = dyn_cast<GlobalVariable>(&GO)) {
+        if (!GV->hasInitializer()) {
+          MCSymbol *Sym = getSymbol(GV);
+          getTargetStreamer()->emitADA(
+              Sym, OutContext.getObjectFileInfo()->getADASection());
+          OutStreamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeObject);
+        }
+      }
+    }
   }
+  emitAttributes(M);
 }
 
 void SystemZAsmPrinter::emitADASection() {
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
index 22150f6a78e02..0f87eb0307911 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
@@ -117,7 +117,6 @@ class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter {
   void emitXXStructorList(const DataLayout &DL, const Constant *List,
                           bool IsCtor) override;
   void emitEndOfAsmFile(Module &M) override;
-  void emitExternalGlobalVariableEnd(MCSymbol *Sym) override;
   bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
                        const char *ExtraCode, raw_ostream &OS) override;
   bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,



More information about the llvm-commits mailing list