@@ -196,7 +196,11 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
196196 }
197197 }
198198
199+ // PowerPC uses addo,addo_carry,subo,subo_carry to propagate carry.
199200 setOperationAction(ISD::UADDO, RegVT, Custom);
201+ setOperationAction(ISD::USUBO, RegVT, Custom);
202+ setOperationAction(ISD::UADDO_CARRY, RegVT, Custom);
203+ setOperationAction(ISD::USUBO_CARRY, RegVT, Custom);
200204
201205 // On P10, the default lowering generates better code using the
202206 // setbc instruction.
@@ -260,15 +264,6 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
260264 setIndexedStoreAction(ISD::PRE_INC, MVT::f64, Legal);
261265 }
262266
263- // PowerPC uses ADDC/ADDE/SUBC/SUBE to propagate carry.
264- const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
265- for (MVT VT : ScalarIntVTs) {
266- setOperationAction(ISD::ADDC, VT, Legal);
267- setOperationAction(ISD::ADDE, VT, Legal);
268- setOperationAction(ISD::SUBC, VT, Legal);
269- setOperationAction(ISD::SUBE, VT, Legal);
270- }
271-
272267 if (Subtarget.useCRBits()) {
273268 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
274269
@@ -1854,6 +1849,14 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
18541849 return "PPCISD::SETBC";
18551850 case PPCISD::SETBCR:
18561851 return "PPCISD::SETBCR";
1852+ case PPCISD::ADDC:
1853+ return "PPCISD::ADDC";
1854+ case PPCISD::ADDE:
1855+ return "PPCISD::ADDE";
1856+ case PPCISD::SUBC:
1857+ return "PPCISD::SUBC";
1858+ case PPCISD::SUBE:
1859+ return "PPCISD::SUBE";
18571860 }
18581861 return nullptr;
18591862}
@@ -12010,43 +12013,74 @@ SDValue PPCTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
1201012013 llvm_unreachable("ERROR:Should return for all cases within swtich.");
1201112014}
1201212015
12013- SDValue PPCTargetLowering::LowerUaddo(SDValue Op, SelectionDAG &DAG) const {
12014- // Default to target independent lowering if there is a logical user of the
12015- // carry-bit.
12016- for (SDNode *U : Op->uses()) {
12017- if (U->getOpcode() == ISD::SELECT)
12018- return SDValue();
12019- if (ISD::isBitwiseLogicOp(U->getOpcode())) {
12020- for (unsigned i = 0, ie = U->getNumOperands(); i != ie; ++i) {
12021- if (U->getOperand(i).getOpcode() != ISD::UADDO &&
12022- U->getOperand(i).getOpcode() != ISD::MERGE_VALUES)
12023- return SDValue();
12024- }
12025- }
12026- }
12027- SDValue LHS = Op.getOperand(0);
12028- SDValue RHS = Op.getOperand(1);
12029- SDLoc dl(Op);
12030-
12031- // Default to target independent lowering for special cases handled there.
12032- if (isOneConstant(RHS) || isAllOnesConstant(RHS))
12033- return SDValue();
12016+ static SDValue ConvertCarryValueToCarryFlag(EVT SumType, SDValue Value,
12017+ SelectionDAG &DAG,
12018+ const PPCSubtarget &STI) {
12019+ SDLoc DL(Value);
12020+ if (STI.useCRBits())
12021+ Value = DAG.getNode(ISD::SELECT, DL, SumType, Value,
12022+ DAG.getConstant(1, DL, SumType),
12023+ DAG.getConstant(0, DL, SumType));
12024+ else
12025+ Value = DAG.getZExtOrTrunc(Value, DL, SumType);
12026+ SDValue Sum = DAG.getNode(PPCISD::ADDC, DL, DAG.getVTList(SumType, MVT::i32),
12027+ Value, DAG.getAllOnesConstant(DL, SumType));
12028+ return Sum.getValue(1);
12029+ }
1203412030
12035- EVT VT = Op.getNode()->getValueType(0);
12031+ static SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag,
12032+ EVT CarryType, SelectionDAG &DAG,
12033+ const PPCSubtarget &STI) {
12034+ SDLoc DL(Flag);
12035+ SDValue Zero = DAG.getConstant(0, DL, SumType);
12036+ SDValue Carry = DAG.getNode(
12037+ PPCISD::ADDE, DL, DAG.getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12038+ if (STI.useCRBits())
12039+ return DAG.getSetCC(DL, CarryType, Carry, Zero, ISD::SETNE);
12040+ return DAG.getZExtOrTrunc(Carry, DL, CarryType);
12041+ }
1203612042
12037- SDValue ADDC;
12038- SDValue Overflow;
12039- SDVTList VTs = Op.getNode()->getVTList();
12043+ SDValue PPCTargetLowering::LowerADDSUBO(SDValue Op, SelectionDAG &DAG) const {
1204012044
12041- ADDC = DAG.getNode(ISD::ADDC, dl, DAG.getVTList(VT, MVT::Glue), LHS, RHS);
12042- Overflow = DAG.getNode(ISD::ADDE, dl, DAG.getVTList(VT, MVT::Glue),
12043- DAG.getConstant(0, dl, VT), DAG.getConstant(0, dl, VT),
12044- ADDC.getValue(1));
12045- SDValue OverflowTrunc =
12046- DAG.getNode(ISD::TRUNCATE, dl, Op.getNode()->getValueType(1), Overflow);
12047- SDValue Res =
12048- DAG.getNode(ISD::MERGE_VALUES, dl, VTs, ADDC.getValue(0), OverflowTrunc);
12049- return Res;
12045+ SDLoc DL(Op);
12046+ SDNode *N = Op.getNode();
12047+ EVT VT = N->getValueType(0);
12048+ EVT CarryType = N->getValueType(1);
12049+ unsigned Opc = N->getOpcode();
12050+ bool IsAdd = Opc == ISD::UADDO;
12051+ Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12052+ SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
12053+ N->getOperand(0), N->getOperand(1));
12054+ SDValue Carry = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType,
12055+ DAG, Subtarget);
12056+ if (!IsAdd)
12057+ Carry = DAG.getNode(ISD::XOR, DL, CarryType, Carry,
12058+ DAG.getAllOnesConstant(DL, CarryType));
12059+ return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, Carry);
12060+ }
12061+
12062+ SDValue PPCTargetLowering::LowerADDSUBO_CARRY(SDValue Op,
12063+ SelectionDAG &DAG) const {
12064+ SDLoc DL(Op);
12065+ SDNode *N = Op.getNode();
12066+ unsigned Opc = N->getOpcode();
12067+ EVT VT = N->getValueType(0);
12068+ EVT CarryType = N->getValueType(1);
12069+ SDValue CarryOp = N->getOperand(2);
12070+ bool IsAdd = Opc == ISD::UADDO_CARRY;
12071+ Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12072+ if (!IsAdd)
12073+ CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12074+ DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
12075+ CarryOp = ConvertCarryValueToCarryFlag(VT, CarryOp, DAG, Subtarget);
12076+ SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
12077+ Op.getOperand(0), Op.getOperand(1), CarryOp);
12078+ CarryOp = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType, DAG,
12079+ Subtarget);
12080+ if (!IsAdd)
12081+ CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12082+ DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
12083+ return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, CarryOp);
1205012084}
1205112085
1205212086SDValue PPCTargetLowering::LowerSSUBO(SDValue Op, SelectionDAG &DAG) const {
@@ -12078,7 +12112,6 @@ SDValue PPCTargetLowering::LowerSSUBO(SDValue Op, SelectionDAG &DAG) const {
1207812112SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
1207912113 switch (Op.getOpcode()) {
1208012114 default: llvm_unreachable("Wasn't expecting to be able to lower this!");
12081- case ISD::UADDO: return LowerUaddo(Op, DAG);
1208212115 case ISD::FPOW: return lowerPow(Op, DAG);
1208312116 case ISD::FSIN: return lowerSin(Op, DAG);
1208412117 case ISD::FCOS: return lowerCos(Op, DAG);
@@ -12171,6 +12204,12 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
1217112204 return LowerATOMIC_LOAD_STORE(Op, DAG);
1217212205 case ISD::IS_FPCLASS:
1217312206 return LowerIS_FPCLASS(Op, DAG);
12207+ case ISD::UADDO:
12208+ case ISD::USUBO:
12209+ return LowerADDSUBO(Op, DAG);
12210+ case ISD::UADDO_CARRY:
12211+ case ISD::USUBO_CARRY:
12212+ return LowerADDSUBO_CARRY(Op, DAG);
1217412213 }
1217512214}
1217612215
@@ -16106,6 +16145,21 @@ static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth) {
1610616145 return true;
1610716146}
1610816147
16148+ static SDValue DAGCombineAddc(SDNode *N,
16149+ llvm::PPCTargetLowering::DAGCombinerInfo &DCI) {
16150+ if (N->getOpcode() == PPCISD::ADDC && N->hasAnyUseOfValue(1)) {
16151+ // (ADDC (ADDE 0, 0, C), -1) -> C
16152+ SDValue LHS = N->getOperand(0);
16153+ SDValue RHS = N->getOperand(1);
16154+ if (LHS->getOpcode() == PPCISD::ADDE &&
16155+ isNullConstant(LHS->getOperand(0)) &&
16156+ isNullConstant(LHS->getOperand(1)) && isAllOnesConstant(RHS)) {
16157+ return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
16158+ }
16159+ }
16160+ return SDValue();
16161+ }
16162+
1610916163SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
1611016164 DAGCombinerInfo &DCI) const {
1611116165 SelectionDAG &DAG = DCI.DAG;
@@ -16895,6 +16949,8 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
1689516949 }
1689616950 case ISD::BUILD_VECTOR:
1689716951 return DAGCombineBuildVector(N, DCI);
16952+ case PPCISD::ADDC:
16953+ return DAGCombineAddc(N, DCI);
1689816954 }
1689916955
1690016956 return SDValue();
@@ -16948,6 +17004,16 @@ void PPCTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
1694817004 Known.Zero = 0xFFFF0000;
1694917005 break;
1695017006 }
17007+ case PPCISD::ADDE: {
17008+ if (Op.getResNo() == 0) {
17009+ // (0|1), _ = ADDE 0, 0, CARRY
17010+ SDValue LHS = Op.getOperand(0);
17011+ SDValue RHS = Op.getOperand(1);
17012+ if (isNullConstant(LHS) && isNullConstant(RHS))
17013+ Known.Zero = ~1ULL;
17014+ }
17015+ break;
17016+ }
1695117017 case ISD::INTRINSIC_WO_CHAIN: {
1695217018 switch (Op.getConstantOperandVal(0)) {
1695317019 default: break;
@@ -18217,7 +18283,8 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1821718283 return SDValue();
1821818284
1821918285 SDLoc DL(N);
18220- SDVTList VTs = DAG.getVTList(MVT::i64, MVT::Glue);
18286+ EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
18287+ SDVTList VTs = DAG.getVTList(MVT::i64, CarryType);
1822118288 SDValue Cmp = RHS.getOperand(0);
1822218289 SDValue Z = Cmp.getOperand(0);
1822318290 auto *Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
@@ -18235,11 +18302,13 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1823518302 SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
1823618303 DAG.getConstant(NegConstant, DL, MVT::i64));
1823718304 SDValue AddOrZ = NegConstant != 0 ? Add : Z;
18238- SDValue Addc = DAG.getNode(ISD::ADDC, DL, DAG.getVTList(MVT::i64, MVT::Glue),
18239- AddOrZ, DAG.getConstant(-1ULL, DL, MVT::i64));
18240- return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
18305+ SDValue Addc =
18306+ DAG.getNode(ISD::UADDO, DL, DAG.getVTList(MVT::i64, CarryType), AddOrZ,
18307+ DAG.getConstant(-1ULL, DL, MVT::i64));
18308+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
18309+ DAG.getConstant(0, DL, MVT::i64),
1824118310 SDValue(Addc.getNode(), 1));
18242- }
18311+ }
1824318312 case ISD::SETEQ: {
1824418313 // when C == 0
1824518314 // --> addze X, (subfic Z, 0).carry
@@ -18250,11 +18319,14 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1825018319 SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
1825118320 DAG.getConstant(NegConstant, DL, MVT::i64));
1825218321 SDValue AddOrZ = NegConstant != 0 ? Add : Z;
18253- SDValue Subc = DAG.getNode(ISD::SUBC, DL, DAG.getVTList(MVT::i64, MVT::Glue),
18254- DAG.getConstant(0, DL, MVT::i64), AddOrZ);
18255- return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
18256- SDValue(Subc.getNode(), 1));
18257- }
18322+ SDValue Subc =
18323+ DAG.getNode(ISD::USUBO, DL, DAG.getVTList(MVT::i64, CarryType),
18324+ DAG.getConstant(0, DL, MVT::i64), AddOrZ);
18325+ SDValue Invert = DAG.getNode(ISD::XOR, DL, CarryType, Subc.getValue(1),
18326+ DAG.getAllOnesConstant(DL, CarryType));
18327+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
18328+ DAG.getConstant(0, DL, MVT::i64), Invert);
18329+ }
1825818330 }
1825918331
1826018332 return SDValue();
0 commit comments