diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.h b/llvm/lib/Target/AMDGPU/SIInstrInfo.h index e55418326a4bd..960fbb7ea15ce 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.h +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.h @@ -1568,6 +1568,11 @@ namespace AMDGPU { LLVM_READONLY int getMFMAEarlyClobberOp(uint16_t Opcode); + /// \returns Version of an MFMA instruction which uses AGPRs for srcC and + /// vdst, given an \p Opcode of an MFMA which uses VGPRs for srcC/vdst. + LLVM_READONLY + int getMFMASrcCVDstAGPROp(uint16_t Opcode); + /// \returns v_cmpx version of a v_cmp instruction. LLVM_READONLY int getVCMPXOpFromVCMP(uint16_t Opcode); diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.td b/llvm/lib/Target/AMDGPU/SIInstrInfo.td index 7f77270a93183..e7fbcee2286be 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.td +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.td @@ -3174,6 +3174,15 @@ def getMFMAEarlyClobberOp : InstrMapping { let ValueCols = [["0"]]; } +// Map from an mfma using VGPRs to one using AGPRs. +def getMFMASrcCVDstAGPROp : InstrMapping { + let FilterClass = "MFMATable"; + let RowFields = ["AGPROp"]; + let ColFields = ["MFMAKind"]; + let KeyCol = ["VGPR"]; + let ValueCols = [["AGPR"]]; +} + // Maps an v_cmp instruction to its v_cmpx equivalent. def getVCMPXOpFromVCMP : InstrMapping { let FilterClass = "VCMPVCMPXTable"; diff --git a/llvm/lib/Target/AMDGPU/VOP3PInstructions.td b/llvm/lib/Target/AMDGPU/VOP3PInstructions.td index 5d8dc5ccd18e5..9099df6e4bf57 100644 --- a/llvm/lib/Target/AMDGPU/VOP3PInstructions.td +++ b/llvm/lib/Target/AMDGPU/VOP3PInstructions.td @@ -742,9 +742,14 @@ def VOPProfileMAI_I32_V4I32_X16 : VOPProfileMAI; -class MFMATable { +class MFMATable { bit IsMac = is_mac; string FMAOp = Name; + string AGPROp = AGPROpName; + + // Does this MFMA use "AGPR" or "VGPR" for srcC/vdst + string MFMAKind = Kind; } class MFMA_F8F6F4_WithSizeTable { @@ -850,12 +855,12 @@ multiclass MAIInst("VOPProfileMAI_" # P), !if(!or(NoDstOverlap, !eq(node, null_frag)), null_frag, AgprMAIFrag), Scaled>, - MFMATable<0, NAME # "_e64">; + MFMATable<0, "AGPR", NAME # "_e64">; let OtherPredicates = [isGFX90APlus], Mnemonic = OpName in def _vgprcd_e64 : MAIInst("VOPProfileMAI_" # P # "_VCD"), !if(!or(NoDstOverlap, !eq(node, null_frag)), null_frag, VgprMAIFrag), Scaled>, - MFMATable<0, NAME # "_vgprcd_e64">; + MFMATable<0, "VGPR", NAME # "_vgprcd_e64", NAME # "_e64">; } if NoDstOverlap then { @@ -864,12 +869,12 @@ multiclass MAIInst("VOPProfileMAI_" # P), !if(!eq(node, null_frag), null_frag, AgprMAIFrag), Scaled>, - MFMATable<1, NAME # "_e64">; + MFMATable<1, "AGPR", NAME # "_e64", NAME # "_mac_e64">; let OtherPredicates = [isGFX90APlus] in def _mac_vgprcd_e64 : MAIInst("VOPProfileMAI_" # P # "_VCD"), !if(!eq(node, null_frag), null_frag, VgprMAIFrag), Scaled>, - MFMATable<1, NAME # "_vgprcd_e64">; + MFMATable<1, "VGPR", NAME # "_vgprcd_e64">; } } } // End isConvergent = 1, mayRaiseFPException = 0, ReadsModeReg = 1 @@ -886,11 +891,11 @@ multiclass ScaledMAIInst_mc(UnscaledOpName#"_e64"), !if(NoDstOverlap, null_frag, AgprMAIFrag)>, - MFMATable<0, NAME # "_e64">; + MFMATable<0, "AGPR", NAME # "_e64">; def _vgprcd_e64 : ScaledMAIInst(UnscaledOpName#"_vgprcd_e64"), !if(NoDstOverlap, null_frag, VgprMAIFrag)>, - MFMATable<0, NAME # "_vgprcd_e64">; + MFMATable<0, "VGPR", NAME # "_vgprcd_e64", NAME # "_e64">; if NoDstOverlap then { let Constraints = !if(NoDstOverlap, "$vdst = $src2", ""), @@ -898,11 +903,11 @@ multiclass ScaledMAIInst_mc(UnscaledOpName # "_mac_e64"), AgprMAIFrag>, - MFMATable<1, NAME # "_e64">; + MFMATable<1, "AGPR", NAME # "_e64">; def _mac_vgprcd_e64 : ScaledMAIInst(UnscaledOpName # "_mac_vgprcd_e64"), VgprMAIFrag>, - MFMATable<1, NAME # "_vgprcd_e64">; + MFMATable<1, "VGPR", NAME # "_vgprcd_e64", NAME # "_mac_e64">; } } }