Skip to content

Commit bcbffd9

Browse files
authored
[AMDGPU] Split Dpp8FI and Dpp16FI operands (#82379)
Split Dpp8FI and Dpp16FI into two different operands sharing an AsmOperandClass. They are parsed and rendered identically as fi:1 but the encoding is different: for DPP16 FI is a single bit, but for DPP8 it uses two different special values in the src0 field. Having a dedicated decoder for Dpp8FI allows it to reject other (non-special) src0 values so that AMDGPUDisassembler::getInstruction no longer needs to call isValidDPP8 to do post hoc validation of decoded DPP8 instructions.
1 parent 6cca23a commit bcbffd9

File tree

8 files changed

+43
-46
lines changed

8 files changed

+43
-46
lines changed

llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,12 @@ static DecodeStatus decodeSplitBarrier(MCInst &Inst, unsigned Val,
119119
return addOperand(Inst, DAsm->decodeSplitBarrier(Val));
120120
}
121121

122+
static DecodeStatus decodeDpp8FI(MCInst &Inst, unsigned Val, uint64_t Addr,
123+
const MCDisassembler *Decoder) {
124+
auto DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
125+
return addOperand(Inst, DAsm->decodeDpp8FI(Val));
126+
}
127+
122128
#define DECODE_OPERAND(StaticDecoderName, DecoderName) \
123129
static DecodeStatus StaticDecoderName(MCInst &Inst, unsigned Imm, \
124130
uint64_t /*Addr*/, \
@@ -440,19 +446,6 @@ static inline DecoderUInt128 eat12Bytes(ArrayRef<uint8_t> &Bytes) {
440446
return DecoderUInt128(Lo, Hi);
441447
}
442448

443-
// The disassembler is greedy, so we need to check FI operand value to
444-
// not parse a dpp if the correct literal is not set. For dpp16 the
445-
// autogenerated decoder checks the dpp literal
446-
static bool isValidDPP8(const MCInst &MI) {
447-
using namespace llvm::AMDGPU::DPP;
448-
int FiIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::fi);
449-
assert(FiIdx != -1);
450-
if ((unsigned)FiIdx >= MI.getNumOperands())
451-
return false;
452-
unsigned Fi = MI.getOperand(FiIdx).getImm();
453-
return Fi == DPP8_FI_0 || Fi == DPP8_FI_1;
454-
}
455-
456449
DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
457450
ArrayRef<uint8_t> Bytes_,
458451
uint64_t Address,
@@ -474,13 +467,11 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
474467
MI, DecW, Address, CS);
475468
if (Res && convertDPP8Inst(MI) == MCDisassembler::Success)
476469
break;
477-
MI = MCInst(); // clear
478470
Res =
479471
tryDecodeInst(DecoderTableDPP8GFX1296, DecoderTableDPP8GFX12_FAKE1696,
480472
MI, DecW, Address, CS);
481473
if (Res && convertDPP8Inst(MI) == MCDisassembler::Success)
482474
break;
483-
MI = MCInst(); // clear
484475

485476
const auto convertVOPDPP = [&]() {
486477
if (MCII->get(MI.getOpcode()).TSFlags & SIInstrFlags::VOP3P) {
@@ -530,26 +521,22 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
530521
break;
531522
if (convertDPP8Inst(MI) == MCDisassembler::Success)
532523
break;
533-
MI = MCInst(); // clear
534524
}
535525
}
536526

537527
Res = tryDecodeInst(DecoderTableDPP864, MI, QW, Address, CS);
538528
if (Res && convertDPP8Inst(MI) == MCDisassembler::Success)
539529
break;
540-
MI = MCInst(); // clear
541530

542531
Res = tryDecodeInst(DecoderTableDPP8GFX1164,
543532
DecoderTableDPP8GFX11_FAKE1664, MI, QW, Address, CS);
544533
if (Res && convertDPP8Inst(MI) == MCDisassembler::Success)
545534
break;
546-
MI = MCInst(); // clear
547535

548536
Res = tryDecodeInst(DecoderTableDPP8GFX1264,
549537
DecoderTableDPP8GFX12_FAKE1664, MI, QW, Address, CS);
550538
if (Res && convertDPP8Inst(MI) == MCDisassembler::Success)
551539
break;
552-
MI = MCInst(); // clear
553540

