@@ -242,13 +242,15 @@ 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);
252254 }
253255
254256 if (Subtarget.useCRBits()) {
@@ -1841,6 +1843,14 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
18411843 case PPCISD::LXVRZX: return "PPCISD::LXVRZX";
18421844 case PPCISD::STORE_COND:
18431845 return "PPCISD::STORE_COND";
1846+ case PPCISD::ADDC:
1847+ return "PPCISD::ADDC";
1848+ case PPCISD::ADDE:
1849+ return "PPCISD::ADDE";
1850+ case PPCISD::SUBC:
1851+ return "PPCISD::SUBC";
1852+ case PPCISD::SUBE:
1853+ 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;
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;
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,12 @@ 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+ return LowerADDSUBO(Op, DAG);
11888+ case ISD::UADDO_CARRY:
11889+ case ISD::USUBO_CARRY:
11890+ return LowerADDSUBO_CARRY(Op, DAG);
1181811891 }
1181911892}
1182011893
@@ -15708,6 +15781,21 @@ static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth) {
1570815781 return true;
1570915782}
1571015783
15784+ static SDValue DAGCombineAddc(SDNode *N,
15785+ llvm::PPCTargetLowering::DAGCombinerInfo &DCI) {
15786+ if (N->getOpcode() == PPCISD::ADDC && N->hasAnyUseOfValue(1)) {
15787+ // (ADDC (ADDE 0, 0, C), -1) -> C
15788+ SDValue LHS = N->getOperand(0);
15789+ SDValue RHS = N->getOperand(1);
15790+ if (LHS->getOpcode() == PPCISD::ADDE &&
15791+ isNullConstant(LHS->getOperand(0)) &&
15792+ isNullConstant(LHS->getOperand(1)) && isAllOnesConstant(RHS)) {
15793+ return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
15794+ }
15795+ }
15796+ return SDValue();
15797+ }
15798+
1571115799SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
1571215800 DAGCombinerInfo &DCI) const {
1571315801 SelectionDAG &DAG = DCI.DAG;
@@ -16497,6 +16585,8 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
1649716585 }
1649816586 case ISD::BUILD_VECTOR:
1649916587 return DAGCombineBuildVector(N, DCI);
16588+ case PPCISD::ADDC:
16589+ return DAGCombineAddc(N, DCI);
1650016590 }
1650116591
1650216592 return SDValue();
@@ -16550,6 +16640,16 @@ void PPCTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
1655016640 Known.Zero = 0xFFFF0000;
1655116641 break;
1655216642 }
16643+ case PPCISD::ADDE: {
16644+ if (Op.getResNo() == 0) {
16645+ // (0|1), _ = ADDE 0, 0, CARRY
16646+ SDValue LHS = Op.getOperand(0);
16647+ SDValue RHS = Op.getOperand(1);
16648+ if (isNullConstant(LHS) && isNullConstant(RHS))
16649+ Known.Zero = ~1U;
16650+ }
16651+ break;
16652+ }
1655316653 case ISD::INTRINSIC_WO_CHAIN: {
1655416654 switch (Op.getConstantOperandVal(0)) {
1655516655 default: break;
@@ -17811,7 +17911,8 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1781117911 return SDValue();
1781217912
1781317913 SDLoc DL(N);
17814- SDVTList VTs = DAG.getVTList(MVT::i64, MVT::Glue);
17914+ EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
17915+ SDVTList VTs = DAG.getVTList(MVT::i64, CarryType);
1781517916 SDValue Cmp = RHS.getOperand(0);
1781617917 SDValue Z = Cmp.getOperand(0);
1781717918 auto *Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
@@ -17829,11 +17930,13 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1782917930 SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
1783017931 DAG.getConstant(NegConstant, DL, MVT::i64));
1783117932 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),
17933+ SDValue Addc =
17934+ DAG.getNode(ISD::UADDO, DL, DAG.getVTList(MVT::i64, CarryType), AddOrZ,
17935+ DAG.getConstant(-1ULL, DL, MVT::i64));
17936+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
17937+ DAG.getConstant(0, DL, MVT::i64),
1783517938 SDValue(Addc.getNode(), 1));
17836- }
17939+ }
1783717940 case ISD::SETEQ: {
1783817941 // when C == 0
1783917942 // --> addze X, (subfic Z, 0).carry
@@ -17844,11 +17947,14 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1784417947 SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
1784517948 DAG.getConstant(NegConstant, DL, MVT::i64));
1784617949 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- }
17950+ SDValue Subc =
17951+ DAG.getNode(ISD::USUBO, DL, DAG.getVTList(MVT::i64, CarryType),
17952+ DAG.getConstant(0, DL, MVT::i64), AddOrZ);
17953+ SDValue Invert = DAG.getNode(ISD::XOR, DL, CarryType, Subc.getValue(1),
17954+ DAG.getAllOnesConstant(DL, CarryType));
17955+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
17956+ DAG.getConstant(0, DL, MVT::i64), Invert);
17957+ }
1785217958 }
1785317959
1785417960 return SDValue();
0 commit comments