Skip to content
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
28 changes: 27 additions & 1 deletion llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5324,6 +5324,12 @@ bool AMDGPUAsmParser::validateCoherencyBits(const MCInst &Inst,
unsigned CPol = Inst.getOperand(CPolPos).getImm();

if (!isGFX1250()) {
if (CPol & CPol::SCAL) {
SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
StringRef CStr(S.getPointer());
S = SMLoc::getFromPointer(&CStr.data()[CStr.find("scale_offset")]);
Error(S, "scale_offset is not supported on this GPU");
}
if (CPol & CPol::NV) {
SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
StringRef CStr(S.getPointer());
Expand All @@ -5332,6 +5338,13 @@ bool AMDGPUAsmParser::validateCoherencyBits(const MCInst &Inst,
}
}

if ((CPol & CPol::SCAL) && !supportsScaleOffset(MII, Inst.getOpcode())) {
SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
StringRef CStr(S.getPointer());
S = SMLoc::getFromPointer(&CStr.data()[CStr.find("scale_offset")]);
Error(S, "scale_offset is not supported for this instruction");
}

if (isGFX12Plus())
return validateTHAndScopeBits(Inst, Operands, CPol);

Expand Down Expand Up @@ -7003,6 +7016,7 @@ ParseStatus AMDGPUAsmParser::parseCPol(OperandVector &Operands) {
ParseStatus ResTH = ParseStatus::NoMatch;
ParseStatus ResScope = ParseStatus::NoMatch;
ParseStatus ResNV = ParseStatus::NoMatch;
ParseStatus ResScal = ParseStatus::NoMatch;

for (;;) {
if (ResTH.isNoMatch()) {
Expand Down Expand Up @@ -7041,10 +7055,22 @@ ParseStatus AMDGPUAsmParser::parseCPol(OperandVector &Operands) {
}
}

if (ResScal.isNoMatch()) {
if (trySkipId("scale_offset")) {
ResScal = ParseStatus::Success;
CPolVal |= CPol::SCAL;
continue;
} else if (trySkipId("no", "scale_offset")) {
ResScal = ParseStatus::Success;
continue;
}
}

break;
}

if (ResTH.isNoMatch() && ResScope.isNoMatch() && ResNV.isNoMatch())
if (ResTH.isNoMatch() && ResScope.isNoMatch() && ResNV.isNoMatch() &&
ResScal.isNoMatch())
return ParseStatus::NoMatch;

Operands.push_back(AMDGPUOperand::CreateImm(this, CPolVal, StringLoc,
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/AMDGPU/FLATInstructions.td
Original file line number Diff line number Diff line change
Expand Up @@ -2941,6 +2941,7 @@ multiclass VFLAT_Real_gfx12 <bits<8> op, string name = get_FLAT_ps<NAME>.Mnemoni
let DecoderNamespace = "GFX12";

let Inst{25-24} = {ps.is_flat_global, ps.is_flat_scratch};
let Inst{48} = cpol{CPolBit.SCAL}; // scale offset
}
}

Expand Down Expand Up @@ -3170,6 +3171,7 @@ multiclass VFLAT_Real_gfx1250<bits<8> op,
let DecoderNamespace = "GFX1250";

let Inst{25-24} = {ps.is_flat_global, ps.is_flat_scratch};
let Inst{48} = cpol{CPolBit.SCAL}; // scale offset
}
}

Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/AMDGPU/GCNSubtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -1162,6 +1162,9 @@ class GCNSubtarget final : public AMDGPUGenSubtargetInfo,

bool hasLshlAddU64Inst() const { return HasLshlAddU64Inst; }

// Scalar and global loads support scale_offset bit.
bool hasScaleOffset() const { return GFX1250Insts; }

bool hasFlatGVSMode() const { return FlatGVSMode; }

bool enableSIScheduler() const {
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ void AMDGPUInstPrinter::printCPol(const MCInst *MI, unsigned OpNo,
const int64_t TH = Imm & CPol::TH;
const int64_t Scope = Imm & CPol::SCOPE;

if (Imm & CPol::SCAL)
O << " scale_offset";

printTH(MI, TH, Scope, O);
printScope(Scope, O);

Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/AMDGPU/SIDefines.h
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,8 @@ enum CPol {

SWZ = 1 << 6, // Swizzle bit

SCAL = 1 << 11, // Scale offset bit

ALL = TH | SCOPE,

// Helper bits
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/AMDGPU/SIInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ def CPolBit {
int DLC = 2;
int SCC = 4;
int NV = 5;
int SCAL = 11;
}

class VOPDstOperand <RegisterClass rc> : RegisterOperand <rc, "printVOPDst">;
Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5482,6 +5482,19 @@ bool SIInstrInfo::verifyInstruction(const MachineInstr &MI,
}
}

if (const MachineOperand *CPol = getNamedOperand(MI, AMDGPU::OpName::cpol)) {
if (CPol->getImm() & AMDGPU::CPol::SCAL) {
if (!ST.hasScaleOffset()) {
ErrInfo = "Subtarget does not support offset scaling";
return false;
}
if (!AMDGPU::supportsScaleOffset(*this, MI.getOpcode())) {
ErrInfo = "Instruction does not support offset scaling";
return false;
}
}
}

return true;
}

Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/AMDGPU/SMInstructions.td
Original file line number Diff line number Diff line change
Expand Up @@ -1488,6 +1488,7 @@ class SMEM_Real_Load_gfx12<bits<6> op, string ps, string opName, OffsetMode offs
let Inst{20} = cpol{CPolBit.NV}; // non-volatile
let Inst{22-21} = cpol{4-3}; // scope
let Inst{24-23} = cpol{1-0}; // th - only lower 2 bits are supported
let Inst{56} = cpol{CPolBit.SCAL}; // scale offset
}

multiclass SM_Real_Loads_gfx12<bits<6> op, string ps = NAME> {
Expand Down
19 changes: 19 additions & 0 deletions llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3228,6 +3228,25 @@ const GcnBufferFormatInfo *getGcnBufferFormatInfo(uint8_t Format,
: getGfx9BufferFormatInfo(Format);
}

bool supportsScaleOffset(const MCInstrInfo &MII, unsigned Opcode) {
uint64_t TSFlags = MII.get(Opcode).TSFlags;

if (TSFlags & SIInstrFlags::SMRD)
return !getSMEMIsBuffer(Opcode);
if (!(TSFlags & SIInstrFlags::FLAT))
return false;

// Only SV and SVS modes are supported.
if (TSFlags & SIInstrFlags::FlatScratch)
return hasNamedOperand(Opcode, OpName::vaddr);

// Only GVS mode is supported.
return hasNamedOperand(Opcode, OpName::vaddr) &&
hasNamedOperand(Opcode, OpName::saddr);

return false;
}

bool hasAny64BitVGPROperands(const MCInstrDesc &OpDesc) {
for (auto OpName : {OpName::vdst, OpName::src0, OpName::src1, OpName::src2}) {
int Idx = getNamedOperandIdx(OpDesc.getOpcode(), OpName);
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -1757,6 +1757,9 @@ bool isIntrinsicSourceOfDivergence(unsigned IntrID);
/// \returns true if the intrinsic is uniform
bool isIntrinsicAlwaysUniform(unsigned IntrID);

/// \returns true if a memory instruction supports scale_offset modifier.
bool supportsScaleOffset(const MCInstrInfo &MII, unsigned Opcode);

/// \returns lds block size in terms of dwords. \p
/// This is used to calculate the lds size encoded for PAL metadata 3.0+ which
/// must be defined in terms of bytes.
Expand Down
27 changes: 27 additions & 0 deletions llvm/test/MC/AMDGPU/gfx1250_asm_smem.s
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,30 @@ s_buffer_load_i8 s5, s[4:7], s0 nv
// GFX12-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: nv is not supported on this GPU
// GFX12-ERR-NEXT:{{^}}s_buffer_load_i8 s5, s[4:7], s0 nv
// GFX12-ERR-NEXT:{{^}} ^

s_load_b32 s4, s[2:3], 0xa scale_offset
// GFX1250: s_load_b32 s4, s[2:3], 0xa scale_offset ; encoding: [0x01,0x01,0x00,0xf4,0x0a,0x00,0x00,0xf9]
// GFX12-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: scale_offset is not supported on this GPU
// GFX12-ERR-NEXT:{{^}}s_load_b32 s4, s[2:3], 0xa scale_offset
// GFX12-ERR-NEXT:{{^}} ^

s_load_b32 s4, s[2:3], 0xa scale_offset nv
// GFX1250: s_load_b32 s4, s[2:3], 0xa scale_offset nv ; encoding: [0x01,0x01,0x10,0xf4,0x0a,0x00,0x00,0xf9]
// GFX12-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: scale_offset is not supported on this GPU
// GFX12-ERR-NEXT:{{^}}s_load_b32 s4, s[2:3], 0xa scale_offset nv
// GFX12-ERR-NEXT:{{^}} ^
// GFX12-ERR-NEXT: error: nv is not supported on this GPU
// GFX12-ERR-NEXT:{{^}}s_load_b32 s4, s[2:3], 0xa scale_offset nv
// GFX12-ERR-NEXT:{{^}} ^

s_load_b32 s4, s[2:3], s5 offset:32 scale_offset
// GFX1250: s_load_b32 s4, s[2:3], s5 offset:0x20 scale_offset ; encoding: [0x01,0x01,0x00,0xf4,0x20,0x00,0x00,0x0b]
// GFX12-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: scale_offset is not supported on this GPU
// GFX12-ERR-NEXT:{{^}}s_load_b32 s4, s[2:3], s5 offset:32 scale_offset
// GFX12-ERR-NEXT:{{^}} ^

s_load_b32 s4, s[2:3], m0 offset:32 scale_offset
// GFX1250: s_load_b32 s4, s[2:3], m0 offset:0x20 scale_offset ; encoding: [0x01,0x01,0x00,0xf4,0x20,0x00,0x00,0xfb]
// GFX12-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: scale_offset is not supported on this GPU
// GFX12-ERR-NEXT:{{^}}s_load_b32 s4, s[2:3], m0 offset:32 scale_offset
// GFX12-ERR-NEXT:{{^}} ^
16 changes: 16 additions & 0 deletions llvm/test/MC/AMDGPU/gfx1250_asm_smem_err.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// RUN: not llvm-mc -triple=amdgcn -mcpu=gfx1250 -show-encoding %s 2>&1 | FileCheck --check-prefix=GFX1250-ERR --implicit-check-not=error: --strict-whitespace %s

s_buffer_load_i8 s5, s[4:7], s0 scale_offset
// GFX1250-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: scale_offset is not supported for this instruction
// GFX1250-ERR-NEXT:{{^}}s_buffer_load_i8 s5, s[4:7], s0 scale_offset
// GFX1250-ERR-NEXT:{{^}} ^

s_prefetch_data s[18:19], 100, s10, 7 nv
// GFX1250-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
// GFX1250-ERR-NEXT:{{^}}s_prefetch_data s[18:19], 100, s10, 7 nv
// GFX1250-ERR-NEXT:{{^}} ^

s_prefetch_data s[18:19], 100, s10, 7 scale_offset
// GFX1250-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
// GFX1250-ERR-NEXT:{{^}}s_prefetch_data s[18:19], 100, s10, 7 scale_offset
// GFX1250-ERR-NEXT:{{^}} ^
6 changes: 6 additions & 0 deletions llvm/test/MC/AMDGPU/gfx1250_asm_vbuffer_mubuf_err.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// RUN: not llvm-mc -triple=amdgcn -mcpu=gfx1250 -show-encoding %s 2>&1 | FileCheck --check-prefix=GFX1250-ERR --implicit-check-not=error: --strict-whitespace %s

buffer_load_b32 v5, v1, s[8:11], s3 offen offset:4095 scale_offset
// GFX1250-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: scale_offset is not supported for this instruction
// GFX1250-ERR-NEXT:{{^}}buffer_load_b32 v5, v1, s[8:11], s3 offen offset:4095 scale_offset
// GFX1250-ERR-NEXT:{{^}} ^
Loading