@@ -198,7 +198,11 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
198198 }
199199 }
200200
201+ // PowerPC uses addo,addo_carry,subo,subo_carry to propagate carry.
201202 setOperationAction(ISD::UADDO, isPPC64 ? MVT::i64 : MVT::i32, Custom);
203+ setOperationAction(ISD::USUBO, isPPC64 ? MVT::i64 : MVT::i32, Custom);
204+ setOperationAction(ISD::UADDO_CARRY, isPPC64 ? MVT::i64 : MVT::i32, Custom);
205+ setOperationAction(ISD::USUBO_CARRY, isPPC64 ? MVT::i64 : MVT::i32, Custom);
202206
203207 // Match BITREVERSE to customized fast code sequence in the td file.
204208 setOperationAction(ISD::BITREVERSE, MVT::i32, Legal);
@@ -254,15 +258,6 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
254258 setIndexedStoreAction(ISD::PRE_INC, MVT::f64, Legal);
255259 }
256260
257- // PowerPC uses ADDC/ADDE/SUBC/SUBE to propagate carry.
258- const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
259- for (MVT VT : ScalarIntVTs) {
260- setOperationAction(ISD::ADDC, VT, Legal);
261- setOperationAction(ISD::ADDE, VT, Legal);
262- setOperationAction(ISD::SUBC, VT, Legal);
263- setOperationAction(ISD::SUBE, VT, Legal);
264- }
265-
266261 if (Subtarget.useCRBits()) {
267262 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
268263
@@ -1853,6 +1848,14 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
18531848 case PPCISD::LXVRZX: return "PPCISD::LXVRZX";
18541849 case PPCISD::STORE_COND:
18551850 return "PPCISD::STORE_COND";
1851+ case PPCISD::ADDC:
1852+ return "PPCISD::ADDC";
1853+ case PPCISD::ADDE:
1854+ return "PPCISD::ADDE";
1855+ case PPCISD::SUBC:
1856+ return "PPCISD::SUBC";
1857+ case PPCISD::SUBE:
1858+ return "PPCISD::SUBE";
18561859 }
18571860 return nullptr;
18581861}
@@ -11977,51 +11980,81 @@ SDValue PPCTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
1197711980 llvm_unreachable("ERROR:Should return for all cases within swtich.");
1197811981}
1197911982
11980- SDValue PPCTargetLowering::LowerUaddo(SDValue Op, SelectionDAG &DAG) const {
11981- // Default to target independent lowering if there is a logical user of the
11982- // carry-bit.
11983- for (SDNode *U : Op->uses()) {
11984- if (U->getOpcode() == ISD::SELECT)
11985- return SDValue();
11986- if (ISD::isBitwiseLogicOp(U->getOpcode())) {
11987- for (unsigned i = 0, ie = U->getNumOperands(); i != ie; ++i) {
11988- if (U->getOperand(i).getOpcode() != ISD::UADDO &&
11989- U->getOperand(i).getOpcode() != ISD::MERGE_VALUES)
11990- return SDValue();
11991- }
11992- }
11993- }
11994- SDValue LHS = Op.getOperand(0);
11995- SDValue RHS = Op.getOperand(1);
11996- SDLoc dl(Op);
11997-
11998- // Default to target independent lowering for special cases handled there.
11999- if (isOneConstant(RHS) || isAllOnesConstant(RHS))
12000- return SDValue();
11983+ static SDValue ConvertCarryValueToCarryFlag(EVT SumType, SDValue Value,
11984+ SelectionDAG &DAG,
11985+ const PPCSubtarget &STI) {
11986+ SDLoc DL(Value);
11987+ if (STI.useCRBits())
11988+ Value = DAG.getNode(ISD::SELECT, DL, SumType, Value,
11989+ DAG.getConstant(1, DL, SumType),
11990+ DAG.getConstant(0, DL, SumType));
11991+ else
11992+ Value = DAG.getZExtOrTrunc(Value, DL, SumType);
11993+ SDValue Sum = DAG.getNode(PPCISD::ADDC, DL, DAG.getVTList(SumType, MVT::i32),
11994+ Value, DAG.getAllOnesConstant(DL, SumType));
11995+ return Sum.getValue(1);
11996+ }
1200111997
12002- EVT VT = Op.getNode()->getValueType(0);
11998+ static SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag,
11999+ EVT CarryType, SelectionDAG &DAG,
12000+ const PPCSubtarget &STI) {
12001+ SDLoc DL(Flag);
12002+ SDValue Zero = DAG.getConstant(0, DL, SumType);
12003+ SDValue Carry = DAG.getNode(
12004+ PPCISD::ADDE, DL, DAG.getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12005+ if (STI.useCRBits())
12006+ return DAG.getSetCC(DL, CarryType, Carry, Zero, ISD::SETNE);
12007+ return DAG.getZExtOrTrunc(Carry, DL, CarryType);
12008+ }
1200312009
12004- SDValue ADDC;
12005- SDValue Overflow;
12006- SDVTList VTs = Op.getNode()->getVTList();
12010+ SDValue PPCTargetLowering::LowerADDSUBO(SDValue Op, SelectionDAG &DAG) const {
1200712011
12008- ADDC = DAG.getNode(ISD::ADDC, dl, DAG.getVTList(VT, MVT::Glue), LHS, RHS);
12009- Overflow = DAG.getNode(ISD::ADDE, dl, DAG.getVTList(VT, MVT::Glue),
12010- DAG.getConstant(0, dl, VT), DAG.getConstant(0, dl, VT),
12011- ADDC.getValue(1));
12012- SDValue OverflowTrunc =
12013- DAG.getNode(ISD::TRUNCATE, dl, Op.getNode()->getValueType(1), Overflow);
12014- SDValue Res =
12015- DAG.getNode(ISD::MERGE_VALUES, dl, VTs, ADDC.getValue(0), OverflowTrunc);
12016- return Res;
12012+ SDLoc DL(Op);
12013+ SDNode *N = Op.getNode();
12014+ EVT VT = N->getValueType(0);
12015+ EVT CarryType = N->getValueType(1);
12016+ unsigned Opc = N->getOpcode();
12017+ bool IsAdd = Opc == ISD::UADDO;
12018+ Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12019+ SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
12020+ N->getOperand(0), N->getOperand(1));
12021+ SDValue Carry = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType,
12022+ DAG, Subtarget);
12023+ if (!IsAdd)
12024+ Carry = DAG.getNode(ISD::XOR, DL, CarryType, Carry,
12025+ DAG.getAllOnesConstant(DL, CarryType));
12026+ return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, Carry);
12027+ }
12028+
12029+ SDValue PPCTargetLowering::LowerADDSUBO_CARRY(SDValue Op,
12030+ SelectionDAG &DAG) const {
12031+ SDLoc DL(Op);
12032+ SDNode *N = Op.getNode();
12033+ unsigned Opc = N->getOpcode();
12034+ EVT VT = N->getValueType(0);
12035+ EVT CarryType = N->getValueType(1);
12036+ SDValue CarryOp = N->getOperand(2);
12037+ bool IsAdd = Opc == ISD::UADDO_CARRY;
12038+ Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12039+ if (!IsAdd)
12040+ CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12041+ DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
12042+ CarryOp = ConvertCarryValueToCarryFlag(VT, CarryOp, DAG, Subtarget);
12043+ SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
12044+ Op.getOperand(0), Op.getOperand(1), CarryOp);
12045+ CarryOp = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType, DAG,
12046+ Subtarget);
12047+ if (!IsAdd)
12048+ CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12049+ DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
12050+ return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, CarryOp);
1201712051}
1201812052
1201912053/// LowerOperation - Provide custom lowering hooks for some operations.
1202012054///
1202112055SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
1202212056 switch (Op.getOpcode()) {
1202312057 default: llvm_unreachable("Wasn't expecting to be able to lower this!");
12024- case ISD::UADDO: return LowerUaddo(Op, DAG);
1202512058 case ISD::FPOW: return lowerPow(Op, DAG);
1202612059 case ISD::FSIN: return lowerSin(Op, DAG);
1202712060 case ISD::FCOS: return lowerCos(Op, DAG);
@@ -12112,6 +12145,12 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
1211212145 return LowerATOMIC_LOAD_STORE(Op, DAG);
1211312146 case ISD::IS_FPCLASS:
1211412147 return LowerIS_FPCLASS(Op, DAG);
12148+ case ISD::UADDO:
12149+ case ISD::USUBO:
12150+ return LowerADDSUBO(Op, DAG);
12151+ case ISD::UADDO_CARRY:
12152+ case ISD::USUBO_CARRY:
12153+ return LowerADDSUBO_CARRY(Op, DAG);
1211512154 }
1211612155}
1211712156
@@ -16005,6 +16044,21 @@ static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth) {
1600516044 return true;
1600616045}
1600716046
16047+ static SDValue DAGCombineAddc(SDNode *N,
16048+ llvm::PPCTargetLowering::DAGCombinerInfo &DCI) {
16049+ if (N->getOpcode() == PPCISD::ADDC && N->hasAnyUseOfValue(1)) {
16050+ // (ADDC (ADDE 0, 0, C), -1) -> C
16051+ SDValue LHS = N->getOperand(0);
16052+ SDValue RHS = N->getOperand(1);
16053+ if (LHS->getOpcode() == PPCISD::ADDE &&
16054+ isNullConstant(LHS->getOperand(0)) &&
16055+ isNullConstant(LHS->getOperand(1)) && isAllOnesConstant(RHS)) {
16056+ return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
16057+ }
16058+ }
16059+ return SDValue();
16060+ }
16061+
1600816062SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
1600916063 DAGCombinerInfo &DCI) const {
1601016064 SelectionDAG &DAG = DCI.DAG;
@@ -16794,6 +16848,8 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
1679416848 }
1679516849 case ISD::BUILD_VECTOR:
1679616850 return DAGCombineBuildVector(N, DCI);
16851+ case PPCISD::ADDC:
16852+ return DAGCombineAddc(N, DCI);
1679716853 }
1679816854
1679916855 return SDValue();
@@ -16847,6 +16903,16 @@ void PPCTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
1684716903 Known.Zero = 0xFFFF0000;
1684816904 break;
1684916905 }
16906+ case PPCISD::ADDE: {
16907+ if (Op.getResNo() == 0) {
16908+ // (0|1), _ = ADDE 0, 0, CARRY
16909+ SDValue LHS = Op.getOperand(0);
16910+ SDValue RHS = Op.getOperand(1);
16911+ if (isNullConstant(LHS) && isNullConstant(RHS))
16912+ Known.Zero = ~1ULL;
16913+ }
16914+ break;
16915+ }
1685016916 case ISD::INTRINSIC_WO_CHAIN: {
1685116917 switch (Op.getConstantOperandVal(0)) {
1685216918 default: break;
@@ -18117,7 +18183,8 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1811718183 return SDValue();
1811818184
1811918185 SDLoc DL(N);
18120- SDVTList VTs = DAG.getVTList(MVT::i64, MVT::Glue);
18186+ EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
18187+ SDVTList VTs = DAG.getVTList(MVT::i64, CarryType);
1812118188 SDValue Cmp = RHS.getOperand(0);
1812218189 SDValue Z = Cmp.getOperand(0);
1812318190 auto *Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
@@ -18135,11 +18202,13 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1813518202 SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
1813618203 DAG.getConstant(NegConstant, DL, MVT::i64));
1813718204 SDValue AddOrZ = NegConstant != 0 ? Add : Z;
18138- SDValue Addc = DAG.getNode(ISD::ADDC, DL, DAG.getVTList(MVT::i64, MVT::Glue),
18139- AddOrZ, DAG.getConstant(-1ULL, DL, MVT::i64));
18140- return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
18205+ SDValue Addc =
18206+ DAG.getNode(ISD::UADDO, DL, DAG.getVTList(MVT::i64, CarryType), AddOrZ,
18207+ DAG.getConstant(-1ULL, DL, MVT::i64));
18208+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
18209+ DAG.getConstant(0, DL, MVT::i64),
1814118210 SDValue(Addc.getNode(), 1));
18142- }
18211+ }
1814318212 case ISD::SETEQ: {
1814418213 // when C == 0
1814518214 // --> addze X, (subfic Z, 0).carry
@@ -18150,11 +18219,14 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1815018219 SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
1815118220 DAG.getConstant(NegConstant, DL, MVT::i64));
1815218221 SDValue AddOrZ = NegConstant != 0 ? Add : Z;
18153- SDValue Subc = DAG.getNode(ISD::SUBC, DL, DAG.getVTList(MVT::i64, MVT::Glue),
18154- DAG.getConstant(0, DL, MVT::i64), AddOrZ);
18155- return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
18156- SDValue(Subc.getNode(), 1));
18157- }
18222+ SDValue Subc =
18223+ DAG.getNode(ISD::USUBO, DL, DAG.getVTList(MVT::i64, CarryType),
18224+ DAG.getConstant(0, DL, MVT::i64), AddOrZ);
18225+ SDValue Invert = DAG.getNode(ISD::XOR, DL, CarryType, Subc.getValue(1),
18226+ DAG.getAllOnesConstant(DL, CarryType));
18227+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
18228+ DAG.getConstant(0, DL, MVT::i64), Invert);
18229+ }
1815818230 }
1815918231
1816018232 return SDValue();
0 commit comments