@@ -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
}
@@ -12013,43 +12016,74 @@ SDValue PPCTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
12013
12016
llvm_unreachable("ERROR:Should return for all cases within swtich.");
12014
12017
}
12015
12018
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();
12019
+ static SDValue ConvertCarryValueToCarryFlag(EVT SumType, SDValue Value,
12020
+ SelectionDAG &DAG,
12021
+ const PPCSubtarget &STI) {
12022
+ SDLoc DL(Value);
12023
+ if (STI.useCRBits())
12024
+ Value = DAG.getNode(ISD::SELECT, DL, SumType, Value,
12025
+ DAG.getConstant(1, DL, SumType),
12026
+ DAG.getConstant(0, DL, SumType));
12027
+ else
12028
+ Value = DAG.getZExtOrTrunc(Value, DL, SumType);
12029
+ SDValue Sum = DAG.getNode(PPCISD::ADDC, DL, DAG.getVTList(SumType, MVT::i32),
12030
+ Value, DAG.getAllOnesConstant(DL, SumType));
12031
+ return Sum.getValue(1);
12032
+ }
12037
12033
12038
- EVT VT = Op.getNode()->getValueType(0);
12034
+ static SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag,
12035
+ EVT CarryType, SelectionDAG &DAG,
12036
+ const PPCSubtarget &STI) {
12037
+ SDLoc DL(Flag);
12038
+ SDValue Zero = DAG.getConstant(0, DL, SumType);
12039
+ SDValue Carry = DAG.getNode(
12040
+ PPCISD::ADDE, DL, DAG.getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12041
+ if (STI.useCRBits())
12042
+ return DAG.getSetCC(DL, CarryType, Carry, Zero, ISD::SETNE);
12043
+ return DAG.getZExtOrTrunc(Carry, DL, CarryType);
12044
+ }
12039
12045
12040
- SDValue ADDC;
12041
- SDValue Overflow;
12042
- SDVTList VTs = Op.getNode()->getVTList();
12046
+ SDValue PPCTargetLowering::LowerADDSUBO(SDValue Op, SelectionDAG &DAG) const {
12043
12047
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;
12048
+ SDLoc DL(Op);
12049
+ SDNode *N = Op.getNode();
12050
+ EVT VT = N->getValueType(0);
12051
+ EVT CarryType = N->getValueType(1);
12052
+ unsigned Opc = N->getOpcode();
12053
+ bool IsAdd = Opc == ISD::UADDO;
12054
+ Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12055
+ SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
12056
+ N->getOperand(0), N->getOperand(1));
12057
+ SDValue Carry = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType,
12058
+ DAG, Subtarget);
12059
+ if (!IsAdd)
12060
+ Carry = DAG.getNode(ISD::XOR, DL, CarryType, Carry,
12061
+ DAG.getAllOnesConstant(DL, CarryType));
12062
+ return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, Carry);
12063
+ }
12064
+
12065
+ SDValue PPCTargetLowering::LowerADDSUBO_CARRY(SDValue Op,
12066
+ SelectionDAG &DAG) const {
12067
+ SDLoc DL(Op);
12068
+ SDNode *N = Op.getNode();
12069
+ unsigned Opc = N->getOpcode();
12070
+ EVT VT = N->getValueType(0);
12071
+ EVT CarryType = N->getValueType(1);
12072
+ SDValue CarryOp = N->getOperand(2);
12073
+ bool IsAdd = Opc == ISD::UADDO_CARRY;
12074
+ Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12075
+ if (!IsAdd)
12076
+ CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12077
+ DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
12078
+ CarryOp = ConvertCarryValueToCarryFlag(VT, CarryOp, DAG, Subtarget);
12079
+ SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
12080
+ Op.getOperand(0), Op.getOperand(1), CarryOp);
12081
+ CarryOp = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType, DAG,
12082
+ Subtarget);
12083
+ if (!IsAdd)
12084
+ CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12085
+ DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
12086
+ return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, CarryOp);
12053
12087
}
12054
12088
12055
12089
SDValue PPCTargetLowering::LowerSSUBO(SDValue Op, SelectionDAG &DAG) const {
@@ -12080,8 +12114,8 @@ SDValue PPCTargetLowering::LowerSSUBO(SDValue Op, SelectionDAG &DAG) const {
12080
12114
///
12081
12115
SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
12082
12116
switch (Op.getOpcode()) {
12083
- default: llvm_unreachable("Wasn't expecting to be able to lower this!");
12084
- case ISD::UADDO: return LowerUaddo(Op, DAG );
12117
+ default:
12118
+ llvm_unreachable("Wasn't expecting to be able to lower this!" );
12085
12119
case ISD::FPOW: return lowerPow(Op, DAG);
12086
12120
case ISD::FSIN: return lowerSin(Op, DAG);
12087
12121
case ISD::FCOS: return lowerCos(Op, DAG);
@@ -12174,6 +12208,12 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
12174
12208
return LowerATOMIC_LOAD_STORE(Op, DAG);
12175
12209
case ISD::IS_FPCLASS:
12176
12210
return LowerIS_FPCLASS(Op, DAG);
12211
+ case ISD::UADDO:
12212
+ case ISD::USUBO:
12213
+ return LowerADDSUBO(Op, DAG);
12214
+ case ISD::UADDO_CARRY:
12215
+ case ISD::USUBO_CARRY:
12216
+ return LowerADDSUBO_CARRY(Op, DAG);
12177
12217
}
12178
12218
}
12179
12219
@@ -16109,6 +16149,21 @@ static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth) {
16109
16149
return true;
16110
16150
}
16111
16151
16152
+ static SDValue DAGCombineAddc(SDNode *N,
16153
+ llvm::PPCTargetLowering::DAGCombinerInfo &DCI) {
16154
+ if (N->getOpcode() == PPCISD::ADDC && N->hasAnyUseOfValue(1)) {
16155
+ // (ADDC (ADDE 0, 0, C), -1) -> C
16156
+ SDValue LHS = N->getOperand(0);
16157
+ SDValue RHS = N->getOperand(1);
16158
+ if (LHS->getOpcode() == PPCISD::ADDE &&
16159
+ isNullConstant(LHS->getOperand(0)) &&
16160
+ isNullConstant(LHS->getOperand(1)) && isAllOnesConstant(RHS)) {
16161
+ return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
16162
+ }
16163
+ }
16164
+ return SDValue();
16165
+ }
16166
+
16112
16167
SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
16113
16168
DAGCombinerInfo &DCI) const {
16114
16169
SelectionDAG &DAG = DCI.DAG;
@@ -16897,6 +16952,8 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
16897
16952
}
16898
16953
case ISD::BUILD_VECTOR:
16899
16954
return DAGCombineBuildVector(N, DCI);
16955
+ case PPCISD::ADDC:
16956
+ return DAGCombineAddc(N, DCI);
16900
16957
}
16901
16958
16902
16959
return SDValue();
@@ -16950,6 +17007,16 @@ void PPCTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
16950
17007
Known.Zero = 0xFFFF0000;
16951
17008
break;
16952
17009
}
17010
+ case PPCISD::ADDE: {
17011
+ if (Op.getResNo() == 0) {
17012
+ // (0|1), _ = ADDE 0, 0, CARRY
17013
+ SDValue LHS = Op.getOperand(0);
17014
+ SDValue RHS = Op.getOperand(1);
17015
+ if (isNullConstant(LHS) && isNullConstant(RHS))
17016
+ Known.Zero = ~1ULL;
17017
+ }
17018
+ break;
17019
+ }
16953
17020
case ISD::INTRINSIC_WO_CHAIN: {
16954
17021
switch (Op.getConstantOperandVal(0)) {
16955
17022
default: break;
@@ -18219,7 +18286,8 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
18219
18286
return SDValue();
18220
18287
18221
18288
SDLoc DL(N);
18222
- SDVTList VTs = DAG.getVTList(MVT::i64, MVT::Glue);
18289
+ EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
18290
+ SDVTList VTs = DAG.getVTList(MVT::i64, CarryType);
18223
18291
SDValue Cmp = RHS.getOperand(0);
18224
18292
SDValue Z = Cmp.getOperand(0);
18225
18293
auto *Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
@@ -18237,11 +18305,13 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
18237
18305
SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
18238
18306
DAG.getConstant(NegConstant, DL, MVT::i64));
18239
18307
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),
18308
+ SDValue Addc =
18309
+ DAG.getNode(ISD::UADDO, DL, DAG.getVTList(MVT::i64, CarryType), AddOrZ,
18310
+ DAG.getConstant(-1ULL, DL, MVT::i64));
18311
+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
18312
+ DAG.getConstant(0, DL, MVT::i64),
18243
18313
SDValue(Addc.getNode(), 1));
18244
- }
18314
+ }
18245
18315
case ISD::SETEQ: {
18246
18316
// when C == 0
18247
18317
// --> addze X, (subfic Z, 0).carry
@@ -18252,11 +18322,14 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
18252
18322
SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
18253
18323
DAG.getConstant(NegConstant, DL, MVT::i64));
18254
18324
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
- }
18325
+ SDValue Subc =
18326
+ DAG.getNode(ISD::USUBO, DL, DAG.getVTList(MVT::i64, CarryType),
18327
+ DAG.getConstant(0, DL, MVT::i64), AddOrZ);
18328
+ SDValue Invert = DAG.getNode(ISD::XOR, DL, CarryType, Subc.getValue(1),
18329
+ DAG.getAllOnesConstant(DL, CarryType));
18330
+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
18331
+ DAG.getConstant(0, DL, MVT::i64), Invert);
18332
+ }
18260
18333
}
18261
18334
18262
18335
return SDValue();
0 commit comments