@@ -197,6 +197,11 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
197197 }
198198
199199 setOperationAction(ISD::UADDO, RegVT, Custom);
200+ setOperationAction(ISD::USUBO, RegVT, Custom);
201+
202+ // PowerPC uses addo_carry,subo_carry to propagate carry.
203+ setOperationAction(ISD::UADDO_CARRY, RegVT, Custom);
204+ setOperationAction(ISD::USUBO_CARRY, RegVT, Custom);
200205
201206 // On P10, the default lowering generates better code using the
202207 // setbc instruction.
@@ -260,15 +265,6 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
260265 setIndexedStoreAction(ISD::PRE_INC, MVT::f64, Legal);
261266 }
262267
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-
272268 if (Subtarget.useCRBits()) {
273269 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
274270
@@ -1854,6 +1850,14 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
18541850 return "PPCISD::SETBC";
18551851 case PPCISD::SETBCR:
18561852 return "PPCISD::SETBCR";
1853+ case PPCISD::ADDC:
1854+ return "PPCISD::ADDC";
1855+ case PPCISD::ADDE:
1856+ return "PPCISD::ADDE";
1857+ case PPCISD::SUBC:
1858+ return "PPCISD::SUBC";
1859+ case PPCISD::SUBE:
1860+ return "PPCISD::SUBE";
18571861 }
18581862 return nullptr;
18591863}
@@ -12013,43 +12017,74 @@ SDValue PPCTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
1201312017 llvm_unreachable("ERROR:Should return for all cases within swtich.");
1201412018}
1201512019
12016- SDValue PPCTargetLowering::LowerUaddo(SDValue Op, SelectionDAG &DAG) const {
12017- // Default to target independent lowering if there is a logical user of the
12018- // carry-bit.
12019- for (SDNode *U : Op->users()) {
12020- if (U->getOpcode() == ISD::SELECT)
12021- return SDValue();
12022- if (ISD::isBitwiseLogicOp(U->getOpcode())) {
12023- for (unsigned i = 0, ie = U->getNumOperands(); i != ie; ++i) {
12024- if (U->getOperand(i).getOpcode() != ISD::UADDO &&
12025- U->getOperand(i).getOpcode() != ISD::MERGE_VALUES)
12026- return SDValue();
12027- }
12028- }
12029- }
12030- SDValue LHS = Op.getOperand(0);
12031- SDValue RHS = Op.getOperand(1);
12032- SDLoc dl(Op);
12033-
12034- // Default to target independent lowering for special cases handled there.
12035- if (isOneConstant(RHS) || isAllOnesConstant(RHS))
12036- return SDValue();
12020+ static SDValue ConvertCarryValueToCarryFlag(EVT SumType, SDValue Value,
12021+ SelectionDAG &DAG,
12022+ const PPCSubtarget &STI) {
12023+ SDLoc DL(Value);
12024+ if (STI.useCRBits())
12025+ Value = DAG.getNode(ISD::SELECT, DL, SumType, Value,
12026+ DAG.getConstant(1, DL, SumType),
12027+ DAG.getConstant(0, DL, SumType));
12028+ else
12029+ Value = DAG.getZExtOrTrunc(Value, DL, SumType);
12030+ SDValue Sum = DAG.getNode(PPCISD::ADDC, DL, DAG.getVTList(SumType, MVT::i32),
12031+ Value, DAG.getAllOnesConstant(DL, SumType));
12032+ return Sum.getValue(1);
12033+ }
1203712034
12038- EVT VT = Op.getNode()->getValueType(0);
12035+ static SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag,
12036+ EVT CarryType, SelectionDAG &DAG,
12037+ const PPCSubtarget &STI) {
12038+ SDLoc DL(Flag);
12039+ SDValue Zero = DAG.getConstant(0, DL, SumType);
12040+ SDValue Carry = DAG.getNode(
12041+ PPCISD::ADDE, DL, DAG.getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12042+ if (STI.useCRBits())
12043+ return DAG.getSetCC(DL, CarryType, Carry, Zero, ISD::SETNE);
12044+ return DAG.getZExtOrTrunc(Carry, DL, CarryType);
12045+ }
1203912046
12040- SDValue ADDC;
12041- SDValue Overflow;
12042- SDVTList VTs = Op.getNode()->getVTList();
12047+ SDValue PPCTargetLowering::LowerADDSUBO(SDValue Op, SelectionDAG &DAG) const {
1204312048
12044- ADDC = DAG.getNode(ISD::ADDC, dl, DAG.getVTList(VT, MVT::Glue), LHS, RHS);
12045- Overflow = DAG.getNode(ISD::ADDE, dl, DAG.getVTList(VT, MVT::Glue),
12046- DAG.getConstant(0, dl, VT), DAG.getConstant(0, dl, VT),
12047- ADDC.getValue(1));
12048- SDValue OverflowTrunc =
12049- DAG.getNode(ISD::TRUNCATE, dl, Op.getNode()->getValueType(1), Overflow);
12050- SDValue Res =
12051- DAG.getNode(ISD::MERGE_VALUES, dl, VTs, ADDC.getValue(0), OverflowTrunc);
12052- return Res;
12049+ SDLoc DL(Op);
12050+ SDNode *N = Op.getNode();
12051+ EVT VT = N->getValueType(0);
12052+ EVT CarryType = N->getValueType(1);
12053+ unsigned Opc = N->getOpcode();
12054+ bool IsAdd = Opc == ISD::UADDO;
12055+ Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12056+ SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
12057+ N->getOperand(0), N->getOperand(1));
12058+ SDValue Carry = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType,
12059+ DAG, Subtarget);
12060+ if (!IsAdd)
12061+ Carry = DAG.getNode(ISD::XOR, DL, CarryType, Carry,
12062+ DAG.getAllOnesConstant(DL, CarryType));
12063+ return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, Carry);
12064+ }
12065+
12066+ SDValue PPCTargetLowering::LowerADDSUBO_CARRY(SDValue Op,
12067+ SelectionDAG &DAG) const {
12068+ SDLoc DL(Op);
12069+ SDNode *N = Op.getNode();
12070+ unsigned Opc = N->getOpcode();
12071+ EVT VT = N->getValueType(0);
12072+ EVT CarryType = N->getValueType(1);
12073+ SDValue CarryOp = N->getOperand(2);
12074+ bool IsAdd = Opc == ISD::UADDO_CARRY;
12075+ Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12076+ if (!IsAdd)
12077+ CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12078+ DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
12079+ CarryOp = ConvertCarryValueToCarryFlag(VT, CarryOp, DAG, Subtarget);
12080+ SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
12081+ Op.getOperand(0), Op.getOperand(1), CarryOp);
12082+ CarryOp = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType, DAG,
12083+ Subtarget);
12084+ if (!IsAdd)
12085+ CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12086+ DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
12087+ return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, CarryOp);
1205312088}
1205412089
1205512090SDValue PPCTargetLowering::LowerSSUBO(SDValue Op, SelectionDAG &DAG) const {
@@ -12080,8 +12115,8 @@ SDValue PPCTargetLowering::LowerSSUBO(SDValue Op, SelectionDAG &DAG) const {
1208012115///
1208112116SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
1208212117 switch (Op.getOpcode()) {
12083- default: llvm_unreachable("Wasn't expecting to be able to lower this!");
12084- case ISD::UADDO: return LowerUaddo(Op, DAG );
12118+ default:
12119+ llvm_unreachable("Wasn't expecting to be able to lower this!" );
1208512120 case ISD::FPOW: return lowerPow(Op, DAG);
1208612121 case ISD::FSIN: return lowerSin(Op, DAG);
1208712122 case ISD::FCOS: return lowerCos(Op, DAG);
@@ -12174,6 +12209,12 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
1217412209 return LowerATOMIC_LOAD_STORE(Op, DAG);
1217512210 case ISD::IS_FPCLASS:
1217612211 return LowerIS_FPCLASS(Op, DAG);
12212+ case ISD::UADDO:
12213+ case ISD::USUBO:
12214+ return LowerADDSUBO(Op, DAG);
12215+ case ISD::UADDO_CARRY:
12216+ case ISD::USUBO_CARRY:
12217+ return LowerADDSUBO_CARRY(Op, DAG);
1217712218 }
1217812219}
1217912220
@@ -16109,6 +16150,21 @@ static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth) {
1610916150 return true;
1611016151}
1611116152
16153+ static SDValue DAGCombineAddc(SDNode *N,
16154+ llvm::PPCTargetLowering::DAGCombinerInfo &DCI) {
16155+ if (N->getOpcode() == PPCISD::ADDC && N->hasAnyUseOfValue(1)) {
16156+ // (ADDC (ADDE 0, 0, C), -1) -> C
16157+ SDValue LHS = N->getOperand(0);
16158+ SDValue RHS = N->getOperand(1);
16159+ if (LHS->getOpcode() == PPCISD::ADDE &&
16160+ isNullConstant(LHS->getOperand(0)) &&
16161+ isNullConstant(LHS->getOperand(1)) && isAllOnesConstant(RHS)) {
16162+ return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
16163+ }
16164+ }
16165+ return SDValue();
16166+ }
16167+
1611216168SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
1611316169 DAGCombinerInfo &DCI) const {
1611416170 SelectionDAG &DAG = DCI.DAG;
@@ -16897,6 +16953,8 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
1689716953 }
1689816954 case ISD::BUILD_VECTOR:
1689916955 return DAGCombineBuildVector(N, DCI);
16956+ case PPCISD::ADDC:
16957+ return DAGCombineAddc(N, DCI);
1690016958 }
1690116959
1690216960 return SDValue();
@@ -16950,6 +17008,16 @@ void PPCTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
1695017008 Known.Zero = 0xFFFF0000;
1695117009 break;
1695217010 }
17011+ case PPCISD::ADDE: {
17012+ if (Op.getResNo() == 0) {
17013+ // (0|1), _ = ADDE 0, 0, CARRY
17014+ SDValue LHS = Op.getOperand(0);
17015+ SDValue RHS = Op.getOperand(1);
17016+ if (isNullConstant(LHS) && isNullConstant(RHS))
17017+ Known.Zero = ~1ULL;
17018+ }
17019+ break;
17020+ }
1695317021 case ISD::INTRINSIC_WO_CHAIN: {
1695417022 switch (Op.getConstantOperandVal(0)) {
1695517023 default: break;
@@ -18219,7 +18287,8 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1821918287 return SDValue();
1822018288
1822118289 SDLoc DL(N);
18222- SDVTList VTs = DAG.getVTList(MVT::i64, MVT::Glue);
18290+ EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
18291+ SDVTList VTs = DAG.getVTList(MVT::i64, CarryType);
1822318292 SDValue Cmp = RHS.getOperand(0);
1822418293 SDValue Z = Cmp.getOperand(0);
1822518294 auto *Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
@@ -18237,11 +18306,14 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1823718306 SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
1823818307 DAG.getConstant(NegConstant, DL, MVT::i64));
1823918308 SDValue AddOrZ = NegConstant != 0 ? Add : Z;
18240- SDValue Addc = DAG.getNode(ISD::ADDC, DL, DAG.getVTList(MVT::i64, MVT::Glue),
18241- AddOrZ, DAG.getConstant(-1ULL, DL, MVT::i64));
18242- return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
18309+ SDValue Addc =
18310+ DAG.getNode(ISD::UADDO_CARRY, DL, DAG.getVTList(MVT::i64, CarryType),
18311+ AddOrZ, DAG.getConstant(-1ULL, DL, MVT::i64),
18312+ DAG.getConstant(0, DL, CarryType));
18313+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
18314+ DAG.getConstant(0, DL, MVT::i64),
1824318315 SDValue(Addc.getNode(), 1));
18244- }
18316+ }
1824518317 case ISD::SETEQ: {
1824618318 // when C == 0
1824718319 // --> addze X, (subfic Z, 0).carry
@@ -18252,11 +18324,15 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1825218324 SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
1825318325 DAG.getConstant(NegConstant, DL, MVT::i64));
1825418326 SDValue AddOrZ = NegConstant != 0 ? Add : Z;
18255- SDValue Subc = DAG.getNode(ISD::SUBC, DL, DAG.getVTList(MVT::i64, MVT::Glue),
18256- DAG.getConstant(0, DL, MVT::i64), AddOrZ);
18257- return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
18258- SDValue(Subc.getNode(), 1));
18259- }
18327+ SDValue Subc =
18328+ DAG.getNode(ISD::USUBO_CARRY, DL, DAG.getVTList(MVT::i64, CarryType),
18329+ DAG.getConstant(0, DL, MVT::i64), AddOrZ,
18330+ DAG.getConstant(0, DL, CarryType));
18331+ SDValue Invert = DAG.getNode(ISD::XOR, DL, CarryType, Subc.getValue(1),
18332+ DAG.getAllOnesConstant(DL, CarryType));
18333+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
18334+ DAG.getConstant(0, DL, MVT::i64), Invert);
18335+ }
1826018336 }
1826118337
1826218338 return SDValue();
0 commit comments