[llvm] [AIX][XCOFF] rename metadata (PR #159435)

Sean Fertile via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 25 11:40:07 PDT 2025


https://github.com/mandlebug updated https://github.com/llvm/llvm-project/pull/159435

>From fd3a314ede3fadbc79860f5aef6be5e9f1b1144a Mon Sep 17 00:00:00 2001
From: Sean Fertile <sd.fertile at gmail.com>
Date: Wed, 17 Sep 2025 15:18:19 -0400
Subject: [PATCH 1/5] 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_<section_name>`` and ``__stop_<section_name>``.
+
+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<GlobalVariable>(GO))
+  // Have to check for either attributes or metadata that can affect the
+  // section type or section name.
+  if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(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<MDNode *, 1> 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<GlobalVariable>(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<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
+    PPCTargetStreamer *TS =
+        static_cast<PPCTargetStreamer *>(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<const MCSymbolXCOFF *>(I.first.first)
+                    ->getSymbolTableName();
+        MCSymbol *S = OutContext.getOrCreateSymbol(Name);
+        TCEntry = static_cast<MCSectionXCOFF *>(
+            getObjFileLowering().getSectionForTOCEntry(S, TM));
+      } else {
+        TCEntry = static_cast<MCSectionXCOFF *>(
+            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<const MCSymbolXCOFF *>(I.first.first)
-                  ->getSymbolTableName();
-      MCSymbol *S = OutContext.getOrCreateSymbol(Name);
-      TCEntry = static_cast<MCSectionXCOFF *>(
-          getObjFileLowering().getSectionForTOCEntry(S, TM));
-    } else {
-      TCEntry = static_cast<MCSectionXCOFF *>(
-          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<MCSectionXCOFF *>(
+          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
+
+ at a = global i32 1, section "abcd", !rename.key !0
+ at b = global i32 2, section "abcd", !rename.key !0
+ at c = global i32 3, section "abcd", !rename.key !0
+ at 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
+
+ at 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
+
+ at 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 <sd.fertile at gmail.com>
Date: Thu, 25 Sep 2025 11:47:18 -0400
Subject: [PATCH 2/5] 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 <sd.fertile at gmail.com>
Date: Thu, 25 Sep 2025 13:23:11 -0400
Subject: [PATCH 3/5] 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<MDNode *, 1> 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<MCSectionXCOFF *>(
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
 
- at a = global i32 1, section "abcd", !rename.key !0
- at b = global i32 2, section "abcd", !rename.key !0
- at c = global i32 3, section "abcd", !rename.key !0
- at d = global i32 4, section "abcd", !rename.key !0
+ at a = global i32 1, section "abcd", !rename !0
+ at b = global i32 2, section "abcd", !rename !0
+ at c = global i32 3, section "abcd", !rename !0
+ at 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
 
- at a = global i32 1, section "abc", !rename.key !0, !rename.key !1
+ at 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
 
- at a = global i32 1, section "abc", !rename.key !0
+ at 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 <sd.fertile at gmail.com>
Date: Thu, 25 Sep 2025 14:06:38 -0400
Subject: [PATCH 4/5] 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
+
+ at 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 <sd.fertile at gmail.com>
Date: Thu, 25 Sep 2025 14:22:07 -0400
Subject: [PATCH 5/5] 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!"}



More information about the llvm-commits mailing list