@@ -19068,13 +19068,53 @@ static SDValue combineADDToMAT_PCREL_ADDR(SDNode *N, SelectionDAG &DAG,
1906819068 return MatPCRel;
1906919069}
1907019070
19071+ static SDValue combineADDToSUB(SDNode *N, SelectionDAG &DAG,
19072+ const PPCSubtarget &Subtarget) {
19073+ EVT VT = N->getValueType(0);
19074+
19075+ // Handle v2i64, v4i32, v8i16 and v16i8 types
19076+ if (!VT.isVector() || VT.getSizeInBits() != 128)
19077+ return SDValue();
19078+
19079+ SDValue LHS = N->getOperand(0);
19080+ SDValue RHS = N->getOperand(1);
19081+
19082+ // Check if RHS is BUILD_VECTOR
19083+ // To satisfy commutative property a+b = b+a
19084+ if (RHS.getOpcode() != ISD::BUILD_VECTOR)
19085+ std::swap(LHS, RHS);
19086+
19087+ if (RHS.getOpcode() != ISD::BUILD_VECTOR)
19088+ return SDValue();
19089+
19090+ // Check if all the elements are 1
19091+ unsigned NumOfEles = RHS.getNumOperands();
19092+ for (unsigned i = 0; i < NumOfEles; ++i) {
19093+ auto *CN = dyn_cast<ConstantSDNode>(RHS.getOperand(i));
19094+ if (!CN || CN->getSExtValue() != 1)
19095+ return SDValue();
19096+ }
19097+ SDLoc DL(N);
19098+
19099+ SDValue MinusOne = DAG.getConstant(APInt::getAllOnes(32), DL, MVT::i32);
19100+ SmallVector<SDValue, 4> Ops(4, MinusOne);
19101+ SDValue AllOnesVec = DAG.getBuildVector(MVT::v4i32, DL, Ops);
19102+
19103+ // Bitcast to the target vector type
19104+ SDValue Bitcast = DAG.getNode(ISD::BITCAST, DL, VT, AllOnesVec);
19105+
19106+ return DAG.getNode(ISD::SUB, DL, VT, LHS, Bitcast);
19107+ }
19108+
1907119109SDValue PPCTargetLowering::combineADD(SDNode *N, DAGCombinerInfo &DCI) const {
1907219110 if (auto Value = combineADDToADDZE(N, DCI.DAG, Subtarget))
1907319111 return Value;
1907419112
1907519113 if (auto Value = combineADDToMAT_PCREL_ADDR(N, DCI.DAG, Subtarget))
1907619114 return Value;
1907719115
19116+ if (auto Value = combineADDToSUB(N, DCI.DAG, Subtarget))
19117+ return Value;
1907819118 return SDValue();
1907919119}
1908019120
0 commit comments