diff options
author | Dan Gohman <djg@cray.com> | 2007-11-26 23:46:11 +0000 |
---|---|---|
committer | Dan Gohman <djg@cray.com> | 2007-11-26 23:46:11 +0000 |
commit | fdb31f1da69c857d4fd7275652d0ccb2f55d9194 (patch) | |
tree | 1d1442c3f403517891e7ab3940371e08660e7639 | |
parent | 9d87b1bd8092c7dff905d861bc593f70000244b2 (diff) | |
download | external_llvm-fdb31f1da69c857d4fd7275652d0ccb2f55d9194.zip external_llvm-fdb31f1da69c857d4fd7275652d0ccb2f55d9194.tar.gz external_llvm-fdb31f1da69c857d4fd7275652d0ccb2f55d9194.tar.bz2 |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44341 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 32 | ||||
-rw-r--r-- | test/CodeGen/X86/urem-i8-constant.ll | 6 |
2 files changed, 24 insertions, 14 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 8f6800a..3be1fdd 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/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 diff --git a/test/CodeGen/X86/urem-i8-constant.ll b/test/CodeGen/X86/urem-i8-constant.ll new file mode 100644 index 0000000..8a43333 --- /dev/null +++ b/test/CodeGen/X86/urem-i8-constant.ll @@ -0,0 +1,6 @@ +; RUN: llvm-as < %s | llc -march=x86 | not grep mul + +define i8 @foo(i8 %tmp325) { + %t546 = urem i8 %tmp325, 37 + ret i8 %t546 +} |