@@ -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
}
@@ -12028,43 +12031,74 @@ SDValue PPCTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
12028
12031
llvm_unreachable("ERROR:Should return for all cases within swtich.");
12029
12032
}
12030
12033
12031
- SDValue PPCTargetLowering::LowerUaddo(SDValue Op, SelectionDAG &DAG) const {
12032
- // Default to target independent lowering if there is a logical user of the
12033
- // carry-bit.
12034
- for (SDNode *U : Op->users()) {
12035
- if (U->getOpcode() == ISD::SELECT)
12036
- return SDValue();
12037
- if (ISD::isBitwiseLogicOp(U->getOpcode())) {
12038
- for (unsigned i = 0, ie = U->getNumOperands(); i != ie; ++i) {
12039
- if (U->getOperand(i).getOpcode() != ISD::UADDO &&
12040
- U->getOperand(i).getOpcode() != ISD::MERGE_VALUES)
12041
- return SDValue();
12042
- }
12043
- }
12044
- }
12045
- SDValue LHS = Op.getOperand(0);
12046
- SDValue RHS = Op.getOperand(1);
12047
- SDLoc dl(Op);
12048
-
12049
- // Default to target independent lowering for special cases handled there.
12050
- if (isOneConstant(RHS) || isAllOnesConstant(RHS))
12051
- return SDValue();
12034
+ static SDValue ConvertCarryValueToCarryFlag(EVT SumType, SDValue Value,
12035
+ SelectionDAG &DAG,
12036
+ const PPCSubtarget &STI) {
12037
+ SDLoc DL(Value);
12038
+ if (STI.useCRBits())
12039
+ Value = DAG.getNode(ISD::SELECT, DL, SumType, Value,
12040
+ DAG.getConstant(1, DL, SumType),
12041
+ DAG.getConstant(0, DL, SumType));
12042
+ else
12043
+ Value = DAG.getZExtOrTrunc(Value, DL, SumType);
12044
+ SDValue Sum = DAG.getNode(PPCISD::ADDC, DL, DAG.getVTList(SumType, MVT::i32),
12045
+ Value, DAG.getAllOnesConstant(DL, SumType));
12046
+ return Sum.getValue(1);
12047
+ }
12052
12048
12053
- EVT VT = Op.getNode()->getValueType(0);
12049
+ static SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag,
12050
+ EVT CarryType, SelectionDAG &DAG,
12051
+ const PPCSubtarget &STI) {
12052
+ SDLoc DL(Flag);
12053
+ SDValue Zero = DAG.getConstant(0, DL, SumType);
12054
+ SDValue Carry = DAG.getNode(
12055
+ PPCISD::ADDE, DL, DAG.getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12056
+ if (STI.useCRBits())
12057
+ return DAG.getSetCC(DL, CarryType, Carry, Zero, ISD::SETNE);
12058
+ return DAG.getZExtOrTrunc(Carry, DL, CarryType);
12059
+ }
12054
12060
12055
- SDValue ADDC;
12056
- SDValue Overflow;
12057
- SDVTList VTs = Op.getNode()->getVTList();
12061
+ SDValue PPCTargetLowering::LowerADDSUBO(SDValue Op, SelectionDAG &DAG) const {
12058
12062
12059
- ADDC = DAG.getNode(ISD::ADDC, dl, DAG.getVTList(VT, MVT::Glue), LHS, RHS);
12060
- Overflow = DAG.getNode(ISD::ADDE, dl, DAG.getVTList(VT, MVT::Glue),
12061
- DAG.getConstant(0, dl, VT), DAG.getConstant(0, dl, VT),
12062
- ADDC.getValue(1));
12063
- SDValue OverflowTrunc =
12064
- DAG.getNode(ISD::TRUNCATE, dl, Op.getNode()->getValueType(1), Overflow);
12065
- SDValue Res =
12066
- DAG.getNode(ISD::MERGE_VALUES, dl, VTs, ADDC.getValue(0), OverflowTrunc);
12067
- return Res;
12063
+ SDLoc DL(Op);
12064
+ SDNode *N = Op.getNode();
12065
+ EVT VT = N->getValueType(0);
12066
+ EVT CarryType = N->getValueType(1);
12067
+ unsigned Opc = N->getOpcode();
12068
+ bool IsAdd = Opc == ISD::UADDO;
12069
+ Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12070
+ SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
12071
+ N->getOperand(0), N->getOperand(1));
12072
+ SDValue Carry = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType,
12073
+ DAG, Subtarget);
12074
+ if (!IsAdd)
12075
+ Carry = DAG.getNode(ISD::XOR, DL, CarryType, Carry,
12076
+ DAG.getAllOnesConstant(DL, CarryType));
12077
+ return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, Carry);
12078
+ }
12079
+
12080
+ SDValue PPCTargetLowering::LowerADDSUBO_CARRY(SDValue Op,
12081
+ SelectionDAG &DAG) const {
12082
+ SDLoc DL(Op);
12083
+ SDNode *N = Op.getNode();
12084
+ unsigned Opc = N->getOpcode();
12085
+ EVT VT = N->getValueType(0);
12086
+ EVT CarryType = N->getValueType(1);
12087
+ SDValue CarryOp = N->getOperand(2);
12088
+ bool IsAdd = Opc == ISD::UADDO_CARRY;
12089
+ Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12090
+ if (!IsAdd)
12091
+ CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12092
+ DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
12093
+ CarryOp = ConvertCarryValueToCarryFlag(VT, CarryOp, DAG, Subtarget);
12094
+ SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
12095
+ Op.getOperand(0), Op.getOperand(1), CarryOp);
12096
+ CarryOp = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType, DAG,
12097
+ Subtarget);
12098
+ if (!IsAdd)
12099
+ CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12100
+ DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
12101
+ return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, CarryOp);
12068
12102
}
12069
12103
12070
12104
SDValue PPCTargetLowering::LowerSSUBO(SDValue Op, SelectionDAG &DAG) const {
@@ -12095,8 +12129,8 @@ SDValue PPCTargetLowering::LowerSSUBO(SDValue Op, SelectionDAG &DAG) const {
12095
12129
///
12096
12130
SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
12097
12131
switch (Op.getOpcode()) {
12098
- default: llvm_unreachable("Wasn't expecting to be able to lower this!");
12099
- case ISD::UADDO: return LowerUaddo(Op, DAG );
12132
+ default:
12133
+ llvm_unreachable("Wasn't expecting to be able to lower this!" );
12100
12134
case ISD::FPOW: return lowerPow(Op, DAG);
12101
12135
case ISD::FSIN: return lowerSin(Op, DAG);
12102
12136
case ISD::FCOS: return lowerCos(Op, DAG);
@@ -12189,6 +12223,12 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
12189
12223
return LowerATOMIC_LOAD_STORE(Op, DAG);
12190
12224
case ISD::IS_FPCLASS:
12191
12225
return LowerIS_FPCLASS(Op, DAG);
12226
+ case ISD::UADDO:
12227
+ case ISD::USUBO:
12228
+ return LowerADDSUBO(Op, DAG);
12229
+ case ISD::UADDO_CARRY:
12230
+ case ISD::USUBO_CARRY:
12231
+ return LowerADDSUBO_CARRY(Op, DAG);
12192
12232
}
12193
12233
}
12194
12234
@@ -16124,6 +16164,21 @@ static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth) {
16124
16164
return true;
16125
16165
}
16126
16166
16167
+ static SDValue DAGCombineAddc(SDNode *N,
16168
+ llvm::PPCTargetLowering::DAGCombinerInfo &DCI) {
16169
+ if (N->getOpcode() == PPCISD::ADDC && N->hasAnyUseOfValue(1)) {
16170
+ // (ADDC (ADDE 0, 0, C), -1) -> C
16171
+ SDValue LHS = N->getOperand(0);
16172
+ SDValue RHS = N->getOperand(1);
16173
+ if (LHS->getOpcode() == PPCISD::ADDE &&
16174
+ isNullConstant(LHS->getOperand(0)) &&
16175
+ isNullConstant(LHS->getOperand(1)) && isAllOnesConstant(RHS)) {
16176
+ return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
16177
+ }
16178
+ }
16179
+ return SDValue();
16180
+ }
16181
+
16127
16182
SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
16128
16183
DAGCombinerInfo &DCI) const {
16129
16184
SelectionDAG &DAG = DCI.DAG;
@@ -16912,6 +16967,8 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
16912
16967
}
16913
16968
case ISD::BUILD_VECTOR:
16914
16969
return DAGCombineBuildVector(N, DCI);
16970
+ case PPCISD::ADDC:
16971
+ return DAGCombineAddc(N, DCI);
16915
16972
}
16916
16973
16917
16974
return SDValue();
@@ -16965,6 +17022,16 @@ void PPCTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
16965
17022
Known.Zero = 0xFFFF0000;
16966
17023
break;
16967
17024
}
17025
+ case PPCISD::ADDE: {
17026
+ if (Op.getResNo() == 0) {
17027
+ // (0|1), _ = ADDE 0, 0, CARRY
17028
+ SDValue LHS = Op.getOperand(0);
17029
+ SDValue RHS = Op.getOperand(1);
17030
+ if (isNullConstant(LHS) && isNullConstant(RHS))
17031
+ Known.Zero = ~1ULL;
17032
+ }
17033
+ break;
17034
+ }
16968
17035
case ISD::INTRINSIC_WO_CHAIN: {
16969
17036
switch (Op.getConstantOperandVal(0)) {
16970
17037
default: break;
@@ -18234,7 +18301,8 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
18234
18301
return SDValue();
18235
18302
18236
18303
SDLoc DL(N);
18237
- SDVTList VTs = DAG.getVTList(MVT::i64, MVT::Glue);
18304
+ EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
18305
+ SDVTList VTs = DAG.getVTList(MVT::i64, CarryType);
18238
18306
SDValue Cmp = RHS.getOperand(0);
18239
18307
SDValue Z = Cmp.getOperand(0);
18240
18308
auto *Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
@@ -18252,11 +18320,13 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
18252
18320
SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
18253
18321
DAG.getConstant(NegConstant, DL, MVT::i64));
18254
18322
SDValue AddOrZ = NegConstant != 0 ? Add : Z;
18255
- SDValue Addc = DAG.getNode(ISD::ADDC, DL, DAG.getVTList(MVT::i64, MVT::Glue),
18256
- AddOrZ, DAG.getConstant(-1ULL, DL, MVT::i64));
18257
- return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
18323
+ SDValue Addc =
18324
+ DAG.getNode(ISD::UADDO, DL, DAG.getVTList(MVT::i64, CarryType), AddOrZ,
18325
+ DAG.getConstant(-1ULL, DL, MVT::i64));
18326
+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
18327
+ DAG.getConstant(0, DL, MVT::i64),
18258
18328
SDValue(Addc.getNode(), 1));
18259
- }
18329
+ }
18260
18330
case ISD::SETEQ: {
18261
18331
// when C == 0
18262
18332
// --> addze X, (subfic Z, 0).carry
@@ -18267,11 +18337,14 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
18267
18337
SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
18268
18338
DAG.getConstant(NegConstant, DL, MVT::i64));
18269
18339
SDValue AddOrZ = NegConstant != 0 ? Add : Z;
18270
- SDValue Subc = DAG.getNode(ISD::SUBC, DL, DAG.getVTList(MVT::i64, MVT::Glue),
18271
- DAG.getConstant(0, DL, MVT::i64), AddOrZ);
18272
- return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
18273
- SDValue(Subc.getNode(), 1));
18274
- }
18340
+ SDValue Subc =
18341
+ DAG.getNode(ISD::USUBO, DL, DAG.getVTList(MVT::i64, CarryType),
18342
+ DAG.getConstant(0, DL, MVT::i64), AddOrZ);
18343
+ SDValue Invert = DAG.getNode(ISD::XOR, DL, CarryType, Subc.getValue(1),
18344
+ DAG.getAllOnesConstant(DL, CarryType));
18345
+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
18346
+ DAG.getConstant(0, DL, MVT::i64), Invert);
18347
+ }
18275
18348
}
18276
18349
18277
18350
return SDValue();
0 commit comments