Skip to content

Commit d737c47

Browse files
committed
[RISCV] Support vector SET[U]LT and SET[U]GE with splatted immediates
This patch adds more optimized codegen for the above SETCC forms, by matching the '.vi' vector forms when the immediate is a 5-bit signed immediate plus 1. The immediate can be decremented and the corresponding SET[U]LE or SET[U]GT forms can be matched. This work was left as a TODO from D94168. Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D100096
1 parent 7f9e36b commit d737c47

File tree

8 files changed

+292
-287
lines changed

8 files changed

+292
-287
lines changed

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,7 +1153,12 @@ bool RISCVDAGToDAGISel::selectVSplat(SDValue N, SDValue &SplatVal) {
11531153
return true;
11541154
}
11551155

1156-
bool RISCVDAGToDAGISel::selectVSplatSimm5(SDValue N, SDValue &SplatVal) {
1156+
using ValidateFn = bool (*)(int64_t);
1157+
1158+
static bool selectVSplatSimmHelper(SDValue N, SDValue &SplatVal,
1159+
SelectionDAG &DAG,
1160+
const RISCVSubtarget &Subtarget,
1161+
ValidateFn ValidateImm) {
11571162
if ((N.getOpcode() != ISD::SPLAT_VECTOR &&
11581163
N.getOpcode() != RISCVISD::SPLAT_VECTOR_I64 &&
11591164
N.getOpcode() != RISCVISD::VMV_V_X_VL) ||
@@ -1162,28 +1167,46 @@ bool RISCVDAGToDAGISel::selectVSplatSimm5(SDValue N, SDValue &SplatVal) {
11621167

11631168
int64_t SplatImm = cast<ConstantSDNode>(N.getOperand(0))->getSExtValue();
11641169

1165-
// Both ISD::SPLAT_VECTOR and RISCVISD::SPLAT_VECTOR_I64 share semantics when
1166-
// the operand type is wider than the resulting vector element type: an
1167-
// implicit truncation first takes place. Therefore, perform a manual
1168-
// truncation/sign-extension in order to ignore any truncated bits and catch
1169-
// any zero-extended immediate.
1170+
// ISD::SPLAT_VECTOR, RISCVISD::SPLAT_VECTOR_I64 and RISCVISD::VMV_V_X_VL
1171+
// share semantics when the operand type is wider than the resulting vector
1172+
// element type: an implicit truncation first takes place. Therefore, perform
1173+
// a manual truncation/sign-extension in order to ignore any truncated bits
1174+
// and catch any zero-extended immediate.
11701175
// For example, we wish to match (i8 -1) -> (XLenVT 255) as a simm5 by first
11711176
// sign-extending to (XLenVT -1).
1172-
MVT XLenVT = Subtarget->getXLenVT();
1177+
MVT XLenVT = Subtarget.getXLenVT();
11731178
assert(XLenVT == N.getOperand(0).getSimpleValueType() &&
11741179
"Unexpected splat operand type");
11751180
MVT EltVT = N.getSimpleValueType().getVectorElementType();
1176-
if (EltVT.bitsLT(XLenVT)) {
1181+
if (EltVT.bitsLT(XLenVT))
11771182
SplatImm = SignExtend64(SplatImm, EltVT.getSizeInBits());
1178-
}
11791183

1180-
if (!isInt<5>(SplatImm))
1184+
if (!ValidateImm(SplatImm))
11811185
return false;
11821186

1183-
SplatVal = CurDAG->getTargetConstant(SplatImm, SDLoc(N), XLenVT);
1187+
SplatVal = DAG.getTargetConstant(SplatImm, SDLoc(N), XLenVT);
11841188
return true;
11851189
}
11861190

1191+
bool RISCVDAGToDAGISel::selectVSplatSimm5(SDValue N, SDValue &SplatVal) {
1192+
return selectVSplatSimmHelper(N, SplatVal, *CurDAG, *Subtarget,
1193+
[](int64_t Imm) { return isInt<5>(Imm); });
1194+
}
1195+
1196+
bool RISCVDAGToDAGISel::selectVSplatSimm5Plus1(SDValue N, SDValue &SplatVal) {
1197+
return selectVSplatSimmHelper(
1198+
N, SplatVal, *CurDAG, *Subtarget,
1199+
[](int64_t Imm) { return (isInt<5>(Imm) && Imm != -16) || Imm == 16; });
1200+
}
1201+
1202+
bool RISCVDAGToDAGISel::selectVSplatSimm5Plus1NonZero(SDValue N,
1203+
SDValue &SplatVal) {
1204+
return selectVSplatSimmHelper(
1205+
N, SplatVal, *CurDAG, *Subtarget, [](int64_t Imm) {
1206+
return Imm != 0 && ((isInt<5>(Imm) && Imm != -16) || Imm == 16);
1207+
});
1208+
}
1209+
11871210
bool RISCVDAGToDAGISel::selectVSplatUimm5(SDValue N, SDValue &SplatVal) {
11881211
if ((N.getOpcode() != ISD::SPLAT_VECTOR &&
11891212
N.getOpcode() != RISCVISD::SPLAT_VECTOR_I64 &&

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
6464
bool selectVSplat(SDValue N, SDValue &SplatVal);
6565
bool selectVSplatSimm5(SDValue N, SDValue &SplatVal);
6666
bool selectVSplatUimm5(SDValue N, SDValue &SplatVal);
67+
bool selectVSplatSimm5Plus1(SDValue N, SDValue &SplatVal);
68+
bool selectVSplatSimm5Plus1NonZero(SDValue N, SDValue &SplatVal);
6769

6870
bool selectRVVSimm5(SDValue N, unsigned Width, SDValue &Imm);
6971
template <unsigned Width> bool selectRVVSimm5(SDValue N, SDValue &Imm) {

llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ def rv32_splat_i64 : SDNode<"RISCVISD::SPLAT_VECTOR_I64", SDTSplatI64>;
3232
def SplatPat : ComplexPattern<vAny, 1, "selectVSplat", [splat_vector, rv32_splat_i64], [], 1>;
3333
def SplatPat_simm5 : ComplexPattern<vAny, 1, "selectVSplatSimm5", [splat_vector, rv32_splat_i64], [], 2>;
3434
def SplatPat_uimm5 : ComplexPattern<vAny, 1, "selectVSplatUimm5", [splat_vector, rv32_splat_i64], [], 2>;
35+
def SplatPat_simm5_plus1
36+
: ComplexPattern<vAny, 1, "selectVSplatSimm5Plus1",
37+
[splat_vector, rv32_splat_i64], [], 2>;
38+
def SplatPat_simm5_plus1_nonzero
39+
: ComplexPattern<vAny, 1, "selectVSplatSimm5Plus1NonZero",
40+
[splat_vector, rv32_splat_i64], [], 2>;
3541

3642
class SwapHelper<dag Prefix, dag A, dag B, dag Suffix, bit swap> {
3743
dag Value = !con(Prefix, !if(swap, B, A), !if(swap, A, B), Suffix);
@@ -255,6 +261,18 @@ multiclass VPatIntegerSetCCSDNode_VX_VI<CondCode cc,
255261
SplatPat_simm5, simm5, swap>;
256262
}
257263

264+
multiclass VPatIntegerSetCCSDNode_VIPlus1<CondCode cc, string instruction_name,
265+
ComplexPattern splatpat_kind> {
266+
foreach vti = AllIntegerVectors in {
267+
defvar instruction = !cast<Instruction>(instruction_name#"_VI_"#vti.LMul.MX);
268+
def : Pat<(vti.Mask (setcc (vti.Vector vti.RegClass:$rs1),
269+
(vti.Vector (splatpat_kind simm5:$rs2)),
270+
cc)),
271+
(instruction vti.RegClass:$rs1, (DecImm simm5:$rs2),
272+
vti.AVL, vti.SEW)>;
273+
}
274+
}
275+
258276
multiclass VPatFPSetCCSDNode_VV_VF_FV<CondCode cc,
259277
string inst_name,
260278
string swapped_op_inst_name> {
@@ -413,10 +431,12 @@ defm : VPatBinarySDNode_VV_VX_VI<sra, "PseudoVSRA", uimm5>;
413431
defm : VPatIntegerSetCCSDNode_VV_VX_VI<SETEQ, "PseudoVMSEQ">;
414432
defm : VPatIntegerSetCCSDNode_VV_VX_VI<SETNE, "PseudoVMSNE">;
415433

416-
// FIXME: Support immediate forms of these by choosing SLE decrementing the
417-
// immediate
418434
defm : VPatIntegerSetCCSDNode_VV_VX<SETLT, "PseudoVMSLT">;
419435
defm : VPatIntegerSetCCSDNode_VV_VX<SETULT, "PseudoVMSLTU">;
436+
defm : VPatIntegerSetCCSDNode_VIPlus1<SETLT, "PseudoVMSLE",
437+
SplatPat_simm5_plus1>;
438+
defm : VPatIntegerSetCCSDNode_VIPlus1<SETULT, "PseudoVMSLEU",
439+
SplatPat_simm5_plus1_nonzero>;
420440

421441
defm : VPatIntegerSetCCSDNode_VV<SETGT, "PseudoVMSLT", /*swap*/1>;
422442
defm : VPatIntegerSetCCSDNode_VV<SETUGT, "PseudoVMSLTU", /*swap*/1>;
@@ -426,10 +446,12 @@ defm : VPatIntegerSetCCSDNode_VX_VI<SETUGT, "PseudoVMSGTU">;
426446
defm : VPatIntegerSetCCSDNode_VV_VX_VI<SETLE, "PseudoVMSLE">;
427447
defm : VPatIntegerSetCCSDNode_VV_VX_VI<SETULE, "PseudoVMSLEU">;
428448

429-
// FIXME: Support immediate forms of these by choosing SGT and decrementing the
430-
// immediate
431449
defm : VPatIntegerSetCCSDNode_VV<SETGE, "PseudoVMSLE", /*swap*/1>;
432450
defm : VPatIntegerSetCCSDNode_VV<SETUGE, "PseudoVMSLEU", /*swap*/1>;
451+
defm : VPatIntegerSetCCSDNode_VIPlus1<SETGE, "PseudoVMSGT",
452+
SplatPat_simm5_plus1>;
453+
defm : VPatIntegerSetCCSDNode_VIPlus1<SETUGE, "PseudoVMSGTU",
454+
SplatPat_simm5_plus1_nonzero>;
433455

434456
// 12.9. Vector Integer Min/Max Instructions
435457
defm : VPatBinarySDNode_VV_VX<umin, "PseudoVMINU">;

llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,6 @@ multiclass VPatIntegerSetCCVL_VX_Swappable<VTypeInfo vti, string instruction_nam
396396
multiclass VPatIntegerSetCCVL_VI_Swappable<VTypeInfo vti, string instruction_name,
397397
CondCode cc, CondCode invcc> {
398398
defvar instruction = !cast<Instruction>(instruction_name#"_VI_"#vti.LMul.MX);
399-
defvar ImmPat = !cast<ComplexPattern>("sew"#vti.SEW#"simm5");
400399
def : Pat<(vti.Mask (riscv_setcc_vl (vti.Vector vti.RegClass:$rs1),
401400
(SplatPat_simm5 simm5:$rs2), cc,
402401
(vti.Mask true_mask),
@@ -409,6 +408,17 @@ multiclass VPatIntegerSetCCVL_VI_Swappable<VTypeInfo vti, string instruction_nam
409408
(instruction vti.RegClass:$rs1, simm5:$rs2, GPR:$vl, vti.SEW)>;
410409
}
411410

411+
multiclass VPatIntegerSetCCVL_VIPlus1<VTypeInfo vti, string instruction_name,
412+
CondCode cc, ComplexPattern splatpat_kind> {
413+
defvar instruction = !cast<Instruction>(instruction_name#"_VI_"#vti.LMul.MX);
414+
def : Pat<(vti.Mask (riscv_setcc_vl (vti.Vector vti.RegClass:$rs1),
415+
(splatpat_kind simm5:$rs2), cc,
416+
(vti.Mask true_mask),
417+
(XLenVT (VLOp GPR:$vl)))),
418+
(instruction vti.RegClass:$rs1, (DecImm simm5:$rs2),
419+
GPR:$vl, vti.SEW)>;
420+
}
421+
412422
multiclass VPatFPSetCCVL_VV_VF_FV<CondCode cc,
413423
string inst_name,
414424
string swapped_op_inst_name> {
@@ -637,12 +647,19 @@ foreach vti = AllIntegerVectors in {
637647
defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSGTU", SETUGT, SETULT>;
638648
// There is no VMSGE(U)_VX instruction
639649

640-
// FIXME: Support immediate forms of these by choosing SGT and decrementing
641-
// the immediate
642650
defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSEQ", SETEQ, SETEQ>;
643651
defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSNE", SETNE, SETNE>;
644652
defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSLE", SETLE, SETGE>;
645653
defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSLEU", SETULE, SETUGE>;
654+
655+
defm : VPatIntegerSetCCVL_VIPlus1<vti, "PseudoVMSLE", SETLT,
656+
SplatPat_simm5_plus1>;
657+
defm : VPatIntegerSetCCVL_VIPlus1<vti, "PseudoVMSLEU", SETULT,
658+
SplatPat_simm5_plus1_nonzero>;
659+
defm : VPatIntegerSetCCVL_VIPlus1<vti, "PseudoVMSGT", SETGE,
660+
SplatPat_simm5_plus1>;
661+
defm : VPatIntegerSetCCVL_VIPlus1<vti, "PseudoVMSGTU", SETUGE,
662+
SplatPat_simm5_plus1_nonzero>;
646663
} // foreach vti = AllIntegerVectors
647664

648665
// 12.9. Vector Integer Min/Max Instructions

llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int-setcc.ll

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ define void @setlt_vi_v128i8(<128 x i8>* %x, <128 x i1>* %z) {
570570
; CHECK-NEXT: addi a2, zero, 128
571571
; CHECK-NEXT: vsetvli a2, a2, e8,m8,ta,mu
572572
; CHECK-NEXT: vle8.v v8, (a0)
573-
; CHECK-NEXT: vmslt.vx v25, v8, zero
573+
; CHECK-NEXT: vmsle.vi v25, v8, -1
574574
; CHECK-NEXT: vse1.v v25, (a1)
575575
; CHECK-NEXT: ret
576576
%a = load <128 x i8>, <128 x i8>* %x
@@ -586,9 +586,8 @@ define void @setge_vi_v8i8(<8 x i8>* %x, <8 x i1>* %z) {
586586
; CHECK: # %bb.0:
587587
; CHECK-NEXT: vsetivli a2, 8, e8,m1,ta,mu
588588
; CHECK-NEXT: vle8.v v25, (a0)
589-
; CHECK-NEXT: vmv.v.i v26, 0
590-
; CHECK-NEXT: vmsle.vv v27, v26, v25
591-
; CHECK-NEXT: vse1.v v27, (a1)
589+
; CHECK-NEXT: vmsgt.vi v26, v25, -1
590+
; CHECK-NEXT: vse1.v v26, (a1)
592591
; CHECK-NEXT: ret
593592
%a = load <8 x i8>, <8 x i8>* %x
594593
%b = insertelement <8 x i8> undef, i8 0, i32 0
@@ -638,8 +637,7 @@ define void @setult_vi_v64i8(<64 x i8>* %x, <64 x i1>* %z) {
638637
; CHECK-NEXT: addi a2, zero, 64
639638
; CHECK-NEXT: vsetvli a2, a2, e8,m4,ta,mu
640639
; CHECK-NEXT: vle8.v v28, (a0)
641-
; CHECK-NEXT: addi a0, zero, 5
642-
; CHECK-NEXT: vmsltu.vx v25, v28, a0
640+
; CHECK-NEXT: vmsleu.vi v25, v28, 4
643641
; CHECK-NEXT: vse1.v v25, (a1)
644642
; CHECK-NEXT: ret
645643
%a = load <64 x i8>, <64 x i8>* %x
@@ -656,8 +654,7 @@ define void @setuge_vi_v128i8(<128 x i8>* %x, <128 x i1>* %z) {
656654
; CHECK-NEXT: addi a2, zero, 128
657655
; CHECK-NEXT: vsetvli a2, a2, e8,m8,ta,mu
658656
; CHECK-NEXT: vle8.v v8, (a0)
659-
; CHECK-NEXT: vmv.v.i v16, 5
660-
; CHECK-NEXT: vmsleu.vv v25, v16, v8
657+
; CHECK-NEXT: vmsgtu.vi v25, v8, 4
661658
; CHECK-NEXT: vse1.v v25, (a1)
662659
; CHECK-NEXT: ret
663660
%a = load <128 x i8>, <128 x i8>* %x

llvm/test/CodeGen/RISCV/rvv/saddo-sdnode.ll

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ define <vscale x 2 x i32> @saddo_nvx2i32(<vscale x 2 x i32> %x, <vscale x 2 x i3
77
; CHECK-LABEL: saddo_nvx2i32:
88
; CHECK: # %bb.0:
99
; CHECK-NEXT: vsetvli a0, zero, e32,m1,ta,mu
10-
; CHECK-NEXT: vmslt.vx v25, v9, zero
11-
; CHECK-NEXT: vadd.vv v26, v8, v9
12-
; CHECK-NEXT: vmslt.vv v27, v26, v8
10+
; CHECK-NEXT: vadd.vv v25, v8, v9
11+
; CHECK-NEXT: vmslt.vv v26, v25, v8
12+
; CHECK-NEXT: vmsle.vi v27, v9, -1
1313
; CHECK-NEXT: vsetvli a0, zero, e8,mf4,ta,mu
14-
; CHECK-NEXT: vmxor.mm v0, v25, v27
14+
; CHECK-NEXT: vmxor.mm v0, v27, v26
1515
; CHECK-NEXT: vsetvli a0, zero, e32,m1,ta,mu
16-
; CHECK-NEXT: vmerge.vim v8, v26, 0, v0
16+
; CHECK-NEXT: vmerge.vim v8, v25, 0, v0
1717
; CHECK-NEXT: ret
1818
%a = call { <vscale x 2 x i32>, <vscale x 2 x i1> } @llvm.sadd.with.overflow.nxv2i32(<vscale x 2 x i32> %x, <vscale x 2 x i32> %y)
1919
%b = extractvalue { <vscale x 2 x i32>, <vscale x 2 x i1> } %a, 0

0 commit comments

Comments
 (0)