Skip to content

Commit 8204931

Browse files
authored
[RISCV] Add disjoint or patterns for vwadd[u].v{v,x} (#136716)
DAGCombiner::hoistLogicOpWithSameOpcodeHands will hoist (or disjoint (ext a), (ext b)) -> (ext (or disjoint a, b)) So this adds patterns to match vwadd[u].v{v,x} in this case. We have to teach the combine to preserve the disjoint flag.
1 parent dfc60b2 commit 8204931

File tree

3 files changed

+61
-11
lines changed

3 files changed

+61
-11
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6037,7 +6037,10 @@ SDValue DAGCombiner::hoistLogicOpWithSameOpcodeHands(SDNode *N) {
60376037
LegalTypes && !TLI.isTypeDesirableForOp(LogicOpcode, XVT))
60386038
return SDValue();
60396039
// logic_op (hand_op X), (hand_op Y) --> hand_op (logic_op X, Y)
6040-
SDValue Logic = DAG.getNode(LogicOpcode, DL, XVT, X, Y);
6040+
SDNodeFlags LogicFlags;
6041+
LogicFlags.setDisjoint(N->getFlags().hasDisjoint() &&
6042+
ISD::isExtOpcode(HandOpcode));
6043+
SDValue Logic = DAG.getNode(LogicOpcode, DL, XVT, X, Y, LogicFlags);
60416044
if (HandOpcode == ISD::SIGN_EXTEND_INREG)
60426045
return DAG.getNode(HandOpcode, DL, VT, Logic, N0.getOperand(1));
60436046
return DAG.getNode(HandOpcode, DL, VT, Logic);

llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,29 @@ defm : VPatWidenBinarySDNode_VV_VX_WV_WX<add, sext_oneuse, "PseudoVWADD">;
912912
defm : VPatWidenBinarySDNode_VV_VX_WV_WX<add, zext_oneuse, "PseudoVWADDU">;
913913
defm : VPatWidenBinarySDNode_VV_VX_WV_WX<add, anyext_oneuse, "PseudoVWADDU">;
914914

915+
// DAGCombiner::hoistLogicOpWithSameOpcodeHands may hoist disjoint ors
916+
// to (ext (or disjoint (a, b)))
917+
multiclass VPatWidenOrDisjoint_VV_VX<SDNode extop, string instruction_name> {
918+
foreach vtiToWti = AllWidenableIntVectors in {
919+
defvar vti = vtiToWti.Vti;
920+
defvar wti = vtiToWti.Wti;
921+
let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,
922+
GetVTypePredicates<wti>.Predicates) in {
923+
def : Pat<(wti.Vector (extop (vti.Vector (or_is_add vti.RegClass:$rs2, vti.RegClass:$rs1)))),
924+
(!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX)
925+
(wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2,
926+
vti.RegClass:$rs1, vti.AVL, vti.Log2SEW, TA_MA)>;
927+
def : Pat<(wti.Vector (extop (vti.Vector (or_is_add vti.RegClass:$rs2, (SplatPat (XLenVT GPR:$rs1)))))),
928+
(!cast<Instruction>(instruction_name#"_VX_"#vti.LMul.MX)
929+
(wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2,
930+
GPR:$rs1, vti.AVL, vti.Log2SEW, TA_MA)>;
931+
}
932+
}
933+
}
934+
defm : VPatWidenOrDisjoint_VV_VX<sext, "PseudoVWADD">;
935+
defm : VPatWidenOrDisjoint_VV_VX<zext, "PseudoVWADDU">;
936+
defm : VPatWidenOrDisjoint_VV_VX<anyext, "PseudoVWADDU">;
937+
915938
defm : VPatWidenBinarySDNode_VV_VX_WV_WX<sub, sext_oneuse, "PseudoVWSUB">;
916939
defm : VPatWidenBinarySDNode_VV_VX_WV_WX<sub, zext_oneuse, "PseudoVWSUBU">;
917940
defm : VPatWidenBinarySDNode_VV_VX_WV_WX<sub, anyext_oneuse, "PseudoVWSUBU">;

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

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,38 +1417,62 @@ define <vscale x 2 x i32> @vwaddu_vv_disjoint_or_add(<vscale x 2 x i8> %x.i8, <v
14171417
ret <vscale x 2 x i32> %add
14181418
}
14191419

1420-
; TODO: We could select vwaddu.vv, but when both arms of the or are the same
1421-
; DAGCombiner::hoistLogicOpWithSameOpcodeHands moves the zext above the or.
14221420
define <vscale x 2 x i32> @vwaddu_vv_disjoint_or(<vscale x 2 x i16> %x.i16, <vscale x 2 x i16> %y.i16) {
14231421
; CHECK-LABEL: vwaddu_vv_disjoint_or:
14241422
; CHECK: # %bb.0:
14251423
; CHECK-NEXT: vsetvli a0, zero, e16, mf2, ta, ma
1426-
; CHECK-NEXT: vor.vv v9, v8, v9
1427-
; CHECK-NEXT: vsetvli zero, zero, e32, m1, ta, ma
1428-
; CHECK-NEXT: vzext.vf2 v8, v9
1424+
; CHECK-NEXT: vwaddu.vv v10, v8, v9
1425+
; CHECK-NEXT: vmv1r.v v8, v10
14291426
; CHECK-NEXT: ret
14301427
%x.i32 = zext <vscale x 2 x i16> %x.i16 to <vscale x 2 x i32>
14311428
%y.i32 = zext <vscale x 2 x i16> %y.i16 to <vscale x 2 x i32>
14321429
%or = or disjoint <vscale x 2 x i32> %x.i32, %y.i32
14331430
ret <vscale x 2 x i32> %or
14341431
}
14351432

1436-
; TODO: We could select vwadd.vv, but when both arms of the or are the same
1437-
; DAGCombiner::hoistLogicOpWithSameOpcodeHands moves the zext above the or.
14381433
define <vscale x 2 x i32> @vwadd_vv_disjoint_or(<vscale x 2 x i16> %x.i16, <vscale x 2 x i16> %y.i16) {
14391434
; CHECK-LABEL: vwadd_vv_disjoint_or:
14401435
; CHECK: # %bb.0:
14411436
; CHECK-NEXT: vsetvli a0, zero, e16, mf2, ta, ma
1442-
; CHECK-NEXT: vor.vv v9, v8, v9
1443-
; CHECK-NEXT: vsetvli zero, zero, e32, m1, ta, ma
1444-
; CHECK-NEXT: vsext.vf2 v8, v9
1437+
; CHECK-NEXT: vwadd.vv v10, v8, v9
1438+
; CHECK-NEXT: vmv1r.v v8, v10
14451439
; CHECK-NEXT: ret
14461440
%x.i32 = sext <vscale x 2 x i16> %x.i16 to <vscale x 2 x i32>
14471441
%y.i32 = sext <vscale x 2 x i16> %y.i16 to <vscale x 2 x i32>
14481442
%or = or disjoint <vscale x 2 x i32> %x.i32, %y.i32
14491443
ret <vscale x 2 x i32> %or
14501444
}
14511445

1446+
define <vscale x 2 x i32> @vwaddu_vx_disjoint_or(<vscale x 2 x i16> %x.i16, i16 %y.i16) {
1447+
; CHECK-LABEL: vwaddu_vx_disjoint_or:
1448+
; CHECK: # %bb.0:
1449+
; CHECK-NEXT: vsetvli a1, zero, e16, mf2, ta, ma
1450+
; CHECK-NEXT: vwaddu.vx v9, v8, a0
1451+
; CHECK-NEXT: vmv1r.v v8, v9
1452+
; CHECK-NEXT: ret
1453+
%x.i32 = zext <vscale x 2 x i16> %x.i16 to <vscale x 2 x i32>
1454+
%y.head = insertelement <vscale x 2 x i16> poison, i16 %y.i16, i32 0
1455+
%y.splat = shufflevector <vscale x 2 x i16> %y.head, <vscale x 2 x i16> poison, <vscale x 2 x i32> zeroinitializer
1456+
%y.i32 = zext <vscale x 2 x i16> %y.splat to <vscale x 2 x i32>
1457+
%or = or disjoint <vscale x 2 x i32> %x.i32, %y.i32
1458+
ret <vscale x 2 x i32> %or
1459+
}
1460+
1461+
define <vscale x 2 x i32> @vwadd_vx_disjoint_or(<vscale x 2 x i16> %x.i16, i16 %y.i16) {
1462+
; CHECK-LABEL: vwadd_vx_disjoint_or:
1463+
; CHECK: # %bb.0:
1464+
; CHECK-NEXT: vsetvli a1, zero, e16, mf2, ta, ma
1465+
; CHECK-NEXT: vwadd.vx v9, v8, a0
1466+
; CHECK-NEXT: vmv1r.v v8, v9
1467+
; CHECK-NEXT: ret
1468+
%x.i32 = sext <vscale x 2 x i16> %x.i16 to <vscale x 2 x i32>
1469+
%y.head = insertelement <vscale x 2 x i16> poison, i16 %y.i16, i32 0
1470+
%y.splat = shufflevector <vscale x 2 x i16> %y.head, <vscale x 2 x i16> poison, <vscale x 2 x i32> zeroinitializer
1471+
%y.i32 = sext <vscale x 2 x i16> %y.splat to <vscale x 2 x i32>
1472+
%or = or disjoint <vscale x 2 x i32> %x.i32, %y.i32
1473+
ret <vscale x 2 x i32> %or
1474+
}
1475+
14521476
define <vscale x 2 x i32> @vwaddu_wv_disjoint_or(<vscale x 2 x i32> %x.i32, <vscale x 2 x i16> %y.i16) {
14531477
; CHECK-LABEL: vwaddu_wv_disjoint_or:
14541478
; CHECK: # %bb.0:

0 commit comments

Comments
 (0)