[RISCV] Add scalable vector icmp ISel patterns

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 <rofirrim@gmail.com>
Co-Authored-by: Fraser Cormack <fraser@codeplay.com>

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D94168
This commit is contained in:
Fraser Cormack 2021-01-09 19:21:23 +00:00
parent 41d06095b0
commit b02eab9058
3 changed files with 6195 additions and 0 deletions

View File

@ -35,6 +35,10 @@ def SplatPat : ComplexPattern<vAny, 1, "selectVSplat", [], [], 1>;
def SplatPat_simm5 : ComplexPattern<vAny, 1, "selectVSplatSimm5", []>; def SplatPat_simm5 : ComplexPattern<vAny, 1, "selectVSplatSimm5", []>;
def SplatPat_uimm5 : ComplexPattern<vAny, 1, "selectVSplatUimm5", []>; 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, multiclass VPatUSLoadStoreSDNode<LLVMType type,
LLVMType mask_type, LLVMType mask_type,
int sew, int sew,
@ -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. // Patterns.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -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<srl, "PseudoVSRL", uimm5>;
defm "" : VPatBinarySDNode_VV_VX_VI<sra, "PseudoVSRA", 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 // 12.9. Vector Integer Min/Max Instructions
defm "" : VPatBinarySDNode_VV_VX<umin, "PseudoVMINU">; defm "" : VPatBinarySDNode_VV_VX<umin, "PseudoVMINU">;
defm "" : VPatBinarySDNode_VV_VX<smin, "PseudoVMIN">; defm "" : VPatBinarySDNode_VV_VX<smin, "PseudoVMIN">;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff