mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-10 05:41:40 +00:00
Add some DAG combines for SUBC/SUBE. If nothing uses the carry/borrow out of subc, turn it into a sub. Turn (subc x, x) into 0 with no borrow. Turn (subc x, 0) into x with no borrow. Turn (subc -1, x) into (xor x, -1) with no borrow. Turn sube with no borrow in into subc.
llvm-svn: 147728
This commit is contained in:
parent
49330adc9c
commit
8648954580
@ -158,7 +158,9 @@ namespace {
|
|||||||
SDValue visitADD(SDNode *N);
|
SDValue visitADD(SDNode *N);
|
||||||
SDValue visitSUB(SDNode *N);
|
SDValue visitSUB(SDNode *N);
|
||||||
SDValue visitADDC(SDNode *N);
|
SDValue visitADDC(SDNode *N);
|
||||||
|
SDValue visitSUBC(SDNode *N);
|
||||||
SDValue visitADDE(SDNode *N);
|
SDValue visitADDE(SDNode *N);
|
||||||
|
SDValue visitSUBE(SDNode *N);
|
||||||
SDValue visitMUL(SDNode *N);
|
SDValue visitMUL(SDNode *N);
|
||||||
SDValue visitSDIV(SDNode *N);
|
SDValue visitSDIV(SDNode *N);
|
||||||
SDValue visitUDIV(SDNode *N);
|
SDValue visitUDIV(SDNode *N);
|
||||||
@ -1059,7 +1061,9 @@ SDValue DAGCombiner::visit(SDNode *N) {
|
|||||||
case ISD::ADD: return visitADD(N);
|
case ISD::ADD: return visitADD(N);
|
||||||
case ISD::SUB: return visitSUB(N);
|
case ISD::SUB: return visitSUB(N);
|
||||||
case ISD::ADDC: return visitADDC(N);
|
case ISD::ADDC: return visitADDC(N);
|
||||||
|
case ISD::SUBC: return visitSUBC(N);
|
||||||
case ISD::ADDE: return visitADDE(N);
|
case ISD::ADDE: return visitADDE(N);
|
||||||
|
case ISD::SUBE: return visitSUBE(N);
|
||||||
case ISD::MUL: return visitMUL(N);
|
case ISD::MUL: return visitMUL(N);
|
||||||
case ISD::SDIV: return visitSDIV(N);
|
case ISD::SDIV: return visitSDIV(N);
|
||||||
case ISD::UDIV: return visitUDIV(N);
|
case ISD::UDIV: return visitUDIV(N);
|
||||||
@ -1498,7 +1502,7 @@ SDValue DAGCombiner::visitADDC(SDNode *N) {
|
|||||||
|
|
||||||
// If the flag result is dead, turn this into an ADD.
|
// If the flag result is dead, turn this into an ADD.
|
||||||
if (N->hasNUsesOfValue(0, 1))
|
if (N->hasNUsesOfValue(0, 1))
|
||||||
return CombineTo(N, DAG.getNode(ISD::ADD, N->getDebugLoc(), VT, N1, N0),
|
return CombineTo(N, DAG.getNode(ISD::ADD, N->getDebugLoc(), VT, N0, N1),
|
||||||
DAG.getNode(ISD::CARRY_FALSE,
|
DAG.getNode(ISD::CARRY_FALSE,
|
||||||
N->getDebugLoc(), MVT::Glue));
|
N->getDebugLoc(), MVT::Glue));
|
||||||
|
|
||||||
@ -1546,7 +1550,7 @@ SDValue DAGCombiner::visitADDE(SDNode *N) {
|
|||||||
|
|
||||||
// fold (adde x, y, false) -> (addc x, y)
|
// fold (adde x, y, false) -> (addc x, y)
|
||||||
if (CarryIn.getOpcode() == ISD::CARRY_FALSE)
|
if (CarryIn.getOpcode() == ISD::CARRY_FALSE)
|
||||||
return DAG.getNode(ISD::ADDC, N->getDebugLoc(), N->getVTList(), N1, N0);
|
return DAG.getNode(ISD::ADDC, N->getDebugLoc(), N->getVTList(), N0, N1);
|
||||||
|
|
||||||
return SDValue();
|
return SDValue();
|
||||||
}
|
}
|
||||||
@ -1656,6 +1660,51 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {
|
|||||||
return SDValue();
|
return SDValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDValue DAGCombiner::visitSUBC(SDNode *N) {
|
||||||
|
SDValue N0 = N->getOperand(0);
|
||||||
|
SDValue N1 = N->getOperand(1);
|
||||||
|
ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
|
||||||
|
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
|
||||||
|
EVT VT = N0.getValueType();
|
||||||
|
|
||||||
|
// If the flag result is dead, turn this into an SUB.
|
||||||
|
if (N->hasNUsesOfValue(0, 1))
|
||||||
|
return CombineTo(N, DAG.getNode(ISD::SUB, N->getDebugLoc(), VT, N0, N1),
|
||||||
|
DAG.getNode(ISD::CARRY_FALSE, N->getDebugLoc(),
|
||||||
|
MVT::Glue));
|
||||||
|
|
||||||
|
// fold (subc x, x) -> 0 + no borrow
|
||||||
|
if (N0 == N1)
|
||||||
|
return CombineTo(N, DAG.getConstant(0, VT),
|
||||||
|
DAG.getNode(ISD::CARRY_FALSE, N->getDebugLoc(),
|
||||||
|
MVT::Glue));
|
||||||
|
|
||||||
|
// fold (subc x, 0) -> x + no borrow
|
||||||
|
if (N1C && N1C->isNullValue())
|
||||||
|
return CombineTo(N, N0, DAG.getNode(ISD::CARRY_FALSE, N->getDebugLoc(),
|
||||||
|
MVT::Glue));
|
||||||
|
|
||||||
|
// Canonicalize (sub -1, x) -> ~x, i.e. (xor x, -1) + no borrow
|
||||||
|
if (N0C && N0C->isAllOnesValue())
|
||||||
|
return CombineTo(N, DAG.getNode(ISD::XOR, N->getDebugLoc(), VT, N1, N0),
|
||||||
|
DAG.getNode(ISD::CARRY_FALSE, N->getDebugLoc(),
|
||||||
|
MVT::Glue));
|
||||||
|
|
||||||
|
return SDValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
SDValue DAGCombiner::visitSUBE(SDNode *N) {
|
||||||
|
SDValue N0 = N->getOperand(0);
|
||||||
|
SDValue N1 = N->getOperand(1);
|
||||||
|
SDValue CarryIn = N->getOperand(2);
|
||||||
|
|
||||||
|
// fold (sube x, y, false) -> (subc x, y)
|
||||||
|
if (CarryIn.getOpcode() == ISD::CARRY_FALSE)
|
||||||
|
return DAG.getNode(ISD::SUBC, N->getDebugLoc(), N->getVTList(), N0, N1);
|
||||||
|
|
||||||
|
return SDValue();
|
||||||
|
}
|
||||||
|
|
||||||
SDValue DAGCombiner::visitMUL(SDNode *N) {
|
SDValue DAGCombiner::visitMUL(SDNode *N) {
|
||||||
SDValue N0 = N->getOperand(0);
|
SDValue N0 = N->getOperand(0);
|
||||||
SDValue N1 = N->getOperand(1);
|
SDValue N1 = N->getOperand(1);
|
||||||
|
Loading…
Reference in New Issue
Block a user