@@ -242,13 +242,19 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
242242 setIndexedStoreAction(ISD::PRE_INC, MVT::f64, Legal);
243243 }
244244
245- // PowerPC uses ADDC/ADDE/SUBC/SUBE to propagate carry.
245+ // PowerPC uses addo,addo_carry,subo,subo_carry to propagate carry.
246246 const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
247247 for (MVT VT : ScalarIntVTs) {
248- setOperationAction(ISD::ADDC, VT, Legal);
249- setOperationAction(ISD::ADDE, VT, Legal);
250- setOperationAction(ISD::SUBC, VT, Legal);
251- setOperationAction(ISD::SUBE, VT, Legal);
248+ if (VT == MVT::i64 && !isPPC64)
249+ continue;
250+ setOperationAction(ISD::UADDO, VT, Custom);
251+ setOperationAction(ISD::USUBO, VT, Custom);
252+ setOperationAction(ISD::UADDO_CARRY, VT, Custom);
253+ setOperationAction(ISD::USUBO_CARRY, VT, Custom);
254+ setOperationAction(ISD::SADDO, VT, Custom);
255+ setOperationAction(ISD::SSUBO, VT, Custom);
256+ setOperationAction(ISD::SADDO_CARRY, VT, Custom);
257+ setOperationAction(ISD::SSUBO_CARRY, VT, Custom);
252258 }
253259
254260 if (Subtarget.useCRBits()) {
@@ -1841,6 +1847,10 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
18411847 case PPCISD::LXVRZX: return "PPCISD::LXVRZX";
18421848 case PPCISD::STORE_COND:
18431849 return "PPCISD::STORE_COND";
1850+ case PPCISD::ADDC: return "PPCISD::ADDC";
1851+ case PPCISD::ADDE: return "PPCISD::ADDE";
1852+ case PPCISD::SUBC: return "PPCISD::SUBC";
1853+ case PPCISD::SUBE: return "PPCISD::SUBE";
18441854 }
18451855 return nullptr;
18461856}
@@ -11722,6 +11732,63 @@ SDValue PPCTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
1172211732 llvm_unreachable("ERROR:Should return for all cases within swtich.");
1172311733}
1172411734
11735+ static SDValue ConvertCarryValueToCarryFlag(SDValue Value, SelectionDAG &DAG) {
11736+ SDLoc DL(Value);
11737+ Value = DAG.getZExtOrTrunc(Value, DL, MVT::i32);
11738+ SDValue Sum = DAG.getNode(PPCISD::ADDC, DL, DAG.getVTList(MVT::i32, MVT::i32),
11739+ Value, DAG.getAllOnesConstant(DL, MVT::i32));
11740+ return Sum.getValue(1);
11741+ }
11742+
11743+ static SDValue ConvertCarryFlagToCarryValue(SDValue Flag, EVT CarryType,
11744+ SelectionDAG &DAG) {
11745+ SDLoc DL(Flag);
11746+ SDValue Zero = DAG.getConstant(0, DL, MVT::i32);
11747+ SDValue Carry = DAG.getNode(
11748+ PPCISD::ADDE, DL, DAG.getVTList(MVT::i32, MVT::i32), Zero, Zero, Flag);
11749+ return DAG.getZExtOrTrunc(Carry, DL, CarryType);
11750+ }
11751+
11752+ SDValue PPCTargetLowering::LowerADDSUBO(SDValue Op, SelectionDAG &DAG) const {
11753+ SDLoc DL(Op);
11754+ SDNode *N = Op.getNode();
11755+ EVT VT = N->getValueType(0);
11756+ EVT CarryType = N->getValueType(1);
11757+ unsigned Opc = N->getOpcode();
11758+ bool IsAdd = (Opc == ISD::UADDO || Opc == ISD::SADDO);
11759+ Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
11760+ SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
11761+ N->getOperand(0), N->getOperand(1));
11762+ SDValue Carry = ConvertCarryFlagToCarryValue(Sum.getValue(1), CarryType, DAG);
11763+ if (!IsAdd)
11764+ Carry = DAG.getNode(ISD::XOR, DL, CarryType, Carry,
11765+ DAG.getAllOnesConstant(DL, CarryType));
11766+ return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, Carry);
11767+ }
11768+
11769+ SDValue PPCTargetLowering::LowerADDSUBO_CARRY(SDValue Op,
11770+ SelectionDAG &DAG) const {
11771+ SDLoc DL(Op);
11772+ SDNode *N = Op.getNode();
11773+ unsigned Opc = N->getOpcode();
11774+ EVT VT = N->getValueType(0);
11775+ EVT CarryType = N->getValueType(1);
11776+ SDValue CarryOp = N->getOperand(2);
11777+ bool IsAdd = (Opc == ISD::UADDO_CARRY || Opc == ISD::SADDO_CARRY);
11778+ Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
11779+ if (!IsAdd)
11780+ CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
11781+ DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
11782+ CarryOp = ConvertCarryValueToCarryFlag(CarryOp, DAG);
11783+ SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
11784+ Op.getOperand(0), Op.getOperand(1), CarryOp);
11785+ CarryOp = ConvertCarryFlagToCarryValue(Sum.getValue(1), CarryType, DAG);
11786+ if (!IsAdd)
11787+ CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
11788+ DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
11789+ return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, CarryOp);
11790+ }
11791+
1172511792/// LowerOperation - Provide custom lowering hooks for some operations.
1172611793///
1172711794SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
@@ -11815,6 +11882,16 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
1181511882 return LowerATOMIC_LOAD_STORE(Op, DAG);
1181611883 case ISD::IS_FPCLASS:
1181711884 return LowerIS_FPCLASS(Op, DAG);
11885+ case ISD::UADDO:
11886+ case ISD::USUBO:
11887+ case ISD::SADDO:
11888+ case ISD::SSUBO:
11889+ return LowerADDSUBO(Op, DAG);
11890+ case ISD::UADDO_CARRY:
11891+ case ISD::USUBO_CARRY:
11892+ case ISD::SADDO_CARRY:
11893+ case ISD::SSUBO_CARRY:
11894+ return LowerADDSUBO_CARRY(Op, DAG);
1181811895 }
1181911896}
1182011897
@@ -15708,6 +15785,21 @@ static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth) {
1570815785 return true;
1570915786}
1571015787
15788+ static SDValue DAGCombineAddc(SDNode *N,
15789+ llvm::PPCTargetLowering::DAGCombinerInfo &DCI) {
15790+ if (N->getOpcode() == PPCISD::ADDC && N->hasAnyUseOfValue(1)) {
15791+ // (ADDC (ADDE 0, 0, C), -1) -> C
15792+ SDValue LHS = N->getOperand(0);
15793+ SDValue RHS = N->getOperand(1);
15794+ if (LHS->getOpcode() == PPCISD::ADDE &&
15795+ isNullConstant(LHS->getOperand(0)) &&
15796+ isNullConstant(LHS->getOperand(1)) && isAllOnesConstant(RHS)) {
15797+ return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
15798+ }
15799+ }
15800+ return SDValue();
15801+ }
15802+
1571115803SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
1571215804 DAGCombinerInfo &DCI) const {
1571315805 SelectionDAG &DAG = DCI.DAG;
@@ -16497,6 +16589,8 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
1649716589 }
1649816590 case ISD::BUILD_VECTOR:
1649916591 return DAGCombineBuildVector(N, DCI);
16592+ case PPCISD::ADDC:
16593+ return DAGCombineAddc(N, DCI);
1650016594 }
1650116595
1650216596 return SDValue();
@@ -16550,6 +16644,16 @@ void PPCTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
1655016644 Known.Zero = 0xFFFF0000;
1655116645 break;
1655216646 }
16647+ case PPCISD::ADDE: {
16648+ if (Op.getResNo() == 0) {
16649+ // (0|1), _ = ADDE 0, 0, CARRY
16650+ SDValue LHS = Op.getOperand(0);
16651+ SDValue RHS = Op.getOperand(1);
16652+ if (isNullConstant(LHS) && isNullConstant(RHS))
16653+ Known.Zero = ~1U;
16654+ }
16655+ break;
16656+ }
1655316657 case ISD::INTRINSIC_WO_CHAIN: {
1655416658 switch (Op.getConstantOperandVal(0)) {
1655516659 default: break;
@@ -17811,7 +17915,8 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1781117915 return SDValue();
1781217916
1781317917 SDLoc DL(N);
17814- SDVTList VTs = DAG.getVTList(MVT::i64, MVT::Glue);
17918+ EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
17919+ SDVTList VTs = DAG.getVTList(MVT::i64, CarryType);
1781517920 SDValue Cmp = RHS.getOperand(0);
1781617921 SDValue Z = Cmp.getOperand(0);
1781717922 auto *Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
@@ -17829,11 +17934,13 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1782917934 SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
1783017935 DAG.getConstant(NegConstant, DL, MVT::i64));
1783117936 SDValue AddOrZ = NegConstant != 0 ? Add : Z;
17832- SDValue Addc = DAG.getNode(ISD::ADDC, DL, DAG.getVTList(MVT::i64, MVT::Glue),
17833- AddOrZ, DAG.getConstant(-1ULL, DL, MVT::i64));
17834- return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
17937+ SDValue Addc =
17938+ DAG.getNode(ISD::UADDO, DL, DAG.getVTList(MVT::i64, CarryType), AddOrZ,
17939+ DAG.getConstant(-1ULL, DL, MVT::i64));
17940+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
17941+ DAG.getConstant(0, DL, MVT::i64),
1783517942 SDValue(Addc.getNode(), 1));
17836- }
17943+ }
1783717944 case ISD::SETEQ: {
1783817945 // when C == 0
1783917946 // --> addze X, (subfic Z, 0).carry
@@ -17844,11 +17951,14 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1784417951 SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
1784517952 DAG.getConstant(NegConstant, DL, MVT::i64));
1784617953 SDValue AddOrZ = NegConstant != 0 ? Add : Z;
17847- SDValue Subc = DAG.getNode(ISD::SUBC, DL, DAG.getVTList(MVT::i64, MVT::Glue),
17848- DAG.getConstant(0, DL, MVT::i64), AddOrZ);
17849- return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
17850- SDValue(Subc.getNode(), 1));
17851- }
17954+ SDValue Subc =
17955+ DAG.getNode(ISD::USUBO, DL, DAG.getVTList(MVT::i64, CarryType),
17956+ DAG.getConstant(0, DL, MVT::i64), AddOrZ);
17957+ SDValue Invert = DAG.getNode(ISD::XOR, DL, CarryType, Subc.getValue(1),
17958+ DAG.getAllOnesConstant(DL, CarryType));
17959+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
17960+ DAG.getConstant(0, DL, MVT::i64), Invert);
17961+ }
1785217962 }
1785317963
1785417964 return SDValue();
0 commit comments