Skip to content

Commit

Permalink
[RISCV] Match vmslt(u).vx intrinsics with a small immediate to vmsle(…
Browse files Browse the repository at this point in the history
…u).vx.

There are vmsle(u).vx and vmsle(u).vi instructions, but there is
only vmslt(u).vx and no vmslt(u).vi. vmslt(u).vi can be emulated
for some immediates by decrementing the immediate and using vmsle(u).vi.

To avoid the user needing to know about this, this patch does this
conversion.

The assembler does the same thing for vmslt(u).vi and vmsge(u).vi
pseudoinstructions. There is no vmsge(u).vx intrinsic or
instruction so this patch is limited to vmslt(u).

Reviewed By: frasercrmck

Differential Revision: https://reviews.llvm.org/D94070
  • Loading branch information
topperc committed Jan 5, 2021
1 parent 761aca1 commit c707716
Show file tree
Hide file tree
Showing 5 changed files with 1,918 additions and 0 deletions.
70 changes: 70 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ def NoX0 : SDNodeXForm<undef,
return SDValue(N, 0);
}]>;

def DecImm : SDNodeXForm<imm, [{
return CurDAG->getTargetConstant(N->getSExtValue() - 1, SDLoc(N),
N->getValueType(0));
}]>;

//===----------------------------------------------------------------------===//
// Utilities.
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -3080,6 +3085,71 @@ defm "" : VPatBinaryM_VV_VX_VI<"int_riscv_vmsle", "PseudoVMSLE", AllIntegerVecto
defm "" : VPatBinaryM_VX_VI<"int_riscv_vmsgtu", "PseudoVMSGTU", AllIntegerVectors>;
defm "" : VPatBinaryM_VX_VI<"int_riscv_vmsgt", "PseudoVMSGT", AllIntegerVectors>;

// Match vmslt(u).vx intrinsics to vmsle(u).vi if the scalar is -15 to 16. This
// avoids the user needing to know that there is no vmslt(u).vi instruction.
// This is limited to vmslt(u).vx as there is no vmsge().vx intrinsic or
// instruction.
foreach vti = AllIntegerVectors in {
def : Pat<(vti.Mask (int_riscv_vmslt (vti.Vector vti.RegClass:$rs1),
(vti.Scalar simm5_plus1:$rs2), GPR:$vl)),
(!cast<Instruction>("PseudoVMSLE_VI_"#vti.LMul.MX) vti.RegClass:$rs1,
(DecImm simm5_plus1:$rs2),
(NoX0 GPR:$vl),
vti.SEW)>;
def : Pat<(vti.Mask (int_riscv_vmslt_mask (vti.Mask V0),
(vti.Vector vti.RegClass:$rs1),
(vti.Scalar simm5_plus1:$rs2),
(vti.Mask VR:$merge),
GPR:$vl)),
(!cast<Instruction>("PseudoVMSLE_VI_"#vti.LMul.MX#"_MASK")
VR:$merge,
vti.RegClass:$rs1,
(DecImm simm5_plus1:$rs2),
(vti.Mask V0),
(NoX0 GPR:$vl),
vti.SEW)>;

def : Pat<(vti.Mask (int_riscv_vmsltu (vti.Vector vti.RegClass:$rs1),
(vti.Scalar simm5_plus1:$rs2), GPR:$vl)),
(!cast<Instruction>("PseudoVMSLEU_VI_"#vti.LMul.MX) vti.RegClass:$rs1,
(DecImm simm5_plus1:$rs2),
(NoX0 GPR:$vl),
vti.SEW)>;
def : Pat<(vti.Mask (int_riscv_vmsltu_mask (vti.Mask V0),
(vti.Vector vti.RegClass:$rs1),
(vti.Scalar simm5_plus1:$rs2),
(vti.Mask VR:$merge),
GPR:$vl)),
(!cast<Instruction>("PseudoVMSLEU_VI_"#vti.LMul.MX#"_MASK")
VR:$merge,
vti.RegClass:$rs1,
(DecImm simm5_plus1:$rs2),
(vti.Mask V0),
(NoX0 GPR:$vl),
vti.SEW)>;

// Special cases to avoid matching vmsltu.vi 0 (always false) to
// vmsleu.vi -1 (always true). Instead match to vmsne.vv.
def : Pat<(vti.Mask (int_riscv_vmsltu (vti.Vector vti.RegClass:$rs1),
(vti.Scalar 0), GPR:$vl)),
(!cast<Instruction>("PseudoVMSNE_VV_"#vti.LMul.MX) vti.RegClass:$rs1,
vti.RegClass:$rs1,
(NoX0 GPR:$vl),
vti.SEW)>;
def : Pat<(vti.Mask (int_riscv_vmsltu_mask (vti.Mask V0),
(vti.Vector vti.RegClass:$rs1),
(vti.Scalar 0),
(vti.Mask VR:$merge),
GPR:$vl)),
(!cast<Instruction>("PseudoVMSNE_VV_"#vti.LMul.MX#"_MASK")
VR:$merge,
vti.RegClass:$rs1,
vti.RegClass:$rs1,
(vti.Mask V0),
(NoX0 GPR:$vl),
vti.SEW)>;
}

//===----------------------------------------------------------------------===//
// 12.9. Vector Integer Min/Max Instructions
//===----------------------------------------------------------------------===//
Expand Down
Loading

0 comments on commit c707716

Please sign in to comment.