From ff90c60a78a183e17c4b1c455c97c618b542f0bd Mon Sep 17 00:00:00 2001 From: Sam Kolton Date: Wed, 6 Apr 2016 13:29:59 +0000 Subject: [AMDGPU] AsmParser: disable DPP for unsupported instructions. New dpp tests. Fix v_nop_dpp. Summary: 1. Disable DPP encoding for instructions that do not support it: - VOP1: - v_readfirstlane_b32 - v_clrexcp - v_movreld_b32 - v_movrels_b32 - v_movrelsd_b32 - VOP2: - v_madmk_f16/32 - v_madak_f16/32 - VOPC, VINTRP, VOP3 2. Fix DPP for v_nop 3. New DPP tests for VOP1 and VOP2 instructions Reviewers: nhaustov, tstellarAMD, vpykhtin Subscribers: tstellarAMD, arsenm Differential Revision: http://reviews.llvm.org/D18552 llvm-svn: 265538 --- llvm/lib/Target/AMDGPU/SIInstrInfo.td | 57 ++++++++++++++++++++++++++++---- llvm/lib/Target/AMDGPU/SIInstructions.td | 8 ++--- 2 files changed, 54 insertions(+), 11 deletions(-) (limited to 'llvm/lib') diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.td b/llvm/lib/Target/AMDGPU/SIInstrInfo.td index c1ef903ef0b..fbdfc879770 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.td +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.td @@ -1361,7 +1361,11 @@ class getIns64 { - dag ret = !if (!eq(NumSrcArgs, 1), + dag ret = !if (!eq(NumSrcArgs, 0), + // VOP1 without input operands (V_NOP) + (ins dpp_ctrl:$dpp_ctrl, row_mask:$row_mask, + bank_mask:$bank_mask, bound_ctrl:$bound_ctrl), + !if (!eq(NumSrcArgs, 1), !if (!eq(HasModifiers, 1), // VOP1_DPP with modifiers (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0, @@ -1384,7 +1388,15 @@ class getInsDPP { + dag ret = !if(HasDst, + !if(!eq(DstVT.Size, 1), + (outs DstRCDPP:$sdst), // sdst for VOPC + (outs DstRCDPP:$vdst)), + (outs)); // V_NOP } // Returns the assembly string for the inputs and outputs of a VOP[12C] @@ -1417,7 +1429,11 @@ class getAsm64 { - string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC + string dst = !if(HasDst, + !if(!eq(DstVT.Size, 1), + "$sdst", + "$vdst"), + ""); // use $sdst for VOPC string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,"); string src1 = !if(!eq(NumSrcArgs, 1), "", !if(!eq(NumSrcArgs, 2), " $src1_modifiers", @@ -1428,6 +1444,26 @@ class getAsmDPP { + bit ret = !if(!eq(NumSrcArgs, 3), + 0, // NumSrcArgs == 3 - No DPP for VOP3 + !if(!eq(DstVT.Size, 1), + 0, // No DPP for VOPC + !if(!eq(DstVT.Size, 64), + 0, // 64-bit dst - No DPP for 64-bit operands + !if(!eq(Src0VT.Size, 64), + 0, // 64-bit src0 + !if(!eq(Src0VT.Size, 64), + 0, // 64-bit src2 + 1 + ) + ) + ) + ) + ); +} + class VOPProfile _ArgVT> { field list ArgVT = _ArgVT; @@ -1451,14 +1487,15 @@ class VOPProfile _ArgVT> { field int NumSrcArgs = getNumSrcArgs.ret; field bit HasModifiers = hasModifiers.ret; + field bit HasDPP = getHasDPP.ret; + field dag Outs = !if(HasDst,(outs DstRC:$vdst),(outs)); // VOP3b instructions are a special case with a second explicit // output. This is manually overridden for them. field dag Outs32 = Outs; field dag Outs64 = Outs; - field dag OutsDPP = !if(!eq(DstVT.Size, 1), (outs DstRCDPP:$sdst), // sdst for VOPC - (outs DstRCDPP:$vdst)); + field dag OutsDPP = getOutsDPP.ret; field dag Ins32 = getIns32.ret; field dag Ins64 = getIns64 _ArgVT> { field string AsmDPP = getAsmDPP.ret; } +class VOP_NO_DPP : VOPProfile { + let HasDPP = 0; +} + // FIXME: I think these F16/I16 profiles will need to use f16/i16 types in order // for the instruction patterns to work. def VOP_F16_F16 : VOPProfile <[f16, f16, untyped, untyped]>; @@ -1578,10 +1619,12 @@ def VOP_F32_F32_F32_F32 : VOPProfile <[f32, f32, f32, f32]>; def VOP_MADAK : VOPProfile <[f32, f32, f32, f32]> { field dag Ins32 = (ins VCSrc_32:$src0, VGPR_32:$src1, u32imm:$imm); field string Asm32 = "$vdst, $src0, $src1, $imm"; + field bit HasDPP = 0; } def VOP_MADMK : VOPProfile <[f32, f32, f32, f32]> { field dag Ins32 = (ins VCSrc_32:$src0, u32imm:$imm, VGPR_32:$src1); field string Asm32 = "$vdst, $src0, $imm, $src1"; + field bit HasDPP = 0; } def VOP_MAC : VOPProfile <[f32, f32, f32, f32]> { let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1, VGPR_32:$src2); @@ -1704,7 +1747,7 @@ multiclass VOP1_m pattern, class VOP1_DPP : VOP1_DPPe , VOP_DPP { - let AssemblerPredicates = [isVI]; + let AssemblerPredicates = !if(p.HasDPP, [isVI], [DisableInst]); let DecoderNamespace = "DPP"; let DisableDecoder = DisableVIDecoder; let src0_modifiers = !if(p.HasModifiers, ?, 0); @@ -1768,7 +1811,7 @@ multiclass VOP2_m pattern, class VOP2_DPP : VOP2_DPPe , VOP_DPP { - let AssemblerPredicates = [isVI]; + let AssemblerPredicates = !if(p.HasDPP, [isVI], [DisableInst]); let DecoderNamespace = "DPP"; let DisableDecoder = DisableVIDecoder; let src0_modifiers = !if(p.HasModifiers, ?, 0); diff --git a/llvm/lib/Target/AMDGPU/SIInstructions.td b/llvm/lib/Target/AMDGPU/SIInstructions.td index 8687b2a207d..88f1f0c8a8d 100644 --- a/llvm/lib/Target/AMDGPU/SIInstructions.td +++ b/llvm/lib/Target/AMDGPU/SIInstructions.td @@ -1367,13 +1367,13 @@ defm V_FREXP_MANT_F32 : VOP1Inst , "v_frexp_mant_f32", VOP_F32_F32, int_amdgcn_frexp_mant >; let vdst = 0, src0 = 0, VOPAsmPrefer32Bit = 1 in { -defm V_CLREXCP : VOP1Inst , "v_clrexcp", VOP_NONE>; +defm V_CLREXCP : VOP1Inst , "v_clrexcp", VOP_NO_DPP>; } let Uses = [M0, EXEC] in { -defm V_MOVRELD_B32 : VOP1Inst , "v_movreld_b32", VOP_I32_I32>; -defm V_MOVRELS_B32 : VOP1Inst , "v_movrels_b32", VOP_I32_I32>; -defm V_MOVRELSD_B32 : VOP1Inst , "v_movrelsd_b32", VOP_I32_I32>; +defm V_MOVRELD_B32 : VOP1Inst , "v_movreld_b32", VOP_NO_DPP>; +defm V_MOVRELS_B32 : VOP1Inst , "v_movrels_b32", VOP_NO_DPP>; +defm V_MOVRELSD_B32 : VOP1Inst , "v_movrelsd_b32", VOP_NO_DPP>; } // End Uses = [M0, EXEC] // These instruction only exist on SI and CI -- cgit v1.2.3