aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-03-04 20:03:15 +0000
committerChris Lattner <sabre@nondot.org>2007-03-04 20:03:15 +0000
commit91153686f04bafe3b10c99edb1735444953f7517 (patch)
treec10b76d5ab01bcb6db46ce33a76b1861d70813e3 /lib
parent175415e116feef0def0f7c084cca3646a403412b (diff)
downloadexternal_llvm-91153686f04bafe3b10c99edb1735444953f7517.zip
external_llvm-91153686f04bafe3b10c99edb1735444953f7517.tar.gz
external_llvm-91153686f04bafe3b10c99edb1735444953f7517.tar.bz2
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34909 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 79d9e79..d48f419 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -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);