@@ -196,7 +196,11 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
196
196
}
197
197
}
198
198
199
+ // PowerPC uses addo,addo_carry,subo,subo_carry to propagate carry.
199
200
setOperationAction(ISD::UADDO, RegVT, Custom);
201
+ setOperationAction(ISD::USUBO, RegVT, Custom);
202
+ setOperationAction(ISD::UADDO_CARRY, RegVT, Custom);
203
+ setOperationAction(ISD::USUBO_CARRY, RegVT, Custom);
200
204
201
205
// On P10, the default lowering generates better code using the
202
206
// setbc instruction.
@@ -260,15 +264,6 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
260
264
setIndexedStoreAction(ISD::PRE_INC, MVT::f64, Legal);
261
265
}
262
266
263
- // PowerPC uses ADDC/ADDE/SUBC/SUBE to propagate carry.
264
- const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
265
- for (MVT VT : ScalarIntVTs) {
266
- setOperationAction(ISD::ADDC, VT, Legal);
267
- setOperationAction(ISD::ADDE, VT, Legal);
268
- setOperationAction(ISD::SUBC, VT, Legal);
269
- setOperationAction(ISD::SUBE, VT, Legal);
270
- }
271
-
272
267
if (Subtarget.useCRBits()) {
273
268
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
274
269
@@ -1854,6 +1849,14 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
1854
1849
return "PPCISD::SETBC";
1855
1850
case PPCISD::SETBCR:
1856
1851
return "PPCISD::SETBCR";
1852
+ case PPCISD::ADDC:
1853
+ return "PPCISD::ADDC";
1854
+ case PPCISD::ADDE:
1855
+ return "PPCISD::ADDE";
1856
+ case PPCISD::SUBC:
1857
+ return "PPCISD::SUBC";
1858
+ case PPCISD::SUBE:
1859
+ return "PPCISD::SUBE";
1857
1860
}
1858
1861
return nullptr;
1859
1862
}
@@ -12010,43 +12013,74 @@ SDValue PPCTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
12010
12013
llvm_unreachable("ERROR:Should return for all cases within swtich.");
12011
12014
}
12012
12015
12013
- SDValue PPCTargetLowering::LowerUaddo(SDValue Op, SelectionDAG &DAG) const {
12014
- // Default to target independent lowering if there is a logical user of the
12015
- // carry-bit.
12016
- for (SDNode *U : Op->uses()) {
12017
- if (U->getOpcode() == ISD::SELECT)
12018
- return SDValue();
12019
- if (ISD::isBitwiseLogicOp(U->getOpcode())) {
12020
- for (unsigned i = 0, ie = U->getNumOperands(); i != ie; ++i) {
12021
- if (U->getOperand(i).getOpcode() != ISD::UADDO &&
12022
- U->getOperand(i).getOpcode() != ISD::MERGE_VALUES)
12023
- return SDValue();
12024
- }
12025
- }
12026
- }
12027
- SDValue LHS = Op.getOperand(0);
12028
- SDValue RHS = Op.getOperand(1);
12029
- SDLoc dl(Op);
12030
-
12031
- // Default to target independent lowering for special cases handled there.
12032
- if (isOneConstant(RHS) || isAllOnesConstant(RHS))
12033
- return SDValue();
12016
+ static SDValue ConvertCarryValueToCarryFlag(EVT SumType, SDValue Value,
12017
+ SelectionDAG &DAG,
12018
+ const PPCSubtarget &STI) {
12019
+ SDLoc DL(Value);
12020
+ if (STI.useCRBits())
12021
+ Value = DAG.getNode(ISD::SELECT, DL, SumType, Value,
12022
+ DAG.getConstant(1, DL, SumType),
12023
+ DAG.getConstant(0, DL, SumType));
12024
+ else
12025
+ Value = DAG.getZExtOrTrunc(Value, DL, SumType);
12026
+ SDValue Sum = DAG.getNode(PPCISD::ADDC, DL, DAG.getVTList(SumType, MVT::i32),
12027
+ Value, DAG.getAllOnesConstant(DL, SumType));
12028
+ return Sum.getValue(1);
12029
+ }
12034
12030
12035
- EVT VT = Op.getNode()->getValueType(0);
12031
+ static SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag,
12032
+ EVT CarryType, SelectionDAG &DAG,
12033
+ const PPCSubtarget &STI) {
12034
+ SDLoc DL(Flag);
12035
+ SDValue Zero = DAG.getConstant(0, DL, SumType);
12036
+ SDValue Carry = DAG.getNode(
12037
+ PPCISD::ADDE, DL, DAG.getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12038
+ if (STI.useCRBits())
12039
+ return DAG.getSetCC(DL, CarryType, Carry, Zero, ISD::SETNE);
12040
+ return DAG.getZExtOrTrunc(Carry, DL, CarryType);
12041
+ }
12036
12042
12037
- SDValue ADDC;
12038
- SDValue Overflow;
12039
- SDVTList VTs = Op.getNode()->getVTList();
12043
+ SDValue PPCTargetLowering::LowerADDSUBO(SDValue Op, SelectionDAG &DAG) const {
12040
12044
12041
- ADDC = DAG.getNode(ISD::ADDC, dl, DAG.getVTList(VT, MVT::Glue), LHS, RHS);
12042
- Overflow = DAG.getNode(ISD::ADDE, dl, DAG.getVTList(VT, MVT::Glue),
12043
- DAG.getConstant(0, dl, VT), DAG.getConstant(0, dl, VT),
12044
- ADDC.getValue(1));
12045
- SDValue OverflowTrunc =
12046
- DAG.getNode(ISD::TRUNCATE, dl, Op.getNode()->getValueType(1), Overflow);
12047
- SDValue Res =
12048
- DAG.getNode(ISD::MERGE_VALUES, dl, VTs, ADDC.getValue(0), OverflowTrunc);
12049
- return Res;
12045
+ SDLoc DL(Op);
12046
+ SDNode *N = Op.getNode();
12047
+ EVT VT = N->getValueType(0);
12048
+ EVT CarryType = N->getValueType(1);
12049
+ unsigned Opc = N->getOpcode();
12050
+ bool IsAdd = Opc == ISD::UADDO;
12051
+ Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12052
+ SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
12053
+ N->getOperand(0), N->getOperand(1));
12054
+ SDValue Carry = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType,
12055
+ DAG, Subtarget);
12056
+ if (!IsAdd)
12057
+ Carry = DAG.getNode(ISD::XOR, DL, CarryType, Carry,
12058
+ DAG.getAllOnesConstant(DL, CarryType));
12059
+ return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, Carry);
12060
+ }
12061
+
12062
+ SDValue PPCTargetLowering::LowerADDSUBO_CARRY(SDValue Op,
12063
+ SelectionDAG &DAG) const {
12064
+ SDLoc DL(Op);
12065
+ SDNode *N = Op.getNode();
12066
+ unsigned Opc = N->getOpcode();
12067
+ EVT VT = N->getValueType(0);
12068
+ EVT CarryType = N->getValueType(1);
12069
+ SDValue CarryOp = N->getOperand(2);
12070
+ bool IsAdd = Opc == ISD::UADDO_CARRY;
12071
+ Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12072
+ if (!IsAdd)
12073
+ CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12074
+ DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
12075
+ CarryOp = ConvertCarryValueToCarryFlag(VT, CarryOp, DAG, Subtarget);
12076
+ SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
12077
+ Op.getOperand(0), Op.getOperand(1), CarryOp);
12078
+ CarryOp = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType, DAG,
12079
+ Subtarget);
12080
+ if (!IsAdd)
12081
+ CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12082
+ DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
12083
+ return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, CarryOp);
12050
12084
}
12051
12085
12052
12086
SDValue PPCTargetLowering::LowerSSUBO(SDValue Op, SelectionDAG &DAG) const {
@@ -12078,7 +12112,6 @@ SDValue PPCTargetLowering::LowerSSUBO(SDValue Op, SelectionDAG &DAG) const {
12078
12112
SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
12079
12113
switch (Op.getOpcode()) {
12080
12114
default: llvm_unreachable("Wasn't expecting to be able to lower this!");
12081
- case ISD::UADDO: return LowerUaddo(Op, DAG);
12082
12115
case ISD::FPOW: return lowerPow(Op, DAG);
12083
12116
case ISD::FSIN: return lowerSin(Op, DAG);
12084
12117
case ISD::FCOS: return lowerCos(Op, DAG);
@@ -12171,6 +12204,12 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
12171
12204
return LowerATOMIC_LOAD_STORE(Op, DAG);
12172
12205
case ISD::IS_FPCLASS:
12173
12206
return LowerIS_FPCLASS(Op, DAG);
12207
+ case ISD::UADDO:
12208
+ case ISD::USUBO:
12209
+ return LowerADDSUBO(Op, DAG);
12210
+ case ISD::UADDO_CARRY:
12211
+ case ISD::USUBO_CARRY:
12212
+ return LowerADDSUBO_CARRY(Op, DAG);
12174
12213
}
12175
12214
}
12176
12215
@@ -16106,6 +16145,21 @@ static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth) {
16106
16145
return true;
16107
16146
}
16108
16147
16148
+ static SDValue DAGCombineAddc(SDNode *N,
16149
+ llvm::PPCTargetLowering::DAGCombinerInfo &DCI) {
16150
+ if (N->getOpcode() == PPCISD::ADDC && N->hasAnyUseOfValue(1)) {
16151
+ // (ADDC (ADDE 0, 0, C), -1) -> C
16152
+ SDValue LHS = N->getOperand(0);
16153
+ SDValue RHS = N->getOperand(1);
16154
+ if (LHS->getOpcode() == PPCISD::ADDE &&
16155
+ isNullConstant(LHS->getOperand(0)) &&
16156
+ isNullConstant(LHS->getOperand(1)) && isAllOnesConstant(RHS)) {
16157
+ return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
16158
+ }
16159
+ }
16160
+ return SDValue();
16161
+ }
16162
+
16109
16163
SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
16110
16164
DAGCombinerInfo &DCI) const {
16111
16165
SelectionDAG &DAG = DCI.DAG;
@@ -16895,6 +16949,8 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
16895
16949
}
16896
16950
case ISD::BUILD_VECTOR:
16897
16951
return DAGCombineBuildVector(N, DCI);
16952
+ case PPCISD::ADDC:
16953
+ return DAGCombineAddc(N, DCI);
16898
16954
}
16899
16955
16900
16956
return SDValue();
@@ -16948,6 +17004,16 @@ void PPCTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
16948
17004
Known.Zero = 0xFFFF0000;
16949
17005
break;
16950
17006
}
17007
+ case PPCISD::ADDE: {
17008
+ if (Op.getResNo() == 0) {
17009
+ // (0|1), _ = ADDE 0, 0, CARRY
17010
+ SDValue LHS = Op.getOperand(0);
17011
+ SDValue RHS = Op.getOperand(1);
17012
+ if (isNullConstant(LHS) && isNullConstant(RHS))
17013
+ Known.Zero = ~1ULL;
17014
+ }
17015
+ break;
17016
+ }
16951
17017
case ISD::INTRINSIC_WO_CHAIN: {
16952
17018
switch (Op.getConstantOperandVal(0)) {
16953
17019
default: break;
@@ -18217,7 +18283,8 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
18217
18283
return SDValue();
18218
18284
18219
18285
SDLoc DL(N);
18220
- SDVTList VTs = DAG.getVTList(MVT::i64, MVT::Glue);
18286
+ EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
18287
+ SDVTList VTs = DAG.getVTList(MVT::i64, CarryType);
18221
18288
SDValue Cmp = RHS.getOperand(0);
18222
18289
SDValue Z = Cmp.getOperand(0);
18223
18290
auto *Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
@@ -18235,11 +18302,13 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
18235
18302
SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
18236
18303
DAG.getConstant(NegConstant, DL, MVT::i64));
18237
18304
SDValue AddOrZ = NegConstant != 0 ? Add : Z;
18238
- SDValue Addc = DAG.getNode(ISD::ADDC, DL, DAG.getVTList(MVT::i64, MVT::Glue),
18239
- AddOrZ, DAG.getConstant(-1ULL, DL, MVT::i64));
18240
- return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
18305
+ SDValue Addc =
18306
+ DAG.getNode(ISD::UADDO, DL, DAG.getVTList(MVT::i64, CarryType), AddOrZ,
18307
+ DAG.getConstant(-1ULL, DL, MVT::i64));
18308
+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
18309
+ DAG.getConstant(0, DL, MVT::i64),
18241
18310
SDValue(Addc.getNode(), 1));
18242
- }
18311
+ }
18243
18312
case ISD::SETEQ: {
18244
18313
// when C == 0
18245
18314
// --> addze X, (subfic Z, 0).carry
@@ -18250,11 +18319,14 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
18250
18319
SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
18251
18320
DAG.getConstant(NegConstant, DL, MVT::i64));
18252
18321
SDValue AddOrZ = NegConstant != 0 ? Add : Z;
18253
- SDValue Subc = DAG.getNode(ISD::SUBC, DL, DAG.getVTList(MVT::i64, MVT::Glue),
18254
- DAG.getConstant(0, DL, MVT::i64), AddOrZ);
18255
- return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
18256
- SDValue(Subc.getNode(), 1));
18257
- }
18322
+ SDValue Subc =
18323
+ DAG.getNode(ISD::USUBO, DL, DAG.getVTList(MVT::i64, CarryType),
18324
+ DAG.getConstant(0, DL, MVT::i64), AddOrZ);
18325
+ SDValue Invert = DAG.getNode(ISD::XOR, DL, CarryType, Subc.getValue(1),
18326
+ DAG.getAllOnesConstant(DL, CarryType));
18327
+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
18328
+ DAG.getConstant(0, DL, MVT::i64), Invert);
18329
+ }
18258
18330
}
18259
18331
18260
18332
return SDValue();
0 commit comments