From fd3a314ede3fadbc79860f5aef6be5e9f1b1144a Mon Sep 17 00:00:00 2001 From: Sean Fertile Date: Wed, 17 Sep 2025 15:18:19 -0400 Subject: [PATCH 1/6] Add a metadata node for XCOFF renames. Adds a metadata node that represents a special case of the XCOFF rename directive. The node must be placed on a variable that has an explict section attribute, and the global with the node will be emitted to a csect with a unique name, which is later renamed to the section attributes name. This is used in pgo when function sections is enabled, becuase otherwise the pgo instrumentation breaks garbage collection which many builds on AIX rely on. Other features which emit data which is meant to be globed together into a contiguous output sections, but may also contain references to other data that pollutes the symbol reference graph inhibiting garbage collection will also find this feature useful. --- llvm/docs/LangRef.rst | 23 ++++ llvm/include/llvm/IR/FixedMetadataKinds.def | 1 + .../CodeGen/TargetLoweringObjectFileImpl.cpp | 14 ++- llvm/lib/IR/Verifier.cpp | 9 ++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp | 106 +++++++++++------- llvm/test/CodeGen/PowerPC/aix-rename.ll | 38 +++++++ llvm/test/Verifier/PowerPC/lit.local.cfg | 2 + llvm/test/Verifier/PowerPC/multiple_rename.ll | 8 ++ llvm/test/Verifier/PowerPC/rename_operands.ll | 6 + 9 files changed, 162 insertions(+), 45 deletions(-) create mode 100644 llvm/test/CodeGen/PowerPC/aix-rename.ll create mode 100644 llvm/test/Verifier/PowerPC/lit.local.cfg create mode 100644 llvm/test/Verifier/PowerPC/multiple_rename.ll create mode 100644 llvm/test/Verifier/PowerPC/rename_operands.ll diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index d61ea07830123..03ba7a1e6b956 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -8441,6 +8441,29 @@ The ``nofree`` metadata indicates the memory pointed by the pointer will not be freed after the attached instruction. +'``rename.key``' Metadata +^^^^^^^^^^^^^^^^^^^^^^^^^ +The rename key may be attached to a global variable definition that has an +explicit section attribute. It is used as a flag so the associated node +must be empty. It only takes effect when function sections is enabled, and +only on XCOFF targets. The metadata will casue the global to be emitted to a +control section (CSECT) with a name that is an amalgamation of both the section +attribute and the global variables identifier. After the control section is +defined it will be renamed to match the name of the section attribute. This +allows the linker to aggressively garbage collect the symbol if unreferenced, +while directing the linker to merge any control sections with the same name +that remain after garbage collecting into the same CSECT in the output binary. +Commonly used where there is a feature that uses a runtime to walk over a +section using the linker-defined encapsulation symbols +``__start_`` and ``__stop_``. + +Example: + +.. code-block:: llvm + + @a = global i32 1, section "abc", !rename.key !0 + !0 = !{} + Module Flags Metadata ===================== diff --git a/llvm/include/llvm/IR/FixedMetadataKinds.def b/llvm/include/llvm/IR/FixedMetadataKinds.def index d09cc15d65ff6..f4b7ebfcf14d5 100644 --- a/llvm/include/llvm/IR/FixedMetadataKinds.def +++ b/llvm/include/llvm/IR/FixedMetadataKinds.def @@ -55,3 +55,4 @@ LLVM_FIXED_MD_KIND(MD_mmra, "mmra", 40) LLVM_FIXED_MD_KIND(MD_noalias_addrspace, "noalias.addrspace", 41) LLVM_FIXED_MD_KIND(MD_callee_type, "callee_type", 42) LLVM_FIXED_MD_KIND(MD_nofree, "nofree", 43) +LLVM_FIXED_MD_KIND(MD_rename_key, "rename.key", 44) diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index ae681b9aebdfb..759b6a8e349cc 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -2431,16 +2431,24 @@ MCSection *TargetLoweringObjectFileXCOFF::getExplicitSectionGlobal( if (!GO->hasSection()) report_fatal_error("#pragma clang section is not yet supported"); - StringRef SectionName = GO->getSection(); + std::string SectionName(GO->getSection()); - // Handle the XCOFF::TD case first, then deal with the rest. - if (const GlobalVariable *GVar = dyn_cast(GO)) + // Have to check for either attributes or metadata that can affect the + // section type or section name. + if (const GlobalVariable *GVar = dyn_cast(GO)) { if (GVar->hasAttribute("toc-data")) return getContext().getXCOFFSection( SectionName, Kind, XCOFF::CsectProperties(/*MappingClass*/ XCOFF::XMC_TD, XCOFF::XTY_SD), /* MultiSymbolsAllowed*/ true); + if (TM.getFunctionSections() && + GVar->hasMetadata(LLVMContext::MD_rename_key)) { + SectionName += "."; + SectionName += GO->getName(); + } + } + XCOFF::StorageMappingClass MappingClass; if (Kind.isText()) MappingClass = XCOFF::XMC_PR; diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index c06b60fd2d9a9..1d11e3f4e3aae 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -766,6 +766,15 @@ void Verifier::visitGlobalValue(const GlobalValue &GV) { DL.getIntPtrType(GO->getType()), RangeLikeMetadataKind::AbsoluteSymbol); } + + if (GO->hasMetadata(LLVMContext::MD_rename_key)) { + SmallVector MDs; + GO->getMetadata(LLVMContext::MD_rename_key, MDs); + Check(MDs.size() == 1, + "global value cannot have more then 1 rename metadata", GO); + Check(MDs[0]->getNumOperands() == 0, + "rename metadata must have no operands", GO); + } } Check(!GV.hasAppendingLinkage() || isa(GV), diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp index 023fd147535ec..962cf518614c8 100644 --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -2970,58 +2970,80 @@ void PPCAIXAsmPrinter::emitGCOVRefs() { } void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) { - // If there are no functions and there are no toc-data definitions in this - // module, we will never need to reference the TOC base. - if (M.empty() && TOCDataGlobalVars.empty()) - return; emitPGORefs(M); emitGCOVRefs(); - // Switch to section to emit TOC base. - OutStreamer->switchSection(getObjFileLowering().getTOCBaseSection()); + // If there are no functions and there are no toc-data definitions in this + // module, we will never need to reference the TOC base. + if (!M.empty() || !TOCDataGlobalVars.empty()) { + // Switch to section to emit TOC base. + OutStreamer->switchSection(getObjFileLowering().getTOCBaseSection()); - PPCTargetStreamer *TS = - static_cast(OutStreamer->getTargetStreamer()); + PPCTargetStreamer *TS = + static_cast(OutStreamer->getTargetStreamer()); + + for (auto &I : TOC) { + MCSectionXCOFF *TCEntry; + // Setup the csect for the current TC entry. If the variant kind is + // VK_AIX_TLSGDM the entry represents the region handle, we create a + // new symbol to prefix the name with a dot. + // If TLS model opt is turned on, create a new symbol to prefix the name + // with a dot. + if (I.first.second == PPC::S_AIX_TLSGDM || + (Subtarget->hasAIXShLibTLSModelOpt() && + I.first.second == PPC::S_AIX_TLSLD)) { + SmallString<128> Name; + StringRef Prefix = "."; + Name += Prefix; + Name += static_cast(I.first.first) + ->getSymbolTableName(); + MCSymbol *S = OutContext.getOrCreateSymbol(Name); + TCEntry = static_cast( + getObjFileLowering().getSectionForTOCEntry(S, TM)); + } else { + TCEntry = static_cast( + getObjFileLowering().getSectionForTOCEntry(I.first.first, TM)); + } + OutStreamer->switchSection(TCEntry); - for (auto &I : TOC) { - MCSectionXCOFF *TCEntry; - // Setup the csect for the current TC entry. If the variant kind is - // VK_AIX_TLSGDM the entry represents the region handle, we create a - // new symbol to prefix the name with a dot. - // If TLS model opt is turned on, create a new symbol to prefix the name - // with a dot. - if (I.first.second == PPC::S_AIX_TLSGDM || - (Subtarget->hasAIXShLibTLSModelOpt() && - I.first.second == PPC::S_AIX_TLSLD)) { - SmallString<128> Name; - StringRef Prefix = "."; - Name += Prefix; - Name += static_cast(I.first.first) - ->getSymbolTableName(); - MCSymbol *S = OutContext.getOrCreateSymbol(Name); - TCEntry = static_cast( - getObjFileLowering().getSectionForTOCEntry(S, TM)); - } else { - TCEntry = static_cast( - getObjFileLowering().getSectionForTOCEntry(I.first.first, TM)); + OutStreamer->emitLabel(I.second); + TS->emitTCEntry(*I.first.first, I.first.second); } - OutStreamer->switchSection(TCEntry); - OutStreamer->emitLabel(I.second); - TS->emitTCEntry(*I.first.first, I.first.second); + // Traverse the list of global variables twice, emitting all of the + // non-common global variables before the common ones, as emitting a + // .comm directive changes the scope from .toc to the common symbol. + for (const auto *GV : TOCDataGlobalVars) { + if (!GV->hasCommonLinkage()) + emitGlobalVariableHelper(GV); + } + for (const auto *GV : TOCDataGlobalVars) { + if (GV->hasCommonLinkage()) + emitGlobalVariableHelper(GV); + } } - // Traverse the list of global variables twice, emitting all of the - // non-common global variables before the common ones, as emitting a - // .comm directive changes the scope from .toc to the common symbol. - for (const auto *GV : TOCDataGlobalVars) { - if (!GV->hasCommonLinkage()) - emitGlobalVariableHelper(GV); - } - for (const auto *GV : TOCDataGlobalVars) { - if (GV->hasCommonLinkage()) - emitGlobalVariableHelper(GV); + // Renames only take effect when function sections is enabled. + if (!TM.getFunctionSections()) + return; + + for (const GlobalVariable &GV : M.globals()) { + if (GV.hasMetadata(LLVMContext::MD_rename_key)) { + // Get orginal csect. + SectionKind GVKind = getObjFileLowering().getKindForGlobal(&GV, TM); + auto *CSect = static_cast( + getObjFileLowering().SectionForGlobal(&GV, GVKind, TM)); + + // Get the section to rename to. + if (!GV.hasSection()) + reportFatalInternalError( + "rename.key metadata used without a section attribute"); + + StringRef SectionName = GV.getSection(); + OutStreamer->emitXCOFFRenameDirective(CSect->getQualNameSymbol(), + SectionName); + } } } diff --git a/llvm/test/CodeGen/PowerPC/aix-rename.ll b/llvm/test/CodeGen/PowerPC/aix-rename.ll new file mode 100644 index 0000000000000..3fe379b8cd33b --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-rename.ll @@ -0,0 +1,38 @@ +; RUN: llc --function-sections -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck --check-prefix=NOFUNCSECT %s + +@a = global i32 1, section "abcd", !rename.key !0 +@b = global i32 2, section "abcd", !rename.key !0 +@c = global i32 3, section "abcd", !rename.key !0 +@d = global i32 4, section "abcd", !rename.key !0 + +!0 = !{} + +;CHECK: .csect abcd.a[RW] +;CHECK: .globl a + +;CHECK: .csect abcd.b[RW] +;CHECK: .globl b + +;CHECK: .csect abcd.c[RW] +;CHECK: .globl c + +;CHECK: .csect abcd.d[RW] +;CHECK: .globl d + +;CHECK: .rename abcd.a[RW],"abcd" +;CHECK: .rename abcd.b[RW],"abcd" +;CHECK: .rename abcd.c[RW],"abcd" +;CHECK: .rename abcd.d[RW],"abcd" + +;NOFUNCSECT: .csect abcd[RW],2 +;NOFUNCSECT-NOT: .csect +;NOFUNCSECT: .globl a +;NOFUNCSECT-NOT: .csect +;NOFUNCSECT: .globl b +;NOFUNCSECT-NOT: .csect +;NOFUNCSECT: .globl c +;NOFUNCSECT-NOT: .csect +;NOFUNCSECT: .globl d + +;NOFUNCSECT-NOT: .rename diff --git a/llvm/test/Verifier/PowerPC/lit.local.cfg b/llvm/test/Verifier/PowerPC/lit.local.cfg new file mode 100644 index 0000000000000..bb982488eb15e --- /dev/null +++ b/llvm/test/Verifier/PowerPC/lit.local.cfg @@ -0,0 +1,2 @@ +if not "PowerPC" in config.root.targets: + config.unsupported = True diff --git a/llvm/test/Verifier/PowerPC/multiple_rename.ll b/llvm/test/Verifier/PowerPC/multiple_rename.ll new file mode 100644 index 0000000000000..16b03dc34be7e --- /dev/null +++ b/llvm/test/Verifier/PowerPC/multiple_rename.ll @@ -0,0 +1,8 @@ +; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s + +@a = global i32 1, section "abc", !rename.key !0, !rename.key !1 + +!0 = !{} +!1 = !{} + +; CHECK: global value cannot have more then 1 rename metadata diff --git a/llvm/test/Verifier/PowerPC/rename_operands.ll b/llvm/test/Verifier/PowerPC/rename_operands.ll new file mode 100644 index 0000000000000..a76575bc5293e --- /dev/null +++ b/llvm/test/Verifier/PowerPC/rename_operands.ll @@ -0,0 +1,6 @@ +; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s + +@a = global i32 1, section "abc", !rename.key !0 + +!0 = !{!"Hello World!"} +; CHECK: rename metadata must have no operands From 97a4f2486018f72effc7ffa5f47be7b881e88a24 Mon Sep 17 00:00:00 2001 From: Sean Fertile Date: Thu, 25 Sep 2025 11:47:18 -0400 Subject: [PATCH 2/6] Fix spelling. --- llvm/docs/LangRef.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 03ba7a1e6b956..4e21a1e884d4b 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -8446,7 +8446,7 @@ freed after the attached instruction. The rename key may be attached to a global variable definition that has an explicit section attribute. It is used as a flag so the associated node must be empty. It only takes effect when function sections is enabled, and -only on XCOFF targets. The metadata will casue the global to be emitted to a +only on XCOFF targets. The metadata will cause the global to be emitted to a control section (CSECT) with a name that is an amalgamation of both the section attribute and the global variables identifier. After the control section is defined it will be renamed to match the name of the section attribute. This From 24583282a7a1dd511e451fc1f6e905d91c478e09 Mon Sep 17 00:00:00 2001 From: Sean Fertile Date: Thu, 25 Sep 2025 13:23:11 -0400 Subject: [PATCH 3/6] Simplify from rename.key to rename. --- llvm/docs/LangRef.rst | 4 ++-- llvm/include/llvm/IR/FixedMetadataKinds.def | 2 +- llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 3 +-- llvm/lib/IR/Verifier.cpp | 4 ++-- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp | 2 +- llvm/test/CodeGen/PowerPC/aix-rename.ll | 8 ++++---- llvm/test/Verifier/PowerPC/multiple_rename.ll | 2 +- llvm/test/Verifier/PowerPC/rename_operands.ll | 2 +- 8 files changed, 13 insertions(+), 14 deletions(-) diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 4e21a1e884d4b..eec3b7e56dfdf 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -8441,7 +8441,7 @@ The ``nofree`` metadata indicates the memory pointed by the pointer will not be freed after the attached instruction. -'``rename.key``' Metadata +'``rename``' Metadata ^^^^^^^^^^^^^^^^^^^^^^^^^ The rename key may be attached to a global variable definition that has an explicit section attribute. It is used as a flag so the associated node @@ -8461,7 +8461,7 @@ Example: .. code-block:: llvm - @a = global i32 1, section "abc", !rename.key !0 + @a = global i32 1, section "abc", !rename !0 !0 = !{} Module Flags Metadata diff --git a/llvm/include/llvm/IR/FixedMetadataKinds.def b/llvm/include/llvm/IR/FixedMetadataKinds.def index f4b7ebfcf14d5..3b532317fa32f 100644 --- a/llvm/include/llvm/IR/FixedMetadataKinds.def +++ b/llvm/include/llvm/IR/FixedMetadataKinds.def @@ -55,4 +55,4 @@ LLVM_FIXED_MD_KIND(MD_mmra, "mmra", 40) LLVM_FIXED_MD_KIND(MD_noalias_addrspace, "noalias.addrspace", 41) LLVM_FIXED_MD_KIND(MD_callee_type, "callee_type", 42) LLVM_FIXED_MD_KIND(MD_nofree, "nofree", 43) -LLVM_FIXED_MD_KIND(MD_rename_key, "rename.key", 44) +LLVM_FIXED_MD_KIND(MD_rename, "rename", 44) diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 759b6a8e349cc..a9377866d661d 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -2442,8 +2442,7 @@ MCSection *TargetLoweringObjectFileXCOFF::getExplicitSectionGlobal( XCOFF::CsectProperties(/*MappingClass*/ XCOFF::XMC_TD, XCOFF::XTY_SD), /* MultiSymbolsAllowed*/ true); - if (TM.getFunctionSections() && - GVar->hasMetadata(LLVMContext::MD_rename_key)) { + if (TM.getFunctionSections() && GVar->hasMetadata(LLVMContext::MD_rename)) { SectionName += "."; SectionName += GO->getName(); } diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 1d11e3f4e3aae..c151bb1418e1e 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -767,9 +767,9 @@ void Verifier::visitGlobalValue(const GlobalValue &GV) { RangeLikeMetadataKind::AbsoluteSymbol); } - if (GO->hasMetadata(LLVMContext::MD_rename_key)) { + if (GO->hasMetadata(LLVMContext::MD_rename)) { SmallVector MDs; - GO->getMetadata(LLVMContext::MD_rename_key, MDs); + GO->getMetadata(LLVMContext::MD_rename, MDs); Check(MDs.size() == 1, "global value cannot have more then 1 rename metadata", GO); Check(MDs[0]->getNumOperands() == 0, diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp index 962cf518614c8..8cc93ba522486 100644 --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -3029,7 +3029,7 @@ void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) { return; for (const GlobalVariable &GV : M.globals()) { - if (GV.hasMetadata(LLVMContext::MD_rename_key)) { + if (GV.hasMetadata(LLVMContext::MD_rename)) { // Get orginal csect. SectionKind GVKind = getObjFileLowering().getKindForGlobal(&GV, TM); auto *CSect = static_cast( diff --git a/llvm/test/CodeGen/PowerPC/aix-rename.ll b/llvm/test/CodeGen/PowerPC/aix-rename.ll index 3fe379b8cd33b..6f5b7c1fd616d 100644 --- a/llvm/test/CodeGen/PowerPC/aix-rename.ll +++ b/llvm/test/CodeGen/PowerPC/aix-rename.ll @@ -1,10 +1,10 @@ ; RUN: llc --function-sections -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck %s ; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck --check-prefix=NOFUNCSECT %s -@a = global i32 1, section "abcd", !rename.key !0 -@b = global i32 2, section "abcd", !rename.key !0 -@c = global i32 3, section "abcd", !rename.key !0 -@d = global i32 4, section "abcd", !rename.key !0 +@a = global i32 1, section "abcd", !rename !0 +@b = global i32 2, section "abcd", !rename !0 +@c = global i32 3, section "abcd", !rename !0 +@d = global i32 4, section "abcd", !rename !0 !0 = !{} diff --git a/llvm/test/Verifier/PowerPC/multiple_rename.ll b/llvm/test/Verifier/PowerPC/multiple_rename.ll index 16b03dc34be7e..deb9665bf9a63 100644 --- a/llvm/test/Verifier/PowerPC/multiple_rename.ll +++ b/llvm/test/Verifier/PowerPC/multiple_rename.ll @@ -1,6 +1,6 @@ ; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s -@a = global i32 1, section "abc", !rename.key !0, !rename.key !1 +@a = global i32 1, section "abc", !rename !0, !rename !1 !0 = !{} !1 = !{} diff --git a/llvm/test/Verifier/PowerPC/rename_operands.ll b/llvm/test/Verifier/PowerPC/rename_operands.ll index a76575bc5293e..c86f49f743123 100644 --- a/llvm/test/Verifier/PowerPC/rename_operands.ll +++ b/llvm/test/Verifier/PowerPC/rename_operands.ll @@ -1,6 +1,6 @@ ; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s -@a = global i32 1, section "abc", !rename.key !0 +@a = global i32 1, section "abc", !rename !0 !0 = !{!"Hello World!"} ; CHECK: rename metadata must have no operands From a8f72b4bdc763b29f0dd67e11f8c6945d37cb5d7 Mon Sep 17 00:00:00 2001 From: Sean Fertile Date: Thu, 25 Sep 2025 14:06:38 -0400 Subject: [PATCH 4/6] Add a verifier check that the globla object has an explicit section. --- llvm/lib/IR/Verifier.cpp | 3 +++ llvm/test/Verifier/PowerPC/rename_no_section.ll | 8 ++++++++ 2 files changed, 11 insertions(+) create mode 100644 llvm/test/Verifier/PowerPC/rename_no_section.ll diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index c151bb1418e1e..8d12aefadfe02 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -774,6 +774,9 @@ void Verifier::visitGlobalValue(const GlobalValue &GV) { "global value cannot have more then 1 rename metadata", GO); Check(MDs[0]->getNumOperands() == 0, "rename metadata must have no operands", GO); + + Check(GO->hasSection(), + "global value with rename metadata must have section attribute", GO); } } diff --git a/llvm/test/Verifier/PowerPC/rename_no_section.ll b/llvm/test/Verifier/PowerPC/rename_no_section.ll new file mode 100644 index 0000000000000..2a709fecb06b2 --- /dev/null +++ b/llvm/test/Verifier/PowerPC/rename_no_section.ll @@ -0,0 +1,8 @@ +; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s + +@a = global i32 1, !rename !0 + +!0 = !{} + +; CHECK: global value with rename metadata must have section attribute +; CHECK: ptr @a From 552a498ed6205079a2ab8de0c80103b2b29bddee Mon Sep 17 00:00:00 2001 From: Sean Fertile Date: Thu, 25 Sep 2025 14:22:07 -0400 Subject: [PATCH 5/6] Add operand to verifier output. --- llvm/lib/IR/Verifier.cpp | 2 +- llvm/test/Verifier/PowerPC/rename_operands.ll | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 8d12aefadfe02..2da9fc2d7b5f5 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -773,7 +773,7 @@ void Verifier::visitGlobalValue(const GlobalValue &GV) { Check(MDs.size() == 1, "global value cannot have more then 1 rename metadata", GO); Check(MDs[0]->getNumOperands() == 0, - "rename metadata must have no operands", GO); + "rename metadata must have no operands", GO, MDs[0]); Check(GO->hasSection(), "global value with rename metadata must have section attribute", GO); diff --git a/llvm/test/Verifier/PowerPC/rename_operands.ll b/llvm/test/Verifier/PowerPC/rename_operands.ll index c86f49f743123..7044b29709af9 100644 --- a/llvm/test/Verifier/PowerPC/rename_operands.ll +++ b/llvm/test/Verifier/PowerPC/rename_operands.ll @@ -3,4 +3,6 @@ @a = global i32 1, section "abc", !rename !0 !0 = !{!"Hello World!"} -; CHECK: rename metadata must have no operands +; CHECK: rename metadata must have no operands +; CHECK: ptr @a +; CHECK: !0 = !{!"Hello World!"} From 25b27459e92a2687c310e4fb960aeba45a17f691 Mon Sep 17 00:00:00 2001 From: Sean Fertile Date: Thu, 25 Sep 2025 16:36:38 -0400 Subject: [PATCH 6/6] Fix formatting. --- llvm/lib/IR/Verifier.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 2da9fc2d7b5f5..7dd3e46c59963 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -776,7 +776,8 @@ void Verifier::visitGlobalValue(const GlobalValue &GV) { "rename metadata must have no operands", GO, MDs[0]); Check(GO->hasSection(), - "global value with rename metadata must have section attribute", GO); + "global value with rename metadata must have section attribute", + GO); } }