Skip to content

[WIP][AMDGPU][MC] Support 128b rsrc reg in mimg instructions #139121

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 10 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
63 changes: 63 additions & 0 deletions llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1781,6 +1781,7 @@ class AMDGPUAsmParser : public MCTargetAsmParser {
bool validateMIMGD16(const MCInst &Inst);
bool validateMIMGDim(const MCInst &Inst, const OperandVector &Operands);
bool validateMIMGMSAA(const MCInst &Inst);
bool validateMIMGR128(const MCInst &Inst, const OperandVector &Operands);
bool validateOpSel(const MCInst &Inst);
bool validateTrue16OpSel(const MCInst &Inst);
bool validateNeg(const MCInst &Inst, AMDGPU::OpName OpName);
Expand Down Expand Up @@ -3974,6 +3975,65 @@ bool AMDGPUAsmParser::validateMIMGAddrSize(const MCInst &Inst,
return false;
}

bool AMDGPUAsmParser::validateMIMGR128(const MCInst &Inst,
const OperandVector &Operands) {
const unsigned Opc = Inst.getOpcode();
const MCInstrDesc &Desc = MII.get(Opc);

if ((Desc.TSFlags & MIMGFlags) == 0)
return true;

// image_bvh_intersect_ray instructions only support 128b RSRC reg
if (AMDGPU::getMIMGBaseOpcode(Opc)->BVH)
return true;

AMDGPU::OpName RSrcOpName = (Desc.TSFlags & SIInstrFlags::MIMG)
? AMDGPU::OpName::srsrc
: AMDGPU::OpName::rsrc;
int SrsrcIdx = AMDGPU::getNamedOperandIdx(Opc, RSrcOpName);
assert(SrsrcIdx != -1);

auto RsrcReg = Inst.getOperand(SrsrcIdx).getReg();

unsigned SrsrcRegSize = 4;
if (getMRI()->getRegClass(AMDGPU::SReg_256_XNULLRegClassID).contains(RsrcReg))
SrsrcRegSize = 8;
else {
switch (RsrcReg.id()) {
case TTMP0_TTMP1_TTMP2_TTMP3_TTMP4_TTMP5_TTMP6_TTMP7_vi:
case TTMP4_TTMP5_TTMP6_TTMP7_TTMP8_TTMP9_TTMP10_TTMP11_vi:
case TTMP8_TTMP9_TTMP10_TTMP11_TTMP12_TTMP13_TTMP14_TTMP15_vi:
case TTMP0_TTMP1_TTMP2_TTMP3_TTMP4_TTMP5_TTMP6_TTMP7_gfx9plus:
case TTMP4_TTMP5_TTMP6_TTMP7_TTMP8_TTMP9_TTMP10_TTMP11_gfx9plus:
case TTMP8_TTMP9_TTMP10_TTMP11_TTMP12_TTMP13_TTMP14_TTMP15_gfx9plus:
SrsrcRegSize = 8;
break;
Comment on lines +4002 to +4010
Copy link
Contributor

Choose a reason for hiding this comment

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

there ought to be a class test you can perform for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In getMCReg(), registers such as TTMP0_TTMP1..._TTMP7 are converted to the ones with a suffix "_vi" or "_gfx9plus". Those new registers don't seem to belong to any reg class.

default:
break;
}
}

int R128Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::r128);
bool IsR128 =
(hasMIMG_R128() && R128Idx != -1 && Inst.getOperand(R128Idx).getImm());

if (SrsrcRegSize == 8 && IsR128) {
auto Loc = getImmLoc(AMDGPUOperand::ImmTyR128A16, Operands);
Error(Loc, "r128 not allowed with 256-bit RSRC reg");
return false;
}

if (SrsrcRegSize == 4 && !IsR128) {
auto Loc = getInstLoc(Operands);
if (hasMIMG_R128())
Error(Loc, "rsrc reg should be 256-bit, or the r128 flag is required");
else
Error(Loc, "operands are not valid for this GPU or mode");
return false;
}
return true;
}

