SDValue visitUADDO(SDNode *N);
SDValue visitUADDOLike(SDValue N0, SDValue N1, SDNode *N);
SDValue visitSUBC(SDNode *N);
- SDValue visitSSUBO(SDNode *N);
- SDValue visitUSUBO(SDNode *N);
+ SDValue visitSUBO(SDNode *N);
SDValue visitADDE(SDNode *N);
SDValue visitADDCARRY(SDNode *N);
SDValue visitADDCARRYLike(SDValue N0, SDValue N1, SDValue CarryIn, SDNode *N);
case ISD::SADDO: return visitSADDO(N);
case ISD::UADDO: return visitUADDO(N);
case ISD::SUBC: return visitSUBC(N);
- case ISD::SSUBO: return visitSSUBO(N);
- case ISD::USUBO: return visitUSUBO(N);
+ case ISD::SSUBO:
+ case ISD::USUBO: return visitSUBO(N);
case ISD::ADDE: return visitADDE(N);
case ISD::ADDCARRY: return visitADDCARRY(N);
case ISD::SUBE: return visitSUBE(N);
return SDValue();
}
-// TODO: merge this with DAGCombiner::visitUSUBO
-SDValue DAGCombiner::visitSSUBO(SDNode *N) {
- SDValue N0 = N->getOperand(0);
- SDValue N1 = N->getOperand(1);
- EVT VT = N0.getValueType();
- EVT CarryVT = N->getValueType(1);
- SDLoc DL(N);
-
- // If the flag result is dead, turn this into an SUB.
- if (!N->hasAnyUseOfValue(1))
- return CombineTo(N, DAG.getNode(ISD::SUB, DL, VT, N0, N1),
- DAG.getUNDEF(CarryVT));
-
- // fold (ssubo x, x) -> 0 + no borrow
- if (N0 == N1)
- return CombineTo(N, DAG.getConstant(0, DL, VT),
- DAG.getConstant(0, DL, CarryVT));
-
- // fold (ssubo x, 0) -> x + no borrow
- if (isNullOrNullSplat(N1))
- return CombineTo(N, N0, DAG.getConstant(0, DL, CarryVT));
-
- return SDValue();
-}
-
-SDValue DAGCombiner::visitUSUBO(SDNode *N) {
+SDValue DAGCombiner::visitSUBO(SDNode *N) {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
EVT VT = N0.getValueType();
+ bool IsSigned = (ISD::SSUBO == N->getOpcode());
EVT CarryVT = N->getValueType(1);
SDLoc DL(N);
return CombineTo(N, DAG.getNode(ISD::SUB, DL, VT, N0, N1),
DAG.getUNDEF(CarryVT));
- // fold (usubo x, x) -> 0 + no borrow
+ // fold (subo x, x) -> 0 + no borrow
if (N0 == N1)
return CombineTo(N, DAG.getConstant(0, DL, VT),
DAG.getConstant(0, DL, CarryVT));
- // fold (usubo x, 0) -> x + no borrow
+ // fold (subo x, 0) -> x + no borrow
if (isNullOrNullSplat(N1))
return CombineTo(N, N0, DAG.getConstant(0, DL, CarryVT));
// Canonicalize (usubo -1, x) -> ~x, i.e. (xor x, -1) + no borrow
- if (isAllOnesOrAllOnesSplat(N0))
+ if (!IsSigned && isAllOnesOrAllOnesSplat(N0))
return CombineTo(N, DAG.getNode(ISD::XOR, DL, VT, N1, N0),
DAG.getConstant(0, DL, CarryVT));