@@ -9673,6 +9673,29 @@ static bool isTruncateOf(SelectionDAG &DAG, SDValue N, SDValue &Op,
9673
9673
return (Known.Zero | 1).isAllOnesValue();
9674
9674
}
9675
9675
9676
+ /// Given an extending node with a pop-count operand, if the target does not
9677
+ /// support a pop-count in the narrow source type but does support it in the
9678
+ /// destination type, widen the pop-count to the destination type.
9679
+ static SDValue widenCtPop(SDNode *Extend, SelectionDAG &DAG) {
9680
+ assert((Extend->getOpcode() == ISD::ZERO_EXTEND ||
9681
+ Extend->getOpcode() == ISD::ANY_EXTEND) && "Expected extend op");
9682
+
9683
+ SDValue CtPop = Extend->getOperand(0);
9684
+ if (CtPop.getOpcode() != ISD::CTPOP || !CtPop.hasOneUse())
9685
+ return SDValue();
9686
+
9687
+ EVT VT = Extend->getValueType(0);
9688
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
9689
+ if (TLI.isOperationLegalOrCustom(ISD::CTPOP, CtPop.getValueType()) ||
9690
+ !TLI.isOperationLegalOrCustom(ISD::CTPOP, VT))
9691
+ return SDValue();
9692
+
9693
+ // zext (ctpop X) --> ctpop (zext X)
9694
+ SDLoc DL(Extend);
9695
+ SDValue NewZext = DAG.getZExtOrTrunc(CtPop.getOperand(0), DL, VT);
9696
+ return DAG.getNode(ISD::CTPOP, DL, VT, NewZext);
9697
+ }
9698
+
9676
9699
SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
9677
9700
SDValue N0 = N->getOperand(0);
9678
9701
EVT VT = N->getValueType(0);
@@ -9923,17 +9946,8 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
9923
9946
if (SDValue NewVSel = matchVSelectOpSizesWithSetCC(N))
9924
9947
return NewVSel;
9925
9948
9926
- // If the target does not support a pop-count in the narrow source type but
9927
- // does support it in the destination type, widen the pop-count to this type:
9928
- // zext (ctpop X) --> ctpop (zext X)
9929
- // TODO: Generalize this to handle starting from anyext.
9930
- if (N0.getOpcode() == ISD::CTPOP && N0.hasOneUse() &&
9931
- !TLI.isOperationLegalOrCustom(ISD::CTPOP, N0.getValueType()) &&
9932
- TLI.isOperationLegalOrCustom(ISD::CTPOP, VT)) {
9933
- SDLoc DL(N);
9934
- SDValue NewZext = DAG.getZExtOrTrunc(N0.getOperand(0), DL, VT);
9935
- return DAG.getNode(ISD::CTPOP, DL, VT, NewZext);
9936
- }
9949
+ if (SDValue NewCtPop = widenCtPop(N, DAG))
9950
+ return NewCtPop;
9937
9951
9938
9952
return SDValue();
9939
9953
}
@@ -10081,6 +10095,9 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {
10081
10095
return SCC;
10082
10096
}
10083
10097
10098
+ if (SDValue NewCtPop = widenCtPop(N, DAG))
10099
+ return NewCtPop;
10100
+
10084
10101
return SDValue();
10085
10102
}
10086
10103
0 commit comments