@@ -2826,6 +2826,36 @@ SDValue DAGCombiner::visitADDLike(SDNode *N) {
2826
2826
return SDValue();
2827
2827
}
2828
2828
2829
+ // Attempt to form ext(avgflooru(A, B)) from add(and(A, B), lshr(xor(A, B), 1))
2830
+ static SDValue combineFixedwidthToAVG(SDNode *N, SelectionDAG &DAG) {
2831
+ assert(N->getOpcode() == ISD::ADD && "ADD node is required here");
2832
+ SDValue And = N->getOperand(0);
2833
+ SDValue Lshr = N->getOperand(1);
2834
+ if (And.getOpcode() != ISD::AND || Lshr.getOpcode() != ISD::SRL)
2835
+ return SDValue();
2836
+ SDValue Xor = Lshr.getOperand(0);
2837
+ if (Xor.getOpcode() != ISD::XOR)
2838
+ return SDValue();
2839
+ SDValue And1 = And.getOperand(0);
2840
+ SDValue And2 = And.getOperand(1);
2841
+ SDValue Xor1 = Xor.getOperand(0);
2842
+ SDValue Xor2 = Xor.getOperand(1);
2843
+ if(Xor1 != And1 && Xor2 != And2)
2844
+ return SDValue();
2845
+ // Is the right shift using an immediate value of 1?
2846
+ ConstantSDNode *N1C = isConstOrConstSplat(Lshr.getOperand(1));
2847
+ if (!N1C || N1C->getAPIntValue() != 1)
2848
+ return SDValue();
2849
+ EVT VT = And.getValueType();
2850
+ SDLoc DL(N);
2851
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
2852
+ if (!TLI.isOperationLegalOrCustom(ISD::AVGFLOORU, VT))
2853
+ return SDValue();
2854
+ return DAG.getNode(ISD::AVGFLOORU, DL, VT,
2855
+ DAG.getExtOrTrunc(false, And1, DL, VT),
2856
+ DAG.getExtOrTrunc(false, And2, DL, VT));
2857
+ }
2858
+
2829
2859
SDValue DAGCombiner::visitADD(SDNode *N) {
2830
2860
SDValue N0 = N->getOperand(0);
2831
2861
SDValue N1 = N->getOperand(1);
@@ -2841,6 +2871,10 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
2841
2871
if (SDValue V = foldAddSubOfSignBit(N, DAG))
2842
2872
return V;
2843
2873
2874
+ // Try to match AVG fixedwidth pattern
2875
+ if (SDValue V = combineFixedwidthToAVG(N, DAG))
2876
+ return V;
2877
+
2844
2878
// fold (a+b) -> (a|b) iff a and b share no bits.
2845
2879
if ((!LegalOperations || TLI.isOperationLegal(ISD::OR, VT)) &&
2846
2880
DAG.haveNoCommonBitsSet(N0, N1))
0 commit comments