[llvm-branch-commits] [llvm] release/22.x: [SystemZ][z/OS] Handle labels for parts (#175665) (PR #178701)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Jan 29 09:17:26 PST 2026
https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/178701
Backport 84bbaa097c591b32e0f20a546ae6397705ba5ceb
Requested by: @amy-kwan
>From e78bb3455742613733bcc832f7cc92d108812404 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Tue, 13 Jan 2026 09:15:27 -0500
Subject: [PATCH] [SystemZ][z/OS] Handle labels for parts (#175665)
Global data is emitted into parts, which are modelled as a MCSection. A
label (symbol of type LD) is not allowed in a part, which requires
special handling. The approach is to not emit the label at all, and
using the part symbol in relocations.
(cherry picked from commit 84bbaa097c591b32e0f20a546ae6397705ba5ceb)
---
llvm/include/llvm/MC/MCGOFFStreamer.h | 5 +-
llvm/include/llvm/MC/MCObjectStreamer.h | 3 +-
llvm/lib/MC/GOFFObjectWriter.cpp | 3 ++
llvm/lib/MC/MCGOFFStreamer.cpp | 13 +++++
.../MCTargetDesc/SystemZHLASMAsmStreamer.cpp | 16 +++---
llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll | 2 +-
llvm/test/CodeGen/SystemZ/zos-symbol-2.ll | 53 +++++++++++++++++++
7 files changed, 83 insertions(+), 12 deletions(-)
create mode 100644 llvm/test/CodeGen/SystemZ/zos-symbol-2.ll
diff --git a/llvm/include/llvm/MC/MCGOFFStreamer.h b/llvm/include/llvm/MC/MCGOFFStreamer.h
index 886efe10d45df..756574d1caaf3 100644
--- a/llvm/include/llvm/MC/MCGOFFStreamer.h
+++ b/llvm/include/llvm/MC/MCGOFFStreamer.h
@@ -11,12 +11,13 @@
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/Support/Compiler.h"
namespace llvm {
class GOFFObjectWriter;
class MCSymbolGOFF;
-class MCGOFFStreamer : public MCObjectStreamer {
+class LLVM_ABI MCGOFFStreamer : public MCObjectStreamer {
public:
MCGOFFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
@@ -31,6 +32,8 @@ class MCGOFFStreamer : public MCObjectStreamer {
GOFFObjectWriter &getWriter();
+ void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
+
bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h
index 3c5a6ce42e4f8..5d43e32f02b86 100644
--- a/llvm/include/llvm/MC/MCObjectStreamer.h
+++ b/llvm/include/llvm/MC/MCObjectStreamer.h
@@ -14,6 +14,7 @@
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
+#include "llvm/Support/Compiler.h"
namespace llvm {
class MCContext;
@@ -36,7 +37,7 @@ class raw_pwrite_stream;
/// are expected to subclass this interface to implement directives specific
/// to that file format or custom semantics expected by the object writer
/// implementation.
-class MCObjectStreamer : public MCStreamer {
+class LLVM_ABI MCObjectStreamer : public MCStreamer {
std::unique_ptr<MCAssembler> Assembler;
bool EmitEHFrame;
bool EmitDebugFrame;
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 366ca088449dc..cbe9c7eb2fac1 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -385,6 +385,9 @@ void GOFFWriter::defineSymbols() {
} else if (Symbol.isInEDSection()) {
Symbol.setIndex(++Ordinal);
defineLabel(Symbol);
+ } else {
+ // Symbol is in PR section, the symbol refers to the section.
+ Symbol.setIndex(Symbol.getSection().getOrdinal());
}
}
}
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index 51580e0063207..7c99fcbc5451c 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -55,6 +55,19 @@ void MCGOFFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
}
}
+void MCGOFFStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
+ MCSectionGOFF *Section =
+ static_cast<MCSectionGOFF *>(getCurrentSectionOnly());
+ if (Section->isPR()) {
+ if (Section->getBeginSymbol() == nullptr)
+ Section->setBeginSymbol(Symbol);
+ else
+ getContext().reportError(
+ Loc, "only one symbol can be defined in a PR section.");
+ }
+ MCObjectStreamer::emitLabel(Symbol, Loc);
+}
+
bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
MCSymbolAttr Attribute) {
return static_cast<MCSymbolGOFF *>(Sym)->setSymbolAttribute(Attribute);
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index 875b7c42e8db2..8a559e1ab261b 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -232,13 +232,15 @@ void SystemZHLASMAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
MCStreamer::emitLabel(Sym, Loc);
- // Emit ENTRY statement only if not implied by CSECT.
- bool EmitEntry = true;
+ // Emit label and ENTRY statement only if not implied by CSECT. Do not emit a
+ // label if the symbol is on a PR section.
+ bool EmitLabelAndEntry =
+ !static_cast<MCSectionGOFF *>(getCurrentSectionOnly())->isPR();
if (!Sym->isTemporary() && Sym->isInEDSection()) {
- EmitEntry =
+ EmitLabelAndEntry =
Sym->getName() !=
static_cast<MCSectionGOFF &>(Sym->getSection()).getParent()->getName();
- if (EmitEntry) {
+ if (EmitLabelAndEntry) {
OS << " ENTRY " << Sym->getName();
EmitEOL();
}
@@ -248,12 +250,8 @@ void SystemZHLASMAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
EmitEOL();
}
- // TODO Need to adjust this based on Label type
- if (EmitEntry) {
+ if (EmitLabelAndEntry) {
OS << Sym->getName() << " DS 0H";
- // TODO Update LabelSuffix in SystemZMCAsmInfoGOFF once tests have been
- // moved to HLASM syntax.
- // OS << MAI->getLabelSuffix();
EmitEOL();
}
}
diff --git a/llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll b/llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll
index 4415cbfee833d..e3d3b0d8825c1 100644
--- a/llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll
@@ -36,8 +36,8 @@ define void @foo() {
; CHECK: DC AD(L#EPM_foo_0-L#PPA1_foo_0)
; CHECK-LABEL: L#.str DS 0H
; CHECK: DC XL10'48656C6C6F2025730A00'
+; CHECK: Greeting XATTR LINKAGE(XPLINK),REFERENCE(DATA),SCOPE(EXPORT)
; CHECK: DS 0B
-; CHECK-LABEL: Greeting DS 0H
; CHECK: DC AD(L#.str)
; CHECK: DS 0B
; CHECK-LABEL: L#.str.1 DS 0H
diff --git a/llvm/test/CodeGen/SystemZ/zos-symbol-2.ll b/llvm/test/CodeGen/SystemZ/zos-symbol-2.ll
new file mode 100644
index 0000000000000..ffea210fa9c7b
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/zos-symbol-2.ll
@@ -0,0 +1,53 @@
+; RUN: llc <%s --mtriple s390x-ibm-zos -emit-gnuas-syntax-on-zos=false | FileCheck %s
+; RUN: llc <%s --mtriple s390x-ibm-zos --filetype=obj | \
+; RUN: od -Ax -tx1 -v | FileCheck --check-prefix=CHECKREL --ignore-case %s
+
+ at a = hidden global i64 0, align 8
+ at b = external global i64, align 8
+
+define i64 @calc() {
+entry:
+ %0 = load i64, ptr @a, align 8
+ %1 = load i64, ptr @b, align 8
+ %add = add i64 %0, %1
+ ret i64 %add
+}
+
+; Check the global CSECT definition
+; CHECK: stdin#C CSECT
+; CHECK-NEXT: C_CODE64 CATTR ALIGN(3),FILL(0),READONLY,RMODE(64)
+
+; Check the attributes on the function
+; CHECK: ENTRY calc
+; CHECK-NEXT: calc XATTR LINKAGE(XPLINK),REFERENCE(CODE),SCOPE(EXPORT)
+; CHECK-NEXT: calc DS 0H
+
+; Check the definition of the variable
+; CHECK: a CSECT
+; CHECK-NEXT: C_WSA64 CATTR ALIGN(3),FILL(0),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(a)
+; 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 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
+; 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
More information about the llvm-branch-commits
mailing list