forked from OSchip/llvm-project
canonicalize constants to the RHS of addc/adde. If nothing uses the carry out of
addc, turn it into add. This allows us to compile: long long test(long long A, unsigned B) { return (A + ((long long)B << 32)) & 123; } into: _test: movl $123, %eax andl 4(%esp), %eax xorl %edx, %edx ret instead of: _test: xorl %edx, %edx movl %edx, %eax addl 4(%esp), %eax ;; add of zero andl $123, %eax ret llvm-svn: 34909
This commit is contained in:
parent
362621c7ae
commit
e2e13caeb2
|
@ -205,6 +205,8 @@ namespace {
|
|||
SDOperand visitTokenFactor(SDNode *N);
|
||||
SDOperand visitADD(SDNode *N);
|
||||
SDOperand visitSUB(SDNode *N);
|
||||
SDOperand visitADDC(SDNode *N);
|
||||
SDOperand visitADDE(SDNode *N);
|
||||
SDOperand visitMUL(SDNode *N);
|
||||
SDOperand visitSDIV(SDNode *N);
|
||||
SDOperand visitUDIV(SDNode *N);
|
||||
|
@ -502,6 +504,8 @@ SDOperand DAGCombiner::visit(SDNode *N) {
|
|||
case ISD::TokenFactor: return visitTokenFactor(N);
|
||||
case ISD::ADD: return visitADD(N);
|
||||
case ISD::SUB: return visitSUB(N);
|
||||
case ISD::ADDC: return visitADDC(N);
|
||||
case ISD::ADDE: return visitADDE(N);
|
||||
case ISD::MUL: return visitMUL(N);
|
||||
case ISD::SDIV: return visitSDIV(N);
|
||||
case ISD::UDIV: return visitUDIV(N);
|
||||
|
@ -740,6 +744,49 @@ SDOperand DAGCombiner::visitADD(SDNode *N) {
|
|||
return SDOperand();
|
||||
}
|
||||
|
||||
SDOperand DAGCombiner::visitADDC(SDNode *N) {
|
||||
SDOperand N0 = N->getOperand(0);
|
||||
SDOperand N1 = N->getOperand(1);
|
||||
ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
|
||||
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
|
||||
MVT::ValueType VT = N0.getValueType();
|
||||
|
||||
// If the flag result is dead, turn this into an ADD.
|
||||
if (N->hasNUsesOfValue(0, 1))
|
||||
return CombineTo(N, DAG.getNode(ISD::ADD, VT, N1, N0),
|
||||
SDOperand(N, 1));
|
||||
|
||||
// canonicalize constant to RHS.
|
||||
if (N0C && !N1C)
|
||||
return DAG.getNode(ISD::ADDC, VT, N1, N0);
|
||||
|
||||
// fold (add x, 0) -> x + no carry out
|
||||
//if (N1C && N1C->isNullValue())
|
||||
// return N0;
|
||||
|
||||
return SDOperand();
|
||||
}
|
||||
|
||||
SDOperand DAGCombiner::visitADDE(SDNode *N) {
|
||||
SDOperand N0 = N->getOperand(0);
|
||||
SDOperand N1 = N->getOperand(1);
|
||||
ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
|
||||
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
|
||||
MVT::ValueType VT = N0.getValueType();
|
||||
|
||||
// canonicalize constant to RHS
|
||||
if (N0C && !N1C)
|
||||
return DAG.getNode(ISD::ADDE, VT, N1, N0, N->getOperand(2));
|
||||
|
||||
// fold (add x, 0) -> x
|
||||
//if (N1C && N1C->isNullValue())
|
||||
// return N0;
|
||||
|
||||
return SDOperand();
|
||||
}
|
||||
|
||||
|
||||
|
||||
SDOperand DAGCombiner::visitSUB(SDNode *N) {
|
||||
SDOperand N0 = N->getOperand(0);
|
||||
SDOperand N1 = N->getOperand(1);
|
||||
|
|
Loading…
Reference in New Issue