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 4 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 @@ -4719,12 +4719,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 not be a negative.
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 unsigned offset for buffer ops");
return false;
}
} else {
Expand Down Expand Up @@ -4807,7 +4808,9 @@ bool AMDGPUAsmParser::validateSMEMOffset(const MCInst &Inst,
return true;

Error(getSMEMOffsetLoc(Operands),
isGFX12Plus() ? "expected a 24-bit signed offset"
isGFX12Plus() && IsBuffer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is pretty horrible how we have to guess at the reason for isLegalSMRDEncoded*Offset rejecting our offset. That is not your fault. But maybe we should try to clean it up, as a a separate patch.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I completely agree. Cleaning it up as a separate patch sounds like a great idea.

? "expected a 23-bit unsigned offset for 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 @@ -828,6 +828,18 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
}
}

// Validate buffer instruction offsets for GFX12+ - must not be a 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 @@ -2653,6 +2665,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 @@ -222,6 +222,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 @@ -3090,8 +3090,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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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 unsigned offset for 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 unsigned offset for 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 unsigned offset for buffer ops

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

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

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

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

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