[llvm] MC,AMDGPU: Don't pad .text with s_code_end if it would otherwise be empty (PR #147980)

Tim Renouf via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 11 09:49:28 PDT 2025


https://github.com/trenouf updated https://github.com/llvm/llvm-project/pull/147980

>From 9f4e8e170bb2978fd5bbb6dbac0900c51ea09af7 Mon Sep 17 00:00:00 2001
From: Tim Renouf <tim.renouf at amd.com>
Date: Thu, 20 Feb 2025 09:47:55 +0000
Subject: [PATCH 1/4] AMDGPU: Don't pad .text with s_code_end if it would
 otherwise be empty

We don't want that padding in a module that only contains data, not
code.
---
 llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
index 749b9efc81378..3765c1d2b106c 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
@@ -486,10 +486,12 @@ bool AMDGPUAsmPrinter::doFinalization(Module &M) {
   // Pad with s_code_end to help tools and guard against instruction prefetch
   // causing stale data in caches. Arguably this should be done by the linker,
   // which is why this isn't done for Mesa.
+  // Don't do it if there are no functions.
   const MCSubtargetInfo &STI = *getGlobalSTI();
   if ((AMDGPU::isGFX10Plus(STI) || AMDGPU::isGFX90A(STI)) &&
       (STI.getTargetTriple().getOS() == Triple::AMDHSA ||
-       STI.getTargetTriple().getOS() == Triple::AMDPAL)) {
+       STI.getTargetTriple().getOS() == Triple::AMDPAL) &&
+      !M.empty()) {
     OutStreamer->switchSection(getObjFileLowering().getTextSection());
     getTargetStreamer()->EmitCodeEnd(STI);
   }

>From dab2b13ecf7809b4dc05fae9b267afdd25d222f3 Mon Sep 17 00:00:00 2001
From: Tim Renouf <tim.renouf at amd.com>
Date: Fri, 11 Jul 2025 10:49:46 +0100
Subject: [PATCH 2/4] Use hasInstructions(), and fix hasInstructions() to work
 on the asm streamer

---
 llvm/lib/MC/MCAsmStreamer.cpp               |  2 ++
 llvm/lib/MC/MCObjectStreamer.cpp            |  6 ++----
 llvm/lib/MC/MCStreamer.cpp                  |  3 +++
 llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp | 12 +++++++-----
 4 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index aae02652564d3..0231a71b4bd23 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -2427,6 +2427,8 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
 
 void MCAsmStreamer::emitInstruction(const MCInst &Inst,
                                     const MCSubtargetInfo &STI) {
+  MCStreamer::emitInstruction(Inst, STI);
+
   if (MAI->isAIX() && CurFrag)
     // Now that a machine instruction has been assembled into this section, make
     // a line entry for any .loc directive that has been seen.
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index 5cc9bed2669d4..5d8822b452f59 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -342,12 +342,10 @@ void MCObjectStreamer::emitInstructionImpl(const MCInst &Inst,
                                            const MCSubtargetInfo &STI) {
   MCStreamer::emitInstruction(Inst, STI);
 
-  MCSection *Sec = getCurrentSectionOnly();
-  Sec->setHasInstructions(true);
-
   // Now that a machine instruction has been assembled into this section, make
   // a line entry for any .loc directive that has been seen.
-  MCDwarfLineEntry::make(this, getCurrentSectionOnly());
+  MCSection *Sec = getCurrentSectionOnly();
+  MCDwarfLineEntry::make(this, Sec);
 
   // If this instruction doesn't need relaxation, just emit it as data.
   MCAssembler &Assembler = getAssembler();
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 6cd6b4abdd327..8603b60d91915 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -1194,6 +1194,9 @@ void MCStreamer::visitUsedExpr(const MCExpr &Expr) {
 }
 
 void MCStreamer::emitInstruction(const MCInst &Inst, const MCSubtargetInfo &) {
+  MCSection *Sec = getCurrentSectionOnly();
+  Sec->setHasInstructions(true);
+
   // Scan for values.
   for (unsigned i = Inst.getNumOperands(); i--;)
     if (Inst.getOperand(i).isExpr())
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
index 3765c1d2b106c..65dade76150f2 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
@@ -486,14 +486,16 @@ bool AMDGPUAsmPrinter::doFinalization(Module &M) {
   // Pad with s_code_end to help tools and guard against instruction prefetch
   // causing stale data in caches. Arguably this should be done by the linker,
   // which is why this isn't done for Mesa.
-  // Don't do it if there are no functions.
+  // Don't do it if there is no code.
   const MCSubtargetInfo &STI = *getGlobalSTI();
   if ((AMDGPU::isGFX10Plus(STI) || AMDGPU::isGFX90A(STI)) &&
       (STI.getTargetTriple().getOS() == Triple::AMDHSA ||
-       STI.getTargetTriple().getOS() == Triple::AMDPAL) &&
-      !M.empty()) {
-    OutStreamer->switchSection(getObjFileLowering().getTextSection());
-    getTargetStreamer()->EmitCodeEnd(STI);
+       STI.getTargetTriple().getOS() == Triple::AMDPAL)) {
+    MCSection *TextSect = getObjFileLowering().getTextSection();
+    if (TextSect->hasInstructions()) {
+      OutStreamer->switchSection(TextSect);
+      getTargetStreamer()->EmitCodeEnd(STI);
+    }
   }
 
   // Assign expressions which can only be resolved when all other functions are

>From 7ab441218bfb4913c3409740c0168c19f4db17bb Mon Sep 17 00:00:00 2001
From: Tim Renouf <tim.renouf at amd.com>
Date: Fri, 11 Jul 2025 09:20:53 +0100
Subject: [PATCH 3/4] Add test

---
 llvm/test/CodeGen/AMDGPU/empty-text.ll | 9 +++++++++
 1 file changed, 9 insertions(+)
 create mode 100644 llvm/test/CodeGen/AMDGPU/empty-text.ll

diff --git a/llvm/test/CodeGen/AMDGPU/empty-text.ll b/llvm/test/CodeGen/AMDGPU/empty-text.ll
new file mode 100644
index 0000000000000..c6a035cd03b3e
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/empty-text.ll
@@ -0,0 +1,9 @@
+; Test that there is no s_code_end padding if .text is othertwise empty.
+
+; RUN: llc -mtriple=amdgcn--amdpal -mcpu=gfx1200 < %s | FileCheck %s --check-prefixes=GCN
+
+ at globalVar = global i32 37
+
+declare amdgpu_ps void @funcDecl()
+
+; GCN-NOT: .fill

>From b31739c28748e208b75a820f9c4375564ea44c86 Mon Sep 17 00:00:00 2001
From: Tim Renouf <tim.renouf at amd.com>
Date: Fri, 11 Jul 2025 17:47:57 +0100
Subject: [PATCH 4/4] Fix setHasInstruction() fix

---
 llvm/lib/MC/MCStreamer.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 8603b60d91915..72a2b2fa5dbe5 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -1194,8 +1194,8 @@ void MCStreamer::visitUsedExpr(const MCExpr &Expr) {
 }
 
 void MCStreamer::emitInstruction(const MCInst &Inst, const MCSubtargetInfo &) {
-  MCSection *Sec = getCurrentSectionOnly();
-  Sec->setHasInstructions(true);
+  if (MCSection *Sec = getCurrentSection().first)
+    Sec->setHasInstructions(true);
 
   // Scan for values.
   for (unsigned i = Inst.getNumOperands(); i--;)



More information about the llvm-commits mailing list