Skip to content

[AMDGPU] Ensure positive InstOffset for buffer operations #145504

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4464,12 +4464,13 @@ bool AMDGPUAsmParser::validateOffset(const MCInst &Inst,
return validateSMEMOffset(Inst, Operands);

const auto &Op = Inst.getOperand(OpNum);
// GFX12+ buffer ops: InstOffset is signed 24, but must be positive
if (isGFX12Plus() &&
(TSFlags & (SIInstrFlags::MUBUF | SIInstrFlags::MTBUF))) {
const unsigned OffsetSize = 24;
if (!isIntN(OffsetSize, Op.getImm())) {
if (!isUIntN(OffsetSize - 1, Op.getImm())) {
Error(getFlatOffsetLoc(Operands),
Twine("expected a ") + Twine(OffsetSize) + "-bit signed offset");
Twine("expected a ") + Twine(OffsetSize - 1) + "-bit non-negative offset for buffer ops");
return false;
}
} else {
Expand Down Expand Up @@ -4552,7 +4553,9 @@ bool AMDGPUAsmParser::validateSMEMOffset(const MCInst &Inst,
return true;

Error(getSMEMOffsetLoc(Operands),
isGFX12Plus() ? "expected a 24-bit signed offset"
isGFX12Plus() && IsBuffer
? "expected a 23-bit non-negative offset for S_BUFFER ops"
: isGFX12Plus() ? "expected a 24-bit signed offset"
: (isVI() || IsBuffer) ? "expected a 20-bit unsigned offset"
: "expected a 21-bit signed offset");

Expand Down
26 changes: 26 additions & 0 deletions llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,18 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
}
}

// Validate buffer instruction offsets for GFX12+ - must be non-negative
if (isGFX12Plus() && isBufferInstruction(MI)) {
int OffsetIdx =
AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::offset);
if (OffsetIdx != -1) {
uint32_t Imm = MI.getOperand(OffsetIdx).getImm();
int64_t SignedOffset = SignExtend64<24>(Imm);
if (SignedOffset < 0)
return MCDisassembler::Fail;
}
}

if (MCII->get(MI.getOpcode()).TSFlags &
(SIInstrFlags::MTBUF | SIInstrFlags::MUBUF)) {
int SWZOpIdx =
Expand Down Expand Up @@ -2608,6 +2620,20 @@ const MCExpr *AMDGPUDisassembler::createConstantSymbolExpr(StringRef Id,
return MCSymbolRefExpr::create(Sym, Ctx);
}

bool AMDGPUDisassembler::isBufferInstruction(const MCInst &MI) const {
const uint64_t TSFlags = MCII->get(MI.getOpcode()).TSFlags;

// Check for MUBUF and MTBUF instructions
if (TSFlags & (SIInstrFlags::MTBUF | SIInstrFlags::MUBUF))
return true;

// Check for SMEM buffer instructions (S_BUFFER_* instructions)
if ((TSFlags & SIInstrFlags::SMRD) && AMDGPU::getSMEMIsBuffer(MI.getOpcode()))
return true;

return false;
}

//===----------------------------------------------------------------------===//
// AMDGPUSymbolizer
//===----------------------------------------------------------------------===//
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,9 @@ class AMDGPUDisassembler : public MCDisassembler {
bool hasKernargPreload() const;

bool isMacDPP(MCInst &MI) const;

/// Check if the instruction is a buffer operation (MUBUF, MTBUF, or S_BUFFER)
bool isBufferInstruction(const MCInst &MI) const;
};

//===----------------------------------------------------------------------===//
Expand Down
5 changes: 4 additions & 1 deletion llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2954,8 +2954,11 @@ bool isLegalSMRDEncodedUnsignedOffset(const MCSubtargetInfo &ST,

bool isLegalSMRDEncodedSignedOffset(const MCSubtargetInfo &ST,
int64_t EncodedOffset, bool IsBuffer) {
if (isGFX12Plus(ST))
if (isGFX12Plus(ST)) {
if (IsBuffer && EncodedOffset < 0)
return false;
return isInt<24>(EncodedOffset);
}

return !IsBuffer && hasSMRDSignedImmOffset(ST) && isInt<21>(EncodedOffset);
}
Expand Down
258 changes: 258 additions & 0 deletions llvm/test/MC/AMDGPU/gfx12_err.s
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,261 @@ s_alloc_vgpr exec

s_alloc_vgpr vcc
// GFX12-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction

buffer_load_dword v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_load_dword v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_load_dwordx2 v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_load_dwordx3 v[0:2], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_load_dwordx4 v[0:3], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_load_short_d16 v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_load_format_d16_x v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_load_format_d16_xy v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_load_format_d16_xyz v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_load_format_d16_xyzw v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_load_short_d16_hi v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_load_format_d16_hi_x v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_load_sbyte_d16_hi v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_load_ubyte_d16_hi v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_load_sbyte_d16 v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_load_ubyte_d16 v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_load_sbyte v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_load_sshort v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_load_ubyte v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_load_ushort v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_store_byte v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_store_short v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_store_dword v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_store_dwordx2 v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_store_dwordx3 v[0:2], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_store_dwordx4 v[0:3], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_store_format_d16_x v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_store_format_d16_xy v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_store_format_d16_xyz v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_store_format_d16_xyzw v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_store_byte_d16_hi v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_store_short_d16_hi v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_store_format_d16_hi_x v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_add v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_add_x2 v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_and v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_and_x2 v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_cmpswap v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_cmpswap_x2 v[0:3], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_csub v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_dec v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_dec_x2 v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_inc v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_inc_x2 v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_fmax v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_smax v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_smax_x2 v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_umax v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_umax_x2 v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_fmin v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_smin v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_smin_x2 v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_umin v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_umin_x2 v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_or v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_or_x2 v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_sub v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_sub_x2 v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_swap v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_swap_x2 v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_xor v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

buffer_atomic_xor_x2 v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

tbuffer_load_format_d16_x v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

tbuffer_load_format_d16_xy v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

tbuffer_load_format_d16_xyz v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

tbuffer_load_format_d16_xyzw v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

tbuffer_load_format_x v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

tbuffer_load_format_xy v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

tbuffer_load_format_xyz v[0:2], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

tbuffer_load_format_xyzw v[0:3], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

tbuffer_store_format_d16_x v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

tbuffer_store_format_d16_xy v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

tbuffer_store_format_d16_xyz v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

tbuffer_store_format_d16_xyzw v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

tbuffer_store_format_x v0, off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

tbuffer_store_format_xy v[0:1], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

tbuffer_store_format_xyz v[0:2], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

tbuffer_store_format_xyzw v[0:3], off, s[4:7], s8 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for buffer ops

s_buffer_load_b32 s5, s[4:7], s0 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for S_BUFFER ops

s_buffer_load_b64 s[10:11], s[4:7], s0 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for S_BUFFER ops

s_buffer_load_b96 s[20:22], s[4:7], s0 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for S_BUFFER ops

s_buffer_load_i8 s5, s[4:7], s0 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for S_BUFFER ops

s_buffer_load_u8 s5, s[4:7], s0 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for S_BUFFER ops

s_buffer_load_i16 s5, s[4:7], s0 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for S_BUFFER ops

s_buffer_load_u16 s5, s[4:7], s0 offset:-1
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for S_BUFFER ops

s_buffer_prefetch_data s[20:23], -1, s10, 7
// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected a 23-bit non-negative offset for S_BUFFER ops
Loading