Skip to content

Commit 4a305d4

Browse files
authored
[AMDGPU] Exclude certain opcodes from being marked as single use (#91802)
The s_singleuse_vdst instruction is used to mark regions of instructions that produce values that have only one use. Certain instructions take more than one cycle to execute, resulting in regions being incorrectly marked. This patch excludes these multi-cycle instructions from being marked as either producing single use values or consuming single use values or both depending on the instruction.
1 parent 7a4fab4 commit 4a305d4

11 files changed

+288
-38
lines changed

llvm/lib/Target/AMDGPU/AMDGPUInsertSingleUseVDST.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
//===----------------------------------------------------------------------===//
1616

1717
#include "AMDGPU.h"
18+
#include "AMDGPUGenSearchableTables.inc"
1819
#include "GCNSubtarget.h"
1920
#include "SIInstrInfo.h"
2021
#include "SIRegisterInfo.h"
@@ -214,12 +215,14 @@ class AMDGPUInsertSingleUseVDST : public MachineFunctionPass {
214215
RegisterUseCount[Unit]++;
215216

216217
// Do not attempt to optimise across exec mask changes.
217-
if (MI.modifiesRegister(AMDGPU::EXEC, TRI)) {
218+
if (MI.modifiesRegister(AMDGPU::EXEC, TRI) ||
219+
AMDGPU::isInvalidSingleUseConsumerInst(MI.getOpcode())) {
218220
for (auto &UsedReg : RegisterUseCount)
219221
UsedReg.second = 2;
220222
}
221223

222-
if (!SIInstrInfo::isVALU(MI))
224+
if (!SIInstrInfo::isVALU(MI) ||
225+
AMDGPU::isInvalidSingleUseProducerInst(MI.getOpcode()))
223226
continue;
224227
if (AllProducerOperandsAreSingleUse) {
225228
SingleUseProducerPositions.push_back({VALUInstrCount, &MI});

llvm/lib/Target/AMDGPU/SIInstrInfo.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2271,6 +2271,8 @@ class VOPProfile <list<ValueType> _ArgVT, bit _EnableClamp = 0> {
22712271
field bit EnableClamp = _EnableClamp;
22722272
field bit IsTrue16 = 0;
22732273
field bit IsRealTrue16 = 0;
2274+
field bit IsInvalidSingleUseConsumer = 0;
2275+
field bit IsInvalidSingleUseProducer = 0;
22742276

22752277
field ValueType DstVT = ArgVT[0];
22762278
field ValueType Src0VT = ArgVT[1];

llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,10 +373,18 @@ struct VOPTrue16Info {
373373
bool IsTrue16;
374374
};
375375

376+
struct SingleUseExceptionInfo {
377+
uint16_t Opcode;
378+
bool IsInvalidSingleUseConsumer;
379+
bool IsInvalidSingleUseProducer;
380+
};
381+
376382
#define GET_MTBUFInfoTable_DECL
377383
#define GET_MTBUFInfoTable_IMPL
378384
#define GET_MUBUFInfoTable_DECL
379385
#define GET_MUBUFInfoTable_IMPL
386+
#define GET_SingleUseExceptionTable_DECL
387+
#define GET_SingleUseExceptionTable_IMPL
380388
#define GET_SMInfoTable_DECL
381389
#define GET_SMInfoTable_IMPL
382390
#define GET_VOP1InfoTable_DECL
@@ -608,6 +616,16 @@ bool isTrue16Inst(unsigned Opc) {
608616
return Info ? Info->IsTrue16 : false;
609617
}
610618

619+
bool isInvalidSingleUseConsumerInst(unsigned Opc) {
620+
const SingleUseExceptionInfo *Info = getSingleUseExceptionHelper(Opc);
621+
return Info && Info->IsInvalidSingleUseConsumer;
622+
}
623+
624+
bool isInvalidSingleUseProducerInst(unsigned Opc) {
625+
const SingleUseExceptionInfo *Info = getSingleUseExceptionHelper(Opc);
626+
return Info && Info->IsInvalidSingleUseProducer;
627+
}
628+
611629
unsigned mapWMMA2AddrTo3AddrOpcode(unsigned Opc) {
612630
const WMMAOpcodeMappingInfo *Info = getWMMAMappingInfoFrom2AddrOpcode(Opc);
613631
return Info ? Info->Opcode3Addr : ~0u;

llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,12 @@ getVOPDInstInfo(unsigned VOPDOpcode, const MCInstrInfo *InstrInfo);
856856
LLVM_READONLY
857857
bool isTrue16Inst(unsigned Opc);
858858

859+
LLVM_READONLY
860+
bool isInvalidSingleUseConsumerInst(unsigned Opc);
861+
862+
LLVM_READONLY
863+
bool isInvalidSingleUseProducerInst(unsigned Opc);
864+
859865
LLVM_READONLY
860866
unsigned mapWMMA2AddrTo3AddrOpcode(unsigned Opc);
861867

llvm/lib/Target/AMDGPU/VOP1Instructions.td

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ def V_READFIRSTLANE_B32 : VOP1_Pseudo <"v_readfirstlane_b32", VOP_READFIRSTLANE,
252252
getVOP1Pat<int_amdgcn_readfirstlane,
253253
VOP_READFIRSTLANE>.ret, 1> {
254254
let isConvergent = 1;
255+
let IsInvalidSingleUseConsumer = 1;
255256
}
256257

257258
let isReMaterializable = 1 in {
@@ -362,6 +363,7 @@ defm V_CLREXCP : VOP1Inst <"v_clrexcp", VOP_NO_EXT<VOP_NONE>>;
362363
def VOP_MOVRELS : VOPProfile<[i32, i32, untyped, untyped]> {
363364
let Src0RC32 = VRegSrc_32;
364365
let Src0RC64 = VRegSrc_32;
366+
let IsInvalidSingleUseConsumer = 1;
365367
}
366368

367369
// Special case because there are no true output operands. Hack vdst
@@ -405,8 +407,12 @@ class VOP_MOVREL<RegisterOperand Src1RC> : VOPProfile<[untyped, i32, untyped, un
405407
let EmitDst = 1; // force vdst emission
406408
}
407409

408-
def VOP_MOVRELD : VOP_MOVREL<VSrc_b32>;
409-
def VOP_MOVRELSD : VOP_MOVREL<VRegSrc_32>;
410+
let IsInvalidSingleUseProducer = 1 in {
411+
def VOP_MOVRELD : VOP_MOVREL<VSrc_b32>;
412+
def VOP_MOVRELSD : VOP_MOVREL<VRegSrc_32> {
413+
let IsInvalidSingleUseConsumer = 1;
414+
}
415+
}
410416

411417
let SubtargetPredicate = HasMovrel, Uses = [M0, EXEC] in {
412418
// v_movreld_b32 is a special case because the destination output
@@ -535,6 +541,7 @@ let SubtargetPredicate = isGFX9Plus in {
535541
let Constraints = "$vdst = $src1, $vdst1 = $src0";
536542
let DisableEncoding = "$vdst1,$src1";
537543
let SchedRW = [Write64Bit, Write64Bit];
544+
let IsInvalidSingleUseConsumer = 1;
538545
}
539546

540547
let isReMaterializable = 1 in
@@ -699,6 +706,8 @@ let SubtargetPredicate = isGFX10Plus in {
699706
let Constraints = "$vdst = $src1, $vdst1 = $src0";
700707
let DisableEncoding = "$vdst1,$src1";
701708
let SchedRW = [Write64Bit, Write64Bit];
709+
let IsInvalidSingleUseConsumer = 1;
710+
let IsInvalidSingleUseProducer = 1;
702711
}
703712
} // End Uses = [M0]
704713
} // End SubtargetPredicate = isGFX10Plus
@@ -720,7 +729,10 @@ let SubtargetPredicate = isGFX11Plus in {
720729
def V_PERMLANE64_B32 : VOP1_Pseudo<"v_permlane64_b32", VOP_MOVRELS,
721730
getVOP1Pat<int_amdgcn_permlane64,
722731
VOP_MOVRELS>.ret,
723-
/*VOP1Only=*/ 1>;
732+
/*VOP1Only=*/ 1> {
733+
let IsInvalidSingleUseConsumer = 1;
734+
let IsInvalidSingleUseProducer = 1;
735+
}
724736
defm V_MOV_B16_t16 : VOP1Inst<"v_mov_b16_t16", VOPProfile_True16<VOP_I16_I16>>;
725737
defm V_NOT_B16 : VOP1Inst_t16<"v_not_b16", VOP_I16_I16>;
726738
defm V_CVT_I32_I16 : VOP1Inst_t16<"v_cvt_i32_i16", VOP_I32_I16>;

llvm/lib/Target/AMDGPU/VOP2Instructions.td

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -779,12 +779,14 @@ defm V_SUBREV_U32 : VOP2Inst <"v_subrev_u32", VOP_I32_I32_I32_ARITH, null_frag,
779779
} // End isCommutable = 1
780780

781781
// These are special and do not read the exec mask.
782-
let isConvergent = 1, Uses = []<Register> in {
782+
let isConvergent = 1, Uses = []<Register>, IsInvalidSingleUseConsumer = 1 in {
783783
def V_READLANE_B32 : VOP2_Pseudo<"v_readlane_b32", VOP_READLANE,
784784
[(set i32:$vdst, (int_amdgcn_readlane i32:$src0, i32:$src1))]>;
785785
let IsNeverUniform = 1, Constraints = "$vdst = $vdst_in", DisableEncoding="$vdst_in" in {
786786
def V_WRITELANE_B32 : VOP2_Pseudo<"v_writelane_b32", VOP_WRITELANE,
787-
[(set i32:$vdst, (int_amdgcn_writelane i32:$src0, i32:$src1, i32:$vdst_in))]>;
787+
[(set i32:$vdst, (int_amdgcn_writelane i32:$src0, i32:$src1, i32:$vdst_in))]> {
788+
let IsInvalidSingleUseProducer = 1;
789+
}
788790
} // End IsNeverUniform, $vdst = $vdst_in, DisableEncoding $vdst_in
789791
} // End isConvergent = 1
790792

llvm/lib/Target/AMDGPU/VOP3Instructions.td

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -155,12 +155,12 @@ defm V_MAX_F64 : VOP3Inst <"v_max_f64", VOP3_Profile<VOP_F64_F64_F64>, fmaxnum_l
155155
} // End SubtargetPredicate = isNotGFX12Plus
156156
} // End SchedRW = [WriteDoubleAdd]
157157

158-
let SchedRW = [WriteIntMul] in {
158+
let SchedRW = [WriteIntMul], IsInvalidSingleUseConsumer = 1 in {
159159
defm V_MUL_LO_U32 : VOP3Inst <"v_mul_lo_u32", V_MUL_PROF<VOP_I32_I32_I32>, DivergentBinFrag<mul>>;
160160
defm V_MUL_HI_U32 : VOP3Inst <"v_mul_hi_u32", V_MUL_PROF<VOP_I32_I32_I32>, mulhu>;
161161
defm V_MUL_LO_I32 : VOP3Inst <"v_mul_lo_i32", V_MUL_PROF<VOP_I32_I32_I32>>;
162162
defm V_MUL_HI_I32 : VOP3Inst <"v_mul_hi_i32", V_MUL_PROF<VOP_I32_I32_I32>, mulhs>;
163-
} // End SchedRW = [WriteIntMul]
163+
} // End SchedRW = [WriteIntMul], IsInvalidSingleUseConsumer = 1
164164

165165
let SubtargetPredicate = isGFX12Plus, ReadsModeReg = 0 in {
166166
defm V_MINIMUM_F32 : VOP3Inst <"v_minimum_f32", VOP3_Profile<VOP_F32_F32_F32>, DivergentBinFrag<fminimum>>;
@@ -258,9 +258,9 @@ let mayRaiseFPException = 0 in { // Seems suspicious but manual doesn't say it d
258258
let isReMaterializable = 1 in
259259
defm V_MSAD_U8 : VOP3Inst <"v_msad_u8", VOP3_Profile<VOP_I32_I32_I32_I32, VOP3_CLAMP>>;
260260

261-
let Constraints = "@earlyclobber $vdst" in {
261+
let Constraints = "@earlyclobber $vdst", IsInvalidSingleUseConsumer = 1 in {
262262
defm V_MQSAD_PK_U16_U8 : VOP3Inst <"v_mqsad_pk_u16_u8", VOP3_Profile<VOP_I64_I64_I32_I64, VOP3_CLAMP>>;
263-
} // End Constraints = "@earlyclobber $vdst"
263+
} // End Constraints = "@earlyclobber $vdst", IsInvalidSingleUseConsumer = 1
264264

265265

266266
let isReMaterializable = 1 in {
@@ -275,14 +275,16 @@ let SchedRW = [Write64Bit] in {
275275
defm V_ASHR_I64 : VOP3Inst <"v_ashr_i64", VOP3_Profile<VOP_I64_I64_I32>, csra_64>;
276276
} // End SubtargetPredicate = isGFX6GFX7
277277

278+
let IsInvalidSingleUseConsumer = 1 in {
278279
let SubtargetPredicate = isGFX8Plus in {
279280
defm V_LSHRREV_B64 : VOP3Inst <"v_lshrrev_b64", VOP3_Profile<VOP_I64_I32_I64>, clshr_rev_64>;
280281
defm V_ASHRREV_I64 : VOP3Inst <"v_ashrrev_i64", VOP3_Profile<VOP_I64_I32_I64>, cashr_rev_64>;
281-
} // End SubtargetPredicate = isGFX8Plus
282+
} // End SubtargetPredicate = isGFX8Plus, , IsInvalidSingleUseConsumer = 1
282283

283284
let SubtargetPredicate = isGFX8GFX9GFX10GFX11 in {
284285
defm V_LSHLREV_B64 : VOP3Inst <"v_lshlrev_b64", VOP3_Profile<VOP_I64_I32_I64>, clshl_rev_64>;
285286
} // End SubtargetPredicate = isGFX8GFX9GFX10GFX11
287+
} // End IsInvalidSingleUseConsumer = 1
286288
} // End SchedRW = [Write64Bit]
287289
} // End isReMaterializable = 1
288290

@@ -307,14 +309,14 @@ def VOPProfileMQSAD : VOP3_Profile<VOP_V4I32_I64_I32_V4I32, VOP3_CLAMP> {
307309
let HasModifiers = 0;
308310
}
309311

310-
let SubtargetPredicate = isGFX7Plus in {
312+
let SubtargetPredicate = isGFX7Plus, IsInvalidSingleUseConsumer = 1 in {
311313
let Constraints = "@earlyclobber $vdst", SchedRW = [WriteQuarterRate32] in {
312314
defm V_QSAD_PK_U16_U8 : VOP3Inst <"v_qsad_pk_u16_u8", VOP3_Profile<VOP_I64_I64_I32_I64, VOP3_CLAMP>>;
313315
defm V_MQSAD_U32_U8 : VOP3Inst <"v_mqsad_u32_u8", VOPProfileMQSAD>;
314316
} // End Constraints = "@earlyclobber $vdst", SchedRW = [WriteQuarterRate32]
315-
} // End SubtargetPredicate = isGFX7Plus
317+
} // End SubtargetPredicate = isGFX7Plus, IsInvalidSingleUseConsumer = 1
316318

317-
let isCommutable = 1, SchedRW = [WriteIntMul, WriteSALU] in {
319+
let isCommutable = 1, SchedRW = [WriteIntMul, WriteSALU], IsInvalidSingleUseConsumer = 1 in {
318320
let SubtargetPredicate = isGFX7Plus, OtherPredicates = [HasNotMADIntraFwdBug] in {
319321
defm V_MAD_U64_U32 : VOP3Inst <"v_mad_u64_u32", VOP3b_I64_I1_I32_I32_I64>;
320322
defm V_MAD_I64_I32 : VOP3Inst <"v_mad_i64_i32", VOP3b_I64_I1_I32_I32_I64>;
@@ -324,7 +326,7 @@ let isCommutable = 1, SchedRW = [WriteIntMul, WriteSALU] in {
324326
defm V_MAD_U64_U32_gfx11 : VOP3Inst <"v_mad_u64_u32", VOP3b_I64_I1_I32_I32_I64>;
325327
defm V_MAD_I64_I32_gfx11 : VOP3Inst <"v_mad_i64_i32", VOP3b_I64_I1_I32_I32_I64>;
326328
}
327-
} // End isCommutable = 1, SchedRW = [WriteIntMul, WriteSALU]
329+
} // End isCommutable = 1, SchedRW = [WriteIntMul, WriteSALU], IsInvalidSingleUseConsumer = 1
328330

329331

330332
let FPDPRounding = 1 in {
@@ -859,10 +861,10 @@ let SubtargetPredicate = isGFX10Plus in {
859861
} // End isCommutable = 1, isReMaterializable = 1
860862
def : ThreeOp_i32_Pats<xor, xor, V_XOR3_B32_e64>;
861863

862-
let Constraints = "$vdst = $vdst_in", DisableEncoding="$vdst_in" in {
864+
let Constraints = "$vdst = $vdst_in", DisableEncoding="$vdst_in", IsInvalidSingleUseConsumer = 1, IsInvalidSingleUseProducer = 1 in {
863865
defm V_PERMLANE16_B32 : VOP3Inst<"v_permlane16_b32", VOP3_PERMLANE_Profile>;
864866
defm V_PERMLANEX16_B32 : VOP3Inst<"v_permlanex16_b32", VOP3_PERMLANE_Profile>;
865-
} // End $vdst = $vdst_in, DisableEncoding $vdst_in
867+
} // End $vdst = $vdst_in, DisableEncoding $vdst_in, IsInvalidSingleUseConsumer = 1, IsInvalidSingleUseProducer = 1
866868

867869
def : PermlanePat<int_amdgcn_permlane16, V_PERMLANE16_B32_e64>;
868870
def : PermlanePat<int_amdgcn_permlanex16, V_PERMLANEX16_B32_e64>;
@@ -1275,11 +1277,12 @@ let AssemblerPredicate = isGFX10Only, DecoderNamespace = "GFX10" in {
12751277
}
12761278
} // End AssemblerPredicate = isGFX10Only, DecoderNamespace = "GFX10"
12771279

1278-
defm V_READLANE_B32 : VOP3_Real_No_Suffix_gfx10<0x360>;
1279-
1280-
let InOperandList = (ins SSrcOrLds_b32:$src0, SCSrc_b32:$src1, VGPR_32:$vdst_in) in {
1281-
defm V_WRITELANE_B32 : VOP3_Real_No_Suffix_gfx10<0x361>;
1282-
} // End InOperandList = (ins SSrcOrLds_b32:$src0, SCSrc_b32:$src1, VGPR_32:$vdst_in)
1280+
let IsInvalidSingleUseConsumer = 1 in {
1281+
defm V_READLANE_B32 : VOP3_Real_No_Suffix_gfx10<0x360>;
1282+
let InOperandList = (ins SSrcOrLds_b32:$src0, SCSrc_b32:$src1, VGPR_32:$vdst_in), IsInvalidSingleUseProducer = 1 in {
1283+
defm V_WRITELANE_B32 : VOP3_Real_No_Suffix_gfx10<0x361>;
1284+
} // End InOperandList = (ins SSrcOrLds_b32:$src0, SCSrc_b32: $src1, VGPR_32:$vdst_in), IsInvalidSingleUseProducer = 1
1285+
} // End IsInvalidSingleUseConsumer = 1
12831286

12841287
let SubtargetPredicate = isGFX10Before1030 in {
12851288
defm V_MUL_LO_I32 : VOP3_Real_gfx10<0x16b>;

llvm/lib/Target/AMDGPU/VOP3PInstructions.td

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -382,15 +382,19 @@ defm V_DOT2_F32_F16 : VOP3PInst<"v_dot2_f32_f16",
382382
AMDGPUfdot2, 1/*ExplicitClamp*/>;
383383

384384
let OtherPredicates = [HasDot7Insts] in {
385-
defm V_DOT4_U32_U8 : VOP3PInst<"v_dot4_u32_u8",
386-
VOP3P_Profile<VOP_I32_I32_I32_I32, VOP3_PACKED>, int_amdgcn_udot4, 1>;
385+
let IsInvalidSingleUseConsumer = 1 in {
386+
defm V_DOT4_U32_U8 : VOP3PInst<"v_dot4_u32_u8",
387+
VOP3P_Profile<VOP_I32_I32_I32_I32, VOP3_PACKED>, int_amdgcn_udot4, 1>;
388+
}
387389
defm V_DOT8_U32_U4 : VOP3PInst<"v_dot8_u32_u4",
388390
VOP3P_Profile<VOP_I32_I32_I32_I32, VOP3_PACKED>, int_amdgcn_udot8, 1>;
389391
} // End OtherPredicates = [HasDot7Insts]
390392

391393
let OtherPredicates = [HasDot1Insts] in {
392-
defm V_DOT4_I32_I8 : VOP3PInst<"v_dot4_i32_i8",
393-
VOP3P_Profile<VOP_I32_I32_I32_I32, VOP3_PACKED>, int_amdgcn_sdot4, 1>;
394+
let IsInvalidSingleUseConsumer = 1 in {
395+
defm V_DOT4_I32_I8 : VOP3PInst<"v_dot4_i32_i8",
396+
VOP3P_Profile<VOP_I32_I32_I32_I32, VOP3_PACKED>, int_amdgcn_sdot4, 1>;
397+
}
394398
defm V_DOT8_I32_I4 : VOP3PInst<"v_dot8_i32_i4",
395399
VOP3P_Profile<VOP_I32_I32_I32_I32, VOP3_PACKED>, int_amdgcn_sdot8, 1>;
396400
} // End OtherPredicates = [HasDot1Insts]

llvm/lib/Target/AMDGPU/VOPCInstructions.td

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -435,8 +435,10 @@ multiclass VOPC_I16 <string opName, SDPatternOperator cond = COND_NULL,
435435
multiclass VOPC_I32 <string opName, SDPatternOperator cond = COND_NULL, string revOp = opName> :
436436
VOPC_Pseudos <opName, VOPC_I1_I32_I32, cond, revOp, 0>;
437437

438-
multiclass VOPC_I64 <string opName, SDPatternOperator cond = COND_NULL, string revOp = opName> :
439-
VOPC_Pseudos <opName, VOPC_I1_I64_I64, cond, revOp, 0>;
438+
let IsInvalidSingleUseConsumer = 1 in {
439+
multiclass VOPC_I64 <string opName, SDPatternOperator cond = COND_NULL, string revOp = opName> :
440+
VOPC_Pseudos <opName, VOPC_I1_I64_I64, cond, revOp, 0>;
441+
}
440442

441443
multiclass VOPCX_F16<string opName, string revOp = opName> {
442444
let OtherPredicates = [Has16BitInsts], True16Predicate = NotHasTrue16BitInsts in {
@@ -465,8 +467,10 @@ multiclass VOPCX_I16<string opName, string revOp = opName> {
465467
multiclass VOPCX_I32 <string opName, string revOp = opName> :
466468
VOPCX_Pseudos <opName, VOPC_I1_I32_I32, VOPC_I32_I32, COND_NULL, revOp>;
467469

468-
multiclass VOPCX_I64 <string opName, string revOp = opName> :
469-
VOPCX_Pseudos <opName, VOPC_I1_I64_I64, VOPC_I64_I64, COND_NULL, revOp>;
470+
let IsInvalidSingleUseConsumer = 1 in {
471+
multiclass VOPCX_I64 <string opName, string revOp = opName> :
472+
VOPCX_Pseudos <opName, VOPC_I1_I64_I64, VOPC_I64_I64, COND_NULL, revOp>;
473+
}
470474

471475

472476
//===----------------------------------------------------------------------===//

llvm/lib/Target/AMDGPU/VOPInstructions.td

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ class LetDummies {
1717
bit isReMaterializable;
1818
bit isAsCheapAsAMove;
1919
bit FPDPRounding;
20+
bit IsInvalidSingleUseConsumer;
21+
bit IsInvalidSingleUseProducer;
2022
Predicate SubtargetPredicate;
2123
string Constraints;
2224
string DisableEncoding;
@@ -81,6 +83,8 @@ class VOP_Pseudo <string opName, string suffix, VOPProfile P, dag outs, dag ins,
8183
string Mnemonic = opName;
8284
Instruction Opcode = !cast<Instruction>(NAME);
8385
bit IsTrue16 = P.IsTrue16;
86+
bit IsInvalidSingleUseConsumer = P.IsInvalidSingleUseConsumer;
87+
bit IsInvalidSingleUseProducer = P.IsInvalidSingleUseProducer;
8488
VOPProfile Pfl = P;
8589

8690
string AsmOperands;
@@ -175,6 +179,8 @@ class VOP3P_Pseudo <string opName, VOPProfile P, list<dag> pattern = []> :
175179
class VOP_Real<VOP_Pseudo ps> {
176180
Instruction Opcode = !cast<Instruction>(NAME);
177181
bit IsSingle = ps.Pfl.IsSingle;
182+
bit IsInvalidSingleUseConsumer = ps.Pfl.IsInvalidSingleUseConsumer;
183+
bit IsInvalidSingleUseProducer = ps.Pfl.IsInvalidSingleUseProducer;
178184
}
179185

180186
class VOP3_Real <VOP_Pseudo ps, int EncodingFamily, string asm_name = ps.Mnemonic> :
@@ -823,9 +829,7 @@ class VOP3P_DPPe_Common<bits<7> op, VOPProfile P> : VOP3P_DPPe_Common_Base<op, P
823829

824830
class VOP_DPP_Pseudo <string OpName, VOPProfile P, list<dag> pattern=[],
825831
dag Ins = P.InsDPP, string asmOps = P.AsmDPP> :
826-
InstSI <P.OutsDPP, Ins, OpName#asmOps, pattern>,
827-
VOP <OpName>,
828-
SIMCInstr <OpName#"_dpp", SIEncodingFamily.NONE> {
832+
VOP_Pseudo<OpName, "_dpp", P, P.OutsDPP, Ins, asmOps, pattern> {
829833

830834
let isPseudo = 1;
831835
let isCodeGenOnly = 1;
@@ -857,6 +861,9 @@ class VOP_DPP_Pseudo <string OpName, VOPProfile P, list<dag> pattern=[],
857861
let DisableEncoding = !if(P.NumSrcArgs, P.TieRegDPP, "");
858862
let DecoderNamespace = "GFX8";
859863

864+
let IsInvalidSingleUseConsumer = !not(VINTERP);
865+
let IsInvalidSingleUseProducer = !not(VINTERP);
866+
860867
VOPProfile Pfl = P;
861868
}
862869

@@ -1725,3 +1732,12 @@ def VOPTrue16Table : GenericTable {
17251732
let PrimaryKey = ["Opcode"];
17261733
let PrimaryKeyName = "getTrue16OpcodeHelper";
17271734
}
1735+
1736+
def SingleUseExceptionTable : GenericTable {
1737+
let FilterClass = "VOP_Pseudo";
1738+
let CppTypeName = "SingleUseExceptionInfo";
1739+
let Fields = ["Opcode", "IsInvalidSingleUseConsumer", "IsInvalidSingleUseProducer"];
1740+
1741+
let PrimaryKey = ["Opcode"];
1742+
let PrimaryKeyName = "getSingleUseExceptionHelper";
1743+
}

0 commit comments

Comments
 (0)