@@ -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}
@@ -12013,43 +12016,74 @@ SDValue PPCTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
1201312016 llvm_unreachable("ERROR:Should return for all cases within swtich.");
1201412017}
1201512018
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();
12019+ static SDValue ConvertCarryValueToCarryFlag(EVT SumType, SDValue Value,
12020+ SelectionDAG &DAG,
12021+ const PPCSubtarget &STI) {
12022+ SDLoc DL(Value);
12023+ if (STI.useCRBits())
12024+ Value = DAG.getNode(ISD::SELECT, DL, SumType, Value,
12025+ DAG.getConstant(1, DL, SumType),
12026+ DAG.getConstant(0, DL, SumType));
12027+ else
12028+ Value = DAG.getZExtOrTrunc(Value, DL, SumType);
12029+ SDValue Sum = DAG.getNode(PPCISD::ADDC, DL, DAG.getVTList(SumType, MVT::i32),
12030+ Value, DAG.getAllOnesConstant(DL, SumType));
12031+ return Sum.getValue(1);
12032+ }
1203712033
12038- EVT VT = Op.getNode()->getValueType(0);
12034+ static SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag,
12035+ EVT CarryType, SelectionDAG &DAG,
12036+ const PPCSubtarget &STI) {
12037+ SDLoc DL(Flag);
12038+ SDValue Zero = DAG.getConstant(0, DL, SumType);
12039+ SDValue Carry = DAG.getNode(
12040+ PPCISD::ADDE, DL, DAG.getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12041+ if (STI.useCRBits())
12042+ return DAG.getSetCC(DL, CarryType, Carry, Zero, ISD::SETNE);
12043+ return DAG.getZExtOrTrunc(Carry, DL, CarryType);
12044+ }
1203912045
12040- SDValue ADDC;
12041- SDValue Overflow;
12042- SDVTList VTs = Op.getNode()->getVTList();
12046+ SDValue PPCTargetLowering::LowerADDSUBO(SDValue Op, SelectionDAG &DAG) const {
1204312047
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;
12048+ SDLoc DL(Op);
12049+ SDNode *N = Op.getNode();
12050+ EVT VT = N->getValueType(0);
12051+ EVT CarryType = N->getValueType(1);
12052+ unsigned Opc = N->getOpcode();
12053+ bool IsAdd = Opc == ISD::UADDO;
12054+ Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12055+ SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
12056+ N->getOperand(0), N->getOperand(1));
12057+ SDValue Carry = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType,
12058+ DAG, Subtarget);
12059+ if (!IsAdd)
12060+ Carry = DAG.getNode(ISD::XOR, DL, CarryType, Carry,
12061+ DAG.getAllOnesConstant(DL, CarryType));
12062+ return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, Carry);
12063+ }
12064+
12065+ SDValue PPCTargetLowering::LowerADDSUBO_CARRY(SDValue Op,
12066+ SelectionDAG &DAG) const {
12067+ SDLoc DL(Op);
12068+ SDNode *N = Op.getNode();
12069+ unsigned Opc = N->getOpcode();
12070+ EVT VT = N->getValueType(0);
12071+ EVT CarryType = N->getValueType(1);
12072+ SDValue CarryOp = N->getOperand(2);
12073+ bool IsAdd = Opc == ISD::UADDO_CARRY;
12074+ Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12075+ if (!IsAdd)
12076+ CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12077+ DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
12078+ CarryOp = ConvertCarryValueToCarryFlag(VT, CarryOp, DAG, Subtarget);
12079+ SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
12080+ Op.getOperand(0), Op.getOperand(1), CarryOp);
12081+ CarryOp = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType, DAG,
12082+ Subtarget);
12083+ if (!IsAdd)
12084+ CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12085+ DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
12086+ return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, CarryOp);
1205312087}
1205412088
1205512089SDValue PPCTargetLowering::LowerSSUBO(SDValue Op, SelectionDAG &DAG) const {
@@ -12080,8 +12114,8 @@ SDValue PPCTargetLowering::LowerSSUBO(SDValue Op, SelectionDAG &DAG) const {
1208012114///
1208112115SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
1208212116 switch (Op.getOpcode()) {
12083- default: llvm_unreachable("Wasn't expecting to be able to lower this!");
12084- case ISD::UADDO: return LowerUaddo(Op, DAG );
12117+ default:
12118+ llvm_unreachable("Wasn't expecting to be able to lower this!" );
1208512119 case ISD::FPOW: return lowerPow(Op, DAG);
1208612120 case ISD::FSIN: return lowerSin(Op, DAG);
1208712121 case ISD::FCOS: return lowerCos(Op, DAG);
@@ -12174,6 +12208,12 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
1217412208 return LowerATOMIC_LOAD_STORE(Op, DAG);
1217512209 case ISD::IS_FPCLASS:
1217612210 return LowerIS_FPCLASS(Op, DAG);
12211+ case ISD::UADDO:
12212+ case ISD::USUBO:
12213+ return LowerADDSUBO(Op, DAG);
12214+ case ISD::UADDO_CARRY:
12215+ case ISD::USUBO_CARRY:
12216+ return LowerADDSUBO_CARRY(Op, DAG);
1217712217 }
1217812218}
1217912219
@@ -16109,6 +16149,21 @@ static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth) {
1610916149 return true;
1611016150}
1611116151
16152+ static SDValue DAGCombineAddc(SDNode *N,
16153+ llvm::PPCTargetLowering::DAGCombinerInfo &DCI) {
16154+ if (N->getOpcode() == PPCISD::ADDC && N->hasAnyUseOfValue(1)) {
16155+ // (ADDC (ADDE 0, 0, C), -1) -> C
16156+ SDValue LHS = N->getOperand(0);
16157+ SDValue RHS = N->getOperand(1);
16158+ if (LHS->getOpcode() == PPCISD::ADDE &&
16159+ isNullConstant(LHS->getOperand(0)) &&
16160+ isNullConstant(LHS->getOperand(1)) && isAllOnesConstant(RHS)) {
16161+ return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
16162+ }
16163+ }
16164+ return SDValue();
16165+ }
16166+
1611216167SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
1611316168 DAGCombinerInfo &DCI) const {
1611416169 SelectionDAG &DAG = DCI.DAG;
@@ -16897,6 +16952,8 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
1689716952 }
1689816953 case ISD::BUILD_VECTOR:
1689916954 return DAGCombineBuildVector(N, DCI);
16955+ case PPCISD::ADDC:
16956+ return DAGCombineAddc(N, DCI);
1690016957 }
1690116958
1690216959 return SDValue();
@@ -16950,6 +17007,16 @@ void PPCTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
1695017007 Known.Zero = 0xFFFF0000;
1695117008 break;
1695217009 }
17010+ case PPCISD::ADDE: {
17011+ if (Op.getResNo() == 0) {
17012+ // (0|1), _ = ADDE 0, 0, CARRY
17013+ SDValue LHS = Op.getOperand(0);
17014+ SDValue RHS = Op.getOperand(1);
17015+ if (isNullConstant(LHS) && isNullConstant(RHS))
17016+ Known.Zero = ~1ULL;
17017+ }
17018+ break;
17019+ }
1695317020 case ISD::INTRINSIC_WO_CHAIN: {
1695417021 switch (Op.getConstantOperandVal(0)) {
1695517022 default: break;
@@ -18219,7 +18286,8 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1821918286 return SDValue();
1822018287
1822118288 SDLoc DL(N);
18222- SDVTList VTs = DAG.getVTList(MVT::i64, MVT::Glue);
18289+ EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
18290+ SDVTList VTs = DAG.getVTList(MVT::i64, CarryType);
1822318291 SDValue Cmp = RHS.getOperand(0);
1822418292 SDValue Z = Cmp.getOperand(0);
1822518293 auto *Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
@@ -18237,11 +18305,13 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1823718305 SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
1823818306 DAG.getConstant(NegConstant, DL, MVT::i64));
1823918307 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),
18308+ SDValue Addc =
18309+ DAG.getNode(ISD::UADDO, DL, DAG.getVTList(MVT::i64, CarryType), AddOrZ,
18310+ DAG.getConstant(-1ULL, DL, MVT::i64));
18311+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
18312+ DAG.getConstant(0, DL, MVT::i64),
1824318313 SDValue(Addc.getNode(), 1));
18244- }
18314+ }
1824518315 case ISD::SETEQ: {
1824618316 // when C == 0
1824718317 // --> addze X, (subfic Z, 0).carry
@@ -18252,11 +18322,14 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1825218322 SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
1825318323 DAG.getConstant(NegConstant, DL, MVT::i64));
1825418324 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- }
18325+ SDValue Subc =
18326+ DAG.getNode(ISD::USUBO, DL, DAG.getVTList(MVT::i64, CarryType),
18327+ DAG.getConstant(0, DL, MVT::i64), AddOrZ);
18328+ SDValue Invert = DAG.getNode(ISD::XOR, DL, CarryType, Subc.getValue(1),
18329+ DAG.getAllOnesConstant(DL, CarryType));
18330+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
18331+ DAG.getConstant(0, DL, MVT::i64), Invert);
18332+ }
1826018333 }
1826118334
1826218335 return SDValue();
0 commit comments