554541
Res = tryDecodeInst(DecoderTableDPP64, MI, QW, Address, CS);
555542
if (Res) break;
@@ -982,7 +969,7 @@ DecodeStatus AMDGPUDisassembler::convertDPP8Inst(MCInst &MI) const {
982969
AMDGPU::OpName::src1_modifiers);
983970
}
984971
}
985-
return isValidDPP8(MI) ? MCDisassembler::Success : MCDisassembler::SoftFail;
972+
return MCDisassembler::Success;
986973
}
987974

988975
DecodeStatus AMDGPUDisassembler::convertVOP3DPPInst(MCInst &MI) const {
@@ -1831,6 +1818,12 @@ MCOperand AMDGPUDisassembler::decodeSplitBarrier(unsigned Val) const {
18311818
return decodeSrcOp(OPW32, Val);
18321819
}
18331820

1821+
MCOperand AMDGPUDisassembler::decodeDpp8FI(unsigned Val) const {
1822+
if (Val != AMDGPU::DPP::DPP8_FI_0 && Val != AMDGPU::DPP::DPP8_FI_1)
1823+
return MCOperand();
1824+
return MCOperand::createImm(Val);
1825+
}
1826+
18341827
bool AMDGPUDisassembler::isVI() const {
18351828
return STI.hasFeature(AMDGPU::FeatureVolcanicIslands);
18361829
}

llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ class AMDGPUDisassembler : public MCDisassembler {
261261

262262
MCOperand decodeBoolReg(unsigned Val) const;
263263
MCOperand decodeSplitBarrier(unsigned Val) const;
264+
MCOperand decodeDpp8FI(unsigned Val) const;
264265

265266
int getTTmpIdx(unsigned Val) const;
266267

llvm/lib/Target/AMDGPU/SIInstrInfo.td

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -987,8 +987,8 @@ def SDWAVopcDst : BoolRC {
987987
}
988988

989989
class NamedIntOperand<ValueType Type, string Prefix, bit Optional = 1,
990-
string ConvertMethod = "nullptr">
991-
: CustomOperand<Type, Optional, NAME> {
990+
string name = NAME, string ConvertMethod = "nullptr">
991+
: CustomOperand<Type, Optional, name> {
992992
let ParserMethod =
993993
"[this](OperandVector &Operands) -> ParseStatus { "#
994994
"return parseIntWithPrefix(\""#Prefix#"\", Operands, "#
@@ -1090,9 +1090,12 @@ let DefaultValue = "0xf" in {
10901090
def DppRowMask : NamedIntOperand<i32, "row_mask">;
10911091
def DppBankMask : NamedIntOperand<i32, "bank_mask">;
10921092
}
1093-
def DppBoundCtrl : NamedIntOperand<i1, "bound_ctrl", 1,
1093+
def DppBoundCtrl : NamedIntOperand<i1, "bound_ctrl", 1, "DppBoundCtrl",
10941094
"[this] (int64_t &BC) -> bool { return convertDppBoundCtrl(BC); }">;
1095-
def DppFI : NamedIntOperand<i32, "fi">;
1095+
1096+
let DecoderMethod = "decodeDpp8FI" in
1097+
def Dpp8FI : NamedIntOperand<i32, "fi", 1, "DppFI">;
1098+
def Dpp16FI : NamedIntOperand<i32, "fi", 1, "DppFI">;
10961099

10971100
def blgp : CustomOperand<i32, 1, "BLGP">;
10981101
def CBSZ : NamedIntOperand<i32, "cbsz">;
@@ -1823,15 +1826,15 @@ class getInsDPP16 <RegisterOperand OldRC, RegisterOperand Src0RC, RegisterOperan
18231826
Operand Src0Mod, Operand Src1Mod, Operand Src2Mod, bit HasOld = 1> {
18241827
dag ret = !con(getInsDPP<OldRC, Src0RC, Src1RC, Src2RC, NumSrcArgs,
18251828
HasModifiers, Src0Mod, Src1Mod, Src2Mod, HasOld>.ret,
1826-
(ins DppFI:$fi));
1829+
(ins Dpp16FI:$fi));
18271830
}
18281831

18291832
class getInsDPP8 <RegisterOperand OldRC, RegisterOperand Src0RC, RegisterOperand Src1RC,
18301833
RegisterOperand Src2RC, int NumSrcArgs, bit HasModifiers,
18311834
Operand Src0Mod, Operand Src1Mod, Operand Src2Mod, bit HasOld = 1> {
18321835
dag ret = !con(getInsDPPBase<OldRC, Src0RC, Src1RC, Src2RC, NumSrcArgs,
18331836
HasModifiers, Src0Mod, Src1Mod, Src2Mod, HasOld>.ret,
1834-
(ins dpp8:$dpp8, DppFI:$fi));
1837+
(ins dpp8:$dpp8, Dpp8FI:$fi));
18351838
}
18361839

18371840
class getInsVOP3DPPBase<dag VOP3Base, RegisterOperand OldRC, int NumSrcArgs, bit HasOld> {
@@ -1851,12 +1854,12 @@ class getInsVOP3DPP<dag VOP3Base, RegisterOperand OldRC, int NumSrcArgs, bit Has
18511854

18521855
class getInsVOP3DPP16<dag VOP3Base, RegisterOperand OldRC, int NumSrcArgs, bit HasOld = 1> {
18531856
dag ret = !con(getInsVOP3DPP<VOP3Base,OldRC,NumSrcArgs,HasOld>.ret,
1854-
(ins DppFI:$fi));
1857+
(ins Dpp16FI:$fi));
18551858
}
18561859

18571860
class getInsVOP3DPP8<dag VOP3Base, RegisterOperand OldRC, int NumSrcArgs, bit HasOld = 1> {
18581861
dag ret = !con(getInsVOP3DPPBase<VOP3Base,OldRC,NumSrcArgs,HasOld>.ret,
1859-
(ins dpp8:$dpp8, DppFI:$fi));
1862+
(ins dpp8:$dpp8, Dpp8FI:$fi));
18601863
}
18611864

18621865
// Ins for SDWA

llvm/lib/Target/AMDGPU/VOP1Instructions.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,9 +380,9 @@ class VOP_MOVREL<RegisterOperand Src1RC> : VOPProfile<[untyped, i32, untyped, un
380380
let OutsDPP = (outs Src0RC32:$vdst);
381381
let InsDPP16 = (ins Src0RC32:$old, Src0RC32:$src0,
382382
dpp_ctrl:$dpp_ctrl, DppRowMask:$row_mask,
383-
DppBankMask:$bank_mask, DppBoundCtrl:$bound_ctrl, DppFI:$fi);
383+
DppBankMask:$bank_mask, DppBoundCtrl:$bound_ctrl, Dpp16FI:$fi);
384384
let AsmDPP16 = getAsmDPP16<1, 1, 0>.ret;
385-
let InsDPP8 = (ins Src0RC32:$old, Src0RC32:$src0, dpp8:$dpp8, DppFI:$fi);
385+
let InsDPP8 = (ins Src0RC32:$old, Src0RC32:$src0, dpp8:$dpp8, Dpp8FI:$fi);
386386
let AsmDPP8 = getAsmDPP8<1, 1, 0>.ret;
387387

388388
let OutsVOP3DPP = (outs Src0RC64:$vdst);

llvm/lib/Target/AMDGPU/VOP2Instructions.td

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ class VOP_MAC <ValueType vt0, ValueType vt1=vt0> : VOPProfile <[vt0, vt1, vt1, v
430430
getVregSrcForVT<Src2VT>.ret:$src2, // stub argument
431431
dpp_ctrl:$dpp_ctrl, DppRowMask:$row_mask,
432432
DppBankMask:$bank_mask, DppBoundCtrl:$bound_ctrl);
433-
let InsDPP16 = !con(InsDPP, (ins DppFI:$fi));
433+
let InsDPP16 = !con(InsDPP, (ins Dpp16FI:$fi));
434434
let InsVOP3Base = getInsVOP3Base<Src0VOP3DPP, Src1VOP3DPP, RegisterOperand<VGPR_32>, 3,
435435
0, HasModifiers, HasModifiers, HasOMod,
436436
Src0ModVOP3DPP, Src1ModVOP3DPP, Src2Mod, HasOpSel>.ret;
@@ -447,7 +447,7 @@ class VOP_MAC <ValueType vt0, ValueType vt1=vt0> : VOPProfile <[vt0, vt1, vt1, v
447447
let InsDPP8 = (ins Src0ModDPP:$src0_modifiers, Src0DPP:$src0,
448448
Src1ModDPP:$src1_modifiers, Src1DPP:$src1,
449449
getVregSrcForVT<Src2VT>.ret:$src2, // stub argument
450-
dpp8:$dpp8, DppFI:$fi);
450+
dpp8:$dpp8, Dpp8FI:$fi);
451451
let InsSDWA = (ins Src0ModSDWA:$src0_modifiers, Src0SDWA:$src0,
452452
Src1ModSDWA:$src1_modifiers, Src1SDWA:$src1,
453453
getVregSrcForVT<Src2VT>.ret:$src2, // stub argument
@@ -500,7 +500,7 @@ def VOP_MAC_F16_t16 : VOP_MAC <f16> {
500500
let InsDPP8 = (ins Src0ModDPP:$src0_modifiers, Src0DPP:$src0,
501501
Src1ModDPP:$src1_modifiers, Src1DPP:$src1,
502502
getVregSrcForVT<Src2VT, 1/*IsTrue16*/, 1/*IsFake16*/>.ret:$src2, // stub argument
503-
dpp8:$dpp8, DppFI:$fi);
503+
dpp8:$dpp8, Dpp8FI:$fi);
504504
let Src2Mod = FP32InputMods; // dummy unused modifiers
505505
let Src2RC64 = VGPRSrc_32; // stub argument
506506
}
@@ -552,11 +552,11 @@ def VOP2b_I32_I1_I32_I32 : VOPProfile<[i32, i32, i32, untyped], /*EnableClamp=*/
552552
Src1DPP:$src1,
553553
dpp_ctrl:$dpp_ctrl, DppRowMask:$row_mask,
554554
DppBankMask:$bank_mask, DppBoundCtrl:$bound_ctrl);
555-
let InsDPP16 = !con(InsDPP, (ins DppFI:$fi));
555+
let InsDPP16 = !con(InsDPP, (ins Dpp16FI:$fi));
556556
let InsDPP8 = (ins DstRCDPP:$old,
557557
Src0DPP:$src0,
558558
Src1DPP:$src1,
559-
dpp8:$dpp8, DppFI:$fi);
559+
dpp8:$dpp8, Dpp8FI:$fi);
560560
let Outs32 = (outs DstRC:$vdst);
561561
let Outs64 = (outs DstRC:$vdst, VOPDstS64orS32:$sdst);
562562
let OutsVOP3DPP = Outs64;
@@ -594,11 +594,11 @@ def VOP2b_I32_I1_I32_I32_I1 : VOPProfile<[i32, i32, i32, i1], /*EnableClamp=*/1>
594594
Src1DPP:$src1,
595595
dpp_ctrl:$dpp_ctrl, DppRowMask:$row_mask,
596596
DppBankMask:$bank_mask, DppBoundCtrl:$bound_ctrl);
597-
let InsDPP16 = !con(InsDPP, (ins DppFI:$fi));
597+
let InsDPP16 = !con(InsDPP, (ins Dpp16FI:$fi));
598598
let InsDPP8 = (ins DstRCDPP:$old,
599599
Src0DPP:$src0,
600600
Src1DPP:$src1,
601-
dpp8:$dpp8, DppFI:$fi);
601+
dpp8:$dpp8, Dpp8FI:$fi);
602602

