Skip to content

Commit 4d2fa25

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

File tree

2 files changed

+103
-8
lines changed

2 files changed

+103
-8
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 23 additions & 8 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);
@@ -11420,35 +11421,40 @@ SDValue DAGCombiner::foldSelectOfConstants(SDNode *N) {
1142011421
return SDValue();
1142111422
}
1142211423

11424+
template <class MatchContextClass>
1142311425
static SDValue foldBoolSelectToLogic(SDNode *N, SelectionDAG &DAG) {
11424-
assert((N->getOpcode() == ISD::SELECT || N->getOpcode() == ISD::VSELECT) &&
11425-
"Expected a (v)select");
11426+
assert((N->getOpcode() == ISD::SELECT || N->getOpcode() == ISD::VSELECT ||
11427+
N->getOpcode() == ISD::VP_SELECT) &&
11428+
"Expected a (v)(vp.)select");
1142611429
SDValue Cond = N->getOperand(0);
1142711430
SDValue T = N->getOperand(1), F = N->getOperand(2);
1142811431
EVT VT = N->getValueType(0);
11432+
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
11433+
MatchContextClass matcher(DAG, TLI, N);
11434+
1142911435
if (VT != Cond.getValueType() || VT.getScalarSizeInBits() != 1)
1143011436
return SDValue();
1143111437

1143211438
// select Cond, Cond, F --> or Cond, F
1143311439
// select Cond, 1, F --> or Cond, F
1143411440
if (Cond == T || isOneOrOneSplat(T, /* AllowUndefs */ true))
11435-
return DAG.getNode(ISD::OR, SDLoc(N), VT, Cond, F);
11441+
return matcher.getNode(ISD::OR, SDLoc(N), VT, Cond, F);
1143611442

1143711443
// select Cond, T, Cond --> and Cond, T
1143811444
// select Cond, T, 0 --> and Cond, T
1143911445
if (Cond == F || isNullOrNullSplat(F, /* AllowUndefs */ true))
11440-
return DAG.getNode(ISD::AND, SDLoc(N), VT, Cond, T);
11446+
return matcher.getNode(ISD::AND, SDLoc(N), VT, Cond, T);
1144111447

1144211448
// select Cond, T, 1 --> or (not Cond), T
1144311449
if (isOneOrOneSplat(F, /* AllowUndefs */ true)) {
1144411450
SDValue NotCond = DAG.getNOT(SDLoc(N), Cond, VT);
11445-
return DAG.getNode(ISD::OR, SDLoc(N), VT, NotCond, T);
11451+
return matcher.getNode(ISD::OR, SDLoc(N), VT, NotCond, T);
1144611452
}
1144711453

1144811454
// select Cond, 0, F --> and (not Cond), F
1144911455
if (isNullOrNullSplat(T, /* AllowUndefs */ true)) {
1145011456
SDValue NotCond = DAG.getNOT(SDLoc(N), Cond, VT);
11451-
return DAG.getNode(ISD::AND, SDLoc(N), VT, NotCond, F);
11457+
return matcher.getNode(ISD::AND, SDLoc(N), VT, NotCond, F);
1145211458
}
1145311459

1145411460
return SDValue();
@@ -11524,7 +11530,7 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) {
1152411530
if (SDValue V = DAG.simplifySelect(N0, N1, N2))
1152511531
return V;
1152611532

11527-
if (SDValue V = foldBoolSelectToLogic(N, DAG))
11533+
if (SDValue V = foldBoolSelectToLogic<EmptyMatchContext>(N, DAG))
1152811534
return V;
1152911535

1153011536
// select (not Cond), N1, N2 -> select Cond, N2, N1
@@ -12138,6 +12144,13 @@ SDValue DAGCombiner::foldVSelectOfConstants(SDNode *N) {
1213812144
return SDValue();
1213912145
}
1214012146

12147+
SDValue DAGCombiner::visitVP_SELECT(SDNode *N) {
12148+
if (SDValue V = foldBoolSelectToLogic<EmptyMatchContext>(N, DAG))
12149+
return V;
12150+
12151+
return SDValue();
12152+
}
12153+
1214112154
SDValue DAGCombiner::visitVSELECT(SDNode *N) {
1214212155
SDValue N0 = N->getOperand(0);
1214312156
SDValue N1 = N->getOperand(1);
@@ -12148,7 +12161,7 @@ SDValue DAGCombiner::visitVSELECT(SDNode *N) {
1214812161
if (SDValue V = DAG.simplifySelect(N0, N1, N2))
1214912162
return V;
1215012163

12151-
if (SDValue V = foldBoolSelectToLogic(N, DAG))
12164+
if (SDValue V = foldBoolSelectToLogic<EmptyMatchContext>(N, DAG))
1215212165
return V;
1215312166

1215412167
// vselect (not Cond), N1, N2 -> vselect Cond, N2, N1
@@ -26398,6 +26411,8 @@ SDValue DAGCombiner::visitVPOp(SDNode *N) {
2639826411
return visitVP_FSUB(N);
2639926412
case ISD::VP_FMA:
2640026413
return visitFMA<VPMatchContext>(N);
26414+
case ISD::VP_SELECT:
26415+
return visitVP_SELECT(N);
2640126416
}
2640226417
return SDValue();
2640326418
}

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 a0, zero, 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 a0, zero, 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 a0, zero, 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 a0, zero, 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 a0, zero, 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 a0, zero, 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 a0, zero, 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 a0, zero, 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)