Skip to content

Commit fa315ec

Browse files
authored
[RISCV] Convert vsub.vx to vadd.vi if possible (#130669)
We'd already had this transform for the intrinsics, but hadn't added it for either fixed length or scalable vectors coming from normal IR. For the record, the fact we have three different sets of patterns here really is quite ugly.
1 parent b15ccd4 commit fa315ec

14 files changed

+2020
-2235
lines changed

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3573,6 +3573,13 @@ bool RISCVDAGToDAGISel::selectVSplatSimm5Plus1(SDValue N, SDValue &SplatVal) {
35733573
/*Decrement=*/true);
35743574
}
35753575

3576+
bool RISCVDAGToDAGISel::selectVSplatSimm5Plus1NoDec(SDValue N, SDValue &SplatVal) {
3577+
return selectVSplatImmHelper(
3578+
N, SplatVal, *CurDAG, *Subtarget,
3579+
[](int64_t Imm) { return (isInt<5>(Imm) && Imm != -16) || Imm == 16; },
3580+
/*Decrement=*/false);
3581+
}
3582+
35763583
bool RISCVDAGToDAGISel::selectVSplatSimm5Plus1NonZero(SDValue N,
35773584
SDValue &SplatVal) {
35783585
return selectVSplatImmHelper(

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
137137
return selectVSplatUimm(N, Bits, Val);
138138
}
139139
bool selectVSplatSimm5Plus1(SDValue N, SDValue &SplatVal);
140+
bool selectVSplatSimm5Plus1NoDec(SDValue N, SDValue &SplatVal);
140141
bool selectVSplatSimm5Plus1NonZero(SDValue N, SDValue &SplatVal);
141142
// Matches the splat of a value which can be extended or truncated, such that
142143
// only the bottom 8 bits are preserved.

llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -877,9 +877,9 @@ foreach mti = AllMasks in
877877
// 11.1. Vector Single-Width Integer Add and Subtract
878878
defm : VPatBinarySDNode_VV_VX_VI<add, "PseudoVADD">;
879879
defm : VPatBinarySDNode_VV_VX<sub, "PseudoVSUB">;
880-
// Handle VRSUB specially since it's the only integer binary op with reversed
881-
// pattern operands
882880
foreach vti = AllIntegerVectors in {
881+
// Handle VRSUB specially since it's the only integer binary op with reversed
882+
// pattern operands
883883
// FIXME: The AddedComplexity here is covering up a missing matcher for
884884
// widening vwsub.vx which can recognize a extended folded into the
885885
// scalar of the splat.
@@ -896,6 +896,15 @@ foreach vti = AllIntegerVectors in {
896896
(vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1,
897897
simm5:$rs2, vti.AVL, vti.Log2SEW, TA_MA)>;
898898
}
899+
900+
let Predicates = GetVTypePredicates<vti>.Predicates in {
901+
// Match VSUB with a small immediate to vadd.vi by negating the immediate.
902+
def : Pat<(sub (vti.Vector vti.RegClass:$rs1),
903+
(vti.Vector (SplatPat_simm5_plus1_nodec simm5_plus1:$rs2))),
904+
(!cast<Instruction>("PseudoVADD_VI_"#vti.LMul.MX)
905+
(vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1,
906+
(NegImm simm5_plus1:$rs2), vti.AVL, vti.Log2SEW, TA_MA)>;
907+
}
899908
}
900909

901910
// 11.2. Vector Widening Integer Add and Subtract

llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,8 @@ def SplatPat_uimm5 : ComplexPattern<vAny, 1, "selectVSplatUimmBits<5>", [], [],
598598
def SplatPat_uimm6 : ComplexPattern<vAny, 1, "selectVSplatUimmBits<6>", [], [], 3>;
599599
def SplatPat_simm5_plus1
600600
: ComplexPattern<vAny, 1, "selectVSplatSimm5Plus1", [], [], 3>;
601+
def SplatPat_simm5_plus1_nodec
602+
: ComplexPattern<vAny, 1, "selectVSplatSimm5Plus1NoDec", [], [], 3>;
601603
def SplatPat_simm5_plus1_nonzero
602604
: ComplexPattern<vAny, 1, "selectVSplatSimm5Plus1NonZero", [], [], 3>;
603605

@@ -1992,10 +1994,10 @@ multiclass VPatAVGADDVL_VV_VX_RM<SDNode vop, int vxrm, string suffix = ""> {
19921994
// 11.1. Vector Single-Width Integer Add and Subtract
19931995
defm : VPatBinaryVL_VV_VX_VI<riscv_add_vl, "PseudoVADD">;
19941996
defm : VPatBinaryVL_VV_VX<riscv_sub_vl, "PseudoVSUB">;
1995-
// Handle VRSUB specially since it's the only integer binary op with reversed
1996-
// pattern operands
19971997
foreach vti = AllIntegerVectors in {
19981998
let Predicates = GetVTypePredicates<vti>.Predicates in {
1999+
// Handle VRSUB specially since it's the only integer binary op with
2000+
// reversed pattern operands
19992001
def : Pat<(riscv_sub_vl (vti.Vector (SplatPat (XLenVT GPR:$rs2))),
20002002
(vti.Vector vti.RegClass:$rs1),
20012003
vti.RegClass:$passthru, (vti.Mask VMV0:$vm), VLOpFrag),
@@ -2008,6 +2010,15 @@ foreach vti = AllIntegerVectors in {
20082010
(!cast<Instruction>("PseudoVRSUB_VI_"# vti.LMul.MX#"_MASK")
20092011
vti.RegClass:$passthru, vti.RegClass:$rs1, simm5:$rs2,
20102012
(vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>;
2013+
2014+
// Match VSUB with a small immediate to vadd.vi by negating the immediate.
2015+
def : Pat<(riscv_sub_vl (vti.Vector vti.RegClass:$rs1),
2016+
(vti.Vector (SplatPat_simm5_plus1_nodec simm5_plus1:$rs2)),
2017+
vti.RegClass:$passthru, (vti.Mask VMV0:$vm), VLOpFrag),
2018+
(!cast<Instruction>("PseudoVADD_VI_"#vti.LMul.MX#"_MASK")
2019+
vti.RegClass:$passthru, vti.RegClass:$rs1,
2020+
(NegImm simm5_plus1:$rs2), (vti.Mask VMV0:$vm),
2021+
GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>;
20112022
}
20122023
}
20132024

llvm/test/CodeGen/RISCV/rvv/ctlz-vp.ll

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2585,8 +2585,7 @@ define <vscale x 1 x i9> @vp_ctlz_nxv1i9(<vscale x 1 x i9> %va, <vscale x 1 x i1
25852585
; CHECK-NEXT: vrsub.vx v8, v8, a0, v0.t
25862586
; CHECK-NEXT: li a0, 16
25872587
; CHECK-NEXT: vminu.vx v8, v8, a0, v0.t
2588-
; CHECK-NEXT: li a0, 7
2589-
; CHECK-NEXT: vsub.vx v8, v8, a0, v0.t
2588+
; CHECK-NEXT: vadd.vi v8, v8, -7, v0.t
25902589
; CHECK-NEXT: ret
25912590
;
25922591
; CHECK-ZVBB-LABEL: vp_ctlz_nxv1i9:
@@ -2595,8 +2594,7 @@ define <vscale x 1 x i9> @vp_ctlz_nxv1i9(<vscale x 1 x i9> %va, <vscale x 1 x i1
25952594
; CHECK-ZVBB-NEXT: vsetvli zero, a0, e16, mf4, ta, ma
25962595
; CHECK-ZVBB-NEXT: vand.vx v8, v8, a1, v0.t
25972596
; CHECK-ZVBB-NEXT: vclz.v v8, v8, v0.t
2598-
; CHECK-ZVBB-NEXT: li a0, 7
2599-
; CHECK-ZVBB-NEXT: vsub.vx v8, v8, a0, v0.t
2597+
; CHECK-ZVBB-NEXT: vadd.vi v8, v8, -7, v0.t
26002598
; CHECK-ZVBB-NEXT: ret
26012599
%v = call <vscale x 1 x i9> @llvm.vp.ctlz.nxv1i9(<vscale x 1 x i9> %va, i1 false, <vscale x 1 x i1> %m, i32 %evl)
26022600
ret <vscale x 1 x i9> %v
@@ -2744,13 +2742,12 @@ define <vscale x 1 x i9> @vp_ctlo_zero_nxv1i9_unpredicated_ctlz_with_vp_xor(<vsc
27442742
; CHECK-NEXT: li a0, 142
27452743
; CHECK-NEXT: vsetvli a2, zero, e16, mf4, ta, ma
27462744
; CHECK-NEXT: vand.vx v8, v8, a1
2747-
; CHECK-NEXT: li a1, 16
27482745
; CHECK-NEXT: vfwcvt.f.xu.v v9, v8
27492746
; CHECK-NEXT: vnsrl.wi v8, v9, 23
27502747
; CHECK-NEXT: vrsub.vx v8, v8, a0
2751-
; CHECK-NEXT: vminu.vx v8, v8, a1
2752-
; CHECK-NEXT: li a0, 7
2753-
; CHECK-NEXT: vsub.vx v8, v8, a0
2748+
; CHECK-NEXT: li a0, 16
2749+
; CHECK-NEXT: vminu.vx v8, v8, a0
2750+
; CHECK-NEXT: vadd.vi v8, v8, -7
27542751
; CHECK-NEXT: ret
27552752
;
27562753
; CHECK-ZVBB-LABEL: vp_ctlo_zero_nxv1i9_unpredicated_ctlz_with_vp_xor:
@@ -2761,8 +2758,7 @@ define <vscale x 1 x i9> @vp_ctlo_zero_nxv1i9_unpredicated_ctlz_with_vp_xor(<vsc
27612758
; CHECK-ZVBB-NEXT: vsetvli a0, zero, e16, mf4, ta, ma
27622759
; CHECK-ZVBB-NEXT: vand.vx v8, v8, a1
27632760
; CHECK-ZVBB-NEXT: vclz.v v8, v8
2764-
; CHECK-ZVBB-NEXT: li a0, 7
2765-
; CHECK-ZVBB-NEXT: vsub.vx v8, v8, a0
2761+
; CHECK-ZVBB-NEXT: vadd.vi v8, v8, -7
27662762
; CHECK-ZVBB-NEXT: ret
27672763
%va.not = call <vscale x 1 x i9> @llvm.vp.xor.nxv1i9(<vscale x 1 x i9> %va, <vscale x 1 x i9> splat (i9 -1), <vscale x 1 x i1> %m, i32 %evl)
27682764
%v = call <vscale x 1 x i9> @llvm.ctlz(<vscale x 1 x i9> %va.not, i1 false)

0 commit comments

Comments
 (0)