603603
let HasExt = 1;
604604
let HasExtDPP = 1;
@@ -645,11 +645,11 @@ class VOP2e_SGPR<list<ValueType> ArgVT> : VOPProfile<ArgVT> {
645645
FPVRegInputMods:$src1_modifiers, Src1DPP:$src1,
646646
dpp_ctrl:$dpp_ctrl, DppRowMask:$row_mask,
647647
DppBankMask:$bank_mask, DppBoundCtrl:$bound_ctrl);
648-
let InsDPP16 = !con(InsDPP, (ins DppFI:$fi));
648+
let InsDPP16 = !con(InsDPP, (ins Dpp16FI:$fi));
649649
let InsDPP8 = (ins DstRCDPP:$old,
650650
FPVRegInputMods:$src0_modifiers, Src0DPP:$src0,
651651
FPVRegInputMods:$src1_modifiers, Src1DPP:$src1,
652-
dpp8:$dpp8, DppFI:$fi);
652+
dpp8:$dpp8, Dpp8FI:$fi);
653653

654654
let Src0ModVOP3DPP = FPVRegInputMods;
655655
let Src1ModVOP3DPP = FPVRegInputMods;

llvm/lib/Target/AMDGPU/VOP3Instructions.td

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -532,11 +532,11 @@ def VOP3_CVT_PK_F8_F32_Profile : VOP3_Profile<VOP_I32_F32_F32, VOP3_OPSEL> {
532532
FP32InputMods:$src1_modifiers, Src1VOP3DPP:$src1,
533533
VGPR_32:$vdst_in, op_sel0:$op_sel,
534534
dpp_ctrl:$dpp_ctrl, DppRowMask:$row_mask,
535-
DppBankMask:$bank_mask, DppBoundCtrl:$bound_ctrl, DppFI:$fi);
535+
DppBankMask:$bank_mask, DppBoundCtrl:$bound_ctrl, Dpp16FI:$fi);
536536
let InsVOP3DPP8 = (ins VGPR_32:$old,
537537
FP32InputMods:$src0_modifiers, Src0VOP3DPP:$src0,
538538
FP32InputMods:$src1_modifiers, Src1VOP3DPP:$src1,
539-
VGPR_32:$vdst_in, op_sel0:$op_sel, dpp8:$dpp8, DppFI:$fi);
539+
VGPR_32:$vdst_in, op_sel0:$op_sel, dpp8:$dpp8, Dpp8FI:$fi);
540540

