Skip to content

Commit 6c0a7a8

Browse files
committed
[DAGCombiner] Use generalized pattern matcher in foldBoolSelectToLogic
support vp.select TODO: Possibly other functions could be supported, eg: SimplifySelect()
1 parent 6b33047 commit 6c0a7a8

File tree

2 files changed

+110
-10
lines changed

2 files changed

+110
-10
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,7 @@ namespace {
478478
SDValue visitCTPOP(SDNode *N);
479479
SDValue visitSELECT(SDNode *N);
480480
SDValue visitVSELECT(SDNode *N);
481+
SDValue visitVP_SELECT(SDNode *N);
481482
SDValue visitSELECT_CC(SDNode *N);
482483
SDValue visitSETCC(SDNode *N);
483484
SDValue visitSETCCCARRY(SDNode *N);
@@ -927,6 +928,9 @@ class VPMatchContext {
927928
assert(Root->isVPOpcode());
928929
if (auto RootMaskPos = ISD::getVPMaskIdx(Root->getOpcode()))
929930
RootMaskOp = Root->getOperand(*RootMaskPos);
931+
else if (Root->getOpcode() == ISD::VP_SELECT)
932+
RootMaskOp = DAG.getAllOnesConstant(SDLoc(Root),
933+
Root->getOperand(0).getValueType());
930934

931935
if (auto RootVLenPos =
932936
ISD::getVPExplicitVectorLengthIdx(Root->getOpcode()))
@@ -11420,35 +11424,42 @@ SDValue DAGCombiner::foldSelectOfConstants(SDNode *N) {
1142011424
return SDValue();
1142111425
}
1142211426

11427+
template <class MatchContextClass>
1142311428
static SDValue foldBoolSelectToLogic(SDNode *N, SelectionDAG &DAG) {
11424-
assert((N->getOpcode() == ISD::SELECT || N->getOpcode() == ISD::VSELECT) &&
11425-
"Expected a (v)select");
11429+
assert((N->getOpcode() == ISD::SELECT || N->getOpcode() == ISD::VSELECT ||
11430+
N->getOpcode() == ISD::VP_SELECT) &&
11431+
"Expected a (v)(vp.)select");
1142611432
SDValue Cond = N->getOperand(0);
1142711433
SDValue T = N->getOperand(1), F = N->getOperand(2);
1142811434
EVT VT = N->getValueType(0);
11435+
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
11436+
MatchContextClass matcher(DAG, TLI, N);
11437+
1142911438
if (VT != Cond.getValueType() || VT.getScalarSizeInBits() != 1)
1143011439
return SDValue();
1143111440

1143211441
// select Cond, Cond, F --> or Cond, F
1143311442
// select Cond, 1, F --> or Cond, F
1143411443
if (Cond == T || isOneOrOneSplat(T, /* AllowUndefs */ true))
11435-
return DAG.getNode(ISD::OR, SDLoc(N), VT, Cond, F);
11444+
return matcher.getNode(ISD::OR, SDLoc(N), VT, Cond, F);
1143611445

1143711446
// select Cond, T, Cond --> and Cond, T
1143811447
// select Cond, T, 0 --> and Cond, T
1143911448
if (Cond == F || isNullOrNullSplat(F, /* AllowUndefs */ true))
11440-
return DAG.getNode(ISD::AND, SDLoc(N), VT, Cond, T);
11449+
return matcher.getNode(ISD::AND, SDLoc(N), VT, Cond, T);
1144111450

1144211451
// select Cond, T, 1 --> or (not Cond), T
1144311452
if (isOneOrOneSplat(F, /* AllowUndefs */ true)) {
11444-
SDValue NotCond = DAG.getNOT(SDLoc(N), Cond, VT);
11445-
return DAG.getNode(ISD::OR, SDLoc(N), VT, NotCond, T);
11453+
SDValue NotCond = matcher.getNode(ISD::XOR, SDLoc(N), VT, Cond,
11454+
DAG.getAllOnesConstant(SDLoc(N), VT));
11455+
return matcher.getNode(ISD::OR, SDLoc(N), VT, NotCond, T);
1144611456
}
1144711457

1144811458
// select Cond, 0, F --> and (not Cond), F
1144911459
if (isNullOrNullSplat(T, /* AllowUndefs */ true)) {
11450-
SDValue NotCond = DAG.getNOT(SDLoc(N), Cond, VT);
11451-
return DAG.getNode(ISD::AND, SDLoc(N), VT, NotCond, F);
11460+
SDValue NotCond = matcher.getNode(ISD::XOR, SDLoc(N), VT, Cond,
11461+
DAG.getAllOnesConstant(SDLoc(N), VT));
11462+
return matcher.getNode(ISD::AND, SDLoc(N), VT, NotCond, F);
1145211463
}
1145311464

1145411465
return SDValue();
@@ -11524,7 +11535,7 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) {
1152411535
if (SDValue V = DAG.simplifySelect(N0, N1, N2))
1152511536
return V;
1152611537

11527-
if (SDValue V = foldBoolSelectToLogic(N, DAG))
11538+
if (SDValue V = foldBoolSelectToLogic<EmptyMatchContext>(N, DAG))
1152811539
return V;
1152911540

1153011541
// select (not Cond), N1, N2 -> select Cond, N2, N1
@@ -12138,6 +12149,13 @@ SDValue DAGCombiner::foldVSelectOfConstants(SDNode *N) {
1213812149
return SDValue();
1213912150
}
1214012151

12152+
SDValue DAGCombiner::visitVP_SELECT(SDNode *N) {
12153+
if (SDValue V = foldBoolSelectToLogic<VPMatchContext>(N, DAG))
12154+
return V;
12155+
12156+
return SDValue();
12157+
}
12158+
1214112159
SDValue DAGCombiner::visitVSELECT(SDNode *N) {
1214212160
SDValue N0 = N->getOperand(0);
1214312161
SDValue N1 = N->getOperand(1);
@@ -12148,7 +12166,7 @@ SDValue DAGCombiner::visitVSELECT(SDNode *N) {
1214812166
if (SDValue V = DAG.simplifySelect(N0, N1, N2))
1214912167
return V;
1215012168

12151-
if (SDValue V = foldBoolSelectToLogic(N, DAG))
12169+
if (SDValue V = foldBoolSelectToLogic<EmptyMatchContext>(N, DAG))
1215212170
return V;
1215312171

1215412172
// vselect (not Cond), N1, N2 -> vselect Cond, N2, N1
@@ -26401,6 +26419,8 @@ SDValue DAGCombiner::visitVPOp(SDNode *N) {
2640126419
return visitVP_FSUB(N);
2640226420
case ISD::VP_FMA:
2640326421
return visitFMA<VPMatchContext>(N);
26422+
case ISD::VP_SELECT:
26423+
return visitVP_SELECT(N);
2640426424
}
2640526425
return SDValue();
2640626426
}

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

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,3 +745,83 @@ define <vscale x 16 x double> @select_nxv16f64(<vscale x 16 x i1> %a, <vscale x
745745
%v = call <vscale x 16 x double> @llvm.vp.select.nxv16f64(<vscale x 16 x i1> %a, <vscale x 16 x double> %b, <vscale x 16 x double> %c, i32 %evl)
746746
ret <vscale x 16 x double> %v
747747
}
748+
749+
define <vscale x 2 x i1> @select_zero(<vscale x 2 x i1> %x, <vscale x 2 x i1> %y, <vscale x 2 x i1> %m, i32 zeroext %evl) {
750+
; CHECK-LABEL: select_zero:
751+
; CHECK: # %bb.0:
752+
; CHECK-NEXT: vsetvli zero, a0, e8, mf4, ta, ma
753+
; CHECK-NEXT: vmand.mm v0, v0, v8
754+
; CHECK-NEXT: ret
755+
%a = call <vscale x 2 x i1> @llvm.vp.select.nxv2i1(<vscale x 2 x i1> %x, <vscale x 2 x i1> %y, <vscale x 2 x i1> zeroinitializer, i32 %evl)
756+
ret <vscale x 2 x i1> %a
757+
}
758+
759+
define <vscale x 2 x i1> @select_one(<vscale x 2 x i1> %x, <vscale x 2 x i1> %y, <vscale x 2 x i1> %m, i32 zeroext %evl) {
760+
; CHECK-LABEL: select_one:
761+
; CHECK: # %bb.0:
762+
; CHECK-NEXT: vsetvli zero, a0, e8, mf4, ta, ma
763+
; CHECK-NEXT: vmorn.mm v0, v8, v0
764+
; CHECK-NEXT: ret
765+
%a = call <vscale x 2 x i1> @llvm.vp.select.nxv2i1(<vscale x 2 x i1> %x, <vscale x 2 x i1> %y, <vscale x 2 x i1> shufflevector (<vscale x 2 x i1> insertelement (<vscale x 2 x i1> undef, i1 true, i32 0), <vscale x 2 x i1> undef, <vscale x 2 x i32> zeroinitializer), i32 %evl)
766+
ret <vscale x 2 x i1> %a
767+
}
768+
769+
define <vscale x 2 x i1> @select_x_zero(<vscale x 2 x i1> %x, <vscale x 2 x i1> %y, i32 zeroext %evl) {
770+
; CHECK-LABEL: select_x_zero:
771+
; CHECK: # %bb.0:
772+
; CHECK-NEXT: vsetvli zero, a0, e8, mf4, ta, ma
773+
; CHECK-NEXT: vmand.mm v0, v0, v8
774+
; CHECK-NEXT: ret
775+
%a = call <vscale x 2 x i1> @llvm.vp.select.nxv2i1(<vscale x 2 x i1> %x, <vscale x 2 x i1> %y, <vscale x 2 x i1> zeroinitializer, i32 %evl)
776+
ret <vscale x 2 x i1> %a
777+
}
778+
779+
define <vscale x 2 x i1> @select_x_one(<vscale x 2 x i1> %x, <vscale x 2 x i1> %y, i32 zeroext %evl) {
780+
; CHECK-LABEL: select_x_one:
781+
; CHECK: # %bb.0:
782+
; CHECK-NEXT: vsetvli zero, a0, e8, mf4, ta, ma
783+
; CHECK-NEXT: vmorn.mm v0, v8, v0
784+
; CHECK-NEXT: ret
785+
%a = call <vscale x 2 x i1> @llvm.vp.select.nxv2i1(<vscale x 2 x i1> %x, <vscale x 2 x i1> %y, <vscale x 2 x i1> shufflevector (<vscale x 2 x i1> insertelement (<vscale x 2 x i1> undef, i1 true, i32 0), <vscale x 2 x i1> undef, <vscale x 2 x i32> zeroinitializer), i32 %evl)
786+
ret <vscale x 2 x i1> %a
787+
}
788+
789+
define <vscale x 2 x i1> @select_zero_x(<vscale x 2 x i1> %x, <vscale x 2 x i1> %y, i32 zeroext %evl) {
790+
; CHECK-LABEL: select_zero_x:
791+
; CHECK: # %bb.0:
792+
; CHECK-NEXT: vsetvli zero, a0, e8, mf4, ta, ma
793+
; CHECK-NEXT: vmandn.mm v0, v8, v0
794+
; CHECK-NEXT: ret
795+
%a = call <vscale x 2 x i1> @llvm.vp.select.nxv2i1(<vscale x 2 x i1> %x, <vscale x 2 x i1> zeroinitializer, <vscale x 2 x i1> %y, i32 %evl)
796+
ret <vscale x 2 x i1> %a
797+
}
798+
799+
define <vscale x 2 x i1> @select_one_x(<vscale x 2 x i1> %x, <vscale x 2 x i1> %y, i32 zeroext %evl) {
800+
; CHECK-LABEL: select_one_x:
801+
; CHECK: # %bb.0:
802+
; CHECK-NEXT: vsetvli zero, a0, e8, mf4, ta, ma
803+
; CHECK-NEXT: vmor.mm v0, v0, v8
804+
; CHECK-NEXT: ret
805+
%a = call <vscale x 2 x i1> @llvm.vp.select.nxv2i1(<vscale x 2 x i1> %x, <vscale x 2 x i1> shufflevector (<vscale x 2 x i1> insertelement (<vscale x 2 x i1> undef, i1 true, i32 0), <vscale x 2 x i1> undef, <vscale x 2 x i32> zeroinitializer), <vscale x 2 x i1> %y, i32 %evl)
806+
ret <vscale x 2 x i1> %a
807+
}
808+
809+
define <vscale x 2 x i1> @select_cond_cond_x(<vscale x 2 x i1> %x, <vscale x 2 x i1> %y, <vscale x 2 x i1> %m, i32 zeroext %evl) {
810+
; CHECK-LABEL: select_cond_cond_x:
811+
; CHECK: # %bb.0:
812+
; CHECK-NEXT: vsetvli zero, a0, e8, mf4, ta, ma
813+
; CHECK-NEXT: vmor.mm v0, v0, v8
814+
; CHECK-NEXT: ret
815+
%a = call <vscale x 2 x i1> @llvm.vp.select.nxv2i1(<vscale x 2 x i1> %x, <vscale x 2 x i1> %x, <vscale x 2 x i1> %y, i32 %evl)
816+
ret <vscale x 2 x i1> %a
817+
}
818+
819+
define <vscale x 2 x i1> @select_cond_x_cond(<vscale x 2 x i1> %x, <vscale x 2 x i1> %y, <vscale x 2 x i1> %m, i32 zeroext %evl) {
820+
; CHECK-LABEL: select_cond_x_cond:
821+
; CHECK: # %bb.0:
822+
; CHECK-NEXT: vsetvli zero, a0, e8, mf4, ta, ma
823+
; CHECK-NEXT: vmand.mm v0, v0, v8
824+
; CHECK-NEXT: ret
825+
%a = call <vscale x 2 x i1> @llvm.vp.select.nxv2i1(<vscale x 2 x i1> %x, <vscale x 2 x i1> %y, <vscale x 2 x i1> %x, i32 %evl)
826+
ret <vscale x 2 x i1> %a
827+
}

0 commit comments

Comments
 (0)