Skip to content

Commit

Permalink
[AMDGPU] AsmParser: disable DPP for unsupported instructions. New dpp…
Browse files Browse the repository at this point in the history
… 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
  • Loading branch information
SamWot committed Apr 6, 2016
1 parent 074ce83 commit ff90c60
Show file tree
Hide file tree
Showing 3 changed files with 417 additions and 23 deletions.
57 changes: 50 additions & 7 deletions llvm/lib/Target/AMDGPU/SIInstrInfo.td
Expand Up @@ -1361,7 +1361,11 @@ class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC,
class getInsDPP <RegisterClass Src0RC, RegisterClass Src1RC, int NumSrcArgs,
bit HasModifiers> {

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,
Expand All @@ -1384,7 +1388,15 @@ class getInsDPP <RegisterClass Src0RC, RegisterClass Src1RC, int NumSrcArgs,
(ins Src0RC:$src0, Src1RC:$src1, dpp_ctrl:$dpp_ctrl,
row_mask:$row_mask, bank_mask:$bank_mask,
bound_ctrl:$bound_ctrl)
/* endif */));
/* endif */)));
}

class getOutsDPP <bit HasDst, ValueType DstVT, RegisterOperand DstRCDPP> {
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]
Expand Down Expand Up @@ -1417,7 +1429,11 @@ class getAsm64 <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT =
}

class getAsmDPP <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> {
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",
Expand All @@ -1428,6 +1444,26 @@ class getAsmDPP <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT =
string ret = dst#args#" $dpp_ctrl $row_mask $bank_mask $bound_ctrl";
}

class getHasDPP <int NumSrcArgs, ValueType DstVT = i32, ValueType Src0VT = i32,
ValueType Src1VT = i32> {
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 <list<ValueType> _ArgVT> {

field list<ValueType> ArgVT = _ArgVT;
Expand All @@ -1451,14 +1487,15 @@ class VOPProfile <list<ValueType> _ArgVT> {
field int NumSrcArgs = getNumSrcArgs<Src0VT, Src1VT, Src2VT>.ret;
field bit HasModifiers = hasModifiers<Src0VT>.ret;

field bit HasDPP = getHasDPP<NumSrcArgs, DstVT, Src0VT, Src1VT>.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<HasDst, DstVT, DstRCDPP>.ret;

field dag Ins32 = getIns32<Src0RC32, Src1RC32, NumSrcArgs>.ret;
field dag Ins64 = getIns64<Src0RC64, Src1RC64, Src2RC64, NumSrcArgs,
Expand All @@ -1470,6 +1507,10 @@ class VOPProfile <list<ValueType> _ArgVT> {
field string AsmDPP = getAsmDPP<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret;
}

class VOP_NO_DPP <VOPProfile p> : VOPProfile <p.ArgVT> {
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]>;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -1704,7 +1747,7 @@ multiclass VOP1_m <vop1 op, string opName, VOPProfile p, list<dag> pattern,
class VOP1_DPP <vop1 op, string opName, VOPProfile p> :
VOP1_DPPe <op.VI>,
VOP_DPP <p.OutsDPP, p.InsDPP, opName#p.AsmDPP, [], p.HasModifiers> {
let AssemblerPredicates = [isVI];
let AssemblerPredicates = !if(p.HasDPP, [isVI], [DisableInst]);
let DecoderNamespace = "DPP";
let DisableDecoder = DisableVIDecoder;
let src0_modifiers = !if(p.HasModifiers, ?, 0);
Expand Down Expand Up @@ -1768,7 +1811,7 @@ multiclass VOP2_m <vop2 op, string opName, VOPProfile p, list <dag> pattern,
class VOP2_DPP <vop2 op, string opName, VOPProfile p> :
VOP2_DPPe <op.VI>,
VOP_DPP <p.OutsDPP, p.InsDPP, opName#p.AsmDPP, [], p.HasModifiers> {
let AssemblerPredicates = [isVI];
let AssemblerPredicates = !if(p.HasDPP, [isVI], [DisableInst]);
let DecoderNamespace = "DPP";
let DisableDecoder = DisableVIDecoder;
let src0_modifiers = !if(p.HasModifiers, ?, 0);
Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/Target/AMDGPU/SIInstructions.td
Expand Up @@ -1367,13 +1367,13 @@ defm V_FREXP_MANT_F32 : VOP1Inst <vop1<0x40, 0x34>, "v_frexp_mant_f32",
VOP_F32_F32, int_amdgcn_frexp_mant
>;
let vdst = 0, src0 = 0, VOPAsmPrefer32Bit = 1 in {
defm V_CLREXCP : VOP1Inst <vop1<0x41,0x35>, "v_clrexcp", VOP_NONE>;
defm V_CLREXCP : VOP1Inst <vop1<0x41,0x35>, "v_clrexcp", VOP_NO_DPP<VOP_NONE>>;
}

let Uses = [M0, EXEC] in {
defm V_MOVRELD_B32 : VOP1Inst <vop1<0x42, 0x36>, "v_movreld_b32", VOP_I32_I32>;
defm V_MOVRELS_B32 : VOP1Inst <vop1<0x43, 0x37>, "v_movrels_b32", VOP_I32_I32>;
defm V_MOVRELSD_B32 : VOP1Inst <vop1<0x44, 0x38>, "v_movrelsd_b32", VOP_I32_I32>;
defm V_MOVRELD_B32 : VOP1Inst <vop1<0x42, 0x36>, "v_movreld_b32", VOP_NO_DPP<VOP_I32_I32>>;
defm V_MOVRELS_B32 : VOP1Inst <vop1<0x43, 0x37>, "v_movrels_b32", VOP_NO_DPP<VOP_I32_I32>>;
defm V_MOVRELSD_B32 : VOP1Inst <vop1<0x44, 0x38>, "v_movrelsd_b32", VOP_NO_DPP<VOP_I32_I32>>;
} // End Uses = [M0, EXEC]

// These instruction only exist on SI and CI
Expand Down

0 comments on commit ff90c60

Please sign in to comment.