541541
let HasClamp = 0;
542542
let HasExtVOP3DPP = 1;
@@ -553,12 +553,12 @@ def VOP3_CVT_SR_F8_F32_Profile : VOP3_Profile<VOPProfile<[i32, f32, i32, f32]>,
553553
FP32InputMods:$src1_modifiers, Src1VOP3DPP:$src1,
554554
FP32InputMods:$src2_modifiers, VGPR_32:$src2,
555555
op_sel0:$op_sel, dpp_ctrl:$dpp_ctrl, DppRowMask:$row_mask,
556-
DppBankMask:$bank_mask, DppBoundCtrl:$bound_ctrl, DppFI:$fi);
556+
DppBankMask:$bank_mask, DppBoundCtrl:$bound_ctrl, Dpp16FI:$fi);
557557
let InsVOP3DPP8 = (ins VGPR_32:$old,
558558
FP32InputMods:$src0_modifiers, Src0VOP3DPP:$src0,
559559
FP32InputMods:$src1_modifiers, Src1VOP3DPP:$src1,
560560
FP32InputMods:$src2_modifiers, VGPR_32:$src2,
561-
op_sel0:$op_sel, dpp8:$dpp8, DppFI:$fi);
561+
op_sel0:$op_sel, dpp8:$dpp8, Dpp8FI:$fi);
562562
let HasClamp = 0;
563563
let HasSrc2 = 0;
564564
let HasSrc2Mods = 1;

