@@ -242,13 +242,19 @@ 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);
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);
252
258
}
253
259
254
260
if (Subtarget.useCRBits()) {
@@ -1841,6 +1847,10 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
1841
1847
case PPCISD::LXVRZX: return "PPCISD::LXVRZX";
1842
1848
case PPCISD::STORE_COND:
1843
1849
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";
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 || 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
+
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,16 @@ 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
+ 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);
11818
11895
}
11819
11896
}
11820
11897
@@ -15708,6 +15785,21 @@ static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth) {
15708
15785
return true;
15709
15786
}
15710
15787
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
+
15711
15803
SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
15712
15804
DAGCombinerInfo &DCI) const {
15713
15805
SelectionDAG &DAG = DCI.DAG;
@@ -16497,6 +16589,8 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
16497
16589
}
16498
16590
case ISD::BUILD_VECTOR:
16499
16591
return DAGCombineBuildVector(N, DCI);
16592
+ case PPCISD::ADDC:
16593
+ return DAGCombineAddc(N, DCI);
16500
16594
}
16501
16595
16502
16596
return SDValue();
@@ -16550,6 +16644,16 @@ void PPCTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
16550
16644
Known.Zero = 0xFFFF0000;
16551
16645
break;
16552
16646
}
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
+ }
16553
16657
case ISD::INTRINSIC_WO_CHAIN: {
16554
16658
switch (Op.getConstantOperandVal(0)) {
16555
16659
default: break;
@@ -17811,7 +17915,8 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
17811
17915
return SDValue();
17812
17916
17813
17917
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);
17815
17920
SDValue Cmp = RHS.getOperand(0);
17816
17921
SDValue Z = Cmp.getOperand(0);
17817
17922
auto *Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
@@ -17829,11 +17934,13 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
17829
17934
SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
17830
17935
DAG.getConstant(NegConstant, DL, MVT::i64));
17831
17936
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),
17835
17942
SDValue(Addc.getNode(), 1));
17836
- }
17943
+ }
17837
17944
case ISD::SETEQ: {
17838
17945
// when C == 0
17839
17946
// --> addze X, (subfic Z, 0).carry
@@ -17844,11 +17951,14 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
17844
17951
SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
17845
17952
DAG.getConstant(NegConstant, DL, MVT::i64));
17846
17953
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
+ }
17852
17962
}
17853
17963
17854
17964
return SDValue();
0 commit comments