aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Gohman <djg@cray.com>2007-11-26 23:46:11 +0000
committerDan Gohman <djg@cray.com>2007-11-26 23:46:11 +0000
commitfdb31f1da69c857d4fd7275652d0ccb2f55d9194 (patch)
tree1d1442c3f403517891e7ab3940371e08660e7639
parent9d87b1bd8092c7dff905d861bc593f70000244b2 (diff)
downloadexternal_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.cpp32
-rw-r--r--test/CodeGen/X86/urem-i8-constant.ll6
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
+}