@@ -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}
@@ -12028,43 +12031,74 @@ SDValue PPCTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
1202812031 llvm_unreachable("ERROR:Should return for all cases within swtich.");
1202912032}
1203012033
12031- SDValue PPCTargetLowering::LowerUaddo(SDValue Op, SelectionDAG &DAG) const {
12032- // Default to target independent lowering if there is a logical user of the
12033- // carry-bit.
12034- for (SDNode *U : Op->users()) {
12035- if (U->getOpcode() == ISD::SELECT)
12036- return SDValue();
12037- if (ISD::isBitwiseLogicOp(U->getOpcode())) {
12038- for (unsigned i = 0, ie = U->getNumOperands(); i != ie; ++i) {
12039- if (U->getOperand(i).getOpcode() != ISD::UADDO &&
12040- U->getOperand(i).getOpcode() != ISD::MERGE_VALUES)
12041- return SDValue();
12042- }
12043- }
12044- }
12045- SDValue LHS = Op.getOperand(0);
12046- SDValue RHS = Op.getOperand(1);
12047- SDLoc dl(Op);
12048-
12049- // Default to target independent lowering for special cases handled there.
12050- if (isOneConstant(RHS) || isAllOnesConstant(RHS))
12051- return SDValue();
12034+ static SDValue ConvertCarryValueToCarryFlag(EVT SumType, SDValue Value,
12035+ SelectionDAG &DAG,
12036+ const PPCSubtarget &STI) {
12037+ SDLoc DL(Value);
12038+ if (STI.useCRBits())
12039+ Value = DAG.getNode(ISD::SELECT, DL, SumType, Value,
12040+ DAG.getConstant(1, DL, SumType),
12041+ DAG.getConstant(0, DL, SumType));
12042+ else
12043+ Value = DAG.getZExtOrTrunc(Value, DL, SumType);
12044+ SDValue Sum = DAG.getNode(PPCISD::ADDC, DL, DAG.getVTList(SumType, MVT::i32),
12045+ Value, DAG.getAllOnesConstant(DL, SumType));
12046+ return Sum.getValue(1);
12047+ }
1205212048
12053- EVT VT = Op.getNode()->getValueType(0);
12049+ static SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag,
12050+ EVT CarryType, SelectionDAG &DAG,
12051+ const PPCSubtarget &STI) {
12052+ SDLoc DL(Flag);
12053+ SDValue Zero = DAG.getConstant(0, DL, SumType);
12054+ SDValue Carry = DAG.getNode(
12055+ PPCISD::ADDE, DL, DAG.getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12056+ if (STI.useCRBits())
12057+ return DAG.getSetCC(DL, CarryType, Carry, Zero, ISD::SETNE);
12058+ return DAG.getZExtOrTrunc(Carry, DL, CarryType);
12059+ }
1205412060
12055- SDValue ADDC;
12056- SDValue Overflow;
12057- SDVTList VTs = Op.getNode()->getVTList();
12061+ SDValue PPCTargetLowering::LowerADDSUBO(SDValue Op, SelectionDAG &DAG) const {
1205812062
12059- ADDC = DAG.getNode(ISD::ADDC, dl, DAG.getVTList(VT, MVT::Glue), LHS, RHS);
12060- Overflow = DAG.getNode(ISD::ADDE, dl, DAG.getVTList(VT, MVT::Glue),
12061- DAG.getConstant(0, dl, VT), DAG.getConstant(0, dl, VT),
12062- ADDC.getValue(1));
12063- SDValue OverflowTrunc =
12064- DAG.getNode(ISD::TRUNCATE, dl, Op.getNode()->getValueType(1), Overflow);
12065- SDValue Res =
12066- DAG.getNode(ISD::MERGE_VALUES, dl, VTs, ADDC.getValue(0), OverflowTrunc);
12067- return Res;
12063+ SDLoc DL(Op);
12064+ SDNode *N = Op.getNode();
12065+ EVT VT = N->getValueType(0);
12066+ EVT CarryType = N->getValueType(1);
12067+ unsigned Opc = N->getOpcode();
12068+ bool IsAdd = Opc == ISD::UADDO;
12069+ Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12070+ SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
12071+ N->getOperand(0), N->getOperand(1));
12072+ SDValue Carry = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType,
12073+ DAG, Subtarget);
12074+ if (!IsAdd)
12075+ Carry = DAG.getNode(ISD::XOR, DL, CarryType, Carry,
12076+ DAG.getAllOnesConstant(DL, CarryType));
12077+ return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, Carry);
12078+ }
12079+
12080+ SDValue PPCTargetLowering::LowerADDSUBO_CARRY(SDValue Op,
12081+ SelectionDAG &DAG) const {
12082+ SDLoc DL(Op);
12083+ SDNode *N = Op.getNode();
12084+ unsigned Opc = N->getOpcode();
12085+ EVT VT = N->getValueType(0);
12086+ EVT CarryType = N->getValueType(1);
12087+ SDValue CarryOp = N->getOperand(2);
12088+ bool IsAdd = Opc == ISD::UADDO_CARRY;
12089+ Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12090+ if (!IsAdd)
12091+ CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12092+ DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
12093+ CarryOp = ConvertCarryValueToCarryFlag(VT, CarryOp, DAG, Subtarget);
12094+ SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
12095+ Op.getOperand(0), Op.getOperand(1), CarryOp);
12096+ CarryOp = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType, DAG,
12097+ Subtarget);
12098+ if (!IsAdd)
12099+ CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12100+ DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
12101+ return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, CarryOp);
1206812102}
1206912103
1207012104SDValue PPCTargetLowering::LowerSSUBO(SDValue Op, SelectionDAG &DAG) const {
@@ -12095,8 +12129,8 @@ SDValue PPCTargetLowering::LowerSSUBO(SDValue Op, SelectionDAG &DAG) const {
1209512129///
1209612130SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
1209712131 switch (Op.getOpcode()) {
12098- default: llvm_unreachable("Wasn't expecting to be able to lower this!");
12099- case ISD::UADDO: return LowerUaddo(Op, DAG );
12132+ default:
12133+ llvm_unreachable("Wasn't expecting to be able to lower this!" );
1210012134 case ISD::FPOW: return lowerPow(Op, DAG);
1210112135 case ISD::FSIN: return lowerSin(Op, DAG);
1210212136 case ISD::FCOS: return lowerCos(Op, DAG);
@@ -12189,6 +12223,12 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
1218912223 return LowerATOMIC_LOAD_STORE(Op, DAG);
1219012224 case ISD::IS_FPCLASS:
1219112225 return LowerIS_FPCLASS(Op, DAG);
12226+ case ISD::UADDO:
12227+ case ISD::USUBO:
12228+ return LowerADDSUBO(Op, DAG);
12229+ case ISD::UADDO_CARRY:
12230+ case ISD::USUBO_CARRY:
12231+ return LowerADDSUBO_CARRY(Op, DAG);
1219212232 }
1219312233}
1219412234
@@ -16124,6 +16164,21 @@ static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth) {
1612416164 return true;
1612516165}
1612616166
16167+ static SDValue DAGCombineAddc(SDNode *N,
16168+ llvm::PPCTargetLowering::DAGCombinerInfo &DCI) {
16169+ if (N->getOpcode() == PPCISD::ADDC && N->hasAnyUseOfValue(1)) {
16170+ // (ADDC (ADDE 0, 0, C), -1) -> C
16171+ SDValue LHS = N->getOperand(0);
16172+ SDValue RHS = N->getOperand(1);
16173+ if (LHS->getOpcode() == PPCISD::ADDE &&
16174+ isNullConstant(LHS->getOperand(0)) &&
16175+ isNullConstant(LHS->getOperand(1)) && isAllOnesConstant(RHS)) {
16176+ return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
16177+ }
16178+ }
16179+ return SDValue();
16180+ }
16181+
1612716182SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
1612816183 DAGCombinerInfo &DCI) const {
1612916184 SelectionDAG &DAG = DCI.DAG;
@@ -16912,6 +16967,8 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
1691216967 }
1691316968 case ISD::BUILD_VECTOR:
1691416969 return DAGCombineBuildVector(N, DCI);
16970+ case PPCISD::ADDC:
16971+ return DAGCombineAddc(N, DCI);
1691516972 }
1691616973
1691716974 return SDValue();
@@ -16965,6 +17022,16 @@ void PPCTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
1696517022 Known.Zero = 0xFFFF0000;
1696617023 break;
1696717024 }
17025+ case PPCISD::ADDE: {
17026+ if (Op.getResNo() == 0) {
17027+ // (0|1), _ = ADDE 0, 0, CARRY
17028+ SDValue LHS = Op.getOperand(0);
17029+ SDValue RHS = Op.getOperand(1);
17030+ if (isNullConstant(LHS) && isNullConstant(RHS))
17031+ Known.Zero = ~1ULL;
17032+ }
17033+ break;
17034+ }
1696817035 case ISD::INTRINSIC_WO_CHAIN: {
1696917036 switch (Op.getConstantOperandVal(0)) {
1697017037 default: break;
@@ -18234,7 +18301,8 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1823418301 return SDValue();
1823518302
1823618303 SDLoc DL(N);
18237- SDVTList VTs = DAG.getVTList(MVT::i64, MVT::Glue);
18304+ EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
18305+ SDVTList VTs = DAG.getVTList(MVT::i64, CarryType);
1823818306 SDValue Cmp = RHS.getOperand(0);
1823918307 SDValue Z = Cmp.getOperand(0);
1824018308 auto *Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
@@ -18252,11 +18320,13 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1825218320 SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
1825318321 DAG.getConstant(NegConstant, DL, MVT::i64));
1825418322 SDValue AddOrZ = NegConstant != 0 ? Add : Z;
18255- SDValue Addc = DAG.getNode(ISD::ADDC, DL, DAG.getVTList(MVT::i64, MVT::Glue),
18256- AddOrZ, DAG.getConstant(-1ULL, DL, MVT::i64));
18257- return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
18323+ SDValue Addc =
18324+ DAG.getNode(ISD::UADDO, DL, DAG.getVTList(MVT::i64, CarryType), AddOrZ,
18325+ DAG.getConstant(-1ULL, DL, MVT::i64));
18326+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
18327+ DAG.getConstant(0, DL, MVT::i64),
1825818328 SDValue(Addc.getNode(), 1));
18259- }
18329+ }
1826018330 case ISD::SETEQ: {
1826118331 // when C == 0
1826218332 // --> addze X, (subfic Z, 0).carry
@@ -18267,11 +18337,14 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1826718337 SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
1826818338 DAG.getConstant(NegConstant, DL, MVT::i64));
1826918339 SDValue AddOrZ = NegConstant != 0 ? Add : Z;
18270- SDValue Subc = DAG.getNode(ISD::SUBC, DL, DAG.getVTList(MVT::i64, MVT::Glue),
18271- DAG.getConstant(0, DL, MVT::i64), AddOrZ);
18272- return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
18273- SDValue(Subc.getNode(), 1));
18274- }
18340+ SDValue Subc =
18341+ DAG.getNode(ISD::USUBO, DL, DAG.getVTList(MVT::i64, CarryType),
18342+ DAG.getConstant(0, DL, MVT::i64), AddOrZ);
18343+ SDValue Invert = DAG.getNode(ISD::XOR, DL, CarryType, Subc.getValue(1),
18344+ DAG.getAllOnesConstant(DL, CarryType));
18345+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
18346+ DAG.getConstant(0, DL, MVT::i64), Invert);
18347+ }
1827518348 }
1827618349
1827718350 return SDValue();
0 commit comments