From 9f4e8e170bb2978fd5bbb6dbac0900c51ea09af7 Mon Sep 17 00:00:00 2001 From: Tim Renouf 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 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 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 + +@globalVar = global i32 37 + +declare amdgpu_ps void @funcDecl() + +; GCN-NOT: .fill From b31739c28748e208b75a820f9c4375564ea44c86 Mon Sep 17 00:00:00 2001 From: Tim Renouf 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--;)