@@ -19208,13 +19208,53 @@ static SDValue combineADDToMAT_PCREL_ADDR(SDNode *N, SelectionDAG &DAG,
1920819208 return MatPCRel;
1920919209}
1921019210
19211+ static SDValue combineADDToSUB(SDNode *N, SelectionDAG &DAG,
19212+ const PPCSubtarget &Subtarget) {
19213+ EVT VT = N->getValueType(0);
19214+
19215+ // Handle v2i64, v4i32, v8i16 and v16i8 types
19216+ if (!VT.isVector() || VT.getSizeInBits() != 128)
19217+ return SDValue();
19218+
19219+ SDValue LHS = N->getOperand(0);
19220+ SDValue RHS = N->getOperand(1);
19221+
19222+ // Check if RHS is BUILD_VECTOR
19223+ // To satisfy commutative property a+b = b+a
19224+ if (RHS.getOpcode() != ISD::BUILD_VECTOR)
19225+ std::swap(LHS, RHS);
19226+
19227+ if (RHS.getOpcode() != ISD::BUILD_VECTOR)
19228+ return SDValue();
19229+
19230+ // Check if all the elements are 1
19231+ unsigned NumOfEles = RHS.getNumOperands();
19232+ for (unsigned i = 0; i < NumOfEles; ++i) {
19233+ auto *CN = dyn_cast<ConstantSDNode>(RHS.getOperand(i));
19234+ if (!CN || CN->getSExtValue() != 1)
19235+ return SDValue();
19236+ }
19237+ SDLoc DL(N);
19238+
19239+ SDValue MinusOne = DAG.getConstant(APInt::getAllOnes(32), DL, MVT::i32);
19240+ SmallVector<SDValue, 4> Ops(4, MinusOne);
19241+ SDValue AllOnesVec = DAG.getBuildVector(MVT::v4i32, DL, Ops);
19242+
19243+ // Bitcast to the target vector type
19244+ SDValue Bitcast = DAG.getNode(ISD::BITCAST, DL, VT, AllOnesVec);
19245+
19246+ return DAG.getNode(ISD::SUB, DL, VT, LHS, Bitcast);
19247+ }
19248+
1921119249SDValue PPCTargetLowering::combineADD(SDNode *N, DAGCombinerInfo &DCI) const {
1921219250 if (auto Value = combineADDToADDZE(N, DCI.DAG, Subtarget))
1921319251 return Value;
1921419252
1921519253 if (auto Value = combineADDToMAT_PCREL_ADDR(N, DCI.DAG, Subtarget))
1921619254 return Value;
1921719255
19256+ if (auto Value = combineADDToSUB(N, DCI.DAG, Subtarget))
19257+ return Value;
1921819258 return SDValue();
1921919259}
1922019260
0 commit comments