diff --git a/llvm/lib/Target/AMDGPU/VOPCInstructions.td b/llvm/lib/Target/AMDGPU/VOPCInstructions.td index 0b3a3d5321bd3..a0d666b39b2bf 100644 --- a/llvm/lib/Target/AMDGPU/VOPCInstructions.td +++ b/llvm/lib/Target/AMDGPU/VOPCInstructions.td @@ -1386,75 +1386,81 @@ multiclass VOPC_Real_Base op> { multiclass VOPC_Real_with_name op, string OpName, string asm_name, string pseudo_mnemonic = ""> { - let AssemblerPredicate = Gen.AssemblerPredicate, DecoderNamespace = Gen.DecoderNamespace in { - defvar ps32 = !cast(OpName#"_e32"); - defvar ps64 = !cast(OpName#"_e64"); - def _e32#Gen.Suffix : - // 32 and 64 bit forms of the instruction have _e32 and _e64 - // respectively appended to their assembly mnemonic. - // _e64 is printed as part of the VOPDstS64orS32 operand, whereas - // the destination-less 32bit forms add it to the asmString here. - VOPC_Real, - VOPCe, - MnemonicAlias, - Requires<[Gen.AssemblerPredicate]>; - def _e64#Gen.Suffix : - VOP3_Real, - VOP3a_gfx11_gfx12<{0, op}, ps64.Pfl>, - MnemonicAlias(OpName#"_e32"); + defvar ps64 = !cast(OpName#"_e64"); + let AssemblerPredicate = Gen.AssemblerPredicate in { + // MnemonicAlias and GCNPredicateControl both define the field Predicates, + // so GCNPredicateControl must come after MnemonicAlias because it contains + // the predicates we actually want. + def : MnemonicAlias, + GCNPredicateControl; + def : MnemonicAlias, - Requires<[Gen.AssemblerPredicate]> { - // Encoding used for VOPC instructions encoded as VOP3 differs from - // VOP3e by destination name (sdst) as VOPC doesn't have vector dst. - bits<8> sdst; - let Inst{7-0} = sdst; - } - - defm : VOPCInstAliases; - - if ps32.Pfl.HasExtDPP then { - defvar psDPP = !cast(OpName #"_e32" #"_dpp"); - defvar AsmDPP = ps32.Pfl.AsmDPP16; - def _e32_dpp#Gen.Suffix : VOPC_DPP16_SIMC; - def _e32_dpp_w32#Gen.Suffix - : VOPC_DPP16 { - let AsmString = asm_name # " vcc_lo, " # AsmDPP; - let isAsmParserOnly = 1; - let WaveSizePredicate = isWave32; - } - def _e32_dpp_w64#Gen.Suffix - : VOPC_DPP16 { - let AsmString = asm_name # " vcc, " # AsmDPP; - let isAsmParserOnly = 1; - let WaveSizePredicate = isWave64; + GCNPredicateControl; + + let DecoderNamespace = Gen.DecoderNamespace in { + def _e32#Gen.Suffix : + // 32 and 64 bit forms of the instruction have _e32 and _e64 + // respectively appended to their assembly mnemonic. + // _e64 is printed as part of the VOPDstS64orS32 operand, whereas + // the destination-less 32bit forms add it to the asmString here. + VOPC_Real, + VOPCe; + def _e64#Gen.Suffix : + VOP3_Real_Gen, + VOP3a_gfx11_gfx12<{0, op}, ps64.Pfl> { + // Encoding used for VOPC instructions encoded as VOP3 differs from + // VOP3e by destination name (sdst) as VOPC doesn't have vector dst. + bits<8> sdst; + let Inst{7-0} = sdst; } - defvar AsmDPP8 = ps32.Pfl.AsmDPP8; - def _e32_dpp8#Gen.Suffix : VOPC_DPP8; - def _e32_dpp8_w32#Gen.Suffix - : VOPC_DPP8 { - let AsmString = asm_name # " vcc_lo, " # AsmDPP8; - let isAsmParserOnly = 1; - let WaveSizePredicate = isWave32; - } - def _e32_dpp8_w64#Gen.Suffix - : VOPC_DPP8 { - let AsmString = asm_name # " vcc, " # AsmDPP8; - let isAsmParserOnly = 1; - let WaveSizePredicate = isWave64; + + defm : VOPCInstAliases; + + if ps32.Pfl.HasExtDPP then { + defvar psDPP = !cast(OpName #"_e32" #"_dpp"); + defvar AsmDPP = ps32.Pfl.AsmDPP16; + def _e32_dpp#Gen.Suffix : VOPC_DPP16_SIMC; + def _e32_dpp_w32#Gen.Suffix + : VOPC_DPP16 { + let AsmString = asm_name # " vcc_lo, " # AsmDPP; + let isAsmParserOnly = 1; + let WaveSizePredicate = isWave32; + } + def _e32_dpp_w64#Gen.Suffix + : VOPC_DPP16 { + let AsmString = asm_name # " vcc, " # AsmDPP; + let isAsmParserOnly = 1; + let WaveSizePredicate = isWave64; + } + defvar AsmDPP8 = ps32.Pfl.AsmDPP8; + def _e32_dpp8#Gen.Suffix : VOPC_DPP8; + def _e32_dpp8_w32#Gen.Suffix + : VOPC_DPP8 { + let AsmString = asm_name # " vcc_lo, " # AsmDPP8; + let isAsmParserOnly = 1; + let WaveSizePredicate = isWave32; + } + def _e32_dpp8_w64#Gen.Suffix + : VOPC_DPP8 { + let AsmString = asm_name # " vcc, " # AsmDPP8; + let isAsmParserOnly = 1; + let WaveSizePredicate = isWave64; + } } - } - if ps64.Pfl.HasExtVOP3DPP then { - defvar psDPP = !cast(OpName #"_e64" #"_dpp"); - def _e64_dpp#Gen.Suffix : VOPC64_DPP16_Dst<{0, op}, psDPP, asm_name>, - SIMCInstr; - def _e64_dpp8#Gen.Suffix : VOPC64_DPP8_Dst<{0, op}, ps64, asm_name>; - } - } // End AssemblerPredicate = Gen.AssemblerPredicate, DecoderNamespace = Gen.DecoderNamespace + if ps64.Pfl.HasExtVOP3DPP then { + defvar psDPP = !cast(OpName #"_e64" #"_dpp"); + def _e64_dpp#Gen.Suffix : VOPC64_DPP16_Dst<{0, op}, psDPP, asm_name>, + SIMCInstr; + def _e64_dpp8#Gen.Suffix : VOPC64_DPP8_Dst<{0, op}, ps64, asm_name>; + } // end if ps64.Pfl.HasExtVOP3DPP + } // End DecoderNamespace + } // End AssemblerPredicate } multiclass VOPC_Real_t16 op, string asm_name, @@ -1514,51 +1520,57 @@ multiclass VOPCX_Real op> { multiclass VOPCX_Real_with_name op, string OpName, string asm_name, string pseudo_mnemonic = ""> { - let AssemblerPredicate = Gen.AssemblerPredicate, DecoderNamespace = Gen.DecoderNamespace in { - defvar ps32 = !cast(OpName#"_nosdst_e32"); - defvar ps64 = !cast(OpName#"_nosdst_e64"); - def _e32#Gen.Suffix - : VOPC_Real, - MnemonicAlias(OpName#"_nosdst_e32"); + defvar ps64 = !cast(OpName#"_nosdst_e64"); + let AssemblerPredicate = Gen.AssemblerPredicate in { + // MnemonicAlias and GCNPredicateControl both define the field Predicates, + // so GCNPredicateControl must come after MnemonicAlias because it contains + // the predicates we actually want. + def : MnemonicAlias, - Requires<[Gen.AssemblerPredicate]>, - VOPCe { - let AsmString = asm_name # "{_e32} " # ps32.AsmOperands; - } - def _e64#Gen.Suffix - : VOP3_Real, - MnemonicAlias, - Requires<[Gen.AssemblerPredicate]>, - VOP3a_gfx11_gfx12<{0, op}, ps64.Pfl> { - let Inst{7-0} = ? ; // sdst - let AsmString = asm_name # "{_e64} " # ps64.AsmOperands; - } - - defm : VOPCXInstAliases; + GCNPredicateControl; - if ps32.Pfl.HasExtDPP then { - defvar psDPP = !cast(OpName#"_nosdst_e32"#"_dpp"); - def _e32_dpp#Gen.Suffix : VOPC_DPP16_SIMC; - def _e32_dpp8#Gen.Suffix : VOPC_DPP8; - } - if ps64.Pfl.HasExtVOP3DPP then { - defvar psDPP = !cast(OpName#"_nosdst_e64"#"_dpp"); - defvar AsmDPP = ps64.Pfl.AsmVOP3DPP16; - def _e64_dpp#Gen.Suffix - : VOPC64_DPP16_NoDst<{0, op}, psDPP, asm_name>, - SIMCInstr { - let AsmString = asm_name # "{_e64_dpp} " # AsmDPP; + let DecoderNamespace = Gen.DecoderNamespace in { + def _e32#Gen.Suffix + : VOPC_Real, + VOPCe { + let AsmString = asm_name # "{_e32} " # ps32.AsmOperands; } - defvar AsmDPP8 = ps64.Pfl.AsmVOP3DPP8; - def _e64_dpp8#Gen.Suffix : VOPC64_DPP8_NoDst<{0, op}, ps64, asm_name> { - let AsmString = asm_name # "{_e64_dpp} " # AsmDPP8; + def _e64#Gen.Suffix + : VOP3_Real_Gen, + VOP3a_gfx11_gfx12<{0, op}, ps64.Pfl> { + let Inst{7-0} = ? ; // sdst + let AsmString = asm_name # "{_e64} " # ps64.AsmOperands; } - } - } // End AssemblerPredicate = Gen.AssemblerPredicate, DecoderNamespace = Gen.DecoderNamespace + + defm : VOPCXInstAliases; + + if ps32.Pfl.HasExtDPP then { + defvar psDPP = !cast(OpName#"_nosdst_e32"#"_dpp"); + def _e32_dpp#Gen.Suffix : VOPC_DPP16_SIMC; + def _e32_dpp8#Gen.Suffix : VOPC_DPP8; + } + if ps64.Pfl.HasExtVOP3DPP then { + defvar psDPP = !cast(OpName#"_nosdst_e64"#"_dpp"); + defvar AsmDPP = ps64.Pfl.AsmVOP3DPP16; + def _e64_dpp#Gen.Suffix + : VOPC64_DPP16_NoDst<{0, op}, psDPP, asm_name>, + SIMCInstr { + let AsmString = asm_name # "{_e64_dpp} " # AsmDPP; + } + defvar AsmDPP8 = ps64.Pfl.AsmVOP3DPP8; + def _e64_dpp8#Gen.Suffix : VOPC64_DPP8_NoDst<{0, op}, ps64, asm_name> { + let AsmString = asm_name # "{_e64_dpp} " # AsmDPP8; + } + } // End if ps64.Pfl.HasExtVOP3DPP + } // End DecoderNamespace + } // End AssemblerPredicate } multiclass VOPCX_Real_t16 op, string asm_name,