Skip to content

Commit

Permalink
[RISCV] Add scalable vector icmp ISel patterns
Browse files Browse the repository at this point in the history
Original patch by @rogfer01.

The RVV integer comparison instructions are defined in such a way that
many LLVM operations are defined by using the "opposite" comparison
instruction and swapping the operands. This is done in this patch in
most cases, except for the mappings where the immediate range must be
adjusted to accomodate:

    va < i --> vmsle{u}.vi vd, va, i-1, vm
    va >= i --> vmsgt{u}.vi vd, va, i-1, vm

That is left for future optimization; this patch supports all operations
but in the case of the missing mappings the immediate will be moved to
a scalar register first.

Since there are so many condition codes and operand cases to check, it
was decided to reduce the test burden by only testing the "vscale x 8"
vector types.

Authored-by: Roger Ferrer Ibanez <[email protected]>
Co-Authored-by: Fraser Cormack <[email protected]>

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D94168
  • Loading branch information
frasercrmck committed Jan 9, 2021
1 parent 41d0609 commit b02eab9
Show file tree
Hide file tree
Showing 3 changed files with 6,195 additions and 0 deletions.
86 changes: 86 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ def SplatPat : ComplexPattern<vAny, 1, "selectVSplat", [], [], 1>;
def SplatPat_simm5 : ComplexPattern<vAny, 1, "selectVSplatSimm5", []>;
def SplatPat_uimm5 : ComplexPattern<vAny, 1, "selectVSplatUimm5", []>;

class SwapHelper<dag Prefix, dag A, dag B, dag Suffix, bit swap> {
dag Value = !con(Prefix, !if(swap, B, A), !if(swap, A, B), Suffix);
}

multiclass VPatUSLoadStoreSDNode<LLVMType type,
LLVMType mask_type,
int sew,
Expand Down Expand Up @@ -128,6 +132,66 @@ multiclass VPatBinarySDNode_VV_VX_VI<SDNode vop, string instruction_name,
}
}

multiclass VPatIntegerSetCCSDNode_VV<CondCode cc,
string instruction_name,
bit swap = 0> {
foreach vti = AllIntegerVectors in {
defvar instruction = !cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX);
def : Pat<(vti.Mask (setcc (vti.Vector vti.RegClass:$rs1),
(vti.Vector vti.RegClass:$rs2), cc)),
SwapHelper<(instruction),
(instruction vti.RegClass:$rs1),
(instruction vti.RegClass:$rs2),
(instruction VLMax, vti.SEW),
swap>.Value>;
}
}

multiclass VPatIntegerSetCCSDNode_XI<CondCode cc,
string instruction_name,
string kind,
ComplexPattern SplatPatKind,
DAGOperand xop_kind,
bit swap = 0> {
foreach vti = AllIntegerVectors in {
defvar instruction = !cast<Instruction>(instruction_name#_#kind#_#vti.LMul.MX);
def : Pat<(vti.Mask (setcc (vti.Vector vti.RegClass:$rs1),
(vti.Vector (SplatPatKind xop_kind:$rs2)), cc)),
SwapHelper<(instruction),
(instruction vti.RegClass:$rs1),
(instruction xop_kind:$rs2),
(instruction VLMax, vti.SEW),
swap>.Value>;
}
}

multiclass VPatIntegerSetCCSDNode_VV_VX_VI<CondCode cc,
string instruction_name,
bit swap = 0> {
defm : VPatIntegerSetCCSDNode_VV<cc, instruction_name, swap>;
defm : VPatIntegerSetCCSDNode_XI<cc, instruction_name, "VX",
SplatPat, GPR, swap>;
defm : VPatIntegerSetCCSDNode_XI<cc, instruction_name, "VI",
SplatPat_simm5, simm5, swap>;
}

multiclass VPatIntegerSetCCSDNode_VV_VX<CondCode cc,
string instruction_name,
bit swap = 0> {
defm : VPatIntegerSetCCSDNode_VV<cc, instruction_name, swap>;
defm : VPatIntegerSetCCSDNode_XI<cc, instruction_name, "VX",
SplatPat, GPR, swap>;
}

multiclass VPatIntegerSetCCSDNode_VX_VI<CondCode cc,
string instruction_name,
bit swap = 0> {
defm : VPatIntegerSetCCSDNode_XI<cc, instruction_name, "VX",
SplatPat, GPR, swap>;
defm : VPatIntegerSetCCSDNode_XI<cc, instruction_name, "VI",
SplatPat_simm5, simm5, swap>;
}

//===----------------------------------------------------------------------===//
// Patterns.
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -164,6 +228,28 @@ defm "" : VPatBinarySDNode_VV_VX_VI<shl, "PseudoVSLL", uimm5>;
defm "" : VPatBinarySDNode_VV_VX_VI<srl, "PseudoVSRL", uimm5>;
defm "" : VPatBinarySDNode_VV_VX_VI<sra, "PseudoVSRA", uimm5>;

// 12.8. Vector Integer Comparison Instructions
defm "" : VPatIntegerSetCCSDNode_VV_VX_VI<SETEQ, "PseudoVMSEQ">;
defm "" : VPatIntegerSetCCSDNode_VV_VX_VI<SETNE, "PseudoVMSNE">;

// FIXME: Support immediate forms of these by choosing SLE decrementing the
// immediate
defm "" : VPatIntegerSetCCSDNode_VV_VX<SETLT, "PseudoVMSLT">;
defm "" : VPatIntegerSetCCSDNode_VV_VX<SETULT, "PseudoVMSLTU">;

defm "" : VPatIntegerSetCCSDNode_VV<SETGT, "PseudoVMSLT", /*swap*/1>;
defm "" : VPatIntegerSetCCSDNode_VV<SETUGT, "PseudoVMSLTU", /*swap*/1>;
defm "" : VPatIntegerSetCCSDNode_VX_VI<SETGT, "PseudoVMSGT">;
defm "" : VPatIntegerSetCCSDNode_VX_VI<SETUGT, "PseudoVMSGTU">;

defm "" : VPatIntegerSetCCSDNode_VV_VX_VI<SETLE, "PseudoVMSLE">;
defm "" : VPatIntegerSetCCSDNode_VV_VX_VI<SETULE, "PseudoVMSLEU">;

// FIXME: Support immediate forms of these by choosing SGT and decrementing the
// immediate
defm "" : VPatIntegerSetCCSDNode_VV<SETGE, "PseudoVMSLE", /*swap*/1>;
defm "" : VPatIntegerSetCCSDNode_VV<SETUGE, "PseudoVMSLEU", /*swap*/1>;

// 12.9. Vector Integer Min/Max Instructions
defm "" : VPatBinarySDNode_VV_VX<umin, "PseudoVMINU">;
defm "" : VPatBinarySDNode_VV_VX<smin, "PseudoVMIN">;
Expand Down
Loading

0 comments on commit b02eab9

Please sign in to comment.