llvm/lib/Target/AMDGPU/VOP3PInstructions.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,13 +461,13 @@ def VOP3P_DOTF8_Profile : VOP3P_Profile<VOPProfile <[f32, i32, i32, f32]>,
461461

462462
let InsVOP3DPP8 = (ins DstRC:$old, VGPR_32:$src0, VRegSrc_32:$src1,
463463
PackedF16InputMods:$src2_modifiers, VRegSrc_32:$src2,
464-
neg_lo0:$neg_lo, neg_hi0:$neg_hi, dpp8:$dpp8, DppFI:$fi);
464+
neg_lo0:$neg_lo, neg_hi0:$neg_hi, dpp8:$dpp8, Dpp8FI:$fi);
465465

466466
let InsVOP3DPP16 = (ins DstRC:$old, VGPR_32:$src0, VRegSrc_32:$src1,
467467
PackedF16InputMods:$src2_modifiers, VRegSrc_32:$src2,
468468
neg_lo0:$neg_lo, neg_hi0:$neg_hi, dpp_ctrl:$dpp_ctrl,
469469
DppRowMask:$row_mask, DppBankMask:$bank_mask,
470-
DppBoundCtrl:$bound_ctrl, DppFI:$fi);
470+
DppBoundCtrl:$bound_ctrl, Dpp16FI:$fi);
471471
}
472472

473473
multiclass VOP3PDOTF8Inst <string OpName, SDPatternOperator intrinsic_node> {

llvm/lib/Target/AMDGPU/VOPCInstructions.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@ class VOPC_Class_Profile<list<SchedReadWrite> sched, ValueType src0VT, ValueType
766766
let AsmDPP = "$src0_modifiers, $src1 $dpp_ctrl$row_mask$bank_mask$bound_ctrl";
767767
let AsmDPP16 = AsmDPP#"$fi";
768768
let InsDPP = (ins Src0ModDPP:$src0_modifiers, Src0DPP:$src0, Src1DPP:$src1, dpp_ctrl:$dpp_ctrl, DppRowMask:$row_mask, DppBankMask:$bank_mask, DppBoundCtrl:$bound_ctrl);
769-
let InsDPP16 = !con(InsDPP, (ins DppFI:$fi));
769+
let InsDPP16 = !con(InsDPP, (ins Dpp16FI:$fi));
770770
// DPP8 forbids modifiers and can inherit from VOPC_Profile
771771

772772
let Ins64 = (ins Src0Mod:$src0_modifiers, Src0RC64:$src0, Src1RC64:$src1);

0 commit comments

Comments
 (0)