[llvm] [MC][X86] Set SHF_X86_64_LARGE on mergeable constant sections for large code-model (PR #190903)

Farid Zakaria via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 30 08:55:47 PDT 2026


https://github.com/fzakaria updated https://github.com/llvm/llvm-project/pull/190903

>From 6a5eb41644fe32ba7c166fc603b903ea786fcb66 Mon Sep 17 00:00:00 2001
From: Farid Zakaria <fmzakari at fb.com>
Date: Wed, 29 Apr 2026 20:31:06 -0700
Subject: [PATCH 1/2] [MC][X86] Set SHF_X86_64_LARGE on mergeable constant
 sections for large code model

Under -mcmodel=large on x86-64, constant pool entries were placed into
.rodata.cst{4,8,16,32} without the SHF_X86_64_LARGE flag. Meanwhile, named global constants correctly received .lrodata with the large flag via getSectionPrefixForGlobal().

Fix initELFMCObjectFileInfo() to use .lrodata.cst* section names with
SHF_X86_64_LARGE when the Large parameter is true and the target is x86-64.
---
 llvm/lib/MC/MCObjectFileInfo.cpp              | 27 ++++++------
 .../X86/code-model-elf-constpool-large.ll     | 42 +++++++++++++++++++
 2 files changed, 57 insertions(+), 12 deletions(-)
 create mode 100644 llvm/test/CodeGen/X86/code-model-elf-constpool-large.ll

diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index cb2ed9ce5ef6e..98ed50c9f9ddd 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -432,21 +432,24 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
   DataRelROSection = Ctx->getELFSection(".data.rel.ro", ELF::SHT_PROGBITS,
                                         ELF::SHF_ALLOC | ELF::SHF_WRITE);
 
-  MergeableConst4Section =
-      Ctx->getELFSection(".rodata.cst4", ELF::SHT_PROGBITS,
-                         ELF::SHF_ALLOC | ELF::SHF_MERGE, 4);
+  unsigned MergeableCstFlags = ELF::SHF_ALLOC | ELF::SHF_MERGE;
+  StringRef CstPrefix = ".rodata";
+  if (Large && T.getArch() == Triple::x86_64) {
+    MergeableCstFlags |= ELF::SHF_X86_64_LARGE;
+    CstPrefix = ".lrodata";
+  }
+
+  MergeableConst4Section = Ctx->getELFSection(
+      (CstPrefix + ".cst4").str(), ELF::SHT_PROGBITS, MergeableCstFlags, 4);
 
-  MergeableConst8Section =
-      Ctx->getELFSection(".rodata.cst8", ELF::SHT_PROGBITS,
-                         ELF::SHF_ALLOC | ELF::SHF_MERGE, 8);
+  MergeableConst8Section = Ctx->getELFSection(
+      (CstPrefix + ".cst8").str(), ELF::SHT_PROGBITS, MergeableCstFlags, 8);
 
-  MergeableConst16Section =
-      Ctx->getELFSection(".rodata.cst16", ELF::SHT_PROGBITS,
-                         ELF::SHF_ALLOC | ELF::SHF_MERGE, 16);
+  MergeableConst16Section = Ctx->getELFSection(
+      (CstPrefix + ".cst16").str(), ELF::SHT_PROGBITS, MergeableCstFlags, 16);
 
-  MergeableConst32Section =
-      Ctx->getELFSection(".rodata.cst32", ELF::SHT_PROGBITS,
-                         ELF::SHF_ALLOC | ELF::SHF_MERGE, 32);
+  MergeableConst32Section = Ctx->getELFSection(
+      (CstPrefix + ".cst32").str(), ELF::SHT_PROGBITS, MergeableCstFlags, 32);
 
   // Exception Handling Sections.
 
diff --git a/llvm/test/CodeGen/X86/code-model-elf-constpool-large.ll b/llvm/test/CodeGen/X86/code-model-elf-constpool-large.ll
new file mode 100644
index 0000000000000..ae568fe5464fe
--- /dev/null
+++ b/llvm/test/CodeGen/X86/code-model-elf-constpool-large.ll
@@ -0,0 +1,42 @@
+; RUN: llc < %s -relocation-model=pic -filetype=obj -code-model=large -o %t
+; RUN: llvm-readelf -S %t | FileCheck %s
+
+; Verify that anonymous constant pool entries get SHF_X86_64_LARGE
+; and are placed in .lrodata.cst* sections under the large code model.
+
+; CHECK: .lrodata.cst16 {{.*}} AMl
+; CHECK: .lrodata.cst4  {{.*}} AMl
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64--linux"
+
+define void @vec_add(ptr %out, ptr %a, ptr %b, i32 %n) {
+entry:
+  %cmp = icmp sgt i32 %n, 0
+  br i1 %cmp, label %loop, label %exit
+
+loop:
+  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
+  %idx = sext i32 %iv to i64
+  %pa = getelementptr float, ptr %a, i64 %idx
+  %pb = getelementptr float, ptr %b, i64 %idx
+  %po = getelementptr float, ptr %out, i64 %idx
+  %va = load <4 x float>, ptr %pa, align 4
+  %vb = load <4 x float>, ptr %pb, align 4
+  %add = fadd <4 x float> %va, %vb
+  ; Adding a vector splat of 1.0 forces a constant pool entry in .rodata.cst16
+  %ones = fadd <4 x float> %add, <float 1.0, float 1.0, float 1.0, float 1.0>
+  store <4 x float> %ones, ptr %po, align 4
+  %iv.next = add i32 %iv, 4
+  %done = icmp sge i32 %iv.next, %n
+  br i1 %done, label %exit, label %loop
+
+exit:
+  ret void
+}
+
+; A scalar float constant forces a .rodata.cst4 entry.
+define float @scalar_const(float %x) {
+  %r = fadd float %x, 1.0
+  ret float %r
+}

>From 205a4f602404a987885ea7df47b00b62e0c72f30 Mon Sep 17 00:00:00 2001
From: Farid Zakaria <fmzakari at meta.com>
Date: Wed, 29 Apr 2026 20:51:15 -0700
Subject: [PATCH 2/2] [MC][X86] Apply large code model flags to suffixed
 constant sections

Extend the prior fix to the getSectionForConstant overload that
handles SectionSuffix.
---
 .../CodeGen/TargetLoweringObjectFileImpl.cpp  | 28 ++++++++++--------
 .../X86/code-model-elf-constpool-large.ll     | 29 ++++++++++++++++++-
 2 files changed, 44 insertions(+), 13 deletions(-)

diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 211d13c19e459..f983c3205f927 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -1078,22 +1078,26 @@ MCSection *TargetLoweringObjectFileELF::getSectionForConstant(
     return getSectionForConstant(DL, Kind, C, Alignment, F);
 
   auto &Context = getContext();
+  StringRef CstPrefix = ".rodata";
+  unsigned MergeableCstFlags = ELF::SHF_ALLOC | ELF::SHF_MERGE;
+  if (TM->getCodeModel() == CodeModel::Large &&
+      TM->getTargetTriple().getArch() == Triple::x86_64) {
+    MergeableCstFlags |= ELF::SHF_X86_64_LARGE;
+    CstPrefix = ".lrodata";
+  }
+
   if (Kind.isMergeableConst4() && MergeableConst4Section)
-    return Context.getELFSection(".rodata.cst4." + SectionSuffix + ".",
-                                 ELF::SHT_PROGBITS,
-                                 ELF::SHF_ALLOC | ELF::SHF_MERGE, 4);
+    return Context.getELFSection(CstPrefix + ".cst4." + SectionSuffix + ".",
+                                 ELF::SHT_PROGBITS, MergeableCstFlags, 4);
   if (Kind.isMergeableConst8() && MergeableConst8Section)
-    return Context.getELFSection(".rodata.cst8." + SectionSuffix + ".",
-                                 ELF::SHT_PROGBITS,
-                                 ELF::SHF_ALLOC | ELF::SHF_MERGE, 8);
+    return Context.getELFSection(CstPrefix + ".cst8." + SectionSuffix + ".",
+                                 ELF::SHT_PROGBITS, MergeableCstFlags, 8);
   if (Kind.isMergeableConst16() && MergeableConst16Section)
-    return Context.getELFSection(".rodata.cst16." + SectionSuffix + ".",
-                                 ELF::SHT_PROGBITS,
-                                 ELF::SHF_ALLOC | ELF::SHF_MERGE, 16);
+    return Context.getELFSection(CstPrefix + ".cst16." + SectionSuffix + ".",
+                                 ELF::SHT_PROGBITS, MergeableCstFlags, 16);
   if (Kind.isMergeableConst32() && MergeableConst32Section)
-    return Context.getELFSection(".rodata.cst32." + SectionSuffix + ".",
-                                 ELF::SHT_PROGBITS,
-                                 ELF::SHF_ALLOC | ELF::SHF_MERGE, 32);
+    return Context.getELFSection(CstPrefix + ".cst32." + SectionSuffix + ".",
+                                 ELF::SHT_PROGBITS, MergeableCstFlags, 32);
   if (Kind.isReadOnly())
     return Context.getELFSection(".rodata." + SectionSuffix + ".",
                                  ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
diff --git a/llvm/test/CodeGen/X86/code-model-elf-constpool-large.ll b/llvm/test/CodeGen/X86/code-model-elf-constpool-large.ll
index ae568fe5464fe..08b2f4e580310 100644
--- a/llvm/test/CodeGen/X86/code-model-elf-constpool-large.ll
+++ b/llvm/test/CodeGen/X86/code-model-elf-constpool-large.ll
@@ -7,10 +7,17 @@
 ; CHECK: .lrodata.cst16 {{.*}} AMl
 ; CHECK: .lrodata.cst4  {{.*}} AMl
 
+; Also verify the suffixed path (via -partition-static-data-sections).
+; RUN: llc < %s -relocation-model=pic -code-model=large \
+; RUN:     -partition-static-data-sections -o - | FileCheck %s --check-prefix=SUFFIX
+
+; SUFFIX: .section .lrodata.cst16.hot.,"aMl", at progbits,16
+; SUFFIX: .section .lrodata.cst4,"aMl", at progbits,4
+
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64--linux"
 
-define void @vec_add(ptr %out, ptr %a, ptr %b, i32 %n) {
+define void @vec_add(ptr %out, ptr %a, ptr %b, i32 %n) !prof !17 {
 entry:
   %cmp = icmp sgt i32 %n, 0
   br i1 %cmp, label %loop, label %exit
@@ -40,3 +47,23 @@ define float @scalar_const(float %x) {
   %r = fadd float %x, 1.0
   ret float %r
 }
+
+!llvm.module.flags = !{!1}
+
+!1 = !{i32 1, !"ProfileSummary", !2}
+!2 = !{!3, !4, !5, !6, !7, !8, !9, !10, !11, !12}
+!3 = !{!"ProfileFormat", !"InstrProf"}
+!4 = !{!"TotalCount", i64 1460617}
+!5 = !{!"MaxCount", i64 849536}
+!6 = !{!"MaxInternalCount", i64 32769}
+!7 = !{!"MaxFunctionCount", i64 849536}
+!8 = !{!"NumCounts", i64 23784}
+!9 = !{!"NumFunctions", i64 3301}
+!10 = !{!"IsPartialProfile", i64 0}
+!11 = !{!"PartialProfileRatio", double 0.000000e+00}
+!12 = !{!"DetailedSummary", !13}
+!13 = !{!14, !15}
+!14 = !{i32 990000, i64 166, i32 73}
+!15 = !{i32 999999, i64 1, i32 1463}
+!16 = !{!"function_entry_count", i64 1}
+!17 = !{!"function_entry_count", i64 100000}



More information about the llvm-commits mailing list