@@ -242,13 +242,15 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
242
242
setIndexedStoreAction(ISD::PRE_INC, MVT::f64, Legal);
243
243
}
244
244
245
- // PowerPC uses ADDC/ADDE/SUBC/SUBE to propagate carry.
245
+ // PowerPC uses addo,addo_carry,subo,subo_carry to propagate carry.
246
246
const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
247
247
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);
252
254
}
253
255
254
256
if (Subtarget.useCRBits()) {
@@ -1841,6 +1843,14 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
1841
1843
case PPCISD::LXVRZX: return "PPCISD::LXVRZX";
1842
1844
case PPCISD::STORE_COND:
1843
1845
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";
1844
1854
}
1845
1855
return nullptr;
1846
1856
}
@@ -11722,6 +11732,63 @@ SDValue PPCTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
11722
11732
llvm_unreachable("ERROR:Should return for all cases within swtich.");
11723
11733
}
11724
11734
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
+
11725
11792
/// LowerOperation - Provide custom lowering hooks for some operations.
11726
11793
///
11727
11794
SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
@@ -11815,6 +11882,12 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
11815
11882
return LowerATOMIC_LOAD_STORE(Op, DAG);
11816
11883
case ISD::IS_FPCLASS:
11817
11884
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);
11818
11891
}
11819
11892
}
11820
11893
@@ -15708,6 +15781,21 @@ static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth) {
15708
15781
return true;
15709
15782
}
15710
15783
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
+
15711
15799
SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
15712
15800
DAGCombinerInfo &DCI) const {
15713
15801
SelectionDAG &DAG = DCI.DAG;
@@ -16497,6 +16585,8 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
16497
16585
}
16498
16586
case ISD::BUILD_VECTOR:
16499
16587
return DAGCombineBuildVector(N, DCI);
16588
+ case PPCISD::ADDC:
16589
+ return DAGCombineAddc(N, DCI);
16500
16590
}
16501
16591
16502
16592
return SDValue();
@@ -16550,6 +16640,16 @@ void PPCTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
16550
16640
Known.Zero = 0xFFFF0000;
16551
16641
break;
16552
16642
}
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
+ }
16553
16653
case ISD::INTRINSIC_WO_CHAIN: {
16554
16654
switch (Op.getConstantOperandVal(0)) {
16555
16655
default: break;
@@ -17811,7 +17911,8 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
17811
17911
return SDValue();
17812
17912
17813
17913
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);
17815
17916
SDValue Cmp = RHS.getOperand(0);
17816
17917
SDValue Z = Cmp.getOperand(0);
17817
17918
auto *Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
@@ -17829,11 +17930,13 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
17829
17930
SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
17830
17931
DAG.getConstant(NegConstant, DL, MVT::i64));
17831
17932
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),
17835
17938
SDValue(Addc.getNode(), 1));
17836
- }
17939
+ }
17837
17940
case ISD::SETEQ: {
17838
17941
// when C == 0
17839
17942
// --> addze X, (subfic Z, 0).carry
@@ -17844,11 +17947,14 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
17844
17947
SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
17845
17948
DAG.getConstant(NegConstant, DL, MVT::i64));
17846
17949
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
+ }
17852
17958
}
17853
17959
17854
17960
return SDValue();
0 commit comments