[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