[llvm] Add !metadata_section_kind global variable metadata (PR #211524)

Orlando Cazalet-Hyams via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 24 03:34:18 PDT 2026


https://github.com/OCHyams updated https://github.com/llvm/llvm-project/pull/211524

>From 473a90d801164482c97c2361da45348188274054 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Wed, 22 Jul 2026 13:14:29 +0100
Subject: [PATCH 1/3] Add !metadata_section_kind global variable metadata

Similar to !exclude in that this attempts to guide section + flag choices in a
generic/abstract way.

`!exclude` tells LLVM to use the generic `SectionKind::Exclude` for the globals.
Likewise, `!metadata_section_kind` tells LLVM to use `SectionKind::Metadata`.

The added docs go into a little more detail.

This is needed for the dynamic debugging feature, otherwise there's no way to
avoid `SHF_EXCLUDE` or `SHF_ALLOC` flags being added to the section without
special handling based on its name. We've moved to using a new section type
for dynamic debugging and we don't want to rely on the name, which may be
omitted.
---
 llvm/docs/LangRef.md                          | 20 +++++++++++++++++++
 llvm/include/llvm/IR/FixedMetadataKinds.def   |  2 +-
 llvm/lib/Target/TargetLoweringObjectFile.cpp  |  8 ++++++--
 .../test/CodeGen/X86/metadata_section_kind.ll |  8 ++++++++
 4 files changed, 35 insertions(+), 3 deletions(-)
 create mode 100644 llvm/test/CodeGen/X86/metadata_section_kind.ll

diff --git a/llvm/docs/LangRef.md b/llvm/docs/LangRef.md
index 361333a7801c0..23a0b8d8d4132 100644
--- a/llvm/docs/LangRef.md
+++ b/llvm/docs/LangRef.md
@@ -7789,6 +7789,26 @@ sections that the user does not want removed after linking.
 !0 = !{}
 ```
 
+#### '`metadata_section_kind`' Metadata
+
+`metadata_section_kind` metadata may be attached to a global variable to signify
+that its section should be treated as "metadata" by LLVM, meaning the the
+section will be generic by default without any flags, unless the section has a
+special name (e.g., `"llvm.metadata"`). Incompatible with `!exclude`; in
+practice, one may be ignored by LLVM. This option is only valid for global
+variables with an explicit section targeting ELF or COFF.
+
+By default this uses `SHT_PROGBITS` with no flags for ELF, and for COFF the
+section is not marked as readable or writable and it uses the section flag
+`IMAGE_SCN_MEM_DISCARDABLE`.
+
+```text
+ at object = private constant [1 x i8] c"\00", section ".foo" !metadata_section_kind !0
+
+...
+!0 = !{}
+```
+
 #### '`unpredictable`' Metadata
 
 `unpredictable` metadata may be attached to any branch, select, or switch
diff --git a/llvm/include/llvm/IR/FixedMetadataKinds.def b/llvm/include/llvm/IR/FixedMetadataKinds.def
index d10d16075fecb..350adfc27bef4 100644
--- a/llvm/include/llvm/IR/FixedMetadataKinds.def
+++ b/llvm/include/llvm/IR/FixedMetadataKinds.def
@@ -66,4 +66,4 @@ LLVM_FIXED_MD_KIND(MD_guid, "guid", 51)
 LLVM_FIXED_MD_KIND(MD_mem_cache_hint, "mem.cache_hint", 52)
 LLVM_FIXED_MD_KIND(MD_block_uniformity_profile, "block.uniformity.profile", 53)
 LLVM_FIXED_MD_KIND(MD_callgraph, "callgraph", 54)
-
+LLVM_FIXED_MD_KIND(MD_metadata_section_kind, "metadata_section_kind", 55)
diff --git a/llvm/lib/Target/TargetLoweringObjectFile.cpp b/llvm/lib/Target/TargetLoweringObjectFile.cpp
index 43649a0cd95c7..9a2e78f5d4da2 100644
--- a/llvm/lib/Target/TargetLoweringObjectFile.cpp
+++ b/llvm/lib/Target/TargetLoweringObjectFile.cpp
@@ -290,11 +290,15 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalObject *GO,
   }
 
   // Global variables with '!exclude' should get the exclude section kind if
-  // they have an explicit section and no other metadata.
-  if (GVar->hasSection())
+  // they have an explicit section and no other metadata. Similarly,
+  // '!metadata_section_kind' forces the section kind to be 'metadata'.
+  if (GVar->hasSection()) {
     if (MDNode *MD = GVar->getMetadata(LLVMContext::MD_exclude))
       if (!MD->getNumOperands())
         return SectionKind::getExclude();
+    if (MDNode *MD = GVar->getMetadata(LLVMContext::MD_metadata_section_kind))
+      return SectionKind::getMetadata();
+  }
 
   // If the global is marked constant, we can put it into a mergable section,
   // a mergable string section, or general .data if it contains relocations.
diff --git a/llvm/test/CodeGen/X86/metadata_section_kind.ll b/llvm/test/CodeGen/X86/metadata_section_kind.ll
new file mode 100644
index 0000000000000..adfbf67cf93ff
--- /dev/null
+++ b/llvm/test/CodeGen/X86/metadata_section_kind.ll
@@ -0,0 +1,8 @@
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefix=CHECK-ELF
+; RUN: llc < %s -mtriple=x86_64-win32-gnu | FileCheck %s --check-prefix=CHECK-COFF
+
+ at a = private constant [1 x i8] c"\00", section ".test", align 8, !metadata_section_kind !{}
+
+;;              section: name, flags, type
+; CHECK-ELF:   .section  .test,"", at progbits
+; CHECK-COFF:  .section  .test,"yD"

>From a37f275ac7512b5d9125abb1b755375d3b437112 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Thu, 23 Jul 2026 18:32:02 +0100
Subject: [PATCH 2/3] fix nits

---
 llvm/docs/LangRef.md                           | 11 ++++++-----
 llvm/test/CodeGen/X86/metadata_section_kind.ll |  5 +++++
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/llvm/docs/LangRef.md b/llvm/docs/LangRef.md
index 23a0b8d8d4132..36fa19544d0eb 100644
--- a/llvm/docs/LangRef.md
+++ b/llvm/docs/LangRef.md
@@ -7792,11 +7792,12 @@ sections that the user does not want removed after linking.
 #### '`metadata_section_kind`' Metadata
 
 `metadata_section_kind` metadata may be attached to a global variable to signify
-that its section should be treated as "metadata" by LLVM, meaning the the
-section will be generic by default without any flags, unless the section has a
-special name (e.g., `"llvm.metadata"`). Incompatible with `!exclude`; in
-practice, one may be ignored by LLVM. This option is only valid for global
-variables with an explicit section targeting ELF or COFF.
+that its section should be treated as "metadata" by LLVM, meaning the section
+will be generic by default without any flags, unless the section has a special
+name (e.g., `"llvm.metadata"`). Incompatible with `!exclude`; in practice, one
+may be ignored by LLVM. This option is only valid for global variables with an
+explicit section targeting ELF or COFF. Additionally, this metadata is only
+used as a flag, so the associated node must be empty.
 
 By default this uses `SHT_PROGBITS` with no flags for ELF, and for COFF the
 section is not marked as readable or writable and it uses the section flag
diff --git a/llvm/test/CodeGen/X86/metadata_section_kind.ll b/llvm/test/CodeGen/X86/metadata_section_kind.ll
index adfbf67cf93ff..c63a0d66ca48e 100644
--- a/llvm/test/CodeGen/X86/metadata_section_kind.ll
+++ b/llvm/test/CodeGen/X86/metadata_section_kind.ll
@@ -2,7 +2,12 @@
 ; RUN: llc < %s -mtriple=x86_64-win32-gnu | FileCheck %s --check-prefix=CHECK-COFF
 
 @a = private constant [1 x i8] c"\00", section ".test", align 8, !metadata_section_kind !{}
+ at b = private constant [1 x i8] c"\00", section ".test2", align 8
 
 ;;              section: name, flags, type
 ; CHECK-ELF:   .section  .test,"", at progbits
 ; CHECK-COFF:  .section  .test,"yD"
+;; Check no metadata results in different output to prevent rotten
+;; green test.
+; CHECK-ELF:   .section  .test2,"a", at progbits
+; CHECK-COFF:  .section  .test2,"dr"

>From 9c4c762f8930b245e3a0fcb238057abe838e0429 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Fri, 24 Jul 2026 11:33:56 +0100
Subject: [PATCH 3/3] check num operands for consistency

---
 llvm/lib/Target/TargetLoweringObjectFile.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/TargetLoweringObjectFile.cpp b/llvm/lib/Target/TargetLoweringObjectFile.cpp
index 9a2e78f5d4da2..4bc5fbc37fcf0 100644
--- a/llvm/lib/Target/TargetLoweringObjectFile.cpp
+++ b/llvm/lib/Target/TargetLoweringObjectFile.cpp
@@ -297,7 +297,8 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalObject *GO,
       if (!MD->getNumOperands())
         return SectionKind::getExclude();
     if (MDNode *MD = GVar->getMetadata(LLVMContext::MD_metadata_section_kind))
-      return SectionKind::getMetadata();
+      if (!MD->getNumOperands())
+        return SectionKind::getMetadata();
   }
 
   // If the global is marked constant, we can put it into a mergable section,



More information about the llvm-commits mailing list