diff options
author | Dan Gohman <gohman@apple.com> | 2007-11-26 23:46:11 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2007-11-26 23:46:11 +0000 |
commit | 9a69341725c48d29bf9d47663cf093691b52bc7c (patch) | |
tree | 48313b6f297d2e695906a5103aca4d79004f4d9f /llvm/lib | |
parent | 084b0eb3ca6774d978cf4b77b45fb8fdd7e42d7a (diff) | |
download | bcm5719-llvm-9a69341725c48d29bf9d47663cf093691b52bc7c.tar.gz bcm5719-llvm-9a69341725c48d29bf9d47663cf093691b52bc7c.zip |
Don't lower srem/urem X%C to X-X/C*C unless the division is actually
optimized. This avoids creating illegal divisions when the combiner is
running after legalize; this fixes PR1815. Also, it produces better
code in the included testcase by avoiding the subtract and multiply
when the division isn't optimized.
llvm-svn: 44341
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 32 |
1 files changed, 18 insertions, 14 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 8f6800a2c6b..3be1fdd0c7f 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1306,15 +1306,17 @@ SDOperand DAGCombiner::visitSREM(SDNode *N) { DAG.MaskedValueIsZero(N0, SignBit)) return DAG.getNode(ISD::UREM, VT, N0, N1); - // Unconditionally lower X%C -> X-X/C*C. This allows the X/C logic to hack on - // the remainder operation. + // If X/C can be simplified by the division-by-constant logic, lower + // X%C to the equivalent of X-X/C*C. if (N1C && !N1C->isNullValue()) { SDOperand Div = DAG.getNode(ISD::SDIV, VT, N0, N1); - SDOperand Mul = DAG.getNode(ISD::MUL, VT, Div, N1); - SDOperand Sub = DAG.getNode(ISD::SUB, VT, N0, Mul); - AddToWorkList(Div.Val); - AddToWorkList(Mul.Val); - return Sub; + SDOperand OptimizedDiv = combine(Div.Val); + if (OptimizedDiv.Val && OptimizedDiv.Val != Div.Val) { + SDOperand Mul = DAG.getNode(ISD::MUL, VT, OptimizedDiv, N1); + SDOperand Sub = DAG.getNode(ISD::SUB, VT, N0, Mul); + AddToWorkList(Mul.Val); + return Sub; + } } // undef % X -> 0 @@ -1351,15 +1353,17 @@ SDOperand DAGCombiner::visitUREM(SDNode *N) { } } - // Unconditionally lower X%C -> X-X/C*C. This allows the X/C logic to hack on - // the remainder operation. + // If X/C can be simplified by the division-by-constant logic, lower + // X%C to the equivalent of X-X/C*C. if (N1C && !N1C->isNullValue()) { SDOperand Div = DAG.getNode(ISD::UDIV, VT, N0, N1); - SDOperand Mul = DAG.getNode(ISD::MUL, VT, Div, N1); - SDOperand Sub = DAG.getNode(ISD::SUB, VT, N0, Mul); - AddToWorkList(Div.Val); - AddToWorkList(Mul.Val); - return Sub; + SDOperand OptimizedDiv = combine(Div.Val); + if (OptimizedDiv.Val && OptimizedDiv.Val != Div.Val) { + SDOperand Mul = DAG.getNode(ISD::MUL, VT, OptimizedDiv, N1); + SDOperand Sub = DAG.getNode(ISD::SUB, VT, N0, Mul); + AddToWorkList(Mul.Val); + return Sub; + } } // undef % X -> 0 |