bool AMDGPUAsmParser::validateMIMGAtomicDMask(const MCInst &Inst) {

const unsigned Opc = Inst.getOpcode();
Expand Down Expand Up @@ -5191,6 +5251,9 @@ bool AMDGPUAsmParser::validateInstruction(const MCInst &Inst,
"invalid dim; must be MSAA type");
return false;
}
if (!validateMIMGR128(Inst, Operands))
return false;

if (!validateMIMGDataSize(Inst, IDLoc)) {
return false;
}
Expand Down
15 changes: 15 additions & 0 deletions llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ DECODE_OPERAND_SREG_7(SReg_128, 128)
DECODE_OPERAND_SREG_7(SReg_128_XNULL, 128)
DECODE_OPERAND_SREG_7(SReg_256, 256)
DECODE_OPERAND_SREG_7(SReg_256_XNULL, 256)
DECODE_OPERAND_SREG_7(SReg_RSRC, 256)
DECODE_OPERAND_SREG_7(SReg_512, 512)

DECODE_OPERAND_SREG_8(SReg_64, 64)
Expand Down Expand Up @@ -1206,6 +1207,20 @@ void AMDGPUDisassembler::convertMIMGInst(MCInst &MI) const {
}
}

// Update RSRC reg to 128b if r128 flag is present.
int R128Idx =
AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::r128);
if (AMDGPU::hasMIMG_R128(STI) && R128Idx != -1 &&
MI.getOperand(R128Idx).getImm()) {
// Get first subregister of RSRC
MCRegister RsrcReg = MI.getOperand(RsrcIdx).getReg();
MCRegister RsrcSubReg0 = MRI.getSubReg(RsrcReg, AMDGPU::sub0);
MCRegister NewRsrcReg = MRI.getMatchingSuperReg(
RsrcSubReg0, AMDGPU::sub0,
&MRI.getRegClass(AMDGPU::SReg_128_XNULLRegClassID));
MI.getOperand(RsrcIdx) = MCOperand::createReg(NewRsrcReg);
}

unsigned DMask = MI.getOperand(DMaskIdx).getImm() & 0xf;
unsigned DstSize = IsGather4 ? 4 : std::max(llvm::popcount(DMask), 1);

