forked from OSchip/llvm-project
[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:
parent
41d06095b0
commit
b02eab9058
|
@ -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,
|
||||
|
@ -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.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -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">;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue