https://github.com/amy-kwan updated https://github.com/llvm/llvm-project/pull/171476
>From 83bae79ec707e8ce457a3643a40056cf62e7a3fa Mon Sep 17 00:00:00 2001 From: Amy Kwan <[email protected]> Date: Fri, 21 Nov 2025 13:54:48 -0500 Subject: [PATCH 1/3] [SystemZ] Implement ctor/dtor emission via @@SQINIT and .xtor sections This patch implements support for constructors/destructors by introducing the @@SQINIT section and emitting .xtor.<priority> sections within the SystemZ AsmPrinter and in the GOFF object lowering layer. Improvements to ADA descriptor handling is also done within this change. --- .../CodeGen/TargetLoweringObjectFileImpl.h | 4 ++ llvm/include/llvm/MC/MCGOFFAttributes.h | 1 + llvm/include/llvm/MC/MCSectionGOFF.h | 11 ++++ .../CodeGen/TargetLoweringObjectFileImpl.cpp | 49 +++++++++++++++ llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 60 +++++++++++++++++++ llvm/lib/Target/SystemZ/SystemZAsmPrinter.h | 5 +- llvm/test/CodeGen/SystemZ/zos_sinit.ll | 36 +++++++++++ 7 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/SystemZ/zos_sinit.ll diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index fe450b3c1a3a2..8f1f20f7ead0c 100644 --- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -331,6 +331,10 @@ class TargetLoweringObjectFileGOFF : public TargetLoweringObjectFile { const TargetMachine &TM) const override; MCSection *getSectionForLSDA(const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const override; + MCSection *getStaticCtorSection(unsigned Priority, + const MCSymbol *KeySym) const override; + MCSection *getStaticDtorSection(unsigned Priority, + const MCSymbol *KeySym) const override; }; } // end namespace llvm diff --git a/llvm/include/llvm/MC/MCGOFFAttributes.h b/llvm/include/llvm/MC/MCGOFFAttributes.h index e771f36f35346..b1c6d73e41f9f 100644 --- a/llvm/include/llvm/MC/MCGOFFAttributes.h +++ b/llvm/include/llvm/MC/MCGOFFAttributes.h @@ -94,6 +94,7 @@ constexpr StringLiteral CLASS_CODE = "C_CODE64"; constexpr StringLiteral CLASS_WSA = "C_WSA64"; constexpr StringLiteral CLASS_DATA = "C_DATA64"; constexpr StringLiteral CLASS_PPA2 = "C_@@QPPA2"; +constexpr StringLiteral CLASS_SINIT = "C_@@SQINIT"; } // namespace GOFF } // namespace llvm diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h index 2136148368fbd..192996551c28b 100644 --- a/llvm/include/llvm/MC/MCSectionGOFF.h +++ b/llvm/include/llvm/MC/MCSectionGOFF.h @@ -27,6 +27,13 @@ namespace llvm { class MCExpr; class LLVM_ABI MCSectionGOFF final : public MCSection { +public: + enum XtorType { NotXtor, CtorType, DtorType }; + +private: + // ctor/dtor section related - i.e. C_@@S[Q]INIT + enum XtorType XtorSectionType = NotXtor; + // Parent of this section. Implies that the parent is emitted first. MCSectionGOFF *Parent; @@ -115,6 +122,10 @@ class LLVM_ABI MCSectionGOFF final : public MCSection { bool requiresNonZeroLength() const { return RequiresNonZeroLength; } void setName(StringRef SectionName) { Name = SectionName; } + + bool isXtorSection() const { return XtorSectionType != NotXtor; } + void setXtorSectionType(XtorType Value) { XtorSectionType = Value; } + XtorType getXtorSectionType() const { return XtorSectionType; } }; } // end namespace llvm diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 5edbc4caf3fae..4ede966702335 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -2794,6 +2794,10 @@ void TargetLoweringObjectFileGOFF::getModuleMetadata(Module &M) { TextLD->setWeak(false); TextLD->setADA(ADAPR); TextSection->setBeginSymbol(TextLD); + // Initialize the label for the ADA section. + MCSymbolGOFF *ADASym = static_cast<MCSymbolGOFF *>( + getContext().getOrCreateSymbol(ADAPR->getName())); + ADAPR->setBeginSymbol(ADASym); } MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal( @@ -2857,3 +2861,48 @@ MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal( } return TextSection; } + +static MCSectionGOFF *getStaticStructorSectionGOFF(MCContext &Ctx, + const MCSection *TextSection, + bool IsCtor, + unsigned Priority) { + // xl compilers on z/OS support priorities from min-int to max-int, with + // sinit as source priority 0. For clang, sinit has source priority 65535. + // For GOFF, the priority sortkey field is an unsigned value. So, we + // add min-int to get sorting to work properly but also subtract the + // clang sinit (65535) value so internally xl sinit and clang sinit have + // the same unsigned GOFF priority sortkey field value (i.e. 0x80000000). + static constexpr const uint32_t ClangDefaultSinitPriority = 65535; + uint32_t Prio = Priority + (0x80000000 - ClangDefaultSinitPriority); + + std::string Name(".xtor"); + if (Priority != ClangDefaultSinitPriority) + Name = llvm::Twine(Name).concat(".").concat(llvm::utostr(Priority)).str(); + + MCSectionGOFF *SInit = Ctx.getGOFFSection( + SectionKind::getMetadata(), GOFF::CLASS_SINIT, + GOFF::EDAttr{false, GOFF::ESD_RMODE_64, GOFF::ESD_NS_Parts, + GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge, + GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0, + GOFF::ESD_ALIGN_Doubleword}, + static_cast<const MCSectionGOFF *>(TextSection)->getParent()); + + MCSectionGOFF *Xtor = Ctx.getGOFFSection( + SectionKind::getData(), Name, + GOFF::PRAttr{true, GOFF::ESD_EXE_DATA, GOFF::ESD_LT_XPLink, + GOFF::ESD_BSC_Section, Prio}, + SInit); + return Xtor; +} + +MCSection *TargetLoweringObjectFileGOFF::getStaticCtorSection( + unsigned Priority, const MCSymbol *KeySym) const { + return getStaticStructorSectionGOFF(getContext(), TextSection, true, + Priority); +} + +MCSection *TargetLoweringObjectFileGOFF::getStaticDtorSection( + unsigned Priority, const MCSymbol *KeySym) const { + return getStaticStructorSectionGOFF(getContext(), TextSection, false, + Priority); +} diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp index b36605ec54374..e9a1cf38e7317 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -31,6 +31,7 @@ #include "llvm/MC/MCInstBuilder.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSymbolGOFF.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Support/Chrono.h" #include "llvm/Support/Compiler.h" @@ -190,6 +191,10 @@ SystemZAsmPrinter::AssociatedDataAreaTable::insert(const MCSymbol *Sym, break; } + // Language Environment DLL logic requires function descriptors, for + // imported functions, that are placed in the ADA to be 8 byte aligned. + if (SlotKind == SystemZII::MO_ADA_DIRECT_FUNC_DESC) + NextDisplacement = alignTo(NextDisplacement, 8); uint32_t Displacement = NextDisplacement; Displacements[std::make_pair(Sym, SlotKind)] = NextDisplacement; NextDisplacement += Length; @@ -1016,6 +1021,59 @@ void SystemZAsmPrinter::emitMachineConstantPoolValue( OutStreamer->emitValue(Expr, Size); } +// Emit the ctor or dtor list taking into account the init priority. +void SystemZAsmPrinter::emitXXStructorList(const DataLayout &DL, + const Constant *List, bool IsCtor) { + if (TM.getTargetTriple().isOSBinFormatGOFF()) + AsmPrinter::emitXXStructorList(DL, List, IsCtor); + + SmallVector<Structor, 8> Structors; + preprocessXXStructorList(DL, List, Structors); + if (Structors.empty()) + return; + + const Align Align = llvm::Align(4); + const TargetLoweringObjectFile &Obj = getObjFileLowering(); + for (Structor &S : Structors) { + MCSection *OutputSection = + (IsCtor ? Obj.getStaticCtorSection(S.Priority, nullptr) + : Obj.getStaticDtorSection(S.Priority, nullptr)); + OutStreamer->switchSection(OutputSection); + if (OutStreamer->getCurrentSection() != OutStreamer->getPreviousSection()) + emitAlignment(Align); + + const MCSectionGOFF *Section = + static_cast<const MCSectionGOFF *>(getCurrentSection()); + uint32_t XtorPriority = Section->getPRAttributes().SortKey; + + const GlobalValue *GV = dyn_cast<GlobalValue>(S.Func->stripPointerCasts()); + assert(GV && "C++ xxtor pointer was not a GlobalValue!"); + MCSymbolGOFF *Symbol = static_cast<MCSymbolGOFF *>(getSymbol(GV)); + + // @@SQINIT entry: { unsigned prio; void (*ctor)(); void (*dtor)(); } + + unsigned PointerSizeInBytes = DL.getPointerSize(); + + auto &Ctx = OutStreamer->getContext(); + const MCExpr *ADAFuncRefExpr; + unsigned SlotKind = SystemZII::MO_ADA_DIRECT_FUNC_DESC; + ADAFuncRefExpr = MCBinaryExpr::createAdd( + MCSpecifierExpr::create(MCSymbolRefExpr::create(ADASym, OutContext), + SystemZ::S_QCon, OutContext), + MCConstantExpr::create(ADATable.insert(Symbol, SlotKind).second, Ctx), + Ctx); + + emitInt32(XtorPriority); + if (IsCtor) { + OutStreamer->emitValue(ADAFuncRefExpr, PointerSizeInBytes); + OutStreamer->emitIntValue(0, PointerSizeInBytes); + } else { + OutStreamer->emitIntValue(0, PointerSizeInBytes); + OutStreamer->emitValue(ADAFuncRefExpr, PointerSizeInBytes); + } + } +} + static void printFormattedRegName(const MCAsmInfo *MAI, unsigned RegNo, raw_ostream &OS) { const char *RegName; @@ -1595,6 +1653,8 @@ void SystemZAsmPrinter::emitStartOfAsmFile(Module &M) { } void SystemZAsmPrinter::emitPPA2(Module &M) { + ADASym = getObjFileLowering().getADASection()->getBeginSymbol(); + OutStreamer->pushSection(); OutStreamer->switchSection(getObjFileLowering().getTextSection(), GOFF::SK_PPA2); diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h index 0611179ee7262..19b517f82d658 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h @@ -31,6 +31,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter { MCSymbol *CurrentFnPPA1Sym; // PPA1 Symbol. MCSymbol *CurrentFnEPMarkerSym; // Entry Point Marker. MCSymbol *PPA2Sym; + MCSymbol *ADASym; SystemZTargetStreamer *getTargetStreamer() { MCTargetStreamer *TS = OutStreamer->getTargetStreamer(); @@ -102,13 +103,15 @@ class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter { public: SystemZAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer) : AsmPrinter(TM, std::move(Streamer), ID), CurrentFnPPA1Sym(nullptr), - CurrentFnEPMarkerSym(nullptr), PPA2Sym(nullptr), + CurrentFnEPMarkerSym(nullptr), PPA2Sym(nullptr), ADASym(nullptr), ADATable(TM.getPointerSize(0)) {} // Override AsmPrinter. StringRef getPassName() const override { return "SystemZ Assembly Printer"; } void emitInstruction(const MachineInstr *MI) override; void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override; + void emitXXStructorList(const DataLayout &DL, const Constant *List, + bool IsCtor) override; void emitEndOfAsmFile(Module &M) override; bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override; diff --git a/llvm/test/CodeGen/SystemZ/zos_sinit.ll b/llvm/test/CodeGen/SystemZ/zos_sinit.ll new file mode 100644 index 0000000000000..036ec71466079 --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/zos_sinit.ll @@ -0,0 +1,36 @@ +; RUN: llc -emit-gnuas-syntax-on-zos=false < %s -mtriple=s390x-ibm-zos | \ +; RUN: FileCheck --check-prefixes=CHECK %s + [email protected]_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 22, ptr @cfuncctor, ptr null }] [email protected]_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 22, ptr @cfuncdtor, ptr null }] + +; Check for presence of C_@@SQINIT: +; CHECK: .xtor.22 +; CHECK: DC AD(cfuncctor) +; CHECK: DC XL4'7FFF0017' +; Check direct relocation and low bit on ctor. +; CHECK: DC AD(QD(stdin#S)+XL8'0') +; CHECK: DC XL8'0000000000000000' +; CHECK: DC AD(cfuncdtor) +; CHECK: DC XL4'7FFF0017' +; CHECK: DC XL8'0000000000000000' +; Check direct relocation and low bit on dtor. +; CHECK: DC AD(QD(stdin#S)+XL8'16') + +; Check for function descriptors in ADA section: +; CHECK: * Offset 0 function descriptor of cfuncctor +; CHECK: DC RD(cfuncctor) +; CHECK: DC VD(cfuncctor) +; CHECK: * Offset 16 function descriptor of cfuncdtor +; CHECK: DC RD(cfuncdtor) +; CHECK: DC VD(cfuncdtor) + +define hidden void @cfuncctor() { +entry: + ret void +} + +define hidden void @cfuncdtor() { +entry: + ret void +} >From 912a2c46a45a6282bedc9ae1dd8d197830b20c08 Mon Sep 17 00:00:00 2001 From: Amy Kwan <[email protected]> Date: Fri, 19 Dec 2025 15:25:29 -0500 Subject: [PATCH 2/3] Update test, movove ADA symbol, fix call to target independent emitXXStructorList --- llvm/include/llvm/MC/MCSectionGOFF.h | 11 ----------- llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 12 +++++++----- llvm/test/CodeGen/SystemZ/zos_sinit.ll | 2 -- 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h index 192996551c28b..2136148368fbd 100644 --- a/llvm/include/llvm/MC/MCSectionGOFF.h +++ b/llvm/include/llvm/MC/MCSectionGOFF.h @@ -27,13 +27,6 @@ namespace llvm { class MCExpr; class LLVM_ABI MCSectionGOFF final : public MCSection { -public: - enum XtorType { NotXtor, CtorType, DtorType }; - -private: - // ctor/dtor section related - i.e. C_@@S[Q]INIT - enum XtorType XtorSectionType = NotXtor; - // Parent of this section. Implies that the parent is emitted first. MCSectionGOFF *Parent; @@ -122,10 +115,6 @@ class LLVM_ABI MCSectionGOFF final : public MCSection { bool requiresNonZeroLength() const { return RequiresNonZeroLength; } void setName(StringRef SectionName) { Name = SectionName; } - - bool isXtorSection() const { return XtorSectionType != NotXtor; } - void setXtorSectionType(XtorType Value) { XtorSectionType = Value; } - XtorType getXtorSectionType() const { return XtorSectionType; } }; } // end namespace llvm diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp index e9a1cf38e7317..906247745474f 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -1024,8 +1024,8 @@ void SystemZAsmPrinter::emitMachineConstantPoolValue( // Emit the ctor or dtor list taking into account the init priority. void SystemZAsmPrinter::emitXXStructorList(const DataLayout &DL, const Constant *List, bool IsCtor) { - if (TM.getTargetTriple().isOSBinFormatGOFF()) - AsmPrinter::emitXXStructorList(DL, List, IsCtor); + if (!TM.getTargetTriple().isOSBinFormatGOFF()) + return AsmPrinter::emitXXStructorList(DL, List, IsCtor); SmallVector<Structor, 8> Structors; preprocessXXStructorList(DL, List, Structors); @@ -1647,14 +1647,16 @@ void SystemZAsmPrinter::emitPPA1(MCSymbol *FnEndSym) { } void SystemZAsmPrinter::emitStartOfAsmFile(Module &M) { - if (TM.getTargetTriple().isOSzOS()) + if (TM.getTargetTriple().isOSzOS()) { + ADASym = getObjFileLowering().getADASection()->getBeginSymbol(); + emitPPA2(M); + } + AsmPrinter::emitStartOfAsmFile(M); } void SystemZAsmPrinter::emitPPA2(Module &M) { - ADASym = getObjFileLowering().getADASection()->getBeginSymbol(); - OutStreamer->pushSection(); OutStreamer->switchSection(getObjFileLowering().getTextSection(), GOFF::SK_PPA2); diff --git a/llvm/test/CodeGen/SystemZ/zos_sinit.ll b/llvm/test/CodeGen/SystemZ/zos_sinit.ll index 036ec71466079..447dec345e175 100644 --- a/llvm/test/CodeGen/SystemZ/zos_sinit.ll +++ b/llvm/test/CodeGen/SystemZ/zos_sinit.ll @@ -6,12 +6,10 @@ ; Check for presence of C_@@SQINIT: ; CHECK: .xtor.22 -; CHECK: DC AD(cfuncctor) ; CHECK: DC XL4'7FFF0017' ; Check direct relocation and low bit on ctor. ; CHECK: DC AD(QD(stdin#S)+XL8'0') ; CHECK: DC XL8'0000000000000000' -; CHECK: DC AD(cfuncdtor) ; CHECK: DC XL4'7FFF0017' ; CHECK: DC XL8'0000000000000000' ; Check direct relocation and low bit on dtor. >From dd37d41b4a652a7d0cb963dc4cbd740bda34b555 Mon Sep 17 00:00:00 2001 From: Amy Kwan <[email protected]> Date: Tue, 6 Jan 2026 13:11:19 -0500 Subject: [PATCH 3/3] Address review comments regarding sections, unused parameter/unnecessary code changes. --- llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 7 ++----- llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 14 ++++---------- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 4ede966702335..b6c52f8c056db 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -2864,7 +2864,6 @@ MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal( static MCSectionGOFF *getStaticStructorSectionGOFF(MCContext &Ctx, const MCSection *TextSection, - bool IsCtor, unsigned Priority) { // xl compilers on z/OS support priorities from min-int to max-int, with // sinit as source priority 0. For clang, sinit has source priority 65535. @@ -2897,12 +2896,10 @@ static MCSectionGOFF *getStaticStructorSectionGOFF(MCContext &Ctx, MCSection *TargetLoweringObjectFileGOFF::getStaticCtorSection( unsigned Priority, const MCSymbol *KeySym) const { - return getStaticStructorSectionGOFF(getContext(), TextSection, true, - Priority); + return getStaticStructorSectionGOFF(getContext(), TextSection, Priority); } MCSection *TargetLoweringObjectFileGOFF::getStaticDtorSection( unsigned Priority, const MCSymbol *KeySym) const { - return getStaticStructorSectionGOFF(getContext(), TextSection, false, - Priority); + return getStaticStructorSectionGOFF(getContext(), TextSection, Priority); } diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp index 906247745474f..52013f8ef9cd9 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -191,10 +191,6 @@ SystemZAsmPrinter::AssociatedDataAreaTable::insert(const MCSymbol *Sym, break; } - // Language Environment DLL logic requires function descriptors, for - // imported functions, that are placed in the ADA to be 8 byte aligned. - if (SlotKind == SystemZII::MO_ADA_DIRECT_FUNC_DESC) - NextDisplacement = alignTo(NextDisplacement, 8); uint32_t Displacement = NextDisplacement; Displacements[std::make_pair(Sym, SlotKind)] = NextDisplacement; NextDisplacement += Length; @@ -1035,15 +1031,13 @@ void SystemZAsmPrinter::emitXXStructorList(const DataLayout &DL, const Align Align = llvm::Align(4); const TargetLoweringObjectFile &Obj = getObjFileLowering(); for (Structor &S : Structors) { - MCSection *OutputSection = - (IsCtor ? Obj.getStaticCtorSection(S.Priority, nullptr) - : Obj.getStaticDtorSection(S.Priority, nullptr)); - OutStreamer->switchSection(OutputSection); + MCSectionGOFF *Section = static_cast<MCSectionGOFF *>( + IsCtor ? Obj.getStaticCtorSection(S.Priority, nullptr) + : Obj.getStaticDtorSection(S.Priority, nullptr)); + OutStreamer->switchSection(Section); if (OutStreamer->getCurrentSection() != OutStreamer->getPreviousSection()) emitAlignment(Align); - const MCSectionGOFF *Section = - static_cast<const MCSectionGOFF *>(getCurrentSection()); uint32_t XtorPriority = Section->getPRAttributes().SortKey; const GlobalValue *GV = dyn_cast<GlobalValue>(S.Func->stripPointerCasts()); _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
