[llvm] [AMDGPU] Account for inline asm size in inst_pref_size calculation (PR #192306)
Adel Ejjeh via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 16 10:47:56 PDT 2026
https://github.com/adelejjeh updated https://github.com/llvm/llvm-project/pull/192306
>From 5b90fa79e30e532d4ea14bc845ab8cf2c7bbc6fb Mon Sep 17 00:00:00 2001
From: Adel Ejjeh <adel.ejjeh at amd.com>
Date: Wed, 15 Apr 2026 13:25:36 -0500
Subject: [PATCH 1/5] [AMDGPU] Account for inline asm size in inst_pref_size
calculation
SIProgramInfo::getFunctionCodeSize() with IsLowerBound=true was
completely skipping inline assembly instructions, treating them as
zero bytes. This caused amdhsa_inst_pref_size to be severely
underestimated for kernels containing inline asm, defeating
instruction prefetch on gfx11+.
Use MCExpr label subtraction (.Lfunc_end - func_sym) to compute
exact function code size, resolved at assembly time. This avoids
inline asm string parsing which cannot reliably estimate code size
and risks overestimation (which causes prefetch of unmapped memory
and a fatal segfault).
Add a new AMDGPUMCExpr variant (AGVK_InstPrefSize) to compute
min(divideCeil(codeSize, 128), maxFieldVal) as a custom MCExpr,
following the same pattern as AGVK_Occupancy and AGVK_AlignTo.
Compute inst_pref_size in AMDGPUAsmPrinter::endFunction() where
.Lfunc_end has already been emitted in the correct position (after
the fix in #191526), and set the bits in ComputePGMRSrc3 before
emitting the kernel descriptor.
Remove the IsLowerBound parameter from getFunctionCodeSize() as it
is no longer needed for inst_pref_size calculation.
Co-Authored-By: Claude Opus 4 (1M context) <noreply at anthropic.com>
---
llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp | 85 ++++++++++---------
.../AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp | 38 +++++++++
.../Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.h | 8 ++
llvm/lib/Target/AMDGPU/SIProgramInfo.cpp | 17 +---
llvm/lib/Target/AMDGPU/SIProgramInfo.h | 5 +-
.../test/CodeGen/AMDGPU/inst-prefetch-hint.ll | 36 ++++++--
.../AMDGPU/inst-prefetch-inline-asm.ll | 83 ++++++++++++++++++
7 files changed, 208 insertions(+), 64 deletions(-)
create mode 100644 llvm/test/CodeGen/AMDGPU/inst-prefetch-inline-asm.ll
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
index 6ac138f97d970..60b61247361b9 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
@@ -232,6 +232,18 @@ void AMDGPUAsmPrinter::emitFunctionBodyStart() {
HSAMetadataStream->emitKernel(*MF, CurrentProgramInfo);
}
+/// Set bits in a kernel descriptor MCExpr field:
+/// return ((Dst & ~Mask) | (Value << Shift))
+static const MCExpr *setBits(const MCExpr *Dst, const MCExpr *Value,
+ uint32_t Mask, uint32_t Shift, MCContext &Ctx) {
+ const auto *Shft = MCConstantExpr::create(Shift, Ctx);
+ const auto *Msk = MCConstantExpr::create(Mask, Ctx);
+ Dst = MCBinaryExpr::createAnd(Dst, MCUnaryExpr::createNot(Msk, Ctx), Ctx);
+ Dst = MCBinaryExpr::createOr(Dst, MCBinaryExpr::createShl(Value, Shft, Ctx),
+ Ctx);
+ return Dst;
+}
+
void AMDGPUAsmPrinter::endFunction(const MachineFunction *MF) {
const SIMachineFunctionInfo &MFI = *MF->getInfo<SIMachineFunctionInfo>();
if (!MFI.isEntryFunction())
@@ -239,6 +251,34 @@ void AMDGPUAsmPrinter::endFunction(const MachineFunction *MF) {
assert(TM.getTargetTriple().getOS() == Triple::AMDHSA);
+ const GCNSubtarget &STM = MF->getSubtarget<GCNSubtarget>();
+ MCContext &Ctx = MF->getContext();
+
+ // Compute inst_pref_size using MCExpr label subtraction for exact code
+ // size. (Lfunc_end - func_sym) gives the exact function code size in bytes.
+ if (isGFX11Plus(STM)) {
+ const MCExpr *CodeSizeExpr = MCBinaryExpr::createSub(
+ MCSymbolRefExpr::create(getFunctionEnd(), OutContext),
+ MCSymbolRefExpr::create(CurrentFnSym, OutContext), OutContext);
+
+ uint32_t Field, Shift, Width;
+ if (isGFX11(STM)) {
+ Field = amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE;
+ Shift = amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE_SHIFT;
+ Width = amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE_WIDTH;
+ } else {
+ Field = amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE;
+ Shift = amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE_SHIFT;
+ Width = amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE_WIDTH;
+ }
+ const MCExpr *InstPrefSizeExpr =
+ AMDGPUMCExpr::createInstPrefSize(CodeSizeExpr, Width, Ctx);
+
+ CurrentProgramInfo.ComputePGMRSrc3 =
+ setBits(CurrentProgramInfo.ComputePGMRSrc3, InstPrefSizeExpr, Field,
+ Shift, Ctx);
+ }
+
auto &Streamer = getTargetStreamer()->getStreamer();
auto &Context = Streamer.getContext();
auto &ObjectFileInfo = *Context.getObjectFileInfo();
@@ -252,8 +292,6 @@ void AMDGPUAsmPrinter::endFunction(const MachineFunction *MF) {
Streamer.emitValueToAlignment(Align(64), 0, 1, 0);
ReadOnlySection.ensureMinAlignment(Align(64));
- const GCNSubtarget &STM = MF->getSubtarget<GCNSubtarget>();
-
SmallString<128> KernelName;
getNameWithPrefix(KernelName, &MF->getFunction());
getTargetStreamer()->EmitAmdhsaKernelDescriptor(
@@ -1273,33 +1311,22 @@ void AMDGPUAsmPrinter::getSIProgramInfo(SIProgramInfo &ProgInfo,
ProgInfo.LdsSize = STM.isAmdHsaOS() ? 0 : ProgInfo.LDSBlocks;
ProgInfo.EXCPEnable = 0;
- // return ((Dst & ~Mask) | (Value << Shift))
- auto SetBits = [&Ctx](const MCExpr *Dst, const MCExpr *Value, uint32_t Mask,
- uint32_t Shift) {
- const auto *Shft = MCConstantExpr::create(Shift, Ctx);
- const auto *Msk = MCConstantExpr::create(Mask, Ctx);
- Dst = MCBinaryExpr::createAnd(Dst, MCUnaryExpr::createNot(Msk, Ctx), Ctx);
- Dst = MCBinaryExpr::createOr(Dst, MCBinaryExpr::createShl(Value, Shft, Ctx),
- Ctx);
- return Dst;
- };
-
if (STM.hasGFX90AInsts()) {
ProgInfo.ComputePGMRSrc3 =
- SetBits(ProgInfo.ComputePGMRSrc3, ProgInfo.AccumOffset,
+ setBits(ProgInfo.ComputePGMRSrc3, ProgInfo.AccumOffset,
amdhsa::COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
- amdhsa::COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT);
+ amdhsa::COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT, Ctx);
ProgInfo.ComputePGMRSrc3 =
- SetBits(ProgInfo.ComputePGMRSrc3, CreateExpr(ProgInfo.TgSplit),
+ setBits(ProgInfo.ComputePGMRSrc3, CreateExpr(ProgInfo.TgSplit),
amdhsa::COMPUTE_PGM_RSRC3_GFX90A_TG_SPLIT,
- amdhsa::COMPUTE_PGM_RSRC3_GFX90A_TG_SPLIT_SHIFT);
+ amdhsa::COMPUTE_PGM_RSRC3_GFX90A_TG_SPLIT_SHIFT, Ctx);
}
if (STM.hasGFX1250Insts())
ProgInfo.ComputePGMRSrc3 =
- SetBits(ProgInfo.ComputePGMRSrc3, ProgInfo.NamedBarCnt,
+ setBits(ProgInfo.ComputePGMRSrc3, ProgInfo.NamedBarCnt,
amdhsa::COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT,
- amdhsa::COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT);
+ amdhsa::COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT, Ctx);
ProgInfo.Occupancy = createOccupancy(
STM.computeOccupancy(F, ProgInfo.LDSSize).second,
@@ -1318,26 +1345,6 @@ void AMDGPUAsmPrinter::getSIProgramInfo(SIProgramInfo &ProgInfo,
", final occupancy is " + Twine(Occupancy));
F.getContext().diagnose(Diag);
}
-
- if (isGFX11Plus(STM)) {
- uint32_t CodeSizeInBytes = (uint32_t)std::min(
- ProgInfo.getFunctionCodeSize(MF, true /* IsLowerBound */),
- (uint64_t)std::numeric_limits<uint32_t>::max());
- uint32_t CodeSizeInLines = divideCeil(CodeSizeInBytes, 128);
- uint32_t Field, Shift, Width;
- if (isGFX11(STM)) {
- Field = amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE;
- Shift = amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE_SHIFT;
- Width = amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE_WIDTH;
- } else {
- Field = amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE;
- Shift = amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE_SHIFT;
- Width = amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE_WIDTH;
- }
- uint64_t InstPrefSize = std::min(CodeSizeInLines, (1u << Width) - 1);
- ProgInfo.ComputePGMRSrc3 = SetBits(ProgInfo.ComputePGMRSrc3,
- CreateExpr(InstPrefSize), Field, Shift);
- }
}
static unsigned getRsrcReg(CallingConv::ID CallConv) {
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp
index 63437779121a7..c13c926832f41 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp
@@ -15,6 +15,7 @@
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/KnownBits.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <optional>
@@ -73,6 +74,9 @@ void AMDGPUMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
case AGVK_Occupancy:
OS << "occupancy(";
break;
+ case AGVK_InstPrefSize:
+ OS << "instprefsize(";
+ break;
case AGVK_Lit:
OS << "lit(";
break;
@@ -218,6 +222,30 @@ bool AMDGPUMCExpr::evaluateOccupancy(MCValue &Res,
return true;
}
+bool AMDGPUMCExpr::evaluateInstPrefSize(MCValue &Res,
+ const MCAssembler *Asm) const {
+ auto TryGetMCExprValue = [&](const MCExpr *Arg, uint64_t &ConstantValue) {
+ MCValue MCVal;
+ if (!Arg->evaluateAsRelocatable(MCVal, Asm) || !MCVal.isAbsolute())
+ return false;
+
+ ConstantValue = MCVal.getConstant();
+ return true;
+ };
+
+ assert(Args.size() == 2 &&
+ "AMDGPUMCExpr Argument count incorrect for InstPrefSize");
+ uint64_t CodeSizeInBytes = 0, FieldWidth = 0;
+ if (!TryGetMCExprValue(Args[0], CodeSizeInBytes) ||
+ !TryGetMCExprValue(Args[1], FieldWidth))
+ return false;
+
+ uint64_t CodeSizeInLines = divideCeil(CodeSizeInBytes, (uint64_t)128);
+ uint64_t MaxVal = (1u << FieldWidth) - 1;
+ Res = MCValue::get(std::min(CodeSizeInLines, MaxVal));
+ return true;
+}
+
bool AMDGPUMCExpr::isSymbolUsedInExpression(const MCSymbol *Sym,
const MCExpr *E) {
switch (E->getKind()) {
@@ -263,6 +291,8 @@ bool AMDGPUMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
return evaluateTotalNumVGPR(Res, Asm);
case AGVK_Occupancy:
return evaluateOccupancy(Res, Asm);
+ case AGVK_InstPrefSize:
+ return evaluateInstPrefSize(Res, Asm);
case AGVK_Lit:
case AGVK_Lit64:
return Args[0]->evaluateAsRelocatable(Res, Asm);
@@ -315,6 +345,13 @@ const AMDGPUMCExpr *AMDGPUMCExpr::createTotalNumVGPR(const MCExpr *NumAGPR,
return create(AGVK_TotalNumVGPRs, {NumAGPR, NumVGPR}, Ctx);
}
+const AMDGPUMCExpr *
+AMDGPUMCExpr::createInstPrefSize(const MCExpr *CodeSizeBytes,
+ unsigned FieldWidth, MCContext &Ctx) {
+ return create(AGVK_InstPrefSize,
+ {CodeSizeBytes, MCConstantExpr::create(FieldWidth, Ctx)}, Ctx);
+}
+
const AMDGPUMCExpr *AMDGPUMCExpr::createLit(LitModifier Lit, int64_t Value,
MCContext &Ctx) {
assert(Lit == LitModifier::Lit || Lit == LitModifier::Lit64);
@@ -505,6 +542,7 @@ static void targetOpKnownBitsMapHelper(const MCExpr *Expr, KnownBitsMap &KBM,
case AMDGPUMCExpr::VariantKind::AGVK_TotalNumVGPRs:
case AMDGPUMCExpr::VariantKind::AGVK_AlignTo:
case AMDGPUMCExpr::VariantKind::AGVK_Occupancy:
+ case AMDGPUMCExpr::VariantKind::AGVK_InstPrefSize:
case AMDGPUMCExpr::VariantKind::AGVK_Lit:
case AMDGPUMCExpr::VariantKind::AGVK_Lit64: {
int64_t Val;
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.h b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.h
index 96bd8f4cf3c13..52c984ac450a7 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.h
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.h
@@ -38,6 +38,7 @@ class AMDGPUMCExpr : public MCTargetExpr {
AGVK_TotalNumVGPRs,
AGVK_AlignTo,
AGVK_Occupancy,
+ AGVK_InstPrefSize,
AGVK_Lit,
AGVK_Lit64,
};
@@ -69,6 +70,7 @@ class AMDGPUMCExpr : public MCTargetExpr {
bool evaluateTotalNumVGPR(MCValue &Res, const MCAssembler *Asm) const;
bool evaluateAlignTo(MCValue &Res, const MCAssembler *Asm) const;
bool evaluateOccupancy(MCValue &Res, const MCAssembler *Asm) const;
+ bool evaluateInstPrefSize(MCValue &Res, const MCAssembler *Asm) const;
public:
static const AMDGPUMCExpr *
@@ -97,6 +99,12 @@ class AMDGPUMCExpr : public MCTargetExpr {
return create(VariantKind::AGVK_AlignTo, {Value, Align}, Ctx);
}
+ /// Create an expression for instruction prefetch size computation:
+ /// min(divideCeil(CodeSizeBytes, 128), (1 << FieldWidth) - 1)
+ static const AMDGPUMCExpr *createInstPrefSize(const MCExpr *CodeSizeBytes,
+ unsigned FieldWidth,
+ MCContext &Ctx);
+
static const AMDGPUMCExpr *createLit(LitModifier Lit, int64_t Value,
MCContext &Ctx);
diff --git a/llvm/lib/Target/AMDGPU/SIProgramInfo.cpp b/llvm/lib/Target/AMDGPU/SIProgramInfo.cpp
index a3f261b87e80b..abc2e01ca1df0 100644
--- a/llvm/lib/Target/AMDGPU/SIProgramInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIProgramInfo.cpp
@@ -203,9 +203,8 @@ const MCExpr *SIProgramInfo::getPGMRSrc2(CallingConv::ID CC,
return MCConstantExpr::create(0, Ctx);
}
-uint64_t SIProgramInfo::getFunctionCodeSize(const MachineFunction &MF,
- bool IsLowerBound) {
- if (!IsLowerBound && CodeSizeInBytes.has_value())
+uint64_t SIProgramInfo::getFunctionCodeSize(const MachineFunction &MF) {
+ if (CodeSizeInBytes.has_value())
return *CodeSizeInBytes;
const GCNSubtarget &STM = MF.getSubtarget<GCNSubtarget>();
@@ -214,12 +213,7 @@ uint64_t SIProgramInfo::getFunctionCodeSize(const MachineFunction &MF,
uint64_t CodeSize = 0;
for (const MachineBasicBlock &MBB : MF) {
- // The amount of padding to align code can be both underestimated and
- // overestimated. In case of inline asm used getInstSizeInBytes() will
- // return a maximum size of a single instruction, where the real size may
- // differ. At this point CodeSize may be already off.
- if (!IsLowerBound)
- CodeSize = alignTo(CodeSize, MBB.getAlignment());
+ CodeSize = alignTo(CodeSize, MBB.getAlignment());
for (const MachineInstr &MI : MBB) {
// TODO: CodeSize should account for multiple functions.
@@ -227,11 +221,6 @@ uint64_t SIProgramInfo::getFunctionCodeSize(const MachineFunction &MF,
if (MI.isMetaInstruction())
continue;
- // We cannot properly estimate inline asm size. It can be as small as zero
- // if that is just a comment.
- if (IsLowerBound && MI.isInlineAsm())
- continue;
-
CodeSize += TII->getInstSizeInBytes(MI);
}
}
diff --git a/llvm/lib/Target/AMDGPU/SIProgramInfo.h b/llvm/lib/Target/AMDGPU/SIProgramInfo.h
index 171c4a313a53b..bfd6b669531ea 100644
--- a/llvm/lib/Target/AMDGPU/SIProgramInfo.h
+++ b/llvm/lib/Target/AMDGPU/SIProgramInfo.h
@@ -105,10 +105,7 @@ struct LLVM_EXTERNAL_VISIBILITY SIProgramInfo {
void reset(const MachineFunction &MF);
// Get function code size and cache the value.
- // If \p IsLowerBound is set it returns a minimal code size which is safe
- // to address.
- uint64_t getFunctionCodeSize(const MachineFunction &MF,
- bool IsLowerBound = false);
+ uint64_t getFunctionCodeSize(const MachineFunction &MF);
/// Compute the value of the ComputePGMRsrc1 register.
const MCExpr *getComputePGMRSrc1(const GCNSubtarget &ST,
diff --git a/llvm/test/CodeGen/AMDGPU/inst-prefetch-hint.ll b/llvm/test/CodeGen/AMDGPU/inst-prefetch-hint.ll
index 580167076e1f0..14b9d1444a271 100644
--- a/llvm/test/CodeGen/AMDGPU/inst-prefetch-hint.ll
+++ b/llvm/test/CodeGen/AMDGPU/inst-prefetch-hint.ll
@@ -1,10 +1,20 @@
; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 --amdgpu-memcpy-loop-unroll=100000 < %s | FileCheck --check-prefixes=GCN,GFX11 %s
; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1200 --amdgpu-memcpy-loop-unroll=100000 < %s | FileCheck --check-prefixes=GCN,GFX12 %s
+;; Verify that inst_pref_size resolves to the correct value in the object file.
+;; COMPUTE_PGM_RSRC3 is at offset 0x2C in each 64-byte kernel descriptor.
+;; GFX11 inst_pref_size is bits [9:4], so value N is encoded as N << 4.
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 --amdgpu-memcpy-loop-unroll=100000 -filetype=obj < %s -o %t.o
+; RUN: llvm-objdump -s -j .rodata %t.o | FileCheck --check-prefix=OBJ %s
+
+; The inst_pref_size is computed via MCExpr label subtraction
+; (code_end - func_sym), which resolves at assembly/link time.
+; In text output it appears as a symbolic expression.
+
; GCN-LABEL: .amdhsa_kernel large
-; GFX11: .amdhsa_inst_pref_size 3
+; GFX11: .amdhsa_inst_pref_size {{.*}}instprefsize({{.*}}large, 6){{.*}}
; GFX11: codeLenInByte = 3{{[0-9][0-9]$}}
-; GFX12: .amdhsa_inst_pref_size 4
+; GFX12: .amdhsa_inst_pref_size {{.*}}instprefsize({{.*}}large, 8){{.*}}
; GFX12: codeLenInByte = 4{{[0-9][0-9]$}}
define amdgpu_kernel void @large(ptr addrspace(1) %out, ptr addrspace(1) %in) {
bb:
@@ -13,20 +23,32 @@ bb:
}
; GCN-LABEL: .amdhsa_kernel small
-; GCN: .amdhsa_inst_pref_size 1
-; GCN: codeLenInByte = {{[0-9]$}}
+; GCN: .amdhsa_inst_pref_size {{.*}}instprefsize({{.*}}small, {{[0-9]+}}){{.*}}
+; GCN: codeLenInByte = {{[0-9]+$}}
define amdgpu_kernel void @small() {
bb:
ret void
}
-; Ignore inline asm in size calculation
+; Inline asm is accounted for via MCExpr label subtraction (exact code size).
+; The MCExpr resolves to the correct inst_pref_size at assembly time.
; GCN-LABEL: .amdhsa_kernel inline_asm
-; GCN: .amdhsa_inst_pref_size 1
-; GCN: codeLenInByte = {{[0-9]$}}
+; GCN: .amdhsa_inst_pref_size {{.*}}instprefsize({{.*}}inline_asm, {{[0-9]+}}){{.*}}
+; GCN: codeLenInByte = {{[0-9]+$}}
define amdgpu_kernel void @inline_asm() {
bb:
call void asm sideeffect ".fill 256, 4, 0", ""()
ret void
}
+
+;; Object file checks: verify COMPUTE_PGM_RSRC3 at offset 0x2C in each KD.
+;; COMPUTE_PGM_RSRC3 is the last dword on the 0x0020/0x0060/0x00a0 lines.
+;; GFX11 inst_pref_size is bits [9:4], so value N is encoded as N << 4.
+;;
+;; large: 348 bytes -> pref_size=3 -> 3<<4=0x30
+; OBJ: 0020 {{.*}}30000000
+;; small: 4 bytes -> pref_size=1 -> 1<<4=0x10
+; OBJ: 0060 {{.*}}10000000
+;; inline_asm: 1028 bytes -> pref_size=9 -> 9<<4=0x90
+; OBJ: 00a0 {{.*}}90000000
diff --git a/llvm/test/CodeGen/AMDGPU/inst-prefetch-inline-asm.ll b/llvm/test/CodeGen/AMDGPU/inst-prefetch-inline-asm.ll
new file mode 100644
index 0000000000000..ee344bd320aaf
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/inst-prefetch-inline-asm.ll
@@ -0,0 +1,83 @@
+;; Verify that inline assembly is correctly accounted for in the
+;; inst_pref_size calculation. The inst_pref_size is computed via MCExpr
+;; label subtraction (code_end - func_sym), giving exact code size.
+;; This resolves at assembly time, so we verify via object file checks.
+
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -filetype=obj < %s -o %t.o
+; RUN: llvm-objdump -s -j .rodata %t.o | FileCheck --check-prefix=OBJ %s
+; RUN: llvm-readobj --symbols %t.o | FileCheck --check-prefix=SYM %s
+
+;; --- .fill directive: .fill 256, 4, 0 => 1024 bytes + 4 (s_endpgm) = 1028 ---
+;; pref_size = divideCeil(1028, 128) = 9
+
+; SYM: Name: test_fill
+; SYM-NEXT: Value:
+; SYM-NEXT: Size: 1028
+
+define amdgpu_kernel void @test_fill() {
+ call void asm sideeffect ".fill 256, 4, 0", ""()
+ ret void
+}
+
+;; --- .space directive: .space 1024 => 1024 bytes + 4 = 1028 ---
+;; pref_size = 9
+
+; SYM: Name: test_space
+; SYM-NEXT: Value:
+; SYM-NEXT: Size: 1028
+
+define amdgpu_kernel void @test_space() {
+ call void asm sideeffect ".space 1024", ""()
+ ret void
+}
+
+;; --- Instructions: 32 x s_nop (4 bytes each) = 128 + 4 = 132 ---
+;; pref_size = divideCeil(132, 128) = 2
+
+; SYM: Name: test_instructions
+; SYM-NEXT: Value:
+; SYM-NEXT: Size: 132
+
+define amdgpu_kernel void @test_instructions() {
+ call void asm sideeffect "s_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0", ""()
+ ret void
+}
+
+;; --- Comments emit no bytes: only s_endpgm = 4 bytes ---
+;; pref_size = 1
+
+; SYM: Name: test_comments
+; SYM-NEXT: Value:
+; SYM-NEXT: Size: 4
+
+define amdgpu_kernel void @test_comments() {
+ call void asm sideeffect "; comment 1\0A; comment 2\0A; comment 3", ""()
+ ret void
+}
+
+;; --- Empty inline asm: only s_endpgm = 4 bytes ---
+;; pref_size = 1
+
+; SYM: Name: test_empty_asm
+; SYM-NEXT: Value:
+; SYM-NEXT: Size: 4
+
+define amdgpu_kernel void @test_empty_asm() {
+ call void asm sideeffect "", ""()
+ ret void
+}
+
+;; Object file checks: verify COMPUTE_PGM_RSRC3 at offset 0x2C in each
+;; 64-byte kernel descriptor. GFX11 inst_pref_size is bits [9:4].
+;;
+;; test_fill: 1028 bytes -> pref_size=9 -> 9<<4 = 0x90
+;; test_space: 1028 bytes -> pref_size=9 -> 9<<4 = 0x90
+;; test_instructions: 132 bytes -> pref_size=2 -> 2<<4 = 0x20
+;; test_comments: 4 bytes -> pref_size=1 -> 1<<4 = 0x10
+;; test_empty_asm: 4 bytes -> pref_size=1 -> 1<<4 = 0x10
+
+; OBJ: 0020 {{.*}}90000000
+; OBJ: 0060 {{.*}}90000000
+; OBJ: 00a0 {{.*}}20000000
+; OBJ: 00e0 {{.*}}10000000
+; OBJ: 0120 {{.*}}10000000
>From 4778728d50c6644118c28d4d3e2723b2b2cc57e9 Mon Sep 17 00:00:00 2001
From: Adel Ejjeh <adel.ejjeh at amd.com>
Date: Wed, 15 Apr 2026 15:24:40 -0500
Subject: [PATCH 2/5] Address review feedback: use exact MCExpr CHECK lines,
add GFX12 obj checks, add more detailed comments
Co-Authored-By: Claude Opus 4 (1M context) <noreply at anthropic.com>
---
.../test/CodeGen/AMDGPU/inst-prefetch-hint.ll | 58 +++++++++++--------
.../AMDGPU/inst-prefetch-inline-asm.ll | 40 +++++++------
2 files changed, 56 insertions(+), 42 deletions(-)
diff --git a/llvm/test/CodeGen/AMDGPU/inst-prefetch-hint.ll b/llvm/test/CodeGen/AMDGPU/inst-prefetch-hint.ll
index 14b9d1444a271..2127c69a6f2fd 100644
--- a/llvm/test/CodeGen/AMDGPU/inst-prefetch-hint.ll
+++ b/llvm/test/CodeGen/AMDGPU/inst-prefetch-hint.ll
@@ -3,19 +3,29 @@
;; Verify that inst_pref_size resolves to the correct value in the object file.
;; COMPUTE_PGM_RSRC3 is at offset 0x2C in each 64-byte kernel descriptor.
-;; GFX11 inst_pref_size is bits [9:4], so value N is encoded as N << 4.
-; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 --amdgpu-memcpy-loop-unroll=100000 -filetype=obj < %s -o %t.o
-; RUN: llvm-objdump -s -j .rodata %t.o | FileCheck --check-prefix=OBJ %s
+;; inst_pref_size is bits [9:4] on GFX11 (6-bit) and bits [11:4] on GFX12+ (8-bit).
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 --amdgpu-memcpy-loop-unroll=100000 -filetype=obj < %s -o %t.gfx11.o
+; RUN: llvm-objdump -s -j .rodata %t.gfx11.o | FileCheck --check-prefix=OBJ-GFX11 %s
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1200 --amdgpu-memcpy-loop-unroll=100000 -filetype=obj < %s -o %t.gfx12.o
+; RUN: llvm-objdump -s -j .rodata %t.gfx12.o | FileCheck --check-prefix=OBJ-GFX12 %s
-; The inst_pref_size is computed via MCExpr label subtraction
-; (code_end - func_sym), which resolves at assembly/link time.
-; In text output it appears as a symbolic expression.
+; The inst_pref_size is computed via MCExpr label subtraction, resolved at
+; assembly/link time. In text output it appears as a symbolic expression:
+; ((instprefsize(<code_size>, <field_width>) << 4) & <mask>) >> 4
+; where:
+; <code_size> = .Lfunc_endN - func_sym (exact function code size in bytes)
+; <field_width> = bit width of the inst_pref_size field (6 for GFX11, 8 for GFX12+)
+; instprefsize = min(divideCeil(code_size, 128), (1 << field_width) - 1)
+; << 4, & mask, >> 4 = bit-field insertion/extraction within COMPUTE_PGM_RSRC3
; GCN-LABEL: .amdhsa_kernel large
-; GFX11: .amdhsa_inst_pref_size {{.*}}instprefsize({{.*}}large, 6){{.*}}
-; GFX11: codeLenInByte = 3{{[0-9][0-9]$}}
-; GFX12: .amdhsa_inst_pref_size {{.*}}instprefsize({{.*}}large, 8){{.*}}
-; GFX12: codeLenInByte = 4{{[0-9][0-9]$}}
+; GFX11: .amdhsa_inst_pref_size ((instprefsize(.Lfunc_end0-large, 6)<<4)&1008)>>4
+; GFX11: codeLenInByte = 348
+; GFX12: .amdhsa_inst_pref_size ((instprefsize(.Lfunc_end0-large, 8)<<4)&4080)>>4
+; GFX12: codeLenInByte = 476
+;; Object: kernel descriptor at 0x00, COMPUTE_PGM_RSRC3 at 0x2C: gfx11 pref=3 (0x30), gfx12 pref=4 (0x40)
+; OBJ-GFX11: 0020 {{.*}}30000000
+; OBJ-GFX12: 0020 {{.*}}40000000
define amdgpu_kernel void @large(ptr addrspace(1) %out, ptr addrspace(1) %in) {
bb:
call void @llvm.memcpy.p1.p3.i32(ptr addrspace(1) %out, ptr addrspace(1) %in, i32 256, i1 false)
@@ -23,8 +33,12 @@ bb:
}
; GCN-LABEL: .amdhsa_kernel small
-; GCN: .amdhsa_inst_pref_size {{.*}}instprefsize({{.*}}small, {{[0-9]+}}){{.*}}
-; GCN: codeLenInByte = {{[0-9]+$}}
+; GFX11: .amdhsa_inst_pref_size ((instprefsize(.Lfunc_end1-small, 6)<<4)&1008)>>4
+; GFX12: .amdhsa_inst_pref_size ((instprefsize(.Lfunc_end1-small, 8)<<4)&4080)>>4
+; GCN: codeLenInByte = 4
+;; Object: kernel descriptor at 0x40, COMPUTE_PGM_RSRC3 at 0x6C: pref=1 (0x10) for both
+; OBJ-GFX11: 0060 {{.*}}10000000
+; OBJ-GFX12: 0060 {{.*}}10000000
define amdgpu_kernel void @small() {
bb:
ret void
@@ -34,21 +48,15 @@ bb:
; The MCExpr resolves to the correct inst_pref_size at assembly time.
; GCN-LABEL: .amdhsa_kernel inline_asm
-; GCN: .amdhsa_inst_pref_size {{.*}}instprefsize({{.*}}inline_asm, {{[0-9]+}}){{.*}}
-; GCN: codeLenInByte = {{[0-9]+$}}
+; GFX11: .amdhsa_inst_pref_size ((instprefsize(.Lfunc_end2-inline_asm, 6)<<4)&1008)>>4
+; GFX12: .amdhsa_inst_pref_size ((instprefsize(.Lfunc_end2-inline_asm, 8)<<4)&4080)>>4
+; GCN: codeLenInByte = 24
+;; Object: kernel descriptor at 0x80, COMPUTE_PGM_RSRC3 at 0xAC: pref=9 (0x90) for both
+;; (.fill 256, 4, 0 = 1024 bytes + 4 s_endpgm = 1028 -> divideCeil(1028,128) = 9)
+; OBJ-GFX11: 00a0 {{.*}}90000000
+; OBJ-GFX12: 00a0 {{.*}}90000000
define amdgpu_kernel void @inline_asm() {
bb:
call void asm sideeffect ".fill 256, 4, 0", ""()
ret void
}
-
-;; Object file checks: verify COMPUTE_PGM_RSRC3 at offset 0x2C in each KD.
-;; COMPUTE_PGM_RSRC3 is the last dword on the 0x0020/0x0060/0x00a0 lines.
-;; GFX11 inst_pref_size is bits [9:4], so value N is encoded as N << 4.
-;;
-;; large: 348 bytes -> pref_size=3 -> 3<<4=0x30
-; OBJ: 0020 {{.*}}30000000
-;; small: 4 bytes -> pref_size=1 -> 1<<4=0x10
-; OBJ: 0060 {{.*}}10000000
-;; inline_asm: 1028 bytes -> pref_size=9 -> 9<<4=0x90
-; OBJ: 00a0 {{.*}}90000000
diff --git a/llvm/test/CodeGen/AMDGPU/inst-prefetch-inline-asm.ll b/llvm/test/CodeGen/AMDGPU/inst-prefetch-inline-asm.ll
index ee344bd320aaf..ca0c928cc0ab6 100644
--- a/llvm/test/CodeGen/AMDGPU/inst-prefetch-inline-asm.ll
+++ b/llvm/test/CodeGen/AMDGPU/inst-prefetch-inline-asm.ll
@@ -1,8 +1,9 @@
;; Verify that inline assembly is correctly accounted for in the
;; inst_pref_size calculation. The inst_pref_size is computed via MCExpr
-;; label subtraction (code_end - func_sym), giving exact code size.
-;; This resolves at assembly time, so we verify via object file checks.
+;; label subtraction (.Lfunc_end - func_sym), giving exact code size.
+;; See inst-prefetch-hint.ll for explanation of the instprefsize expression.
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 < %s | FileCheck --check-prefix=ASM %s
; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -filetype=obj < %s -o %t.o
; RUN: llvm-objdump -s -j .rodata %t.o | FileCheck --check-prefix=OBJ %s
; RUN: llvm-readobj --symbols %t.o | FileCheck --check-prefix=SYM %s
@@ -10,9 +11,13 @@
;; --- .fill directive: .fill 256, 4, 0 => 1024 bytes + 4 (s_endpgm) = 1028 ---
;; pref_size = divideCeil(1028, 128) = 9
+; ASM-LABEL: .amdhsa_kernel test_fill
+; ASM: .amdhsa_inst_pref_size ((instprefsize(.Lfunc_end0-test_fill, 6)<<4)&1008)>>4
; SYM: Name: test_fill
; SYM-NEXT: Value:
; SYM-NEXT: Size: 1028
+;; Object: kernel descriptor at 0x00, COMPUTE_PGM_RSRC3 at 0x2C: pref_size=9 -> 9<<4 = 0x90
+; OBJ: 0020 {{.*}}90000000
define amdgpu_kernel void @test_fill() {
call void asm sideeffect ".fill 256, 4, 0", ""()
@@ -22,9 +27,13 @@ define amdgpu_kernel void @test_fill() {
;; --- .space directive: .space 1024 => 1024 bytes + 4 = 1028 ---
;; pref_size = 9
+; ASM-LABEL: .amdhsa_kernel test_space
+; ASM: .amdhsa_inst_pref_size ((instprefsize(.Lfunc_end1-test_space, 6)<<4)&1008)>>4
; SYM: Name: test_space
; SYM-NEXT: Value:
; SYM-NEXT: Size: 1028
+;; Object: kernel descriptor at 0x40, COMPUTE_PGM_RSRC3 at 0x6C: pref_size=9 -> 9<<4 = 0x90
+; OBJ: 0060 {{.*}}90000000
define amdgpu_kernel void @test_space() {
call void asm sideeffect ".space 1024", ""()
@@ -34,9 +43,13 @@ define amdgpu_kernel void @test_space() {
;; --- Instructions: 32 x s_nop (4 bytes each) = 128 + 4 = 132 ---
;; pref_size = divideCeil(132, 128) = 2
+; ASM-LABEL: .amdhsa_kernel test_instructions
+; ASM: .amdhsa_inst_pref_size ((instprefsize(.Lfunc_end2-test_instructions, 6)<<4)&1008)>>4
; SYM: Name: test_instructions
; SYM-NEXT: Value:
; SYM-NEXT: Size: 132
+;; Object: kernel descriptor at 0x80, COMPUTE_PGM_RSRC3 at 0xAC: pref_size=2 -> 2<<4 = 0x20
+; OBJ: 00a0 {{.*}}20000000
define amdgpu_kernel void @test_instructions() {
call void asm sideeffect "s_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0", ""()
@@ -46,9 +59,13 @@ define amdgpu_kernel void @test_instructions() {
;; --- Comments emit no bytes: only s_endpgm = 4 bytes ---
;; pref_size = 1
+; ASM-LABEL: .amdhsa_kernel test_comments
+; ASM: .amdhsa_inst_pref_size ((instprefsize(.Lfunc_end3-test_comments, 6)<<4)&1008)>>4
; SYM: Name: test_comments
; SYM-NEXT: Value:
; SYM-NEXT: Size: 4
+;; Object: kernel descriptor at 0xC0, COMPUTE_PGM_RSRC3 at 0xEC: pref_size=1 -> 1<<4 = 0x10
+; OBJ: 00e0 {{.*}}10000000
define amdgpu_kernel void @test_comments() {
call void asm sideeffect "; comment 1\0A; comment 2\0A; comment 3", ""()
@@ -58,26 +75,15 @@ define amdgpu_kernel void @test_comments() {
;; --- Empty inline asm: only s_endpgm = 4 bytes ---
;; pref_size = 1
+; ASM-LABEL: .amdhsa_kernel test_empty_asm
+; ASM: .amdhsa_inst_pref_size ((instprefsize(.Lfunc_end4-test_empty_asm, 6)<<4)&1008)>>4
; SYM: Name: test_empty_asm
; SYM-NEXT: Value:
; SYM-NEXT: Size: 4
+;; Object: kernel descriptor at 0x100, COMPUTE_PGM_RSRC3 at 0x12C: pref_size=1 -> 1<<4 = 0x10
+; OBJ: 0120 {{.*}}10000000
define amdgpu_kernel void @test_empty_asm() {
call void asm sideeffect "", ""()
ret void
}
-
-;; Object file checks: verify COMPUTE_PGM_RSRC3 at offset 0x2C in each
-;; 64-byte kernel descriptor. GFX11 inst_pref_size is bits [9:4].
-;;
-;; test_fill: 1028 bytes -> pref_size=9 -> 9<<4 = 0x90
-;; test_space: 1028 bytes -> pref_size=9 -> 9<<4 = 0x90
-;; test_instructions: 132 bytes -> pref_size=2 -> 2<<4 = 0x20
-;; test_comments: 4 bytes -> pref_size=1 -> 1<<4 = 0x10
-;; test_empty_asm: 4 bytes -> pref_size=1 -> 1<<4 = 0x10
-
-; OBJ: 0020 {{.*}}90000000
-; OBJ: 0060 {{.*}}90000000
-; OBJ: 00a0 {{.*}}20000000
-; OBJ: 00e0 {{.*}}10000000
-; OBJ: 0120 {{.*}}10000000
>From 721ac70cb36e7dc951fa37a1c5510d5026ac1902 Mon Sep 17 00:00:00 2001
From: Adel Ejjeh <adel.ejjeh at amd.com>
Date: Wed, 15 Apr 2026 16:19:27 -0500
Subject: [PATCH 3/5] Keep inst_pref_size separate from ComputePGMRSrc3 to fix
s-barrier-lowering regression
Co-Authored-By: Claude Opus 4 (1M context) <noreply at anthropic.com>
---
llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp | 33 +++++++++++-------
.../MCTargetDesc/AMDGPUMCKernelDescriptor.h | 8 +++++
.../MCTargetDesc/AMDGPUTargetStreamer.cpp | 29 ++++++++++------
.../test/CodeGen/AMDGPU/inst-prefetch-hint.ll | 34 ++++++++++---------
.../AMDGPU/inst-prefetch-inline-asm.ll | 25 ++++++++------
5 files changed, 80 insertions(+), 49 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
index 60b61247361b9..52720b8c0afbc 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
@@ -254,29 +254,37 @@ void AMDGPUAsmPrinter::endFunction(const MachineFunction *MF) {
const GCNSubtarget &STM = MF->getSubtarget<GCNSubtarget>();
MCContext &Ctx = MF->getContext();
+ AMDGPU::MCKernelDescriptor KD =
+ getAmdhsaKernelDescriptor(*MF, CurrentProgramInfo);
+
// Compute inst_pref_size using MCExpr label subtraction for exact code
- // size. (Lfunc_end - func_sym) gives the exact function code size in bytes.
+ // size. At this point .Lfunc_end has been emitted (by the base AsmPrinter)
+ // right after the function code, so (Lfunc_end - func_sym) gives the
+ // exact function code size in bytes.
+ // We store it as a separate KD field rather than OR'ing into
+ // compute_pgm_rsrc3, because the label subtraction MCExpr is unresolvable
+ // in text mode and would prevent printing of other fields (e.g.
+ // named_barrier_count) that share the same register.
if (isGFX11Plus(STM)) {
const MCExpr *CodeSizeExpr = MCBinaryExpr::createSub(
MCSymbolRefExpr::create(getFunctionEnd(), OutContext),
MCSymbolRefExpr::create(CurrentFnSym, OutContext), OutContext);
- uint32_t Field, Shift, Width;
+ uint32_t Width;
if (isGFX11(STM)) {
- Field = amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE;
- Shift = amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE_SHIFT;
+ KD.inst_pref_size_mask = amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE;
+ KD.inst_pref_size_shift =
+ amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE_SHIFT;
Width = amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE_WIDTH;
} else {
- Field = amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE;
- Shift = amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE_SHIFT;
+ KD.inst_pref_size_mask =
+ amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE;
+ KD.inst_pref_size_shift =
+ amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE_SHIFT;
Width = amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE_WIDTH;
}
- const MCExpr *InstPrefSizeExpr =
+ KD.inst_pref_size =
AMDGPUMCExpr::createInstPrefSize(CodeSizeExpr, Width, Ctx);
-
- CurrentProgramInfo.ComputePGMRSrc3 =
- setBits(CurrentProgramInfo.ComputePGMRSrc3, InstPrefSizeExpr, Field,
- Shift, Ctx);
}
auto &Streamer = getTargetStreamer()->getStreamer();
@@ -295,8 +303,7 @@ void AMDGPUAsmPrinter::endFunction(const MachineFunction *MF) {
SmallString<128> KernelName;
getNameWithPrefix(KernelName, &MF->getFunction());
getTargetStreamer()->EmitAmdhsaKernelDescriptor(
- STM, KernelName, getAmdhsaKernelDescriptor(*MF, CurrentProgramInfo),
- CurrentProgramInfo.NumVGPRsForWavesPerEU,
+ STM, KernelName, KD, CurrentProgramInfo.NumVGPRsForWavesPerEU,
MCBinaryExpr::createSub(
CurrentProgramInfo.NumSGPRsForWavesPerEU,
AMDGPUMCExpr::createExtraSGPRs(
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCKernelDescriptor.h b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCKernelDescriptor.h
index 26958ac8b9ee1..d8bd41cdff5ce 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCKernelDescriptor.h
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCKernelDescriptor.h
@@ -34,6 +34,14 @@ struct MCKernelDescriptor {
const MCExpr *kernel_code_properties = nullptr;
const MCExpr *kernarg_preload = nullptr;
+ /// Instruction prefetch size, kept separate from compute_pgm_rsrc3 to avoid
+ /// contaminating the register MCExpr with an unresolvable label subtraction
+ /// (which would prevent text-mode printing of other fields in the register).
+ /// The ELF streamer OR's this into compute_pgm_rsrc3 when emitting bytes.
+ const MCExpr *inst_pref_size = nullptr;
+ uint32_t inst_pref_size_shift = 0;
+ uint32_t inst_pref_size_mask = 0;
+
static MCKernelDescriptor
getDefaultAmdhsaKernelDescriptor(const MCSubtargetInfo *STI, MCContext &Ctx);
// MCExpr for:
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
index d276bab0ff3be..712218b36203f 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
@@ -607,17 +607,17 @@ void AMDGPUTargetAsmStreamer::EmitAmdhsaKernelDescriptor(
amdhsa::COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT,
".amdhsa_shared_vgpr_count");
}
- if (IVersion.Major == 11) {
- PrintField(KD.compute_pgm_rsrc3,
- amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE_SHIFT,
- amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE,
- ".amdhsa_inst_pref_size");
+ if (IVersion.Major >= 11) {
+ OS << "\t\t.amdhsa_inst_pref_size ";
+ if (KD.inst_pref_size) {
+ const MCExpr *New = foldAMDGPUMCExpr(KD.inst_pref_size, getContext());
+ printAMDGPUMCExpr(New, OS, MAI);
+ } else {
+ OS << 0;
+ }
+ OS << '\n';
}
if (IVersion.Major >= 12) {
- PrintField(KD.compute_pgm_rsrc3,
- amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE_SHIFT,
- amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE,
- ".amdhsa_inst_pref_size");
PrintField(KD.compute_pgm_rsrc1,
amdhsa::COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN_SHIFT,
amdhsa::COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN,
@@ -1051,7 +1051,16 @@ void AMDGPUTargetELFStreamer::EmitAmdhsaKernelDescriptor(
sizeof(amdhsa::kernel_descriptor_t::kernel_code_entry_byte_offset));
for (uint32_t i = 0; i < sizeof(amdhsa::kernel_descriptor_t::reserved1); ++i)
Streamer.emitInt8(0u);
- Streamer.emitValue(KernelDescriptor.compute_pgm_rsrc3,
+ // OR inst_pref_size into compute_pgm_rsrc3 for the binary encoding.
+ // This is kept separate in the KD struct to avoid making the MCExpr
+ // unresolvable in text mode (see AMDGPUAsmPrinter::endFunction).
+ const MCExpr *Rsrc3 = KernelDescriptor.compute_pgm_rsrc3;
+ if (KernelDescriptor.inst_pref_size) {
+ MCKernelDescriptor::bits_set(Rsrc3, KernelDescriptor.inst_pref_size,
+ KernelDescriptor.inst_pref_size_shift,
+ KernelDescriptor.inst_pref_size_mask, Context);
+ }
+ Streamer.emitValue(Rsrc3,
sizeof(amdhsa::kernel_descriptor_t::compute_pgm_rsrc3));
Streamer.emitValue(KernelDescriptor.compute_pgm_rsrc1,
sizeof(amdhsa::kernel_descriptor_t::compute_pgm_rsrc1));
diff --git a/llvm/test/CodeGen/AMDGPU/inst-prefetch-hint.ll b/llvm/test/CodeGen/AMDGPU/inst-prefetch-hint.ll
index 2127c69a6f2fd..99adbce0d37dc 100644
--- a/llvm/test/CodeGen/AMDGPU/inst-prefetch-hint.ll
+++ b/llvm/test/CodeGen/AMDGPU/inst-prefetch-hint.ll
@@ -10,20 +10,20 @@
; RUN: llvm-objdump -s -j .rodata %t.gfx12.o | FileCheck --check-prefix=OBJ-GFX12 %s
; The inst_pref_size is computed via MCExpr label subtraction, resolved at
-; assembly/link time. In text output it appears as a symbolic expression:
-; ((instprefsize(<code_size>, <field_width>) << 4) & <mask>) >> 4
+; assembly/link time. In text output it appears as:
+; instprefsize(<code_size>, <field_width>)
; where:
; <code_size> = .Lfunc_endN - func_sym (exact function code size in bytes)
; <field_width> = bit width of the inst_pref_size field (6 for GFX11, 8 for GFX12+)
; instprefsize = min(divideCeil(code_size, 128), (1 << field_width) - 1)
-; << 4, & mask, >> 4 = bit-field insertion/extraction within COMPUTE_PGM_RSRC3
; GCN-LABEL: .amdhsa_kernel large
-; GFX11: .amdhsa_inst_pref_size ((instprefsize(.Lfunc_end0-large, 6)<<4)&1008)>>4
-; GFX11: codeLenInByte = 348
-; GFX12: .amdhsa_inst_pref_size ((instprefsize(.Lfunc_end0-large, 8)<<4)&4080)>>4
-; GFX12: codeLenInByte = 476
-;; Object: kernel descriptor at 0x00, COMPUTE_PGM_RSRC3 at 0x2C: gfx11 pref=3 (0x30), gfx12 pref=4 (0x40)
+; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end0-large, 6)
+; GFX11: codeLenInByte = {{[0-9]+}}
+; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end0-large, 8)
+; GFX12: codeLenInByte = {{[0-9]+}}
+;; Object: kernel descriptor at 0x00, COMPUTE_PGM_RSRC3 at 0x2C:
+;; gfx11 pref=3 (0x30), gfx12 pref=4 (0x40)
; OBJ-GFX11: 0020 {{.*}}30000000
; OBJ-GFX12: 0020 {{.*}}40000000
define amdgpu_kernel void @large(ptr addrspace(1) %out, ptr addrspace(1) %in) {
@@ -33,10 +33,11 @@ bb:
}
; GCN-LABEL: .amdhsa_kernel small
-; GFX11: .amdhsa_inst_pref_size ((instprefsize(.Lfunc_end1-small, 6)<<4)&1008)>>4
-; GFX12: .amdhsa_inst_pref_size ((instprefsize(.Lfunc_end1-small, 8)<<4)&4080)>>4
-; GCN: codeLenInByte = 4
-;; Object: kernel descriptor at 0x40, COMPUTE_PGM_RSRC3 at 0x6C: pref=1 (0x10) for both
+; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end1-small, 6)
+; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end1-small, 8)
+; GCN: codeLenInByte = {{[0-9]+}}
+;; Object: kernel descriptor at 0x40, COMPUTE_PGM_RSRC3 at 0x6C:
+;; pref=1 (0x10) for both
; OBJ-GFX11: 0060 {{.*}}10000000
; OBJ-GFX12: 0060 {{.*}}10000000
define amdgpu_kernel void @small() {
@@ -48,10 +49,11 @@ bb:
; The MCExpr resolves to the correct inst_pref_size at assembly time.
; GCN-LABEL: .amdhsa_kernel inline_asm
-; GFX11: .amdhsa_inst_pref_size ((instprefsize(.Lfunc_end2-inline_asm, 6)<<4)&1008)>>4
-; GFX12: .amdhsa_inst_pref_size ((instprefsize(.Lfunc_end2-inline_asm, 8)<<4)&4080)>>4
-; GCN: codeLenInByte = 24
-;; Object: kernel descriptor at 0x80, COMPUTE_PGM_RSRC3 at 0xAC: pref=9 (0x90) for both
+; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end2-inline_asm, 6)
+; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end2-inline_asm, 8)
+; GCN: codeLenInByte = {{[0-9]+}}
+;; Object: kernel descriptor at 0x80, COMPUTE_PGM_RSRC3 at 0xAC:
+;; pref=9 (0x90) for both
;; (.fill 256, 4, 0 = 1024 bytes + 4 s_endpgm = 1028 -> divideCeil(1028,128) = 9)
; OBJ-GFX11: 00a0 {{.*}}90000000
; OBJ-GFX12: 00a0 {{.*}}90000000
diff --git a/llvm/test/CodeGen/AMDGPU/inst-prefetch-inline-asm.ll b/llvm/test/CodeGen/AMDGPU/inst-prefetch-inline-asm.ll
index ca0c928cc0ab6..2e3ad07c89f3d 100644
--- a/llvm/test/CodeGen/AMDGPU/inst-prefetch-inline-asm.ll
+++ b/llvm/test/CodeGen/AMDGPU/inst-prefetch-inline-asm.ll
@@ -12,11 +12,12 @@
;; pref_size = divideCeil(1028, 128) = 9
; ASM-LABEL: .amdhsa_kernel test_fill
-; ASM: .amdhsa_inst_pref_size ((instprefsize(.Lfunc_end0-test_fill, 6)<<4)&1008)>>4
+; ASM: .amdhsa_inst_pref_size instprefsize(.Lfunc_end0-test_fill, 6)
; SYM: Name: test_fill
; SYM-NEXT: Value:
; SYM-NEXT: Size: 1028
-;; Object: kernel descriptor at 0x00, COMPUTE_PGM_RSRC3 at 0x2C: pref_size=9 -> 9<<4 = 0x90
+;; Object: kernel descriptor at 0x00, COMPUTE_PGM_RSRC3 at 0x2C:
+;; pref_size=9 -> 9<<4 = 0x90
; OBJ: 0020 {{.*}}90000000
define amdgpu_kernel void @test_fill() {
@@ -28,11 +29,12 @@ define amdgpu_kernel void @test_fill() {
;; pref_size = 9
; ASM-LABEL: .amdhsa_kernel test_space
-; ASM: .amdhsa_inst_pref_size ((instprefsize(.Lfunc_end1-test_space, 6)<<4)&1008)>>4
+; ASM: .amdhsa_inst_pref_size instprefsize(.Lfunc_end1-test_space, 6)
; SYM: Name: test_space
; SYM-NEXT: Value:
; SYM-NEXT: Size: 1028
-;; Object: kernel descriptor at 0x40, COMPUTE_PGM_RSRC3 at 0x6C: pref_size=9 -> 9<<4 = 0x90
+;; Object: kernel descriptor at 0x40, COMPUTE_PGM_RSRC3 at 0x6C:
+;; pref_size=9 -> 9<<4 = 0x90
; OBJ: 0060 {{.*}}90000000
define amdgpu_kernel void @test_space() {
@@ -44,11 +46,12 @@ define amdgpu_kernel void @test_space() {
;; pref_size = divideCeil(132, 128) = 2
; ASM-LABEL: .amdhsa_kernel test_instructions
-; ASM: .amdhsa_inst_pref_size ((instprefsize(.Lfunc_end2-test_instructions, 6)<<4)&1008)>>4
+; ASM: .amdhsa_inst_pref_size instprefsize(.Lfunc_end2-test_instructions, 6)
; SYM: Name: test_instructions
; SYM-NEXT: Value:
; SYM-NEXT: Size: 132
-;; Object: kernel descriptor at 0x80, COMPUTE_PGM_RSRC3 at 0xAC: pref_size=2 -> 2<<4 = 0x20
+;; Object: kernel descriptor at 0x80, COMPUTE_PGM_RSRC3 at 0xAC:
+;; pref_size=2 -> 2<<4 = 0x20
; OBJ: 00a0 {{.*}}20000000
define amdgpu_kernel void @test_instructions() {
@@ -60,11 +63,12 @@ define amdgpu_kernel void @test_instructions() {
;; pref_size = 1
; ASM-LABEL: .amdhsa_kernel test_comments
-; ASM: .amdhsa_inst_pref_size ((instprefsize(.Lfunc_end3-test_comments, 6)<<4)&1008)>>4
+; ASM: .amdhsa_inst_pref_size instprefsize(.Lfunc_end3-test_comments, 6)
; SYM: Name: test_comments
; SYM-NEXT: Value:
; SYM-NEXT: Size: 4
-;; Object: kernel descriptor at 0xC0, COMPUTE_PGM_RSRC3 at 0xEC: pref_size=1 -> 1<<4 = 0x10
+;; Object: kernel descriptor at 0xC0, COMPUTE_PGM_RSRC3 at 0xEC:
+;; pref_size=1 -> 1<<4 = 0x10
; OBJ: 00e0 {{.*}}10000000
define amdgpu_kernel void @test_comments() {
@@ -76,11 +80,12 @@ define amdgpu_kernel void @test_comments() {
;; pref_size = 1
; ASM-LABEL: .amdhsa_kernel test_empty_asm
-; ASM: .amdhsa_inst_pref_size ((instprefsize(.Lfunc_end4-test_empty_asm, 6)<<4)&1008)>>4
+; ASM: .amdhsa_inst_pref_size instprefsize(.Lfunc_end4-test_empty_asm, 6)
; SYM: Name: test_empty_asm
; SYM-NEXT: Value:
; SYM-NEXT: Size: 4
-;; Object: kernel descriptor at 0x100, COMPUTE_PGM_RSRC3 at 0x12C: pref_size=1 -> 1<<4 = 0x10
+;; Object: kernel descriptor at 0x100, COMPUTE_PGM_RSRC3 at 0x12C:
+;; pref_size=1 -> 1<<4 = 0x10
; OBJ: 0120 {{.*}}10000000
define amdgpu_kernel void @test_empty_asm() {
>From 26d7ba1da932869d40ca33a83275c17cabdad9d8 Mon Sep 17 00:00:00 2001
From: Adel Ejjeh <adel.ejjeh at amd.com>
Date: Wed, 15 Apr 2026 16:45:25 -0500
Subject: [PATCH 4/5] Fix MC assembler round-trip: fall back to PrintField when
inst_pref_size is not set
Co-Authored-By: Claude Opus 4 (1M context) <noreply at anthropic.com>
---
.../MCTargetDesc/AMDGPUTargetStreamer.cpp | 24 +++-
.../AMDGPU/inst-prefetch-inline-asm.ll | 128 +++++++++++++-----
2 files changed, 114 insertions(+), 38 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
index 712218b36203f..aa16a5dac8fe8 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
@@ -607,17 +607,33 @@ void AMDGPUTargetAsmStreamer::EmitAmdhsaKernelDescriptor(
amdhsa::COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT,
".amdhsa_shared_vgpr_count");
}
- if (IVersion.Major >= 11) {
- OS << "\t\t.amdhsa_inst_pref_size ";
+ if (IVersion.Major == 11) {
if (KD.inst_pref_size) {
+ // CodeGen path: print the MCExpr directly (label subtraction).
+ OS << "\t\t.amdhsa_inst_pref_size ";
const MCExpr *New = foldAMDGPUMCExpr(KD.inst_pref_size, getContext());
printAMDGPUMCExpr(New, OS, MAI);
+ OS << '\n';
} else {
- OS << 0;
+ // MC assembler path: extract from compute_pgm_rsrc3.
+ PrintField(KD.compute_pgm_rsrc3,
+ amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE_SHIFT,
+ amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE,
+ ".amdhsa_inst_pref_size");
}
- OS << '\n';
}
if (IVersion.Major >= 12) {
+ if (KD.inst_pref_size) {
+ OS << "\t\t.amdhsa_inst_pref_size ";
+ const MCExpr *New = foldAMDGPUMCExpr(KD.inst_pref_size, getContext());
+ printAMDGPUMCExpr(New, OS, MAI);
+ OS << '\n';
+ } else {
+ PrintField(KD.compute_pgm_rsrc3,
+ amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE_SHIFT,
+ amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE,
+ ".amdhsa_inst_pref_size");
+ }
PrintField(KD.compute_pgm_rsrc1,
amdhsa::COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN_SHIFT,
amdhsa::COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN,
diff --git a/llvm/test/CodeGen/AMDGPU/inst-prefetch-inline-asm.ll b/llvm/test/CodeGen/AMDGPU/inst-prefetch-inline-asm.ll
index 2e3ad07c89f3d..1dff24e6c234f 100644
--- a/llvm/test/CodeGen/AMDGPU/inst-prefetch-inline-asm.ll
+++ b/llvm/test/CodeGen/AMDGPU/inst-prefetch-inline-asm.ll
@@ -3,22 +3,24 @@
;; label subtraction (.Lfunc_end - func_sym), giving exact code size.
;; See inst-prefetch-hint.ll for explanation of the instprefsize expression.
-; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 < %s | FileCheck --check-prefix=ASM %s
-; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -filetype=obj < %s -o %t.o
-; RUN: llvm-objdump -s -j .rodata %t.o | FileCheck --check-prefix=OBJ %s
-; RUN: llvm-readobj --symbols %t.o | FileCheck --check-prefix=SYM %s
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 < %s | FileCheck --check-prefix=GFX11 %s
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1200 < %s | FileCheck --check-prefix=GFX12 %s
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -filetype=obj < %s -o %t.gfx11.o
+; RUN: llvm-objdump -s -j .rodata %t.gfx11.o | FileCheck --check-prefix=OBJ-GFX11 %s
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1200 -filetype=obj < %s -o %t.gfx12.o
+; RUN: llvm-objdump -s -j .rodata %t.gfx12.o | FileCheck --check-prefix=OBJ-GFX12 %s
;; --- .fill directive: .fill 256, 4, 0 => 1024 bytes + 4 (s_endpgm) = 1028 ---
;; pref_size = divideCeil(1028, 128) = 9
-; ASM-LABEL: .amdhsa_kernel test_fill
-; ASM: .amdhsa_inst_pref_size instprefsize(.Lfunc_end0-test_fill, 6)
-; SYM: Name: test_fill
-; SYM-NEXT: Value:
-; SYM-NEXT: Size: 1028
+; GFX11-LABEL: .amdhsa_kernel test_fill
+; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end0-test_fill, 6)
+; GFX12-LABEL: .amdhsa_kernel test_fill
+; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end0-test_fill, 8)
;; Object: kernel descriptor at 0x00, COMPUTE_PGM_RSRC3 at 0x2C:
;; pref_size=9 -> 9<<4 = 0x90
-; OBJ: 0020 {{.*}}90000000
+; OBJ-GFX11: 0020 {{.*}}90000000
+; OBJ-GFX12: 0020 {{.*}}90000000
define amdgpu_kernel void @test_fill() {
call void asm sideeffect ".fill 256, 4, 0", ""()
@@ -28,14 +30,14 @@ define amdgpu_kernel void @test_fill() {
;; --- .space directive: .space 1024 => 1024 bytes + 4 = 1028 ---
;; pref_size = 9
-; ASM-LABEL: .amdhsa_kernel test_space
-; ASM: .amdhsa_inst_pref_size instprefsize(.Lfunc_end1-test_space, 6)
-; SYM: Name: test_space
-; SYM-NEXT: Value:
-; SYM-NEXT: Size: 1028
+; GFX11-LABEL: .amdhsa_kernel test_space
+; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end1-test_space, 6)
+; GFX12-LABEL: .amdhsa_kernel test_space
+; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end1-test_space, 8)
;; Object: kernel descriptor at 0x40, COMPUTE_PGM_RSRC3 at 0x6C:
;; pref_size=9 -> 9<<4 = 0x90
-; OBJ: 0060 {{.*}}90000000
+; OBJ-GFX11: 0060 {{.*}}90000000
+; OBJ-GFX12: 0060 {{.*}}90000000
define amdgpu_kernel void @test_space() {
call void asm sideeffect ".space 1024", ""()
@@ -45,14 +47,14 @@ define amdgpu_kernel void @test_space() {
;; --- Instructions: 32 x s_nop (4 bytes each) = 128 + 4 = 132 ---
;; pref_size = divideCeil(132, 128) = 2
-; ASM-LABEL: .amdhsa_kernel test_instructions
-; ASM: .amdhsa_inst_pref_size instprefsize(.Lfunc_end2-test_instructions, 6)
-; SYM: Name: test_instructions
-; SYM-NEXT: Value:
-; SYM-NEXT: Size: 132
+; GFX11-LABEL: .amdhsa_kernel test_instructions
+; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end2-test_instructions, 6)
+; GFX12-LABEL: .amdhsa_kernel test_instructions
+; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end2-test_instructions, 8)
;; Object: kernel descriptor at 0x80, COMPUTE_PGM_RSRC3 at 0xAC:
;; pref_size=2 -> 2<<4 = 0x20
-; OBJ: 00a0 {{.*}}20000000
+; OBJ-GFX11: 00a0 {{.*}}20000000
+; OBJ-GFX12: 00a0 {{.*}}20000000
define amdgpu_kernel void @test_instructions() {
call void asm sideeffect "s_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0\0As_nop 0", ""()
@@ -62,14 +64,14 @@ define amdgpu_kernel void @test_instructions() {
;; --- Comments emit no bytes: only s_endpgm = 4 bytes ---
;; pref_size = 1
-; ASM-LABEL: .amdhsa_kernel test_comments
-; ASM: .amdhsa_inst_pref_size instprefsize(.Lfunc_end3-test_comments, 6)
-; SYM: Name: test_comments
-; SYM-NEXT: Value:
-; SYM-NEXT: Size: 4
+; GFX11-LABEL: .amdhsa_kernel test_comments
+; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end3-test_comments, 6)
+; GFX12-LABEL: .amdhsa_kernel test_comments
+; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end3-test_comments, 8)
;; Object: kernel descriptor at 0xC0, COMPUTE_PGM_RSRC3 at 0xEC:
;; pref_size=1 -> 1<<4 = 0x10
-; OBJ: 00e0 {{.*}}10000000
+; OBJ-GFX11: 00e0 {{.*}}10000000
+; OBJ-GFX12: 00e0 {{.*}}10000000
define amdgpu_kernel void @test_comments() {
call void asm sideeffect "; comment 1\0A; comment 2\0A; comment 3", ""()
@@ -79,16 +81,74 @@ define amdgpu_kernel void @test_comments() {
;; --- Empty inline asm: only s_endpgm = 4 bytes ---
;; pref_size = 1
-; ASM-LABEL: .amdhsa_kernel test_empty_asm
-; ASM: .amdhsa_inst_pref_size instprefsize(.Lfunc_end4-test_empty_asm, 6)
-; SYM: Name: test_empty_asm
-; SYM-NEXT: Value:
-; SYM-NEXT: Size: 4
+; GFX11-LABEL: .amdhsa_kernel test_empty_asm
+; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end4-test_empty_asm, 6)
+; GFX12-LABEL: .amdhsa_kernel test_empty_asm
+; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end4-test_empty_asm, 8)
;; Object: kernel descriptor at 0x100, COMPUTE_PGM_RSRC3 at 0x12C:
;; pref_size=1 -> 1<<4 = 0x10
-; OBJ: 0120 {{.*}}10000000
+; OBJ-GFX11: 0120 {{.*}}10000000
+; OBJ-GFX12: 0120 {{.*}}10000000
define amdgpu_kernel void @test_empty_asm() {
call void asm sideeffect "", ""()
ret void
}
+
+;; --- Multiple inline asm blocks: .fill (512) + .space (512) + s_endpgm (4) = 1028 ---
+;; pref_size = divideCeil(1028, 128) = 9
+
+; GFX11-LABEL: .amdhsa_kernel test_multiple_asm
+; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end5-test_multiple_asm, 6)
+; GFX12-LABEL: .amdhsa_kernel test_multiple_asm
+; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end5-test_multiple_asm, 8)
+;; Object: kernel descriptor at 0x140, COMPUTE_PGM_RSRC3 at 0x16C:
+;; pref_size=9 -> 9<<4 = 0x90
+; OBJ-GFX11: 0160 {{.*}}90000000
+; OBJ-GFX12: 0160 {{.*}}90000000
+
+define amdgpu_kernel void @test_multiple_asm() {
+ call void asm sideeffect ".fill 128, 4, 0", ""()
+ call void asm sideeffect ".space 512", ""()
+ ret void
+}
+
+;; --- Large function that exceeds GFX11 6-bit field max (63) ---
+;; .fill 2048, 4, 0 = 8192 bytes + 4 = 8196 bytes
+;; divideCeil(8196, 128) = 65, but GFX11 max = (1<<6)-1 = 63
+;; pref_size should clamp to 63
+
+; GFX11-LABEL: .amdhsa_kernel test_clamping
+; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end6-test_clamping, 6)
+; GFX12-LABEL: .amdhsa_kernel test_clamping
+; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end6-test_clamping, 8)
+;; Object: kernel descriptor at 0x180, COMPUTE_PGM_RSRC3 at 0x1AC:
+;; gfx11: clamped to 63 -> 63<<4 = 0x3F0
+;; gfx12: no clamping, 65 -> 65<<4 = 0x410
+; OBJ-GFX11: 01a0 {{.*}}f0030000
+; OBJ-GFX12: 01a0 {{.*}}10040000
+
+define amdgpu_kernel void @test_clamping() {
+ call void asm sideeffect ".fill 2048, 4, 0", ""()
+ ret void
+}
+
+;; --- Large function that exceeds both GFX11 and GFX12 field max ---
+;; .fill 8192, 4, 0 = 32768 bytes + 4 = 32772 bytes
+;; divideCeil(32772, 128) = 257
+;; GFX11 max = 63, GFX12 max = 255 -> both clamp
+
+; GFX11-LABEL: .amdhsa_kernel test_clamping_both
+; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end7-test_clamping_both, 6)
+; GFX12-LABEL: .amdhsa_kernel test_clamping_both
+; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end7-test_clamping_both, 8)
+;; Object: kernel descriptor at 0x1C0, COMPUTE_PGM_RSRC3 at 0x1EC:
+;; gfx11: clamped to 63 -> 63<<4 = 0x3F0
+;; gfx12: clamped to 255 -> 255<<4 = 0xFF0
+; OBJ-GFX11: 01e0 {{.*}}f0030000
+; OBJ-GFX12: 01e0 {{.*}}f00f0000
+
+define amdgpu_kernel void @test_clamping_both() {
+ call void asm sideeffect ".fill 8192, 4, 0", ""()
+ ret void
+}
>From e0bca7a6adc96396b48a2a4634f48e88f10f1c22 Mon Sep 17 00:00:00 2001
From: Adel Ejjeh <adel.ejjeh at amd.com>
Date: Thu, 16 Apr 2026 11:33:17 -0500
Subject: [PATCH 5/5] Refactor inst prefetch size checks
---
llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp | 22 ++++---------
llvm/lib/Target/AMDGPU/GCNSubtarget.h | 18 +++++++++++
.../AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp | 16 ++++++----
.../Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.h | 3 +-
.../test/CodeGen/AMDGPU/inst-prefetch-hint.ll | 21 ++++++------
.../AMDGPU/inst-prefetch-inline-asm.ll | 32 +++++++++----------
6 files changed, 63 insertions(+), 49 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
index 52720b8c0afbc..38ff778622fc2 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
@@ -265,26 +265,16 @@ void AMDGPUAsmPrinter::endFunction(const MachineFunction *MF) {
// compute_pgm_rsrc3, because the label subtraction MCExpr is unresolvable
// in text mode and would prevent printing of other fields (e.g.
// named_barrier_count) that share the same register.
- if (isGFX11Plus(STM)) {
+ if (STM.hasInstPrefSize()) {
const MCExpr *CodeSizeExpr = MCBinaryExpr::createSub(
MCSymbolRefExpr::create(getFunctionEnd(), OutContext),
MCSymbolRefExpr::create(CurrentFnSym, OutContext), OutContext);
- uint32_t Width;
- if (isGFX11(STM)) {
- KD.inst_pref_size_mask = amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE;
- KD.inst_pref_size_shift =
- amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE_SHIFT;
- Width = amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE_WIDTH;
- } else {
- KD.inst_pref_size_mask =
- amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE;
- KD.inst_pref_size_shift =
- amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE_SHIFT;
- Width = amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE_WIDTH;
- }
- KD.inst_pref_size =
- AMDGPUMCExpr::createInstPrefSize(CodeSizeExpr, Width, Ctx);
+ uint32_t Width, CacheLineSize;
+ STM.getInstPrefSizeArgs(KD.inst_pref_size_mask, KD.inst_pref_size_shift,
+ Width, CacheLineSize);
+ KD.inst_pref_size = AMDGPUMCExpr::createInstPrefSize(CodeSizeExpr, Width,
+ CacheLineSize, Ctx);
}
auto &Streamer = getTargetStreamer()->getStreamer();
diff --git a/llvm/lib/Target/AMDGPU/GCNSubtarget.h b/llvm/lib/Target/AMDGPU/GCNSubtarget.h
index d4af5d2451be7..4e6069ab4da61 100644
--- a/llvm/lib/Target/AMDGPU/GCNSubtarget.h
+++ b/llvm/lib/Target/AMDGPU/GCNSubtarget.h
@@ -21,6 +21,7 @@
#include "SIISelLowering.h"
#include "SIInstrInfo.h"
#include "Utils/AMDGPUBaseInfo.h"
+#include "llvm/Support/AMDHSAKernelDescriptor.h"
#include "llvm/Support/ErrorHandling.h"
#define GET_SUBTARGETINFO_HEADER
@@ -420,6 +421,23 @@ class GCNSubtarget final : public AMDGPUGenSubtargetInfo,
bool hasPrefetch() const { return HasGFX12Insts; }
+ bool hasInstPrefSize() const { return isGFX11Plus(); }
+
+ void getInstPrefSizeArgs(uint32_t &Mask, uint32_t &Shift, uint32_t &Width,
+ uint32_t &CacheLineSize) const {
+ assert(isGFX11Plus());
+ CacheLineSize = getInstCacheLineSize();
+ if (getGeneration() == GFX11) {
+ Mask = amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE;
+ Shift = amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE_SHIFT;
+ Width = amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE_WIDTH;
+ } else {
+ Mask = amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE;
+ Shift = amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE_SHIFT;
+ Width = amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE_WIDTH;
+ }
+ }
+
// Has s_cmpk_* instructions.
bool hasSCmpK() const { return getGeneration() < GFX12; }
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp
index c13c926832f41..00e778c253957 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp
@@ -233,14 +233,15 @@ bool AMDGPUMCExpr::evaluateInstPrefSize(MCValue &Res,
return true;
};
- assert(Args.size() == 2 &&
+ assert(Args.size() == 3 &&
"AMDGPUMCExpr Argument count incorrect for InstPrefSize");
- uint64_t CodeSizeInBytes = 0, FieldWidth = 0;
+ uint64_t CodeSizeInBytes = 0, FieldWidth = 0, CacheLineSize = 0;
if (!TryGetMCExprValue(Args[0], CodeSizeInBytes) ||
- !TryGetMCExprValue(Args[1], FieldWidth))
+ !TryGetMCExprValue(Args[1], FieldWidth) ||
+ !TryGetMCExprValue(Args[2], CacheLineSize))
return false;
- uint64_t CodeSizeInLines = divideCeil(CodeSizeInBytes, (uint64_t)128);
+ uint64_t CodeSizeInLines = divideCeil(CodeSizeInBytes, CacheLineSize);
uint64_t MaxVal = (1u << FieldWidth) - 1;
Res = MCValue::get(std::min(CodeSizeInLines, MaxVal));
return true;
@@ -347,9 +348,12 @@ const AMDGPUMCExpr *AMDGPUMCExpr::createTotalNumVGPR(const MCExpr *NumAGPR,
const AMDGPUMCExpr *
AMDGPUMCExpr::createInstPrefSize(const MCExpr *CodeSizeBytes,
- unsigned FieldWidth, MCContext &Ctx) {
+ unsigned FieldWidth, unsigned CacheLineSize,
+ MCContext &Ctx) {
return create(AGVK_InstPrefSize,
- {CodeSizeBytes, MCConstantExpr::create(FieldWidth, Ctx)}, Ctx);
+ {CodeSizeBytes, MCConstantExpr::create(FieldWidth, Ctx),
+ MCConstantExpr::create(CacheLineSize, Ctx)},
+ Ctx);
}
const AMDGPUMCExpr *AMDGPUMCExpr::createLit(LitModifier Lit, int64_t Value,
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.h b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.h
index 52c984ac450a7..67a4074df4292 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.h
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.h
@@ -100,9 +100,10 @@ class AMDGPUMCExpr : public MCTargetExpr {
}
/// Create an expression for instruction prefetch size computation:
- /// min(divideCeil(CodeSizeBytes, 128), (1 << FieldWidth) - 1)
+ /// min(divideCeil(CodeSizeBytes, CacheLineSize), (1 << FieldWidth) - 1)
static const AMDGPUMCExpr *createInstPrefSize(const MCExpr *CodeSizeBytes,
unsigned FieldWidth,
+ unsigned CacheLineSize,
MCContext &Ctx);
static const AMDGPUMCExpr *createLit(LitModifier Lit, int64_t Value,
diff --git a/llvm/test/CodeGen/AMDGPU/inst-prefetch-hint.ll b/llvm/test/CodeGen/AMDGPU/inst-prefetch-hint.ll
index 99adbce0d37dc..e2e803afa3a22 100644
--- a/llvm/test/CodeGen/AMDGPU/inst-prefetch-hint.ll
+++ b/llvm/test/CodeGen/AMDGPU/inst-prefetch-hint.ll
@@ -11,16 +11,17 @@
; The inst_pref_size is computed via MCExpr label subtraction, resolved at
; assembly/link time. In text output it appears as:
-; instprefsize(<code_size>, <field_width>)
+; instprefsize(<code_size>, <field_width>, <cache_line_size>)
; where:
-; <code_size> = .Lfunc_endN - func_sym (exact function code size in bytes)
-; <field_width> = bit width of the inst_pref_size field (6 for GFX11, 8 for GFX12+)
-; instprefsize = min(divideCeil(code_size, 128), (1 << field_width) - 1)
+; <code_size> = .Lfunc_endN - func_sym (exact function code size in bytes)
+; <field_width> = bit width of the inst_pref_size field (6 for GFX11, 8 for GFX12+)
+; <cache_line_size> = instruction cache line size in bytes (128 for GFX11+)
+; instprefsize = min(divideCeil(code_size, cache_line_size), (1 << field_width) - 1)
; GCN-LABEL: .amdhsa_kernel large
-; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end0-large, 6)
+; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end0-large, 6, 128)
; GFX11: codeLenInByte = {{[0-9]+}}
-; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end0-large, 8)
+; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end0-large, 8, 128)
; GFX12: codeLenInByte = {{[0-9]+}}
;; Object: kernel descriptor at 0x00, COMPUTE_PGM_RSRC3 at 0x2C:
;; gfx11 pref=3 (0x30), gfx12 pref=4 (0x40)
@@ -33,8 +34,8 @@ bb:
}
; GCN-LABEL: .amdhsa_kernel small
-; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end1-small, 6)
-; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end1-small, 8)
+; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end1-small, 6, 128)
+; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end1-small, 8, 128)
; GCN: codeLenInByte = {{[0-9]+}}
;; Object: kernel descriptor at 0x40, COMPUTE_PGM_RSRC3 at 0x6C:
;; pref=1 (0x10) for both
@@ -49,8 +50,8 @@ bb:
; The MCExpr resolves to the correct inst_pref_size at assembly time.
; GCN-LABEL: .amdhsa_kernel inline_asm
-; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end2-inline_asm, 6)
-; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end2-inline_asm, 8)
+; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end2-inline_asm, 6, 128)
+; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end2-inline_asm, 8, 128)
; GCN: codeLenInByte = {{[0-9]+}}
;; Object: kernel descriptor at 0x80, COMPUTE_PGM_RSRC3 at 0xAC:
;; pref=9 (0x90) for both
diff --git a/llvm/test/CodeGen/AMDGPU/inst-prefetch-inline-asm.ll b/llvm/test/CodeGen/AMDGPU/inst-prefetch-inline-asm.ll
index 1dff24e6c234f..8066ee864627e 100644
--- a/llvm/test/CodeGen/AMDGPU/inst-prefetch-inline-asm.ll
+++ b/llvm/test/CodeGen/AMDGPU/inst-prefetch-inline-asm.ll
@@ -14,9 +14,9 @@
;; pref_size = divideCeil(1028, 128) = 9
; GFX11-LABEL: .amdhsa_kernel test_fill
-; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end0-test_fill, 6)
+; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end0-test_fill, 6, 128)
; GFX12-LABEL: .amdhsa_kernel test_fill
-; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end0-test_fill, 8)
+; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end0-test_fill, 8, 128)
;; Object: kernel descriptor at 0x00, COMPUTE_PGM_RSRC3 at 0x2C:
;; pref_size=9 -> 9<<4 = 0x90
; OBJ-GFX11: 0020 {{.*}}90000000
@@ -31,9 +31,9 @@ define amdgpu_kernel void @test_fill() {
;; pref_size = 9
; GFX11-LABEL: .amdhsa_kernel test_space
-; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end1-test_space, 6)
+; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end1-test_space, 6, 128)
; GFX12-LABEL: .amdhsa_kernel test_space
-; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end1-test_space, 8)
+; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end1-test_space, 8, 128)
;; Object: kernel descriptor at 0x40, COMPUTE_PGM_RSRC3 at 0x6C:
;; pref_size=9 -> 9<<4 = 0x90
; OBJ-GFX11: 0060 {{.*}}90000000
@@ -48,9 +48,9 @@ define amdgpu_kernel void @test_space() {
;; pref_size = divideCeil(132, 128) = 2
; GFX11-LABEL: .amdhsa_kernel test_instructions
-; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end2-test_instructions, 6)
+; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end2-test_instructions, 6, 128)
; GFX12-LABEL: .amdhsa_kernel test_instructions
-; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end2-test_instructions, 8)
+; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end2-test_instructions, 8, 128)
;; Object: kernel descriptor at 0x80, COMPUTE_PGM_RSRC3 at 0xAC:
;; pref_size=2 -> 2<<4 = 0x20
; OBJ-GFX11: 00a0 {{.*}}20000000
@@ -65,9 +65,9 @@ define amdgpu_kernel void @test_instructions() {
;; pref_size = 1
; GFX11-LABEL: .amdhsa_kernel test_comments
-; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end3-test_comments, 6)
+; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end3-test_comments, 6, 128)
; GFX12-LABEL: .amdhsa_kernel test_comments
-; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end3-test_comments, 8)
+; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end3-test_comments, 8, 128)
;; Object: kernel descriptor at 0xC0, COMPUTE_PGM_RSRC3 at 0xEC:
;; pref_size=1 -> 1<<4 = 0x10
; OBJ-GFX11: 00e0 {{.*}}10000000
@@ -82,9 +82,9 @@ define amdgpu_kernel void @test_comments() {
;; pref_size = 1
; GFX11-LABEL: .amdhsa_kernel test_empty_asm
-; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end4-test_empty_asm, 6)
+; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end4-test_empty_asm, 6, 128)
; GFX12-LABEL: .amdhsa_kernel test_empty_asm
-; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end4-test_empty_asm, 8)
+; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end4-test_empty_asm, 8, 128)
;; Object: kernel descriptor at 0x100, COMPUTE_PGM_RSRC3 at 0x12C:
;; pref_size=1 -> 1<<4 = 0x10
; OBJ-GFX11: 0120 {{.*}}10000000
@@ -99,9 +99,9 @@ define amdgpu_kernel void @test_empty_asm() {
;; pref_size = divideCeil(1028, 128) = 9
; GFX11-LABEL: .amdhsa_kernel test_multiple_asm
-; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end5-test_multiple_asm, 6)
+; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end5-test_multiple_asm, 6, 128)
; GFX12-LABEL: .amdhsa_kernel test_multiple_asm
-; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end5-test_multiple_asm, 8)
+; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end5-test_multiple_asm, 8, 128)
;; Object: kernel descriptor at 0x140, COMPUTE_PGM_RSRC3 at 0x16C:
;; pref_size=9 -> 9<<4 = 0x90
; OBJ-GFX11: 0160 {{.*}}90000000
@@ -119,9 +119,9 @@ define amdgpu_kernel void @test_multiple_asm() {
;; pref_size should clamp to 63
; GFX11-LABEL: .amdhsa_kernel test_clamping
-; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end6-test_clamping, 6)
+; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end6-test_clamping, 6, 128)
; GFX12-LABEL: .amdhsa_kernel test_clamping
-; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end6-test_clamping, 8)
+; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end6-test_clamping, 8, 128)
;; Object: kernel descriptor at 0x180, COMPUTE_PGM_RSRC3 at 0x1AC:
;; gfx11: clamped to 63 -> 63<<4 = 0x3F0
;; gfx12: no clamping, 65 -> 65<<4 = 0x410
@@ -139,9 +139,9 @@ define amdgpu_kernel void @test_clamping() {
;; GFX11 max = 63, GFX12 max = 255 -> both clamp
; GFX11-LABEL: .amdhsa_kernel test_clamping_both
-; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end7-test_clamping_both, 6)
+; GFX11: .amdhsa_inst_pref_size instprefsize(.Lfunc_end7-test_clamping_both, 6, 128)
; GFX12-LABEL: .amdhsa_kernel test_clamping_both
-; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end7-test_clamping_both, 8)
+; GFX12: .amdhsa_inst_pref_size instprefsize(.Lfunc_end7-test_clamping_both, 8, 128)
;; Object: kernel descriptor at 0x1C0, COMPUTE_PGM_RSRC3 at 0x1EC:
;; gfx11: clamped to 63 -> 63<<4 = 0x3F0
;; gfx12: clamped to 255 -> 255<<4 = 0xFF0
More information about the llvm-commits
mailing list