Skip to content

[AMDGPU][MC] Add GFX12 VBUFFER encoding #75195

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

Merged
merged 1 commit into from
Dec 14, 2023
Merged
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
42 changes: 37 additions & 5 deletions llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ class AMDGPUOperand : public MCParsedAsmOperand {
bool isOffen() const { return isImmTy(ImmTyOffen); }
bool isIdxen() const { return isImmTy(ImmTyIdxen); }
bool isAddr64() const { return isImmTy(ImmTyAddr64); }
bool isOffset() const { return isImmTy(ImmTyOffset) && isUInt<16>(getImm()); }
bool isOffset() const { return isImmTy(ImmTyOffset); }
bool isOffset0() const { return isImmTy(ImmTyOffset0) && isUInt<8>(getImm()); }
bool isOffset1() const { return isImmTy(ImmTyOffset1) && isUInt<8>(getImm()); }
bool isSMEMOffsetMod() const { return isImmTy(ImmTySMEMOffsetMod); }
Expand Down Expand Up @@ -1666,6 +1666,7 @@ class AMDGPUAsmParser : public MCTargetAsmParser {
SMLoc getInstLoc(const OperandVector &Operands) const;

bool validateInstruction(const MCInst &Inst, const SMLoc &IDLoc, const OperandVector &Operands);
bool validateOffset(const MCInst &Inst, const OperandVector &Operands);
bool validateFlatOffset(const MCInst &Inst, const OperandVector &Operands);
bool validateSMEMOffset(const MCInst &Inst, const OperandVector &Operands);
bool validateSOPLiteral(const MCInst &Inst) const;
Expand Down Expand Up @@ -4143,6 +4144,40 @@ SMLoc AMDGPUAsmParser::getFlatOffsetLoc(const OperandVector &Operands) const {
return getLoc();
}

bool AMDGPUAsmParser::validateOffset(const MCInst &Inst,
const OperandVector &Operands) {
auto Opcode = Inst.getOpcode();
auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
if (OpNum == -1)
return true;

uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
if ((TSFlags & SIInstrFlags::FLAT))
return validateFlatOffset(Inst, Operands);

if ((TSFlags & SIInstrFlags::SMRD))
return validateSMEMOffset(Inst, Operands);

const auto &Op = Inst.getOperand(OpNum);
if (isGFX12Plus() &&
(TSFlags & (SIInstrFlags::MUBUF | SIInstrFlags::MTBUF))) {
const unsigned OffsetSize = 24;
if (!isIntN(OffsetSize, Op.getImm())) {
Error(getFlatOffsetLoc(Operands),
Twine("expected a ") + Twine(OffsetSize) + "-bit signed offset");
return false;
}
} else {
const unsigned OffsetSize = 16;
if (!isUIntN(OffsetSize, Op.getImm())) {
Error(getFlatOffsetLoc(Operands),
Twine("expected a ") + Twine(OffsetSize) + "-bit unsigned offset");
return false;
}
}
return true;
}

bool AMDGPUAsmParser::validateFlatOffset(const MCInst &Inst,
const OperandVector &Operands) {
uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
Expand Down Expand Up @@ -4800,10 +4835,7 @@ bool AMDGPUAsmParser::validateInstruction(const MCInst &Inst,
if (!validateMovrels(Inst, Operands)) {
return false;
}
if (!validateFlatOffset(Inst, Operands)) {
return false;
}
if (!validateSMEMOffset(Inst, Operands)) {
if (!validateOffset(Inst, Operands)) {
return false;
}
if (!validateMAIAccWrite(Inst, Operands)) {
Expand Down
638 changes: 440 additions & 198 deletions llvm/lib/Target/AMDGPU/BUFInstructions.td

Large diffs are not rendered by default.

11 changes: 9 additions & 2 deletions llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,17 @@ void AMDGPUInstPrinter::printNamedBit(const MCInst *MI, unsigned OpNo,
void AMDGPUInstPrinter::printOffset(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI,
raw_ostream &O) {
uint16_t Imm = MI->getOperand(OpNo).getImm();
uint32_t Imm = MI->getOperand(OpNo).getImm();
if (Imm != 0) {
O << " offset:";
printU16ImmDecOperand(MI, OpNo, O);

// GFX12 uses a 24-bit signed offset for VBUFFER.
const MCInstrDesc &Desc = MII.get(MI->getOpcode());
bool IsVBuffer = Desc.TSFlags & (SIInstrFlags::MUBUF | SIInstrFlags::MTBUF);
if (AMDGPU::isGFX12(STI) && IsVBuffer)
O << formatDec(SignExtend32<24>(Imm));
else
printU16ImmDecOperand(MI, OpNo, O);
}
}

Expand Down
4 changes: 2 additions & 2 deletions llvm/test/MC/AMDGPU/ds-err.s
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
// RUN: not llvm-mc -triple=amdgcn -mcpu=tahiti %s 2>&1 | FileCheck --implicit-check-not=error: %s

// offset too big
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: invalid operand for instruction
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: expected a 16-bit unsigned offset
ds_add_u32 v2, v4 offset:1000000000

// offset too big
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: invalid operand for instruction
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: expected a 16-bit unsigned offset
ds_add_u32 v2, v4 offset:0x10000

// offset0 twice
Expand Down
9 changes: 9 additions & 0 deletions llvm/test/MC/AMDGPU/gfx11_unsupported.s
Original file line number Diff line number Diff line change
Expand Up @@ -1984,6 +1984,15 @@ s_cmp_nlt_f16 s1, s2
s_singleuse_vdst 0x1234
// CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU

buffer_atomic_sub_clamp_u32 v5, off, s[8:11], s3 offset:0 glc
// CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU

buffer_atomic_max_num_f32 v5, off, s[8:11], s3 offset:4095
// CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU

buffer_atomic_min_num_f32 v5, off, s[8:11], s3 offset:4095
// CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU

ds_sub_clamp_rtn_u32 v5, v1, v2
// CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU

Expand Down
Loading