Skip to content

Commit 0a1ac91

Browse files
committed
[AMDGPU][MC] Separate VOPC MnemonicAlias from Instruction
Tablegen classes MnemonicAlias, Requires, and VOPC_Real, all define a field 'Predicates'. The prior formulation resulted in the instantiated record inheriting from all three to only have the Predicate set in Requires, i.e. Gen.AssemblerPredicate. This breaks the design of GCNPredicateControl (which is a parent class of VOPC_Real) that allows multiple predicates such as SubtargetPredicate and OtherPredicates to be set on an Instruction. MnemonicAlias does not need to be defined in the same record as VOPC_Real, so we can separate the definitions and remove Requires to avoid the issue. NFCI, but it enables future changes, such as setting multiple predicates on a VOPC_Real.
1 parent 5d31435 commit 0a1ac91

File tree

1 file changed

+42
-30
lines changed

1 file changed

+42
-30
lines changed

llvm/lib/Target/AMDGPU/VOPCInstructions.td

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,27 +1386,32 @@ multiclass VOPC_Real_Base<GFXGen Gen, bits<9> op> {
13861386

13871387
multiclass VOPC_Real_with_name<GFXGen Gen, bits<9> op, string OpName,
13881388
string asm_name, string pseudo_mnemonic = ""> {
1389-
let AssemblerPredicate = Gen.AssemblerPredicate, DecoderNamespace = Gen.DecoderNamespace in {
1390-
defvar ps32 = !cast<VOPC_Pseudo>(OpName#"_e32");
1391-
defvar ps64 = !cast<VOP3_Pseudo>(OpName#"_e64");
1389+
defvar ps32 = !cast<VOPC_Pseudo>(OpName#"_e32");
1390+
defvar ps64 = !cast<VOP3_Pseudo>(OpName#"_e64");
1391+
let AssemblerPredicate = Gen.AssemblerPredicate in {
1392+
// MnemonicAlias and GCNPredicateControl both define the field Predicates,
1393+
// so GCNPredicateControl must come after MnemonicAlias because it contains
1394+
// the predicates we actually want.
1395+
def : MnemonicAlias<!if(!empty(pseudo_mnemonic), ps32.Mnemonic,
1396+
pseudo_mnemonic),
1397+
asm_name, ps32.AsmVariantName>,
1398+
GCNPredicateControl;
1399+
def : MnemonicAlias<!if(!empty(pseudo_mnemonic), ps64.Mnemonic,
1400+
pseudo_mnemonic),
1401+
asm_name, ps64.AsmVariantName>,
1402+
GCNPredicateControl;
1403+
1404+
let DecoderNamespace = Gen.DecoderNamespace in {
13921405
def _e32#Gen.Suffix :
13931406
// 32 and 64 bit forms of the instruction have _e32 and _e64
13941407
// respectively appended to their assembly mnemonic.
13951408
// _e64 is printed as part of the VOPDstS64orS32 operand, whereas
13961409
// the destination-less 32bit forms add it to the asmString here.
13971410
VOPC_Real<ps32, Gen.Subtarget, asm_name#"_e32">,
1398-
VOPCe<op{7-0}>,
1399-
MnemonicAlias<!if(!empty(pseudo_mnemonic), ps32.Mnemonic,
1400-
pseudo_mnemonic),
1401-
asm_name, ps32.AsmVariantName>,
1402-
Requires<[Gen.AssemblerPredicate]>;
1411+
VOPCe<op{7-0}>;
14031412
def _e64#Gen.Suffix :
1404-
VOP3_Real<ps64, Gen.Subtarget, asm_name>,
1405-
VOP3a_gfx11_gfx12<{0, op}, ps64.Pfl>,
1406-
MnemonicAlias<!if(!empty(pseudo_mnemonic), ps64.Mnemonic,
1407-
pseudo_mnemonic),
1408-
asm_name, ps64.AsmVariantName>,
1409-
Requires<[Gen.AssemblerPredicate]> {
1413+
VOP3_Real_Gen<ps64, Gen, asm_name>,
1414+
VOP3a_gfx11_gfx12<{0, op}, ps64.Pfl> {
14101415
// Encoding used for VOPC instructions encoded as VOP3 differs from
14111416
// VOP3e by destination name (sdst) as VOPC doesn't have vector dst.
14121417
bits<8> sdst;
@@ -1453,8 +1458,9 @@ multiclass VOPC_Real_with_name<GFXGen Gen, bits<9> op, string OpName,
14531458
def _e64_dpp#Gen.Suffix : VOPC64_DPP16_Dst<{0, op}, psDPP, asm_name>,
14541459
SIMCInstr<psDPP.PseudoInstr, Gen.Subtarget>;
14551460
def _e64_dpp8#Gen.Suffix : VOPC64_DPP8_Dst<{0, op}, ps64, asm_name>;
1456-
}
1457-
} // End AssemblerPredicate = Gen.AssemblerPredicate, DecoderNamespace = Gen.DecoderNamespace
1461+
} // end if ps64.Pfl.HasExtVOP3DPP
1462+
} // End DecoderNamespace
1463+
} // End AssemblerPredicate
14581464
}
14591465

14601466
multiclass VOPC_Real_t16<GFXGen Gen, bits<9> op, string asm_name,
@@ -1514,24 +1520,29 @@ multiclass VOPCX_Real<GFXGen Gen, bits<9> op> {
15141520

15151521
multiclass VOPCX_Real_with_name<GFXGen Gen, bits<9> op, string OpName,
15161522
string asm_name, string pseudo_mnemonic = ""> {
1517-
let AssemblerPredicate = Gen.AssemblerPredicate, DecoderNamespace = Gen.DecoderNamespace in {
1518-
defvar ps32 = !cast<VOPC_Pseudo>(OpName#"_nosdst_e32");
1519-
defvar ps64 = !cast<VOP3_Pseudo>(OpName#"_nosdst_e64");
1523+
defvar ps32 = !cast<VOPC_Pseudo>(OpName#"_nosdst_e32");
1524+
defvar ps64 = !cast<VOP3_Pseudo>(OpName#"_nosdst_e64");
1525+
let AssemblerPredicate = Gen.AssemblerPredicate in {
1526+
// MnemonicAlias and GCNPredicateControl both define the field Predicates,
1527+
// so GCNPredicateControl must come after MnemonicAlias because it contains
1528+
// the predicates we actually want.
1529+
def : MnemonicAlias<!if(!empty(pseudo_mnemonic), !subst("_nosdst", "", ps32.Mnemonic),
1530+
pseudo_mnemonic),
1531+
asm_name, ps32.AsmVariantName>,
1532+
GCNPredicateControl;
1533+
def : MnemonicAlias<!if(!empty(pseudo_mnemonic), !subst("_nosdst", "", ps64.Mnemonic),
1534+
pseudo_mnemonic),
1535+
asm_name, ps64.AsmVariantName>,
1536+
GCNPredicateControl;
1537+
1538+
let DecoderNamespace = Gen.DecoderNamespace in {
15201539
def _e32#Gen.Suffix
15211540
: VOPC_Real<ps32, Gen.Subtarget, asm_name>,
1522-
MnemonicAlias<!if(!empty(pseudo_mnemonic), !subst("_nosdst", "", ps32.Mnemonic),
1523-
pseudo_mnemonic),
1524-
asm_name, ps32.AsmVariantName>,
1525-
Requires<[Gen.AssemblerPredicate]>,
15261541
VOPCe<op{7-0}> {
15271542
let AsmString = asm_name # "{_e32} " # ps32.AsmOperands;
15281543
}
15291544
def _e64#Gen.Suffix
1530-
: VOP3_Real<ps64, Gen.Subtarget, asm_name>,
1531-
MnemonicAlias<!if(!empty(pseudo_mnemonic), !subst("_nosdst", "", ps64.Mnemonic),
1532-
pseudo_mnemonic),
1533-
asm_name, ps64.AsmVariantName>,
1534-
Requires<[Gen.AssemblerPredicate]>,
1545+
: VOP3_Real_Gen<ps64, Gen, asm_name>,
15351546
VOP3a_gfx11_gfx12<{0, op}, ps64.Pfl> {
15361547
let Inst{7-0} = ? ; // sdst
15371548
let AsmString = asm_name # "{_e64} " # ps64.AsmOperands;
@@ -1557,8 +1568,9 @@ multiclass VOPCX_Real_with_name<GFXGen Gen, bits<9> op, string OpName,
15571568
def _e64_dpp8#Gen.Suffix : VOPC64_DPP8_NoDst<{0, op}, ps64, asm_name> {
15581569
let AsmString = asm_name # "{_e64_dpp} " # AsmDPP8;
15591570
}
1560-
}
1561-
} // End AssemblerPredicate = Gen.AssemblerPredicate, DecoderNamespace = Gen.DecoderNamespace
1571+
} // End if ps64.Pfl.HasExtVOP3DPP
1572+
} // End DecoderNamespace
1573+
} // End AssemblerPredicate
15621574
}
15631575

15641576
multiclass VOPCX_Real_t16<GFXGen Gen, bits<9> op, string asm_name,

0 commit comments

Comments
 (0)