[llvm-branch-commits] [llvm] [GOFF] Write out relocations in the GOFF writer (PR #167054)
Kai Nacke via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Nov 28 15:57:27 PST 2025
https://github.com/redstar updated https://github.com/llvm/llvm-project/pull/167054
>From 0d1109a022dfaeab8022870c248fe35a2398ddae Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 7 Nov 2025 11:13:49 -0500
Subject: [PATCH 1/8] [GOFF] Write out relocations in the GOFF writer
Add support for writing relocations. Since the symbol numbering is only
available after the symbols are written, the relocations are collected
in a vector. At write time, the relocations are converted using the
symbols ids, compressed and written out. A relocation data record is
limited to 32K-1 bytes, which requires making sure that larger relocation
data is written into multiple records.
---
llvm/include/llvm/BinaryFormat/GOFF.h | 26 ++
llvm/include/llvm/MC/MCGOFFObjectWriter.h | 36 ++-
llvm/lib/MC/GOFFObjectWriter.cpp | 266 +++++++++++++++++-
.../MCTargetDesc/SystemZGOFFObjectWriter.cpp | 24 ++
.../SystemZ/MCTargetDesc/SystemZMCAsmInfo.h | 1 +
llvm/test/CodeGen/SystemZ/zos-section-1.ll | 23 +-
llvm/test/CodeGen/SystemZ/zos-section-2.ll | 16 +-
7 files changed, 377 insertions(+), 15 deletions(-)
diff --git a/llvm/include/llvm/BinaryFormat/GOFF.h b/llvm/include/llvm/BinaryFormat/GOFF.h
index 49d2809cb6524..08bdb5d624fca 100644
--- a/llvm/include/llvm/BinaryFormat/GOFF.h
+++ b/llvm/include/llvm/BinaryFormat/GOFF.h
@@ -157,6 +157,32 @@ enum ESDAlignment : uint8_t {
ESD_ALIGN_4Kpage = 12,
};
+enum RLDReferenceType : uint8_t {
+ RLD_RT_RAddress = 0,
+ RLD_RT_ROffset = 1,
+ RLD_RT_RLength = 2,
+ RLD_RT_RRelativeImmediate = 6,
+ RLD_RT_RTypeConstant = 7,
+ RLD_RT_RLongDisplacement = 9,
+};
+
+enum RLDReferentType : uint8_t {
+ RLD_RO_Label = 0,
+ RLD_RO_Element = 1,
+ RLD_RO_Class = 2,
+ RLD_RO_Part = 3,
+};
+
+enum RLDAction : uint8_t {
+ RLD_ACT_Add = 0,
+ RLD_ACT_Subtract = 1,
+};
+
+enum RLDFetchStore : uint8_t {
+ RLD_FS_Fetch = 0,
+ RLD_FS_Store = 1
+};
+
enum ENDEntryPointRequest : uint8_t {
END_EPR_None = 0,
END_EPR_EsdidOffset = 1,
diff --git a/llvm/include/llvm/MC/MCGOFFObjectWriter.h b/llvm/include/llvm/MC/MCGOFFObjectWriter.h
index 90887b296d46f..4e23353536adf 100644
--- a/llvm/include/llvm/MC/MCGOFFObjectWriter.h
+++ b/llvm/include/llvm/MC/MCGOFFObjectWriter.h
@@ -11,10 +11,13 @@
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCValue.h"
+#include <memory>
+#include <vector>
namespace llvm {
class MCObjectWriter;
class MCSectionGOFF;
+class MCSymbolGOFF;
class raw_pwrite_stream;
class MCGOFFObjectTargetWriter : public MCObjectTargetWriter {
@@ -22,8 +25,19 @@ class MCGOFFObjectTargetWriter : public MCObjectTargetWriter {
MCGOFFObjectTargetWriter() = default;
public:
+ enum RLDRelocationType {
+ Reloc_Type_ACon = 0x1, // General address.
+ Reloc_Type_RelImm = 0x2, // Relative-immediate address.
+ Reloc_Type_QCon = 0x3, // Offset of symbol in class.
+ Reloc_Type_VCon = 0x4, // Address of external symbol.
+ Reloc_Type_RCon = 0x5, // PSECT of symbol.
+ };
+
~MCGOFFObjectTargetWriter() override = default;
+ virtual unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
+ bool IsPCRel) const = 0;
+
Triple::ObjectFormatType getFormat() const override { return Triple::GOFF; }
static bool classof(const MCObjectTargetWriter *W) {
@@ -31,6 +45,23 @@ class MCGOFFObjectTargetWriter : public MCObjectTargetWriter {
}
};
+struct GOFFSavedRelocationEntry {
+ const MCSectionGOFF *Section;
+ const MCSymbolGOFF *SymA;
+ const MCSymbolGOFF *SymB;
+ unsigned RelocType;
+ uint64_t FixupOffset;
+ uint32_t Length;
+ uint64_t FixedValue; // Info only.
+
+ GOFFSavedRelocationEntry(const MCSectionGOFF *Section,
+ const MCSymbolGOFF *SymA, const MCSymbolGOFF *SymB,
+ unsigned RelocType, uint64_t FixupOffset,
+ uint32_t Length, uint64_t FixedValue)
+ : Section(Section), SymA(SymA), SymB(SymB), RelocType(RelocType),
+ FixupOffset(FixupOffset), Length(Length), FixedValue(FixedValue) {}
+};
+
class GOFFObjectWriter : public MCObjectWriter {
// The target specific GOFF writer instance.
std::unique_ptr<MCGOFFObjectTargetWriter> TargetObjectWriter;
@@ -41,6 +72,9 @@ class GOFFObjectWriter : public MCObjectWriter {
// The RootSD section.
MCSectionGOFF *RootSD = nullptr;
+ // Saved relocation data.
+ std::vector<GOFFSavedRelocationEntry> SavedRelocs;
+
public:
GOFFObjectWriter(std::unique_ptr<MCGOFFObjectTargetWriter> MOTW,
raw_pwrite_stream &OS);
@@ -50,7 +84,7 @@ class GOFFObjectWriter : public MCObjectWriter {
// Implementation of the MCObjectWriter interface.
void recordRelocation(const MCFragment &F, const MCFixup &Fixup,
- MCValue Target, uint64_t &FixedValue) override {}
+ MCValue Target, uint64_t &FixedValue) override;
uint64_t writeObject() override;
};
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 02e7666af1d1f..c3c34301ed3f4 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -10,7 +10,9 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/SmallVector.h"
#include "llvm/BinaryFormat/GOFF.h"
+#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCGOFFAttributes.h"
#include "llvm/MC/MCGOFFObjectWriter.h"
@@ -280,14 +282,43 @@ class GOFFSymbol {
}
};
+// A GOFFRelocationEntry describes a single relocation.
+struct GOFFRelocationEntry {
+ uint32_t REsdId; // The R pointer.
+ uint32_t PEsdId; // The P pointer.
+ uint64_t POffset; // The offset within the element described by the P pointer.
+
+ uint32_t TargetLength; // The byte length of the target field.
+
+ // Details of the relocation.
+ GOFF::RLDReferenceType ReferenceType : 4;
+ GOFF::RLDReferentType ReferentType : 2;
+ GOFF::RLDAction Action : 1;
+ GOFF::RLDFetchStore FetchStore : 1;
+
+ GOFFRelocationEntry() = default;
+ GOFFRelocationEntry(uint32_t REsdId, uint32_t PEsdId, uint64_t POffset,
+ GOFF::RLDReferenceType ReferenceType,
+ GOFF::RLDReferentType ReferentType,
+ GOFF::RLDAction Action, GOFF::RLDFetchStore FetchStore,
+ uint32_t TargetLength)
+ : REsdId(REsdId), PEsdId(PEsdId), POffset(POffset),
+ TargetLength(TargetLength), ReferenceType(ReferenceType),
+ ReferentType(ReferentType), Action(Action), FetchStore(FetchStore) {}
+};
+
class GOFFWriter {
GOFFOstream OS;
MCAssembler &Asm;
MCSectionGOFF *RootSD;
+ /// Saved relocation data collected in recordRelocations().
+ const std::vector<GOFFSavedRelocationEntry> &SavedRelocs;
+
void writeHeader();
void writeSymbol(const GOFFSymbol &Symbol);
void writeText(const MCSectionGOFF *MC);
+ void writeRelocations();
void writeEnd();
void defineSectionSymbols(const MCSectionGOFF &Section);
@@ -296,14 +327,16 @@ class GOFFWriter {
void defineSymbols();
public:
- GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm, MCSectionGOFF *RootSD);
+ GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm, MCSectionGOFF *RootSD,
+ const std::vector<GOFFSavedRelocationEntry> &SavedRelocs);
uint64_t writeObject();
};
} // namespace
GOFFWriter::GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm,
- MCSectionGOFF *RootSD)
- : OS(OS), Asm(Asm), RootSD(RootSD) {}
+ MCSectionGOFF *RootSD,
+ const std::vector<GOFFSavedRelocationEntry> &SavedRelocs)
+ : OS(OS), Asm(Asm), RootSD(RootSD), SavedRelocs(SavedRelocs) {}
void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
if (Section.isSD()) {
@@ -515,6 +548,169 @@ void GOFFWriter::writeText(const MCSectionGOFF *Section) {
Asm.writeSectionData(S, Section);
}
+namespace {
+// RelocDataItemBuffer provides a static buffer for relocation data items.
+class RelocDataItemBuffer {
+ char Buffer[GOFF::MaxDataLength];
+ char *Ptr;
+
+public:
+ RelocDataItemBuffer() : Ptr(Buffer) {}
+ const char *data() { return Buffer; }
+ size_t size() { return Ptr - Buffer; }
+ void reset() { Ptr = Buffer; }
+ bool fits(size_t S) { return size() + S < GOFF::MaxDataLength; }
+ template <typename T> void writebe(T Val) {
+ assert(fits(sizeof(T)) && "Out-of-bounds write");
+ support::endian::write<T, llvm::endianness::big>(Ptr, Val);
+ Ptr += sizeof(T);
+ }
+};
+} // namespace
+
+void GOFFWriter::writeRelocations() {
+ // Transform a GOFFSavedRelocationEntry to 1 or 2 GOFFRelocationEntry
+ // instances. An expression like SymA - SymB + Const is implemented by storing
+ // Const in the memory (aka the FixedValue), and then having a relocation to
+ // add SymA, and another relocation to subtract SymB.
+ std::vector<GOFFRelocationEntry> Relocations;
+ for (auto &RelocEntry : SavedRelocs) {
+ auto *PSection = RelocEntry.Section;
+ auto RelocType = RelocEntry.RelocType;
+ auto *A = RelocEntry.SymA;
+ auto *B = RelocEntry.SymB;
+ auto FixupOffset = RelocEntry.FixupOffset;
+ auto Length = RelocEntry.Length;
+
+ auto GetRptr = [](const MCSymbolGOFF *Sym) -> uint32_t {
+ if (Sym->isTemporary())
+ return static_cast<MCSectionGOFF &>(Sym->getSection())
+ .getBeginSymbol()
+ ->getIndex();
+ return Sym->getIndex();
+ };
+
+ const uint32_t Pptr = PSection->getOrdinal();
+ uint32_t RptrA = GetRptr(A);
+ uint32_t RptrB = B ? GetRptr(B) : 0;
+
+ // UseQCon causes class offsets versus absolute addresses to be used. This
+ // is analogous to using QCONs in older OBJ object file format.
+ bool UseQCon = RelocType == MCGOFFObjectTargetWriter::Reloc_Type_QCon;
+
+ GOFF::RLDFetchStore FetchStore =
+ (RelocType == MCGOFFObjectTargetWriter::Reloc_Type_RCon ||
+ RelocType == MCGOFFObjectTargetWriter::Reloc_Type_VCon)
+ ? GOFF::RLDFetchStore::RLD_FS_Store
+ : GOFF::RLDFetchStore::RLD_FS_Fetch;
+ assert(FetchStore == GOFF::RLDFetchStore::RLD_FS_Fetch ||
+ RptrB == 0 && "No dependent relocations expected");
+
+ enum GOFF::RLDReferenceType ReferenceType = GOFF::RLD_RT_RAddress;
+ enum GOFF::RLDReferentType ReferentType = GOFF::RLD_RO_Label;
+ if (UseQCon) {
+ ReferenceType = GOFF::RLD_RT_ROffset;
+ ReferentType = GOFF::RLD_RO_Class;
+ }
+ if (RelocType == MCGOFFObjectTargetWriter::Reloc_Type_RCon)
+ ReferenceType = GOFF::RLD_RT_RTypeConstant;
+
+ if (RptrA) {
+ LLVM_DEBUG(dbgs() << "Reloc A: " << (UseQCon ? "QCon" : "ACon")
+ << " Rptr: " << RptrA << " Pptr: " << Pptr
+ << " Offset: " << FixupOffset
+ << " Fixed Imm: " << RelocEntry.FixedValue << "\n");
+ Relocations.emplace_back(RptrA, Pptr, FixupOffset, ReferenceType,
+ ReferentType, GOFF::RLD_ACT_Add, FetchStore,
+ Length);
+ }
+ if (RptrB) {
+ LLVM_DEBUG(dbgs() << "Reloc B: " << (UseQCon ? "QCon" : "ACon")
+ << " Rptr: " << RptrA << " Pptr: " << Pptr
+ << " Offset: " << FixupOffset
+ << " Fixed Imm: " << RelocEntry.FixedValue << "\n");
+ Relocations.emplace_back(RptrB, Pptr, FixupOffset, ReferenceType,
+ ReferentType, GOFF::RLD_ACT_Subtract,
+ GOFF::RLDFetchStore::RLD_FS_Fetch, Length);
+ }
+ }
+
+ // Sort relocation data items by the P pointer to save space.
+ std::sort(
+ Relocations.begin(), Relocations.end(),
+ [](const GOFFRelocationEntry &Left, const GOFFRelocationEntry &Right) {
+ return std::tie(Left.PEsdId, Left.REsdId, Left.POffset) <
+ std::tie(Right.PEsdId, Right.REsdId, Right.POffset);
+ });
+
+ // Construct the compressed relocation data items, and write them out.
+ RelocDataItemBuffer Buffer;
+ for (auto I = Relocations.begin(), E = Relocations.end(); I != E;) {
+ Buffer.reset();
+
+ uint32_t PrevResdId = -1;
+ uint32_t PrevPesdId = -1;
+ uint64_t PrevPOffset = -1;
+ for (; I != E; ++I) {
+ const GOFFRelocationEntry &Rel = *I;
+
+ bool SameREsdId = (Rel.REsdId == PrevResdId);
+ bool SamePEsdId = (Rel.PEsdId == PrevPesdId);
+ bool SamePOffset = (Rel.POffset == PrevPOffset);
+ bool EightByteOffset = ((Rel.POffset >> 32) & 0xffffffff);
+
+ // Calculate size of relocation data item, and check if it still fits into
+ // the record.
+ size_t ItemSize = 8; // Smallest size of a relocation data item.
+ if (!SameREsdId)
+ ItemSize += 4;
+ if (!SamePEsdId)
+ ItemSize += 4;
+ if (!SamePOffset)
+ ItemSize += (EightByteOffset ? 8 : 4);
+ if (!Buffer.fits(ItemSize))
+ break;
+
+ GOFF::Flags RelocFlags[6];
+ RelocFlags[0].set(0, 1, SameREsdId);
+ RelocFlags[0].set(1, 1, SamePEsdId);
+ RelocFlags[0].set(2, 1, SamePOffset);
+ RelocFlags[0].set(6, 1, EightByteOffset);
+
+ RelocFlags[1].set(0, 4, Rel.ReferenceType);
+ RelocFlags[1].set(4, 4, Rel.ReferentType);
+
+ RelocFlags[2].set(0, 7, Rel.Action);
+ RelocFlags[2].set(7, 1, Rel.FetchStore);
+
+ RelocFlags[4].set(0, 8, Rel.TargetLength);
+
+ for (auto F : RelocFlags)
+ Buffer.writebe<uint8_t>(F);
+ Buffer.writebe<uint16_t>(0); // Reserved.
+ if (!SameREsdId)
+ Buffer.writebe<uint32_t>(Rel.REsdId);
+ if (!SamePEsdId)
+ Buffer.writebe<uint32_t>(Rel.PEsdId);
+ if (!SamePOffset) {
+ if (EightByteOffset)
+ Buffer.writebe<uint64_t>(Rel.POffset);
+ else
+ Buffer.writebe<uint32_t>(Rel.POffset);
+ }
+
+ PrevResdId = Rel.REsdId;
+ PrevPesdId = Rel.PEsdId;
+ PrevPOffset = Rel.POffset;
+ }
+
+ OS.newRecord(GOFF::RT_RLD);
+ OS.writebe<uint8_t>(0); // Reserved.
+ OS.writebe<uint16_t>(Buffer.size()); // Length (of the relocation data).
+ OS.write(Buffer.data(), Buffer.size()); // Relocation Directory Data Items.
+ }
+}
+
void GOFFWriter::writeEnd() {
uint8_t F = GOFF::END_EPR_None;
uint8_t AMODE = 0;
@@ -541,6 +737,8 @@ uint64_t GOFFWriter::writeObject() {
for (const MCSection &Section : Asm)
writeText(static_cast<const MCSectionGOFF *>(&Section));
+ writeRelocations();
+
writeEnd();
// Make sure all records are written.
@@ -558,8 +756,68 @@ GOFFObjectWriter::GOFFObjectWriter(
GOFFObjectWriter::~GOFFObjectWriter() = default;
+void GOFFObjectWriter::recordRelocation(const MCFragment &F,
+ const MCFixup &Fixup, MCValue Target,
+ uint64_t &FixedValue) {
+ const MCFixupKindInfo &FKI =
+ Asm->getBackend().getFixupKindInfo(Fixup.getKind());
+ const uint32_t Length = FKI.TargetSize / 8;
+ assert(FKI.TargetSize % 8 == 0 && "Target Size not multiple of 8");
+ const uint64_t FixupOffset = Asm->getFragmentOffset(F) + Fixup.getOffset();
+ bool IsPCRel = Fixup.isPCRel();
+
+ unsigned RelocType = TargetObjectWriter->getRelocType(Target, Fixup, IsPCRel);
+
+ const MCSectionGOFF *PSection = static_cast<MCSectionGOFF *>(F.getParent());
+ const auto &A = *static_cast<const MCSymbolGOFF *>(Target.getAddSym());
+ const MCSymbolGOFF *B = static_cast<const MCSymbolGOFF *>(Target.getSubSym());
+ if (RelocType == MCGOFFObjectTargetWriter::Reloc_Type_RelImm) {
+ if (A.isUndefined()) {
+ Asm->reportError(
+ Fixup.getLoc(),
+ Twine("symbol ")
+ .concat(A.getName())
+ .concat(" must be defined for a relative immediate relocation"));
+ return;
+ }
+ if (&A.getSection() != PSection) {
+ Asm->reportError(Fixup.getLoc(),
+ Twine("relative immediate relocation section mismatch: ")
+ .concat(A.getSection().getName())
+ .concat(" of symbol ")
+ .concat(A.getName())
+ .concat(" <-> ")
+ .concat(PSection->getName()));
+ return;
+ }
+ if (B) {
+ Asm->reportError(
+ Fixup.getLoc(),
+ Twine("subtractive symbol ")
+ .concat(B->getName())
+ .concat(" not supported for a relative immediate relocation"));
+ return;
+ }
+ FixedValue = Asm->getSymbolOffset(A) - FixupOffset + Target.getConstant();
+ return;
+ }
+ FixedValue = Target.getConstant();
+
+ // The symbol only has a section-relative offset if it is a temporary symbol.
+ FixedValue += A.isTemporary() ? Asm->getSymbolOffset(A) : 0;
+ A.setUsedInReloc();
+ if (B) {
+ FixedValue -= B->isTemporary() ? Asm->getSymbolOffset(*B) : 0;
+ B->setUsedInReloc();
+ }
+
+ // Save relocation data for later writing.
+ SavedRelocs.emplace_back(PSection, &A, B, RelocType, FixupOffset, Length,
+ FixedValue);
+}
+
uint64_t GOFFObjectWriter::writeObject() {
- uint64_t Size = GOFFWriter(OS, *Asm, RootSD).writeObject();
+ uint64_t Size = GOFFWriter(OS, *Asm, RootSD, SavedRelocs).writeObject();
return Size;
}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp
index 205066814fbd0..8c042d1dbb014 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "MCTargetDesc/SystemZMCTargetDesc.h"
+#include "SystemZMCAsmInfo.h"
#include "llvm/MC/MCGOFFObjectWriter.h"
#include <memory>
@@ -16,12 +17,35 @@ namespace {
class SystemZGOFFObjectWriter : public MCGOFFObjectTargetWriter {
public:
SystemZGOFFObjectWriter();
+
+ unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
+ bool IsPCRel) const override;
};
} // end anonymous namespace
SystemZGOFFObjectWriter::SystemZGOFFObjectWriter()
: MCGOFFObjectTargetWriter() {}
+unsigned SystemZGOFFObjectWriter::getRelocType(const MCValue &Target,
+ const MCFixup &Fixup,
+ bool IsPCRel) const {
+ switch (Target.getSpecifier()) {
+ case SystemZ::S_PLT: // TODO This doen't make sense.
+ return Reloc_Type_RelImm;
+ case SystemZ::S_RCon:
+ return Reloc_Type_RCon;
+ case SystemZ::S_VCon:
+ return Reloc_Type_VCon;
+ case SystemZ::S_QCon:
+ return Reloc_Type_QCon;
+ case SystemZ::S_None:
+ if (IsPCRel)
+ return Reloc_Type_RelImm;
+ return Reloc_Type_ACon;
+ }
+ llvm_unreachable("Modifier not supported");
+}
+
std::unique_ptr<MCObjectTargetWriter> llvm::createSystemZGOFFObjectWriter() {
return std::make_unique<SystemZGOFFObjectWriter>();
}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.h
index 11c2833b8ada8..668158b896856 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.h
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.h
@@ -51,6 +51,7 @@ enum {
// https://www.ibm.com/docs/en/hla-and-tf/1.6?topic=value-address-constants
S_RCon, // Address of ADA of symbol.
S_VCon, // Address of external function symbol.
+ S_QCon, // Class-based offset.
};
} // namespace SystemZ
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-1.ll b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
index cae371b07d0eb..f4e245addc2c3 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-1.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
@@ -145,9 +145,22 @@ entry:
; 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: 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: 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: 0005a0 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0005b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0005c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0005d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0005e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; 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
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-2.ll b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
index f59bace65ca73..d3eb6d9505340 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-2.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
@@ -175,9 +175,15 @@ source_filename = "test.ll"
; 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: 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: 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
+; 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 511ce34a5334ca12813465f116f8e2c1562766d3 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Mon, 17 Nov 2025 11:16:45 -0500
Subject: [PATCH 2/8] Remove `IsPCRel` parameter
Information can be retrieved from `Fixup`.
---
llvm/include/llvm/MC/MCGOFFObjectWriter.h | 4 ++--
llvm/lib/MC/GOFFObjectWriter.cpp | 3 +--
.../SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp | 11 +++++------
3 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/llvm/include/llvm/MC/MCGOFFObjectWriter.h b/llvm/include/llvm/MC/MCGOFFObjectWriter.h
index 4e23353536adf..3bffffc5fbdec 100644
--- a/llvm/include/llvm/MC/MCGOFFObjectWriter.h
+++ b/llvm/include/llvm/MC/MCGOFFObjectWriter.h
@@ -35,8 +35,8 @@ class MCGOFFObjectTargetWriter : public MCObjectTargetWriter {
~MCGOFFObjectTargetWriter() override = default;
- virtual unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
- bool IsPCRel) const = 0;
+ virtual unsigned getRelocType(const MCValue &Target,
+ const MCFixup &Fixup) const = 0;
Triple::ObjectFormatType getFormat() const override { return Triple::GOFF; }
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index c3c34301ed3f4..3fa0e8350b0a8 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -764,9 +764,8 @@ void GOFFObjectWriter::recordRelocation(const MCFragment &F,
const uint32_t Length = FKI.TargetSize / 8;
assert(FKI.TargetSize % 8 == 0 && "Target Size not multiple of 8");
const uint64_t FixupOffset = Asm->getFragmentOffset(F) + Fixup.getOffset();
- bool IsPCRel = Fixup.isPCRel();
- unsigned RelocType = TargetObjectWriter->getRelocType(Target, Fixup, IsPCRel);
+ unsigned RelocType = TargetObjectWriter->getRelocType(Target, Fixup);
const MCSectionGOFF *PSection = static_cast<MCSectionGOFF *>(F.getParent());
const auto &A = *static_cast<const MCSymbolGOFF *>(Target.getAddSym());
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp
index 8c042d1dbb014..cfbdd5d4780ab 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp
@@ -18,8 +18,8 @@ class SystemZGOFFObjectWriter : public MCGOFFObjectTargetWriter {
public:
SystemZGOFFObjectWriter();
- unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
- bool IsPCRel) const override;
+ unsigned getRelocType(const MCValue &Target,
+ const MCFixup &Fixup) const override;
};
} // end anonymous namespace
@@ -27,10 +27,9 @@ SystemZGOFFObjectWriter::SystemZGOFFObjectWriter()
: MCGOFFObjectTargetWriter() {}
unsigned SystemZGOFFObjectWriter::getRelocType(const MCValue &Target,
- const MCFixup &Fixup,
- bool IsPCRel) const {
+ const MCFixup &Fixup) const {
switch (Target.getSpecifier()) {
- case SystemZ::S_PLT: // TODO This doen't make sense.
+ case SystemZ::S_PLT: // TODO This doen't make sense.
return Reloc_Type_RelImm;
case SystemZ::S_RCon:
return Reloc_Type_RCon;
@@ -39,7 +38,7 @@ unsigned SystemZGOFFObjectWriter::getRelocType(const MCValue &Target,
case SystemZ::S_QCon:
return Reloc_Type_QCon;
case SystemZ::S_None:
- if (IsPCRel)
+ if (Fixup.isPCRel())
return Reloc_Type_RelImm;
return Reloc_Type_ACon;
}
>From 87dd5fa9975b6049c7498a78241b0216a9049a67 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Mon, 17 Nov 2025 16:38:02 -0500
Subject: [PATCH 3/8] Use only one vector to store the relocations.
---
llvm/include/llvm/MC/MCGOFFObjectWriter.h | 43 ++++---
llvm/lib/MC/GOFFObjectWriter.cpp | 150 +++++++++-------------
2 files changed, 88 insertions(+), 105 deletions(-)
diff --git a/llvm/include/llvm/MC/MCGOFFObjectWriter.h b/llvm/include/llvm/MC/MCGOFFObjectWriter.h
index 3bffffc5fbdec..1079009e8b13c 100644
--- a/llvm/include/llvm/MC/MCGOFFObjectWriter.h
+++ b/llvm/include/llvm/MC/MCGOFFObjectWriter.h
@@ -9,6 +9,7 @@
#ifndef LLVM_MC_MCGOFFOBJECTWRITER_H
#define LLVM_MC_MCGOFFOBJECTWRITER_H
+#include "llvm/BinaryFormat/GOFF.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCValue.h"
#include <memory>
@@ -45,21 +46,31 @@ class MCGOFFObjectTargetWriter : public MCObjectTargetWriter {
}
};
-struct GOFFSavedRelocationEntry {
- const MCSectionGOFF *Section;
- const MCSymbolGOFF *SymA;
- const MCSymbolGOFF *SymB;
- unsigned RelocType;
- uint64_t FixupOffset;
- uint32_t Length;
- uint64_t FixedValue; // Info only.
-
- GOFFSavedRelocationEntry(const MCSectionGOFF *Section,
- const MCSymbolGOFF *SymA, const MCSymbolGOFF *SymB,
- unsigned RelocType, uint64_t FixupOffset,
- uint32_t Length, uint64_t FixedValue)
- : Section(Section), SymA(SymA), SymB(SymB), RelocType(RelocType),
- FixupOffset(FixupOffset), Length(Length), FixedValue(FixedValue) {}
+// A GOFFRelocationEntry describes a single relocation.
+// For the naming, see
+// https://www.ibm.com/docs/en/zos/3.1.0?topic=record-relocation-directory-data-item.
+struct GOFFRelocationEntry {
+ const MCSymbolGOFF *Rptr; // The R pointer.
+ const MCSectionGOFF *Pptr; // The P pointer.
+ uint32_t REsdId = 0; // The R pointer id.
+ uint32_t PEsdId = 0; // The P pointer id.
+ uint64_t POffset; // The offset within the element described by the P pointer.
+ uint32_t TargetLength; // The byte length of the target field.
+
+ // Details of the relocation.
+ GOFF::RLDReferenceType ReferenceType : 4;
+ GOFF::RLDReferentType ReferentType : 2;
+ GOFF::RLDAction Action : 1;
+ GOFF::RLDFetchStore FetchStore : 1;
+
+ GOFFRelocationEntry(const MCSectionGOFF *Pptr, const MCSymbolGOFF *Rptr,
+ GOFF::RLDReferenceType ReferenceType,
+ GOFF::RLDReferentType ReferentType,
+ GOFF::RLDAction Action, GOFF::RLDFetchStore FetchStore,
+ uint64_t POffset, uint32_t TargetLength)
+ : Rptr(Rptr), Pptr(Pptr), POffset(POffset), TargetLength(TargetLength),
+ ReferenceType(ReferenceType), ReferentType(ReferentType),
+ Action(Action), FetchStore(FetchStore) {}
};
class GOFFObjectWriter : public MCObjectWriter {
@@ -73,7 +84,7 @@ class GOFFObjectWriter : public MCObjectWriter {
MCSectionGOFF *RootSD = nullptr;
// Saved relocation data.
- std::vector<GOFFSavedRelocationEntry> SavedRelocs;
+ std::vector<GOFFRelocationEntry> Relocations;
public:
GOFFObjectWriter(std::unique_ptr<MCGOFFObjectTargetWriter> MOTW,
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 3fa0e8350b0a8..f13504c486cb2 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -10,7 +10,6 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/SmallVector.h"
#include "llvm/BinaryFormat/GOFF.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAssembler.h"
@@ -282,38 +281,13 @@ class GOFFSymbol {
}
};
-// A GOFFRelocationEntry describes a single relocation.
-struct GOFFRelocationEntry {
- uint32_t REsdId; // The R pointer.
- uint32_t PEsdId; // The P pointer.
- uint64_t POffset; // The offset within the element described by the P pointer.
-
- uint32_t TargetLength; // The byte length of the target field.
-
- // Details of the relocation.
- GOFF::RLDReferenceType ReferenceType : 4;
- GOFF::RLDReferentType ReferentType : 2;
- GOFF::RLDAction Action : 1;
- GOFF::RLDFetchStore FetchStore : 1;
-
- GOFFRelocationEntry() = default;
- GOFFRelocationEntry(uint32_t REsdId, uint32_t PEsdId, uint64_t POffset,
- GOFF::RLDReferenceType ReferenceType,
- GOFF::RLDReferentType ReferentType,
- GOFF::RLDAction Action, GOFF::RLDFetchStore FetchStore,
- uint32_t TargetLength)
- : REsdId(REsdId), PEsdId(PEsdId), POffset(POffset),
- TargetLength(TargetLength), ReferenceType(ReferenceType),
- ReferentType(ReferentType), Action(Action), FetchStore(FetchStore) {}
-};
-
class GOFFWriter {
GOFFOstream OS;
MCAssembler &Asm;
MCSectionGOFF *RootSD;
/// Saved relocation data collected in recordRelocations().
- const std::vector<GOFFSavedRelocationEntry> &SavedRelocs;
+ std::vector<GOFFRelocationEntry> &Relocations;
void writeHeader();
void writeSymbol(const GOFFSymbol &Symbol);
@@ -328,15 +302,15 @@ class GOFFWriter {
public:
GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm, MCSectionGOFF *RootSD,
- const std::vector<GOFFSavedRelocationEntry> &SavedRelocs);
+ std::vector<GOFFRelocationEntry> &Relocations);
uint64_t writeObject();
};
} // namespace
GOFFWriter::GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm,
MCSectionGOFF *RootSD,
- const std::vector<GOFFSavedRelocationEntry> &SavedRelocs)
- : OS(OS), Asm(Asm), RootSD(RootSD), SavedRelocs(SavedRelocs) {}
+ std::vector<GOFFRelocationEntry> &Relocations)
+ : OS(OS), Asm(Asm), RootSD(RootSD), Relocations(Relocations) {}
void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
if (Section.isSD()) {
@@ -569,19 +543,8 @@ class RelocDataItemBuffer {
} // namespace
void GOFFWriter::writeRelocations() {
- // Transform a GOFFSavedRelocationEntry to 1 or 2 GOFFRelocationEntry
- // instances. An expression like SymA - SymB + Const is implemented by storing
- // Const in the memory (aka the FixedValue), and then having a relocation to
- // add SymA, and another relocation to subtract SymB.
- std::vector<GOFFRelocationEntry> Relocations;
- for (auto &RelocEntry : SavedRelocs) {
- auto *PSection = RelocEntry.Section;
- auto RelocType = RelocEntry.RelocType;
- auto *A = RelocEntry.SymA;
- auto *B = RelocEntry.SymB;
- auto FixupOffset = RelocEntry.FixupOffset;
- auto Length = RelocEntry.Length;
-
+ // Set the IDs in the relocation entries.
+ for (auto &RelocEntry : Relocations) {
auto GetRptr = [](const MCSymbolGOFF *Sym) -> uint32_t {
if (Sym->isTemporary())
return static_cast<MCSectionGOFF &>(Sym->getSection())
@@ -590,49 +553,8 @@ void GOFFWriter::writeRelocations() {
return Sym->getIndex();
};
- const uint32_t Pptr = PSection->getOrdinal();
- uint32_t RptrA = GetRptr(A);
- uint32_t RptrB = B ? GetRptr(B) : 0;
-
- // UseQCon causes class offsets versus absolute addresses to be used. This
- // is analogous to using QCONs in older OBJ object file format.
- bool UseQCon = RelocType == MCGOFFObjectTargetWriter::Reloc_Type_QCon;
-
- GOFF::RLDFetchStore FetchStore =
- (RelocType == MCGOFFObjectTargetWriter::Reloc_Type_RCon ||
- RelocType == MCGOFFObjectTargetWriter::Reloc_Type_VCon)
- ? GOFF::RLDFetchStore::RLD_FS_Store
- : GOFF::RLDFetchStore::RLD_FS_Fetch;
- assert(FetchStore == GOFF::RLDFetchStore::RLD_FS_Fetch ||
- RptrB == 0 && "No dependent relocations expected");
-
- enum GOFF::RLDReferenceType ReferenceType = GOFF::RLD_RT_RAddress;
- enum GOFF::RLDReferentType ReferentType = GOFF::RLD_RO_Label;
- if (UseQCon) {
- ReferenceType = GOFF::RLD_RT_ROffset;
- ReferentType = GOFF::RLD_RO_Class;
- }
- if (RelocType == MCGOFFObjectTargetWriter::Reloc_Type_RCon)
- ReferenceType = GOFF::RLD_RT_RTypeConstant;
-
- if (RptrA) {
- LLVM_DEBUG(dbgs() << "Reloc A: " << (UseQCon ? "QCon" : "ACon")
- << " Rptr: " << RptrA << " Pptr: " << Pptr
- << " Offset: " << FixupOffset
- << " Fixed Imm: " << RelocEntry.FixedValue << "\n");
- Relocations.emplace_back(RptrA, Pptr, FixupOffset, ReferenceType,
- ReferentType, GOFF::RLD_ACT_Add, FetchStore,
- Length);
- }
- if (RptrB) {
- LLVM_DEBUG(dbgs() << "Reloc B: " << (UseQCon ? "QCon" : "ACon")
- << " Rptr: " << RptrA << " Pptr: " << Pptr
- << " Offset: " << FixupOffset
- << " Fixed Imm: " << RelocEntry.FixedValue << "\n");
- Relocations.emplace_back(RptrB, Pptr, FixupOffset, ReferenceType,
- ReferentType, GOFF::RLD_ACT_Subtract,
- GOFF::RLDFetchStore::RLD_FS_Fetch, Length);
- }
+ RelocEntry.PEsdId = RelocEntry.Pptr->getOrdinal();
+ RelocEntry.REsdId = GetRptr(RelocEntry.Rptr);
}
// Sort relocation data items by the P pointer to save space.
@@ -810,13 +732,63 @@ void GOFFObjectWriter::recordRelocation(const MCFragment &F,
B->setUsedInReloc();
}
+ // UseQCon causes class offsets versus absolute addresses to be used. This
+ // is analogous to using QCONs in older OBJ object file format.
+ bool UseQCon = RelocType == MCGOFFObjectTargetWriter::Reloc_Type_QCon;
+
+ GOFF::RLDFetchStore FetchStore =
+ (RelocType == MCGOFFObjectTargetWriter::Reloc_Type_RCon ||
+ RelocType == MCGOFFObjectTargetWriter::Reloc_Type_VCon)
+ ? GOFF::RLDFetchStore::RLD_FS_Store
+ : GOFF::RLDFetchStore::RLD_FS_Fetch;
+ assert(FetchStore == GOFF::RLDFetchStore::RLD_FS_Fetch ||
+ B == nullptr && "No dependent relocations expected");
+
+ enum GOFF::RLDReferenceType ReferenceType = GOFF::RLD_RT_RAddress;
+ enum GOFF::RLDReferentType ReferentType = GOFF::RLD_RO_Label;
+ if (UseQCon) {
+ ReferenceType = GOFF::RLD_RT_ROffset;
+ ReferentType = GOFF::RLD_RO_Class;
+ }
+ if (RelocType == MCGOFFObjectTargetWriter::Reloc_Type_RCon)
+ ReferenceType = GOFF::RLD_RT_RTypeConstant;
+
+ auto DumpReloc = [&PSection, &ReferenceType, &FixupOffset,
+ &FixedValue](const char *N, const MCSymbolGOFF *Sym) {
+ const char *Con;
+ switch (ReferenceType) {
+ case GOFF::RLDReferenceType::RLD_RT_RAddress:
+ Con = "ACon";
+ break;
+ case GOFF::RLDReferenceType::RLD_RT_ROffset:
+ Con = "QCon";
+ break;
+ case GOFF::RLDReferenceType::RLD_RT_RTypeConstant:
+ Con = "VCon";
+ break;
+ default:
+ Con = "(unknown)";
+ }
+ dbgs() << "Reloc " << N << ": " << Con << " Rptr: " << Sym->getName()
+ << " Pptr: " << PSection->getName() << " Offset: " << FixupOffset
+ << " Fixed Imm: " << FixedValue << "\n";
+ };
+ (void)DumpReloc;
+
// Save relocation data for later writing.
- SavedRelocs.emplace_back(PSection, &A, B, RelocType, FixupOffset, Length,
- FixedValue);
+ LLVM_DEBUG(DumpReloc("A", &A));
+ Relocations.emplace_back(PSection, &A, ReferenceType, ReferentType,
+ GOFF::RLD_ACT_Add, FetchStore, FixupOffset, Length);
+ if (B) {
+ LLVM_DEBUG(DumpReloc("B", B));
+ Relocations.emplace_back(
+ PSection, B, ReferenceType, ReferentType, GOFF::RLD_ACT_Subtract,
+ GOFF::RLDFetchStore::RLD_FS_Fetch, FixupOffset, Length);
+ }
}
uint64_t GOFFObjectWriter::writeObject() {
- uint64_t Size = GOFFWriter(OS, *Asm, RootSD, SavedRelocs).writeObject();
+ uint64_t Size = GOFFWriter(OS, *Asm, RootSD, Relocations).writeObject();
return Size;
}
>From 6e9cf9606020344e8e6fbec1e2f40a15594d66d5 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Mon, 17 Nov 2025 16:59:45 -0500
Subject: [PATCH 4/8] Fix formatting.
---
llvm/include/llvm/BinaryFormat/GOFF.h | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/llvm/include/llvm/BinaryFormat/GOFF.h b/llvm/include/llvm/BinaryFormat/GOFF.h
index 08bdb5d624fca..f54d8cd19c86b 100644
--- a/llvm/include/llvm/BinaryFormat/GOFF.h
+++ b/llvm/include/llvm/BinaryFormat/GOFF.h
@@ -178,10 +178,7 @@ enum RLDAction : uint8_t {
RLD_ACT_Subtract = 1,
};
-enum RLDFetchStore : uint8_t {
- RLD_FS_Fetch = 0,
- RLD_FS_Store = 1
-};
+enum RLDFetchStore : uint8_t { RLD_FS_Fetch = 0, RLD_FS_Store = 1 };
enum ENDEntryPointRequest : uint8_t {
END_EPR_None = 0,
>From 4e12b6c4900d9eaa116f442d422c72d9e69309f7 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 19 Nov 2025 10:25:06 -0500
Subject: [PATCH 5/8] Remove use of S_PLT
---
llvm/include/llvm/MC/MCGOFFObjectWriter.h | 10 +++++-----
llvm/lib/MC/GOFFObjectWriter.cpp | 2 +-
.../SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp | 4 +---
.../Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp | 3 +++
.../lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.h | 6 +++---
llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 2 +-
llvm/test/CodeGen/SystemZ/call-zos-02.ll | 4 ++--
llvm/test/CodeGen/SystemZ/zos-ada.ll | 2 +-
8 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/llvm/include/llvm/MC/MCGOFFObjectWriter.h b/llvm/include/llvm/MC/MCGOFFObjectWriter.h
index 1079009e8b13c..57e152f6a61dc 100644
--- a/llvm/include/llvm/MC/MCGOFFObjectWriter.h
+++ b/llvm/include/llvm/MC/MCGOFFObjectWriter.h
@@ -27,11 +27,11 @@ class MCGOFFObjectTargetWriter : public MCObjectTargetWriter {
public:
enum RLDRelocationType {
- Reloc_Type_ACon = 0x1, // General address.
- Reloc_Type_RelImm = 0x2, // Relative-immediate address.
- Reloc_Type_QCon = 0x3, // Offset of symbol in class.
- Reloc_Type_VCon = 0x4, // Address of external symbol.
- Reloc_Type_RCon = 0x5, // PSECT of symbol.
+ Reloc_Type_ACon = 0x1, // General address.
+ Reloc_Type_RICon = 0x2, // Relative-immediate address.
+ Reloc_Type_QCon = 0x3, // Offset of symbol in class.
+ Reloc_Type_VCon = 0x4, // Address of external symbol.
+ Reloc_Type_RCon = 0x5, // PSECT of symbol.
};
~MCGOFFObjectTargetWriter() override = default;
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index f13504c486cb2..68dee92c4ec9b 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -692,7 +692,7 @@ void GOFFObjectWriter::recordRelocation(const MCFragment &F,
const MCSectionGOFF *PSection = static_cast<MCSectionGOFF *>(F.getParent());
const auto &A = *static_cast<const MCSymbolGOFF *>(Target.getAddSym());
const MCSymbolGOFF *B = static_cast<const MCSymbolGOFF *>(Target.getSubSym());
- if (RelocType == MCGOFFObjectTargetWriter::Reloc_Type_RelImm) {
+ if (RelocType == MCGOFFObjectTargetWriter::Reloc_Type_RICon) {
if (A.isUndefined()) {
Asm->reportError(
Fixup.getLoc(),
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp
index cfbdd5d4780ab..43e06e2cbafeb 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp
@@ -29,8 +29,6 @@ SystemZGOFFObjectWriter::SystemZGOFFObjectWriter()
unsigned SystemZGOFFObjectWriter::getRelocType(const MCValue &Target,
const MCFixup &Fixup) const {
switch (Target.getSpecifier()) {
- case SystemZ::S_PLT: // TODO This doen't make sense.
- return Reloc_Type_RelImm;
case SystemZ::S_RCon:
return Reloc_Type_RCon;
case SystemZ::S_VCon:
@@ -39,7 +37,7 @@ unsigned SystemZGOFFObjectWriter::getRelocType(const MCValue &Target,
return Reloc_Type_QCon;
case SystemZ::S_None:
if (Fixup.isPCRel())
- return Reloc_Type_RelImm;
+ return Reloc_Type_RICon;
return Reloc_Type_ACon;
}
llvm_unreachable("Modifier not supported");
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp
index 2933b4becba05..887531f3e2299 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp
@@ -65,6 +65,9 @@ void SystemZMCAsmInfoGOFF::printSpecifierExpr(
case SystemZ::S_None:
OS << "A";
break;
+ case SystemZ::S_QCon:
+ OS << "Q";
+ break;
case SystemZ::S_RCon:
OS << "R";
break;
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.h
index 668158b896856..36bbf2f19a674 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.h
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.h
@@ -49,9 +49,9 @@ enum {
// HLASM docs for address constants:
// https://www.ibm.com/docs/en/hla-and-tf/1.6?topic=value-address-constants
- S_RCon, // Address of ADA of symbol.
- S_VCon, // Address of external function symbol.
- S_QCon, // Class-based offset.
+ S_RCon, // Address of ADA of symbol.
+ S_VCon, // Address of external function symbol.
+ S_QCon, // Class-based offset.
};
} // namespace SystemZ
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index 31c57a63e5c87..414d68e2678ed 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -325,7 +325,7 @@ void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) {
EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BRASL)
.addReg(SystemZ::R7D)
.addExpr(Lower.getExpr(MI->getOperand(0),
- SystemZ::S_PLT)));
+ SystemZ::S_None)));
emitCallInformation(CallType::BRASL7);
return;
diff --git a/llvm/test/CodeGen/SystemZ/call-zos-02.ll b/llvm/test/CodeGen/SystemZ/call-zos-02.ll
index 444972fa8765e..a7f600ae99db0 100644
--- a/llvm/test/CodeGen/SystemZ/call-zos-02.ll
+++ b/llvm/test/CodeGen/SystemZ/call-zos-02.ll
@@ -9,8 +9,8 @@ entry:
define hidden signext i32 @caller2() {
entry:
; CHECK-LABEL: caller2:
-; CHECK: brasl 7,caller at PLT * encoding: [0xc0,0x75,A,A,A,A]
-; CHECK-NEXT: * fixup A - offset: 2, value: caller at PLT+2, kind: FK_390_PC32DBL
+; CHECK: brasl 7,caller * encoding: [0xc0,0x75,A,A,A,A]
+; CHECK-NEXT: * fixup A - offset: 2, value: caller+2, kind: FK_390_PC32DBL
; CHECK-NEXT: bcr 0,3 * encoding: [0x07,0x03]
%call = call signext i32 @caller()
ret i32 %call
diff --git a/llvm/test/CodeGen/SystemZ/zos-ada.ll b/llvm/test/CodeGen/SystemZ/zos-ada.ll
index bb2bd1c7672ea..8f00f32c1b805 100644
--- a/llvm/test/CodeGen/SystemZ/zos-ada.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-ada.ll
@@ -6,7 +6,7 @@
; CHECK: stmg 6,8,1872(4)
; CHECK-NEXT: aghi 4,-192
; CHECK-NEXT: lgr 8,5
-; CHECK-NEXT: brasl 7,callee_internal at PLT
+; CHECK-NEXT: brasl 7,callee_internal
; CHECK-NEXT: bcr 0,3
; CHECK-NEXT: lg 6,8(8)
; CHECK-NEXT: lg 5,0(8)
>From a112e7b8a4810bf902084e61debf656ad4206a7c Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 28 Nov 2025 17:54:12 -0500
Subject: [PATCH 6/8] Also test relocations
---
.../SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp | 3 +++
llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll | 8 ++++++++
2 files changed, 11 insertions(+)
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index 349f7d777e9d3..6e39bd84919f1 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -9,6 +9,7 @@
#include "SystemZHLASMAsmStreamer.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/BinaryFormat/GOFF.h"
+#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCGOFFAttributes.h"
#include "llvm/MC/MCGOFFStreamer.h"
#include "llvm/MC/MCSymbolGOFF.h"
@@ -80,6 +81,7 @@ void SystemZHLASMAsmStreamer::changeSection(MCSection *Section,
MAI->printSwitchToSection(*Section, Subsection,
getContext().getTargetTriple(), OS);
MCStreamer::changeSection(Section, Subsection);
+ EmitEOL();
}
void SystemZHLASMAsmStreamer::emitAlignmentDS(uint64_t ByteAlignment,
@@ -332,6 +334,7 @@ void SystemZHLASMAsmStreamer::emitHLASMValueImpl(const MCExpr *Value,
MAI->printExpr(OS, *Value);
return;
default:
+ Parens &= isa<MCSymbolRefExpr>(Value);
if (Parens)
OS << "A(";
MAI->printExpr(OS, *Value);
diff --git a/llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll b/llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll
index a29646b8bcc61..cbfac001c9e2e 100644
--- a/llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll
@@ -42,6 +42,14 @@ define void @foo() {
; CHECK: DS 0B
; CHECK-LABEL: L#.str.1 DS 0H
; CHECK: DC XL6'576F726C6400'
+; CHECK: C_WSA64 CATTR ALIGN(4),FILL(0),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(stdi
+; CHECK: in#S)
+; CHECK: stdin#S XATTR LINKAGE(XPLINK),REFERENCE(DATA),SCOPE(SECTION)
+; CHECK: * Offset 0 pointer to data symbol Greeting
+; CHECK: DC A(Greeting)
+; CHECK: * Offset 8 function descriptor of outs
+; CHECK: DC R(outs)
+; CHECK: DC V(outs)
; CHECK: END
entry:
%0 = load ptr, ptr @Greeting, align 8
>From b634514b5d1028ee829ab027a62978c79421aecb Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 28 Nov 2025 17:57:56 -0500
Subject: [PATCH 7/8] Fix formatting.
---
llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.h
index 36bbf2f19a674..668158b896856 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.h
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.h
@@ -49,9 +49,9 @@ enum {
// HLASM docs for address constants:
// https://www.ibm.com/docs/en/hla-and-tf/1.6?topic=value-address-constants
- S_RCon, // Address of ADA of symbol.
- S_VCon, // Address of external function symbol.
- S_QCon, // Class-based offset.
+ S_RCon, // Address of ADA of symbol.
+ S_VCon, // Address of external function symbol.
+ S_QCon, // Class-based offset.
};
} // namespace SystemZ
>From b1dfd8ccb0d249fc8f9a9da351bb7b19626b7a7a Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 28 Nov 2025 18:57:01 -0500
Subject: [PATCH 8/8] Use correct type extension for relocations
D means 8 byte.
---
.../MCTargetDesc/SystemZHLASMAsmStreamer.cpp | 4 ++--
.../SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp | 8 +++----
llvm/test/CodeGen/SystemZ/llvm.sincos.ll | 24 +++++++++----------
.../CodeGen/SystemZ/zos-ada-relocations.ll | 14 +++++------
llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll | 18 +++++++-------
llvm/test/CodeGen/SystemZ/zos-intrinsics.ll | 21 ++++++++--------
6 files changed, 45 insertions(+), 44 deletions(-)
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index 6e39bd84919f1..f19f9841c522a 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -298,7 +298,7 @@ void SystemZHLASMAsmStreamer::emitHLASMValueImpl(const MCExpr *Value,
}
if (Parens)
- OS << "A(";
+ OS << "AD(";
emitHLASMValueImpl(BE.getLHS(), Size);
switch (BE.getOpcode()) {
@@ -336,7 +336,7 @@ void SystemZHLASMAsmStreamer::emitHLASMValueImpl(const MCExpr *Value,
default:
Parens &= isa<MCSymbolRefExpr>(Value);
if (Parens)
- OS << "A(";
+ OS << "AD(";
MAI->printExpr(OS, *Value);
if (Parens)
OS << ')';
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp
index 887531f3e2299..2b5a24bd30c32 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp
@@ -63,16 +63,16 @@ void SystemZMCAsmInfoGOFF::printSpecifierExpr(
raw_ostream &OS, const MCSpecifierExpr &Expr) const {
switch (Expr.getSpecifier()) {
case SystemZ::S_None:
- OS << "A";
+ OS << "AD";
break;
case SystemZ::S_QCon:
- OS << "Q";
+ OS << "QD";
break;
case SystemZ::S_RCon:
- OS << "R";
+ OS << "RD";
break;
case SystemZ::S_VCon:
- OS << "V";
+ OS << "VD";
break;
default:
llvm_unreachable("Invalid kind");
diff --git a/llvm/test/CodeGen/SystemZ/llvm.sincos.ll b/llvm/test/CodeGen/SystemZ/llvm.sincos.ll
index e3ed31fae70c0..e47759b188296 100644
--- a/llvm/test/CodeGen/SystemZ/llvm.sincos.ll
+++ b/llvm/test/CodeGen/SystemZ/llvm.sincos.ll
@@ -184,18 +184,18 @@ define { <2 x fp128>, <2 x fp128> } @test_sincos_v2f128(<2 x fp128> %a) #0 {
}
-; ZOS: .quad R(@@FSIN at B) * Offset 0 function descriptor of @@FSIN at B
-; ZOS: .quad V(@@FSIN at B)
-; ZOS: .quad R(@@FCOS at B) * Offset 16 function descriptor of @@FCOS at B
-; ZOS: .quad V(@@FCOS at B)
-; ZOS: .quad R(@@SSIN at B) * Offset 32 function descriptor of @@SSIN at B
-; ZOS: .quad V(@@SSIN at B)
-; ZOS: .quad R(@@SCOS at B) * Offset 48 function descriptor of @@SCOS at B
-; ZOS: .quad V(@@SCOS at B)
-; ZOS: .quad R(@@LSIN at B) * Offset 64 function descriptor of @@LSIN at B
-; ZOS: .quad V(@@LSIN at B)
-; ZOS: .quad R(@@LCOS at B) * Offset 80 function descriptor of @@LCOS at B
-; ZOS: .quad V(@@LCOS at B)
+; ZOS: .quad RD(@@FSIN at B) * Offset 0 function descriptor of @@FSIN at B
+; ZOS: .quad VD(@@FSIN at B)
+; ZOS: .quad RD(@@FCOS at B) * Offset 16 function descriptor of @@FCOS at B
+; ZOS: .quad VD(@@FCOS at B)
+; ZOS: .quad RD(@@SSIN at B) * Offset 32 function descriptor of @@SSIN at B
+; ZOS: .quad VD(@@SSIN at B)
+; ZOS: .quad RD(@@SCOS at B) * Offset 48 function descriptor of @@SCOS at B
+; ZOS: .quad VD(@@SCOS at B)
+; ZOS: .quad RD(@@LSIN at B) * Offset 64 function descriptor of @@LSIN at B
+; ZOS: .quad VD(@@LSIN at B)
+; ZOS: .quad RD(@@LCOS at B) * Offset 80 function descriptor of @@LCOS at B
+; ZOS: .quad VD(@@LCOS at B)
attributes #0 = { nounwind }
diff --git a/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll b/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll
index d6aa99b5634d7..616cb370f6fc8 100644
--- a/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll
@@ -60,10 +60,10 @@ declare signext i32 @callout(i32 signext)
; CHECK: stdin#S XATTR LINKAGE(XPLINK),REFERENCE(DATA),SCOPE(SECTION)
; CHECK: .set L#DoFunc at indirect0, DoFunc
; CHECK: .indirect_symbol L#DoFunc at indirect0
-; CHECK: .quad V(L#DoFunc at indirect0) * Offset 0 pointer to function descriptor DoFunc
-; CHECK: .quad R(Caller) * Offset 8 function descriptor of Caller
-; CHECK: .quad V(Caller)
-; CHECK: .quad A(i2) * Offset 24 pointer to data symbol i2
-; CHECK: .quad A(i) * Offset 32 pointer to data symbol i
-; CHECK: .quad R(callout) * Offset 40 function descriptor of callout
-; CHECK: .quad V(callout)
+; CHECK: .quad VD(L#DoFunc at indirect0) * Offset 0 pointer to function descriptor DoFunc
+; CHECK: .quad RD(Caller) * Offset 8 function descriptor of Caller
+; CHECK: .quad VD(Caller)
+; CHECK: .quad AD(i2) * Offset 24 pointer to data symbol i2
+; CHECK: .quad AD(i) * Offset 32 pointer to data symbol i
+; CHECK: .quad RD(callout) * Offset 40 function descriptor of callout
+; CHECK: .quad VD(callout)
diff --git a/llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll b/llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll
index cbfac001c9e2e..a82be947f8deb 100644
--- a/llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll
@@ -13,9 +13,9 @@ define void @foo() {
; CHECK: DC XL1'E7'
; CHECK: DC XL1'22'
; CHECK: DC XL1'04'
-; CHECK: DC A(CELQSTRT-L#PPA2)
+; CHECK: DC AD(CELQSTRT-L#PPA2)
; CHECK: DC XL4'00000000'
-; CHECK: DC A(L#DVS-L#PPA2)
+; CHECK: DC AD(L#DVS-L#PPA2)
; CHECK: DC XL4'00000000'
; CHECK: DC XL1'81'
; CHECK: DC XL1'00'
@@ -24,21 +24,21 @@ define void @foo() {
; CHECK: DC XL1'02'
; CHECK: DC XL1'CE'
; CHECK: DC XL2'0300'
-; CHECK: DC A(L#PPA2-L#PPA1_foo_0)
+; CHECK: DC AD(L#PPA2-L#PPA1_foo_0)
; CHECK: DC XL1'80'
; CHECK: DC XL1'80'
; CHECK: DC XL1'00'
; CHECK: DC XL1'81'
; CHECK: DC XL2'0000'
-; CHECK: DC A(L#func_end0-L#EPM_foo_0)
+; CHECK: DC AD(L#func_end0-L#EPM_foo_0)
; CHECK: DC XL2'0003'
; CHECK: DC XL3'869696'
-; CHECK: DC A(L#EPM_foo_0-L#PPA1_foo_0)
+; CHECK: DC AD(L#EPM_foo_0-L#PPA1_foo_0)
; CHECK-LABEL: L#.str DS 0H
; CHECK: DC XL10'48656C6C6F2025730A00'
; CHECK: DS 0B
; CHECK-LABEL: Greeting DS 0H
-; CHECK: DC A(L#.str)
+; CHECK: DC AD(L#.str)
; CHECK: DS 0B
; CHECK-LABEL: L#.str.1 DS 0H
; CHECK: DC XL6'576F726C6400'
@@ -46,10 +46,10 @@ define void @foo() {
; CHECK: in#S)
; CHECK: stdin#S XATTR LINKAGE(XPLINK),REFERENCE(DATA),SCOPE(SECTION)
; CHECK: * Offset 0 pointer to data symbol Greeting
-; CHECK: DC A(Greeting)
+; CHECK: DC AD(Greeting)
; CHECK: * Offset 8 function descriptor of outs
-; CHECK: DC R(outs)
-; CHECK: DC V(outs)
+; CHECK: DC RD(outs)
+; CHECK: DC VD(outs)
; CHECK: END
entry:
%0 = load ptr, ptr @Greeting, align 8
diff --git a/llvm/test/CodeGen/SystemZ/zos-intrinsics.ll b/llvm/test/CodeGen/SystemZ/zos-intrinsics.ll
index c963d85d60f1c..ccae97888d70c 100644
--- a/llvm/test/CodeGen/SystemZ/zos-intrinsics.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-intrinsics.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple s390x-zos < %s | FileCheck %s
+; RUN: llc -mtriple s390x-zos -emit-gnuas-syntax-on-zos=0 < %s | FileCheck %s
define float @sqrt_ieee(float %x) {
entry:
@@ -31,17 +31,18 @@ declare fp128 @llvm.exp2.f128(fp128)
; Check the calls in the ADA.
; CHECK: stdin#C CSECT
-; CHECK: C_WSA64 CATTR ALIGN(4),FILL(0),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(stdin#S)
+; CHECK: C_WSA64 CATTR ALIGN(4),FILL(0),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(stdi
+; CHECK-NEXT: in#S)
; CHECK: stdin#S XATTR LINKAGE(XPLINK),REFERENCE(DATA),SCOPE(SECTION)
; Check that there is no call to sqrt.
-; CHECK-NOT: .quad R(@@WSQT at B)
-; CHECK-NOT: .quad V(@@WSQT at B)
+; CHECK-NOT: DC RD(@@WSQT at B)
+; CHECK-NOT: DC VD(@@WSQT at B)
; Check that there is the correct library call.
-; CHECK: .quad R(@@FCOS at B)
-; CHECK-NEXT: .quad V(@@FCOS at B)
-; CHECK: .quad R(@@SSIN at B)
-; CHECK-NEXT: .quad V(@@SSIN at B)
-; CHECK: .quad R(@@LXP2 at B)
-; CHECK-NEXT: .quad V(@@LXP2 at B)
+; CHECK: DC RD(@@FCOS at B)
+; CHECK-NEXT: DC VD(@@FCOS at B)
+; CHECK: DC RD(@@SSIN at B)
+; CHECK-NEXT: DC VD(@@SSIN at B)
+; CHECK: DC RD(@@LXP2 at B)
+; CHECK-NEXT: DC VD(@@LXP2 at B)
More information about the llvm-branch-commits
mailing list