@@ -198,7 +198,11 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
198
198
}
199
199
}
200
200
201
+ // PowerPC uses addo,addo_carry,subo,subo_carry to propagate carry.
201
202
setOperationAction(ISD::UADDO, isPPC64 ? MVT::i64 : MVT::i32, Custom);
203
+ setOperationAction(ISD::USUBO, isPPC64 ? MVT::i64 : MVT::i32, Custom);
204
+ setOperationAction(ISD::UADDO_CARRY, isPPC64 ? MVT::i64 : MVT::i32, Custom);
205
+ setOperationAction(ISD::USUBO_CARRY, isPPC64 ? MVT::i64 : MVT::i32, Custom);
202
206
203
207
// Match BITREVERSE to customized fast code sequence in the td file.
204
208
setOperationAction(ISD::BITREVERSE, MVT::i32, Legal);
@@ -254,15 +258,6 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
254
258
setIndexedStoreAction(ISD::PRE_INC, MVT::f64, Legal);
255
259
}
256
260
257
- // PowerPC uses ADDC/ADDE/SUBC/SUBE to propagate carry.
258
- const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
259
- for (MVT VT : ScalarIntVTs) {
260
- setOperationAction(ISD::ADDC, VT, Legal);
261
- setOperationAction(ISD::ADDE, VT, Legal);
262
- setOperationAction(ISD::SUBC, VT, Legal);
263
- setOperationAction(ISD::SUBE, VT, Legal);
264
- }
265
-
266
261
if (Subtarget.useCRBits()) {
267
262
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
268
263
@@ -1853,6 +1848,14 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
1853
1848
case PPCISD::LXVRZX: return "PPCISD::LXVRZX";
1854
1849
case PPCISD::STORE_COND:
1855
1850
return "PPCISD::STORE_COND";
1851
+ case PPCISD::ADDC:
1852
+ return "PPCISD::ADDC";
1853
+ case PPCISD::ADDE:
1854
+ return "PPCISD::ADDE";
1855
+ case PPCISD::SUBC:
1856
+ return "PPCISD::SUBC";
1857
+ case PPCISD::SUBE:
1858
+ return "PPCISD::SUBE";
1856
1859
}
1857
1860
return nullptr;
1858
1861
}
@@ -11977,51 +11980,81 @@ SDValue PPCTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
11977
11980
llvm_unreachable("ERROR:Should return for all cases within swtich.");
11978
11981
}
11979
11982
11980
- SDValue PPCTargetLowering::LowerUaddo(SDValue Op, SelectionDAG &DAG) const {
11981
- // Default to target independent lowering if there is a logical user of the
11982
- // carry-bit.
11983
- for (SDNode *U : Op->uses()) {
11984
- if (U->getOpcode() == ISD::SELECT)
11985
- return SDValue();
11986
- if (ISD::isBitwiseLogicOp(U->getOpcode())) {
11987
- for (unsigned i = 0, ie = U->getNumOperands(); i != ie; ++i) {
11988
- if (U->getOperand(i).getOpcode() != ISD::UADDO &&
11989
- U->getOperand(i).getOpcode() != ISD::MERGE_VALUES)
11990
- return SDValue();
11991
- }
11992
- }
11993
- }
11994
- SDValue LHS = Op.getOperand(0);
11995
- SDValue RHS = Op.getOperand(1);
11996
- SDLoc dl(Op);
11997
-
11998
- // Default to target independent lowering for special cases handled there.
11999
- if (isOneConstant(RHS) || isAllOnesConstant(RHS))
12000
- return SDValue();
11983
+ static SDValue ConvertCarryValueToCarryFlag(EVT SumType, SDValue Value,
11984
+ SelectionDAG &DAG,
11985
+ const PPCSubtarget &STI) {
11986
+ SDLoc DL(Value);
11987
+ if (STI.useCRBits())
11988
+ Value = DAG.getNode(ISD::SELECT, DL, SumType, Value,
11989
+ DAG.getConstant(1, DL, SumType),
11990
+ DAG.getConstant(0, DL, SumType));
11991
+ else
11992
+ Value = DAG.getZExtOrTrunc(Value, DL, SumType);
11993
+ SDValue Sum = DAG.getNode(PPCISD::ADDC, DL, DAG.getVTList(SumType, MVT::i32),
11994
+ Value, DAG.getAllOnesConstant(DL, SumType));
11995
+ return Sum.getValue(1);
11996
+ }
12001
11997
12002
- EVT VT = Op.getNode()->getValueType(0);
11998
+ static SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag,
11999
+ EVT CarryType, SelectionDAG &DAG,
12000
+ const PPCSubtarget &STI) {
12001
+ SDLoc DL(Flag);
12002
+ SDValue Zero = DAG.getConstant(0, DL, SumType);
12003
+ SDValue Carry = DAG.getNode(
12004
+ PPCISD::ADDE, DL, DAG.getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12005
+ if (STI.useCRBits())
12006
+ return DAG.getSetCC(DL, CarryType, Carry, Zero, ISD::SETNE);
12007
+ return DAG.getZExtOrTrunc(Carry, DL, CarryType);
12008
+ }
12003
12009
12004
- SDValue ADDC;
12005
- SDValue Overflow;
12006
- SDVTList VTs = Op.getNode()->getVTList();
12010
+ SDValue PPCTargetLowering::LowerADDSUBO(SDValue Op, SelectionDAG &DAG) const {
12007
12011
12008
- ADDC = DAG.getNode(ISD::ADDC, dl, DAG.getVTList(VT, MVT::Glue), LHS, RHS);
12009
- Overflow = DAG.getNode(ISD::ADDE, dl, DAG.getVTList(VT, MVT::Glue),
12010
- DAG.getConstant(0, dl, VT), DAG.getConstant(0, dl, VT),
12011
- ADDC.getValue(1));
12012
- SDValue OverflowTrunc =
12013
- DAG.getNode(ISD::TRUNCATE, dl, Op.getNode()->getValueType(1), Overflow);
12014
- SDValue Res =
12015
- DAG.getNode(ISD::MERGE_VALUES, dl, VTs, ADDC.getValue(0), OverflowTrunc);
12016
- return Res;
12012
+ SDLoc DL(Op);
12013
+ SDNode *N = Op.getNode();
12014
+ EVT VT = N->getValueType(0);
12015
+ EVT CarryType = N->getValueType(1);
12016
+ unsigned Opc = N->getOpcode();
12017
+ bool IsAdd = Opc == ISD::UADDO;
12018
+ Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12019
+ SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
12020
+ N->getOperand(0), N->getOperand(1));
12021
+ SDValue Carry = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType,
12022
+ DAG, Subtarget);
12023
+ if (!IsAdd)
12024
+ Carry = DAG.getNode(ISD::XOR, DL, CarryType, Carry,
12025
+ DAG.getAllOnesConstant(DL, CarryType));
12026
+ return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, Carry);
12027
+ }
12028
+
12029
+ SDValue PPCTargetLowering::LowerADDSUBO_CARRY(SDValue Op,
12030
+ SelectionDAG &DAG) const {
12031
+ SDLoc DL(Op);
12032
+ SDNode *N = Op.getNode();
12033
+ unsigned Opc = N->getOpcode();
12034
+ EVT VT = N->getValueType(0);
12035
+ EVT CarryType = N->getValueType(1);
12036
+ SDValue CarryOp = N->getOperand(2);
12037
+ bool IsAdd = Opc == ISD::UADDO_CARRY;
12038
+ Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12039
+ if (!IsAdd)
12040
+ CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12041
+ DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
12042
+ CarryOp = ConvertCarryValueToCarryFlag(VT, CarryOp, DAG, Subtarget);
12043
+ SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
12044
+ Op.getOperand(0), Op.getOperand(1), CarryOp);
12045
+ CarryOp = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType, DAG,
12046
+ Subtarget);
12047
+ if (!IsAdd)
12048
+ CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12049
+ DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
12050
+ return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, CarryOp);
12017
12051
}
12018
12052
12019
12053
/// LowerOperation - Provide custom lowering hooks for some operations.
12020
12054
///
12021
12055
SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
12022
12056
switch (Op.getOpcode()) {
12023
12057
default: llvm_unreachable("Wasn't expecting to be able to lower this!");
12024
- case ISD::UADDO: return LowerUaddo(Op, DAG);
12025
12058
case ISD::FPOW: return lowerPow(Op, DAG);
12026
12059
case ISD::FSIN: return lowerSin(Op, DAG);
12027
12060
case ISD::FCOS: return lowerCos(Op, DAG);
@@ -12112,6 +12145,12 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
12112
12145
return LowerATOMIC_LOAD_STORE(Op, DAG);
12113
12146
case ISD::IS_FPCLASS:
12114
12147
return LowerIS_FPCLASS(Op, DAG);
12148
+ case ISD::UADDO:
12149
+ case ISD::USUBO:
12150
+ return LowerADDSUBO(Op, DAG);
12151
+ case ISD::UADDO_CARRY:
12152
+ case ISD::USUBO_CARRY:
12153
+ return LowerADDSUBO_CARRY(Op, DAG);
12115
12154
}
12116
12155
}
12117
12156
@@ -16005,6 +16044,21 @@ static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth) {
16005
16044
return true;
16006
16045
}
16007
16046
16047
+ static SDValue DAGCombineAddc(SDNode *N,
16048
+ llvm::PPCTargetLowering::DAGCombinerInfo &DCI) {
16049
+ if (N->getOpcode() == PPCISD::ADDC && N->hasAnyUseOfValue(1)) {
16050
+ // (ADDC (ADDE 0, 0, C), -1) -> C
16051
+ SDValue LHS = N->getOperand(0);
16052
+ SDValue RHS = N->getOperand(1);
16053
+ if (LHS->getOpcode() == PPCISD::ADDE &&
16054
+ isNullConstant(LHS->getOperand(0)) &&
16055
+ isNullConstant(LHS->getOperand(1)) && isAllOnesConstant(RHS)) {
16056
+ return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
16057
+ }
16058
+ }
16059
+ return SDValue();
16060
+ }
16061
+
16008
16062
SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
16009
16063
DAGCombinerInfo &DCI) const {
16010
16064
SelectionDAG &DAG = DCI.DAG;
@@ -16794,6 +16848,8 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
16794
16848
}
16795
16849
case ISD::BUILD_VECTOR:
16796
16850
return DAGCombineBuildVector(N, DCI);
16851
+ case PPCISD::ADDC:
16852
+ return DAGCombineAddc(N, DCI);
16797
16853
}
16798
16854
16799
16855
return SDValue();
@@ -16847,6 +16903,16 @@ void PPCTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
16847
16903
Known.Zero = 0xFFFF0000;
16848
16904
break;
16849
16905
}
16906
+ case PPCISD::ADDE: {
16907
+ if (Op.getResNo() == 0) {
16908
+ // (0|1), _ = ADDE 0, 0, CARRY
16909
+ SDValue LHS = Op.getOperand(0);
16910
+ SDValue RHS = Op.getOperand(1);
16911
+ if (isNullConstant(LHS) && isNullConstant(RHS))
16912
+ Known.Zero = ~1ULL;
16913
+ }
16914
+ break;
16915
+ }
16850
16916
case ISD::INTRINSIC_WO_CHAIN: {
16851
16917
switch (Op.getConstantOperandVal(0)) {
16852
16918
default: break;
@@ -18117,7 +18183,8 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
18117
18183
return SDValue();
18118
18184
18119
18185
SDLoc DL(N);
18120
- SDVTList VTs = DAG.getVTList(MVT::i64, MVT::Glue);
18186
+ EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
18187
+ SDVTList VTs = DAG.getVTList(MVT::i64, CarryType);
18121
18188
SDValue Cmp = RHS.getOperand(0);
18122
18189
SDValue Z = Cmp.getOperand(0);
18123
18190
auto *Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
@@ -18135,11 +18202,13 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
18135
18202
SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
18136
18203
DAG.getConstant(NegConstant, DL, MVT::i64));
18137
18204
SDValue AddOrZ = NegConstant != 0 ? Add : Z;
18138
- SDValue Addc = DAG.getNode(ISD::ADDC, DL, DAG.getVTList(MVT::i64, MVT::Glue),
18139
- AddOrZ, DAG.getConstant(-1ULL, DL, MVT::i64));
18140
- return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
18205
+ SDValue Addc =
18206
+ DAG.getNode(ISD::UADDO, DL, DAG.getVTList(MVT::i64, CarryType), AddOrZ,
18207
+ DAG.getConstant(-1ULL, DL, MVT::i64));
18208
+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
18209
+ DAG.getConstant(0, DL, MVT::i64),
18141
18210
SDValue(Addc.getNode(), 1));
18142
- }
18211
+ }
18143
18212
case ISD::SETEQ: {
18144
18213
// when C == 0
18145
18214
// --> addze X, (subfic Z, 0).carry
@@ -18150,11 +18219,14 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
18150
18219
SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
18151
18220
DAG.getConstant(NegConstant, DL, MVT::i64));
18152
18221
SDValue AddOrZ = NegConstant != 0 ? Add : Z;
18153
- SDValue Subc = DAG.getNode(ISD::SUBC, DL, DAG.getVTList(MVT::i64, MVT::Glue),
18154
- DAG.getConstant(0, DL, MVT::i64), AddOrZ);
18155
- return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
18156
- SDValue(Subc.getNode(), 1));
18157
- }
18222
+ SDValue Subc =
18223
+ DAG.getNode(ISD::USUBO, DL, DAG.getVTList(MVT::i64, CarryType),
18224
+ DAG.getConstant(0, DL, MVT::i64), AddOrZ);
18225
+ SDValue Invert = DAG.getNode(ISD::XOR, DL, CarryType, Subc.getValue(1),
18226
+ DAG.getAllOnesConstant(DL, CarryType));
18227
+ return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
18228
+ DAG.getConstant(0, DL, MVT::i64), Invert);
18229
+ }
18158
18230
}
18159
18231
18160
18232
return SDValue();
0 commit comments