@@ -197,6 +197,11 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
197
197
}
198
198
199
199
setOperationAction(ISD::UADDO, RegVT, Custom);
200
+ setOperationAction(ISD::USUBO, RegVT, Custom);
201
+
202
+ // PowerPC uses addo_carry,subo_carry to propagate carry.
203
+ setOperationAction(ISD::UADDO_CARRY, RegVT, Custom);
204
+ setOperationAction(ISD::USUBO_CARRY, RegVT, Custom);
200
205
201
206
// On P10, the default lowering generates better code using the
202
207
// setbc instruction.
@@ -260,15 +265,6 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
260
265
setIndexedStoreAction(ISD::PRE_INC, MVT::f64, Legal);
261
266
}
262
267
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
268
if (Subtarget.useCRBits()) {
273
269
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
274
270
@@ -1854,6 +1850,14 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
1854
1850
return "PPCISD::SETBC";
1855
1851
case PPCISD::SETBCR:
1856
1852
return "PPCISD::SETBCR";
1853
+ case PPCISD::ADDC:
1854
+ return "PPCISD::ADDC";
1855
+ case PPCISD::ADDE:
1856
+ return "PPCISD::ADDE";
1857
+ case PPCISD::SUBC:
1858
+ return "PPCISD::SUBC";
1859
+ case PPCISD::SUBE:
1860
+ return "PPCISD::SUBE";
1857
1861
}
1858
1862
return nullptr;
1859
1863
}
@@ -12013,43 +12017,74 @@ SDValue PPCTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
12013
12017
llvm_unreachable("ERROR:Should return for all cases within swtich.");
12014
12018
}
12015
12019
12016
- SDValue PPCTargetLowering::LowerUaddo(SDValue Op, SelectionDAG &DAG) const {
12017
- // Default to target independent lowering if there is a logical user of the
12018
- // carry-bit.
12019
- for (SDNode *U : Op->users()) {
12020
- if (U->getOpcode() == ISD::SELECT)
12021
- return SDValue();
12022
- if (ISD::isBitwiseLogicOp(U->getOpcode())) {
12023
- for (unsigned i = 0, ie = U->getNumOperands(); i != ie; ++i) {
12024
- if (U->getOperand(i).getOpcode() != ISD::UADDO &&
12025
- U->getOperand(i).getOpcode() != ISD::MERGE_VALUES)
12026
- return SDValue();
12027
- }
12028
- }
12029
- }
12030
- SDValue LHS = Op.getOperand(0);
12031
- SDValue RHS = Op.getOperand(1);
12032
- SDLoc dl(Op);
12033
-
12034
- // Default to target independent lowering for special cases handled there.
12035
- if (isOneConstant(RHS) || isAllOnesConstant(RHS))
12036
- return SDValue();
12020
+ static SDValue ConvertCarryValueToCarryFlag(EVT SumType, SDValue Value,
12021
+ SelectionDAG &DAG,
12022
+ const PPCSubtarget &STI) {
12023
+ SDLoc DL(Value);
12024
+ if (STI.useCRBits())
12025
+ Value = DAG.getNode(ISD::SELECT, DL, SumType, Value,
12026
+ DAG.getConstant(1, DL, SumType),
12027
+ DAG.getConstant(0, DL, SumType));
12028
+ else
12029
+ Value = DAG.getZExtOrTrunc(Value, DL, SumType);
12030
+ SDValue Sum = DAG.getNode(PPCISD::ADDC, DL, DAG.getVTList(SumType, MVT::i32),
12031
+ Value, DAG.getAllOnesConstant(DL, SumType));
12032
+ return Sum.getValue(1);
12033
+ }
12037
12034
12038
- EVT VT = Op.getNode()->getValueType(0);
12035
+ static SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag,
12036
+ EVT CarryType, SelectionDAG &DAG,
12037
+ const PPCSubtarget &STI) {
12038
+ SDLoc DL(Flag);
12039
+ SDValue Zero = DAG.getConstant(0, DL, SumType);
12040
+ SDValue Carry = DAG.getNode(
12041
+ PPCISD::ADDE, DL, DAG.getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12042
+ if (STI.useCRBits())
12043
+ return DAG.getSetCC(DL, CarryType, Carry, Zero, ISD::SETNE);
12044
+ return DAG.getZExtOrTrunc(Carry, DL, CarryType);
12045
+ }
12039
12046
12040
- SDValue ADDC;
12041
- SDValue Overflow;
12042
- SDVTList VTs = Op.getNode()->getVTList();
12047
+ SDValue PPCTargetLowering::LowerADDSUBO(SDValue Op, SelectionDAG &DAG) const {
12043
12048
12044
- ADDC = DAG.getNode(ISD::ADDC, dl, DAG.getVTList(VT, MVT::Glue), LHS, RHS);
12045
- Overflow = DAG.getNode(ISD::ADDE, dl, DAG.getVTList(VT, MVT::Glue),
12046
- DAG.getConstant(0, dl, VT), DAG.getConstant(0, dl, VT),
12047
- ADDC.getValue(1));
12048
- SDValue OverflowTrunc =
12049
- DAG.getNode(ISD::TRUNCATE, dl, Op.getNode()->getValueType(1), Overflow);
12050
- SDValue Res =
12051
- DAG.getNode(ISD::MERGE_VALUES, dl, VTs, ADDC.getValue(0), OverflowTrunc);
12052
- return Res;
12049
+ SDLoc DL(Op);
12050
+ SDNode *N = Op.getNode();
12051
+ EVT VT = N->getValueType(0);
12052
+ EVT CarryType = N->getValueType(1);
12053
+ unsigned Opc = N->getOpcode();
12054
+ bool IsAdd = Opc == ISD::UADDO;
12055
+ Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12056
+ SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
12057
+ N->getOperand(0), N->getOperand(1));
12058
+ SDValue Carry = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType,
12059
+ DAG, Subtarget);
12060
+ if (!IsAdd)
12061
+ Carry = DAG.getNode(ISD::XOR, DL, CarryType, Carry,
12062
+ DAG.getAllOnesConstant(DL, CarryType));
12063
+ return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, Carry);
12064
+ }
12065
+
12066
+ SDValue PPCTargetLowering::LowerADDSUBO_CARRY(SDValue Op,
12067
+ SelectionDAG &DAG) const {
12068
+ SDLoc DL(Op);
12069
+ SDNode *N = Op.getNode();
12070
+ unsigned Opc = N->getOpcode();
12071
+ EVT VT = N->getValueType(0);
12072
+ EVT CarryType = N->getValueType(1);
12073
+ SDValue CarryOp = N->getOperand(2);
12074
+ bool IsAdd = Opc == ISD::UADDO_CARRY;
12075
+ Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12076
+ if (!IsAdd)
12077
+ CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12078
+ DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
12079
+ CarryOp = ConvertCarryValueToCarryFlag(VT, CarryOp, DAG, Subtarget);
12080
+ SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
12081
+ Op.getOperand(0), Op.getOperand(1), CarryOp);
12082
+ CarryOp = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType, DAG,
12083
+ Subtarget);
12084
+ if (!IsAdd)
12085
+ CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12086
+ DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
12087
+ return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, CarryOp);
12053
12088
}
12054
12089
12055
12090
SDValue PPCTargetLowering::LowerSSUBO(SDValue Op, SelectionDAG &DAG) const {
@@ -12080,8 +12115,8 @@ SDValue PPCTargetLowering::LowerSSUBO(SDValue Op, SelectionDAG &DAG) const {
12080
12115
///
12081
12116
SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
12082
12117
switch (Op.getOpcode()) {
12083
- default: llvm_unreachable("Wasn't expecting to be able to lower this!");
12084
- case ISD::UADDO: return LowerUaddo(Op, DAG );
12118
+ default:
12119
+ llvm_unreachable("Wasn't expecting to be able to lower this!" );
12085
12120
case ISD::FPOW: return lowerPow(Op, DAG);
12086
12121
case ISD::FSIN: return lowerSin(Op, DAG);
12087
12122
case ISD::FCOS: return lowerCos(Op, DAG);
@@ -12174,6 +12209,12 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
12174
12209
return LowerATOMIC_LOAD_STORE(Op, DAG);
12175
12210
case ISD::IS_FPCLASS:
12176
12211
return LowerIS_FPCLASS(Op, DAG);
12212
+ case ISD::UADDO:
12213
+ case ISD::USUBO:
12214
+ return LowerADDSUBO(Op, DAG);
12215
+ case ISD::UADDO_CARRY:
12216
+ case ISD::USUBO_CARRY:
12217
+ return LowerADDSUBO_CARRY(Op, DAG);
12177
12218
}
12178
12219
}
12179
12220
@@ -16109,6 +16150,21 @@ static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth) {
16109
16150
return true;
16110
16151
}
16111
16152
16153
+ static SDValue DAGCombineAddc(SDNode *N,
16154
+ llvm::PPCTargetLowering::DAGCombinerInfo &DCI) {
16155
+ if (N->getOpcode() == PPCISD::ADDC && N->hasAnyUseOfValue(1)) {
16156
+ // (ADDC (ADDE 0, 0, C), -1) -> C
16157
+ SDValue LHS = N->getOperand(0);
16158
+ SDValue RHS = N->getOperand(1);
16159
+ if (LHS->getOpcode() == PPCISD::ADDE &&
16160
+ isNullConstant(LHS->getOperand(0)) &&
16161
+ isNullConstant(LHS->getOperand(1)) && isAllOnesConstant(RHS)) {
16162
+ return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
16163
+ }
16164
+ }
16165
+ return SDValue();
16166
+ }
16167
+
16112
16168
SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
16113
16169
DAGCombinerInfo &DCI) const {
16114
16170
SelectionDAG &DAG = DCI.DAG;
@@ -16897,6 +16953,8 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
16897
16953
}
16898
16954
case ISD::BUILD_VECTOR:
16899
16955
return DAGCombineBuildVector(N, DCI);
16956
+ case PPCISD::ADDC:
16957
+ return DAGCombineAddc(N, DCI);
16900
16958
}
16901
16959
16902
16960
return SDValue();
@@ -16950,6 +17008,16 @@ void PPCTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
16950
17008
Known.Zero = 0xFFFF0000;
16951
17009
break;
16952
17010
}
17011
+ case PPCISD::ADDE: {
17012
+ if (Op.getResNo() == 0) {
17013
+ // (0|1), _ = ADDE 0, 0, CARRY
17014
+ SDValue LHS = Op.getOperand(0);
17015
+ SDValue RHS = Op.getOperand(1);
17016
+ if (isNullConstant(LHS) && isNullConstant(RHS))
17017
+ Known.Zero = ~1ULL;
17018
+ }
17019
+ break;
17020
+ }
16953
17021
case ISD::INTRINSIC_WO_CHAIN: {
16954
17022
switch (Op.getConstantOperandVal(0)) {
16955
17023
default: break;
@@ -18219,7 +18287,8 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
18219
18287
return SDValue();
18220
18288
18221
18289
SDLoc DL(N);
18222
- SDVTList VTs = DAG.getVTList(MVT::i64, MVT::Glue);
18290
+ EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
18291
+ SDVTList VTs = DAG.getVTList(MVT::i64, CarryType);
18223
18292
SDValue Cmp = RHS.getOperand(0);
18224
18293
SDValue Z = Cmp.getOperand(0);
18225
18294
auto *Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
@@ -18237,11 +18306,14 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
18237
18306
SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
18238
18307
DAG.getConstant(NegConstant, DL, MVT::i64));
18239
18308
SDValue AddOrZ = NegConstant != 0 ? Add : Z;
18240
- SDValue Addc = DAG.getNode(ISD::ADDC, DL, DAG.getVTList(MVT::i64, MVT::Glue),
18241
- AddOrZ, DAG.getConstant(-1ULL, DL, MVT::i64));
18242
- return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
18309
+ SDValue Addc =
18310
+ DAG.getNode(ISD::UADDO_CARRY, DL, DAG.getVTList(MVT::i64, CarryType),
18311
+ AddOrZ, DAG.getConstant(-1ULL, DL, MVT::i64),
18312
+ DAG.getConstant(0, DL, CarryType));
18313
+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
18314
+ DAG.getConstant(0, DL, MVT::i64),
18243
18315
SDValue(Addc.getNode(), 1));
18244
- }
18316
+ }
18245
18317
case ISD::SETEQ: {
18246
18318
// when C == 0
18247
18319
// --> addze X, (subfic Z, 0).carry
@@ -18252,11 +18324,15 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
18252
18324
SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
18253
18325
DAG.getConstant(NegConstant, DL, MVT::i64));
18254
18326
SDValue AddOrZ = NegConstant != 0 ? Add : Z;
18255
- SDValue Subc = DAG.getNode(ISD::SUBC, DL, DAG.getVTList(MVT::i64, MVT::Glue),
18256
- DAG.getConstant(0, DL, MVT::i64), AddOrZ);
18257
- return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
18258
- SDValue(Subc.getNode(), 1));
18259
- }
18327
+ SDValue Subc =
18328
+ DAG.getNode(ISD::USUBO_CARRY, DL, DAG.getVTList(MVT::i64, CarryType),
18329
+ DAG.getConstant(0, DL, MVT::i64), AddOrZ,
18330
+ DAG.getConstant(0, DL, CarryType));
18331
+ SDValue Invert = DAG.getNode(ISD::XOR, DL, CarryType, Subc.getValue(1),
18332
+ DAG.getAllOnesConstant(DL, CarryType));
18333
+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
18334
+ DAG.getConstant(0, DL, MVT::i64), Invert);
18335
+ }
18260
18336
}
18261
18337
18262
18338
return SDValue();
0 commit comments