Expand Down
44 changes: 22 additions & 22 deletions llvm/lib/Target/AMDGPU/MIMGInstructions.td
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ class MIMG_NoSampler_Helper <mimgopc op, string asm,
RegisterClass addr_rc,
string dns="">
: MIMG_gfx6789 <op.GFX10M, (outs dst_rc:$vdata), dns> {
let InOperandList = !con((ins addr_rc:$vaddr, SReg_256_XNULL:$srsrc,
let InOperandList = !con((ins addr_rc:$vaddr, SReg_RSRC:$srsrc,
DMask:$dmask, UNorm:$unorm, CPol:$cpol,
R128A16:$r128, TFE:$tfe, LWE:$lwe, DA:$da),
!if(BaseOpcode.HasD16, (ins D16:$d16), (ins)));
Expand All @@ -449,7 +449,7 @@ class MIMG_NoSampler_gfx10<mimgopc op, string opcode,
RegisterClass DataRC, RegisterClass AddrRC,
string dns="">
: MIMG_gfx10<op.GFX10M, (outs DataRC:$vdata), dns> {
let InOperandList = !con((ins AddrRC:$vaddr0, SReg_256_XNULL:$srsrc, DMask:$dmask,
let InOperandList = !con((ins AddrRC:$vaddr0, SReg_RSRC:$srsrc, DMask:$dmask,
Dim:$dim, UNorm:$unorm, CPol:$cpol,
R128A16:$r128, A16:$a16, TFE:$tfe, LWE:$lwe),
!if(BaseOpcode.HasD16, (ins D16:$d16), (ins)));
Expand All @@ -462,7 +462,7 @@ class MIMG_NoSampler_nsa_gfx10<mimgopc op, string opcode,
string dns="">
: MIMG_nsa_gfx10<op.GFX10M, (outs DataRC:$vdata), num_addrs, dns> {
let InOperandList = !con(AddrIns,
(ins SReg_256_XNULL:$srsrc, DMask:$dmask,
(ins SReg_RSRC:$srsrc, DMask:$dmask,
Dim:$dim, UNorm:$unorm, CPol:$cpol,
R128A16:$r128, A16:$a16, TFE:$tfe, LWE:$lwe),
!if(BaseOpcode.HasD16, (ins D16:$d16), (ins)));
Expand All @@ -474,7 +474,7 @@ class MIMG_NoSampler_gfx11<mimgopc op, string opcode,
RegisterClass DataRC, RegisterClass AddrRC,
string dns="">
: MIMG_gfx11<op.GFX11, (outs DataRC:$vdata), dns> {
let InOperandList = !con((ins AddrRC:$vaddr0, SReg_256_XNULL:$srsrc, DMask:$dmask,
let InOperandList = !con((ins AddrRC:$vaddr0, SReg_RSRC:$srsrc, DMask:$dmask,
Dim:$dim, UNorm:$unorm, CPol:$cpol,
R128A16:$r128, A16:$a16, TFE:$tfe, LWE:$lwe),
!if(BaseOpcode.HasD16, (ins D16:$d16), (ins)));
Expand All @@ -487,7 +487,7 @@ class MIMG_NoSampler_nsa_gfx11<mimgopc op, string opcode,
string dns="">
: MIMG_nsa_gfx11<op.GFX11, (outs DataRC:$vdata), num_addrs, dns> {
let InOperandList = !con(AddrIns,
(ins SReg_256_XNULL:$srsrc, DMask:$dmask,
(ins SReg_RSRC:$srsrc, DMask:$dmask,
Dim:$dim, UNorm:$unorm, CPol:$cpol,
R128A16:$r128, A16:$a16, TFE:$tfe, LWE:$lwe),
!if(BaseOpcode.HasD16, (ins D16:$d16), (ins)));
Expand All @@ -500,7 +500,7 @@ class VIMAGE_NoSampler_gfx12<mimgopc op, string opcode,
string dns="">
: VIMAGE_gfx12<op.GFX12, (outs DataRC:$vdata), num_addrs, dns> {
let InOperandList = !con(AddrIns,
(ins SReg_256_XNULL:$rsrc, DMask:$dmask, Dim:$dim,
(ins SReg_RSRC:$rsrc, DMask:$dmask, Dim:$dim,
CPol:$cpol, R128A16:$r128, A16:$a16, TFE:$tfe),
!if(BaseOpcode.HasD16, (ins D16:$d16), (ins)));
let AsmString = opcode#" $vdata, "#AddrAsm#", $rsrc$dmask$dim$cpol$r128$a16$tfe"
Expand All @@ -512,7 +512,7 @@ class VSAMPLE_Sampler_gfx12<mimgopc op, string opcode, RegisterClass DataRC,
string dns="">
: VSAMPLE_gfx12<op.GFX12, (outs DataRC:$vdata), num_addrs, dns, Addr3RC> {
let InOperandList = !con(AddrIns,
(ins SReg_256_XNULL:$rsrc),
(ins SReg_RSRC:$rsrc),
!if(BaseOpcode.Sampler, (ins SReg_128_XNULL:$samp), (ins)),
(ins DMask:$dmask, Dim:$dim, UNorm:$unorm,
CPol:$cpol, R128A16:$r128, A16:$a16, TFE:$tfe,
Expand All @@ -529,7 +529,7 @@ class VSAMPLE_Sampler_nortn_gfx12<mimgopc op, string opcode,
string dns="">
: VSAMPLE_gfx12<op.GFX12, (outs), num_addrs, dns, Addr3RC> {
let InOperandList = !con(AddrIns,
(ins SReg_256_XNULL:$rsrc),
(ins SReg_RSRC:$rsrc),
!if(BaseOpcode.Sampler, (ins SReg_128_XNULL:$samp), (ins)),
(ins DMask:$dmask, Dim:$dim, UNorm:$unorm,
CPol:$cpol, R128A16:$r128, A16:$a16, TFE:$tfe,
Expand Down Expand Up @@ -681,7 +681,7 @@ class MIMG_Store_Helper <mimgopc op, string asm,
RegisterClass addr_rc,
string dns = "">
: MIMG_gfx6789<op.GFX10M, (outs), dns> {
let InOperandList = !con((ins data_rc:$vdata, addr_rc:$vaddr, SReg_256_XNULL:$srsrc,
let InOperandList = !con((ins data_rc:$vdata, addr_rc:$vaddr, SReg_RSRC:$srsrc,
DMask:$dmask, UNorm:$unorm, CPol:$cpol,
R128A16:$r128, TFE:$tfe, LWE:$lwe, DA:$da),
!if(BaseOpcode.HasD16, (ins D16:$d16), (ins)));
Expand All @@ -707,7 +707,7 @@ class MIMG_Store_gfx10<mimgopc op, string opcode,
RegisterClass DataRC, RegisterClass AddrRC,
string dns="">
: MIMG_gfx10<op.GFX10M, (outs), dns> {
let InOperandList = !con((ins DataRC:$vdata, AddrRC:$vaddr0, SReg_256_XNULL:$srsrc,
let InOperandList = !con((ins DataRC:$vdata, AddrRC:$vaddr0, SReg_RSRC:$srsrc,
DMask:$dmask, Dim:$dim, UNorm:$unorm, CPol:$cpol,
R128A16:$r128, A16:$a16, TFE:$tfe, LWE:$lwe),
!if(BaseOpcode.HasD16, (ins D16:$d16), (ins)));
Expand All @@ -721,7 +721,7 @@ class MIMG_Store_nsa_gfx10<mimgopc op, string opcode,
: MIMG_nsa_gfx10<op.GFX10M, (outs), num_addrs, dns> {
let InOperandList = !con((ins DataRC:$vdata),
AddrIns,
(ins SReg_256_XNULL:$srsrc, DMask:$dmask,
(ins SReg_RSRC:$srsrc, DMask:$dmask,
Dim:$dim, UNorm:$unorm, CPol:$cpol,
R128A16:$r128, A16:$a16, TFE:$tfe, LWE:$lwe),
!if(BaseOpcode.HasD16, (ins D16:$d16), (ins)));
Expand All @@ -733,7 +733,7 @@ class MIMG_Store_gfx11<mimgopc op, string opcode,
RegisterClass DataRC, RegisterClass AddrRC,
string dns="">
: MIMG_gfx11<op.GFX11, (outs), dns> {
let InOperandList = !con((ins DataRC:$vdata, AddrRC:$vaddr0, SReg_256_XNULL:$srsrc,
let InOperandList = !con((ins DataRC:$vdata, AddrRC:$vaddr0, SReg_RSRC:$srsrc,
DMask:$dmask, Dim:$dim, UNorm:$unorm, CPol:$cpol,
R128A16:$r128, A16:$a16, TFE:$tfe, LWE:$lwe),
!if(BaseOpcode.HasD16, (ins D16:$d16), (ins)));
Expand All @@ -747,7 +747,7 @@ class MIMG_Store_nsa_gfx11<mimgopc op, string opcode,
: MIMG_nsa_gfx11<op.GFX11, (outs), num_addrs, dns> {
let InOperandList = !con((ins DataRC:$vdata),
AddrIns,
(ins SReg_256_XNULL:$srsrc, DMask:$dmask,
(ins SReg_RSRC:$srsrc, DMask:$dmask,
Dim:$dim, UNorm:$unorm, CPol:$cpol,
R128A16:$r128, A16:$a16, TFE:$tfe, LWE:$lwe),
!if(BaseOpcode.HasD16, (ins D16:$d16), (ins)));
Expand All @@ -761,7 +761,7 @@ class VIMAGE_Store_gfx12<mimgopc op, string opcode,
: VIMAGE_gfx12<op.GFX12, (outs), num_addrs, dns> {
let InOperandList = !con((ins DataRC:$vdata),
AddrIns,
(ins SReg_256_XNULL:$rsrc, DMask:$dmask, Dim:$dim,
(ins SReg_RSRC:$rsrc, DMask:$dmask, Dim:$dim,
CPol:$cpol, R128A16:$r128, A16:$a16, TFE:$tfe),
!if(BaseOpcode.HasD16, (ins D16:$d16), (ins)));
let AsmString = opcode#" $vdata, "#AddrAsm#", $rsrc$dmask$dim$cpol$r128$a16$tfe"
Expand Down Expand Up @@ -877,7 +877,7 @@ class MIMG_Atomic_gfx6789_base <bits<8> op, string asm, RegisterClass data_rc,
: MIMG_gfx6789 <op, (outs data_rc:$vdst), dns> {
let Constraints = "$vdst = $vdata";

let InOperandList = (ins data_rc:$vdata, addr_rc:$vaddr, SReg_256_XNULL:$srsrc,
let InOperandList = (ins data_rc:$vdata, addr_rc:$vaddr, SReg_RSRC:$srsrc,
DMask:$dmask, UNorm:$unorm, CPol:$cpol,
R128A16:$r128, TFE:$tfe, LWE:$lwe, DA:$da);
let AsmString = asm#" $vdst, $vaddr, $srsrc$dmask$unorm$cpol$r128$tfe$lwe$da";
Expand Down Expand Up @@ -923,7 +923,7 @@ class MIMG_Atomic_gfx10<mimgopc op, string opcode,
!if(enableDisasm, "GFX10", "")> {
let Constraints = "$vdst = $vdata";

let InOperandList = (ins DataRC:$vdata, AddrRC:$vaddr0, SReg_256_XNULL:$srsrc,
let InOperandList = (ins DataRC:$vdata, AddrRC:$vaddr0, SReg_RSRC:$srsrc,
DMask:$dmask, Dim:$dim, UNorm:$unorm, CPol:$cpol,
R128A16:$r128, A16:$a16, TFE:$tfe, LWE:$lwe);
let AsmString = opcode#" $vdst, $vaddr0, $srsrc$dmask$dim$unorm$cpol$r128$a16$tfe$lwe";
Expand All @@ -938,7 +938,7 @@ class MIMG_Atomic_nsa_gfx10<mimgopc op, string opcode,

let InOperandList = !con((ins DataRC:$vdata),
AddrIns,
(ins SReg_256_XNULL:$srsrc, DMask:$dmask,
(ins SReg_RSRC:$srsrc, DMask:$dmask,
Dim:$dim, UNorm:$unorm, CPol:$cpol,
R128A16:$r128, A16:$a16, TFE:$tfe, LWE:$lwe));
let AsmString = opcode#" $vdata, "#AddrAsm#", $srsrc$dmask$dim$unorm$cpol$r128$a16$tfe$lwe";
Expand All @@ -951,7 +951,7 @@ class MIMG_Atomic_gfx11<mimgopc op, string opcode,
!if(enableDisasm, "GFX11", "")> {
let Constraints = "$vdst = $vdata";

let InOperandList = (ins DataRC:$vdata, AddrRC:$vaddr0, SReg_256_XNULL:$srsrc,
let InOperandList = (ins DataRC:$vdata, AddrRC:$vaddr0, SReg_RSRC:$srsrc,
DMask:$dmask, Dim:$dim, UNorm:$unorm, CPol:$cpol,
R128A16:$r128, A16:$a16, TFE:$tfe, LWE:$lwe);
let AsmString = opcode#" $vdst, $vaddr0, $srsrc$dmask$dim$unorm$cpol$r128$a16$tfe$lwe";
Expand All @@ -966,7 +966,7 @@ class MIMG_Atomic_nsa_gfx11<mimgopc op, string opcode,

let InOperandList = !con((ins DataRC:$vdata),
AddrIns,
(ins SReg_256_XNULL:$srsrc, DMask:$dmask,
(ins SReg_RSRC:$srsrc, DMask:$dmask,
Dim:$dim, UNorm:$unorm, CPol:$cpol,
R128A16:$r128, A16:$a16, TFE:$tfe, LWE:$lwe));
let AsmString = opcode#" $vdata, "#AddrAsm#", $srsrc$dmask$dim$unorm$cpol$r128$a16$tfe$lwe";
Expand All @@ -980,7 +980,7 @@ class VIMAGE_Atomic_gfx12<mimgopc op, string opcode, RegisterClass DataRC,

let InOperandList = !con((ins DataRC:$vdata),
AddrIns,
(ins SReg_256_XNULL:$rsrc, DMask:$dmask, Dim:$dim,
(ins SReg_RSRC:$rsrc, DMask:$dmask, Dim:$dim,
CPol:$cpol, R128A16:$r128, A16:$a16, TFE:$tfe));
let AsmString = !if(!empty(renamed), opcode, renamed)#" $vdata, "#AddrAsm#
", $rsrc$dmask$dim$cpol$r128$a16$tfe";
Expand Down Expand Up @@ -1130,7 +1130,7 @@ multiclass MIMG_Atomic_Renamed <mimgopc op, string asm, string renamed,
class MIMG_Sampler_Helper <mimgopc op, string asm, RegisterClass dst_rc,
RegisterClass src_rc, string dns="">
: MIMG_gfx6789 <op.VI, (outs dst_rc:$vdata), dns> {
let InOperandList = !con((ins src_rc:$vaddr, SReg_256_XNULL:$srsrc, SReg_128_XNULL:$ssamp,
let InOperandList = !con((ins src_rc:$vaddr, SReg_RSRC:$srsrc, SReg_128_XNULL:$ssamp,
DMask:$dmask, UNorm:$unorm, CPol:$cpol,
R128A16:$r128, TFE:$tfe, LWE:$lwe, DA:$da),
!if(BaseOpcode.HasD16, (ins D16:$d16), (ins)));
Expand All @@ -1151,7 +1151,7 @@ class MIMG_Sampler_gfx90a<mimgopc op, string asm, RegisterClass dst_rc,

class MIMG_Sampler_OpList_gfx10p<dag OpPrefix, bit HasD16> {
dag ret = !con(OpPrefix,
(ins SReg_256_XNULL:$srsrc, SReg_128_XNULL:$ssamp,
(ins SReg_RSRC:$srsrc, SReg_128_XNULL:$ssamp,
DMask:$dmask, Dim:$dim, UNorm:$unorm, CPol:$cpol,
R128A16:$r128, A16:$a16, TFE:$tfe, LWE:$lwe),
!if(HasD16, (ins D16:$d16), (ins)));
Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/Target/AMDGPU/SIRegisterInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,15 @@ defm "" : SRegClass<16, Reg512Types.types, SGPR_512Regs, TTMP_512Regs>;
defm "" : SRegClass<32, Reg1024Types.types, SGPR_1024Regs>;
}

def SReg_RSRC : SIRegisterClass<"AMDGPU", [v8i32], 32,
(add SReg_256_XNULL, SReg_128_XNULL)> {
let Size = 8;
let CopyCost = -1;
let isAllocatable = 0;
let HasSGPR = 1;
let BaseClassOrder = 10000;
}

def VRegOrLds_32 : SIRegisterClass<"AMDGPU", [i32, f32, i16, f16, bf16, v2i16, v2f16, v2bf16], 32,
(add VGPR_32, LDS_DIRECT_CLASS)> {
let isAllocatable = 0;
Expand Down
Loading