summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2005-05-14 12:53:20 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2005-05-14 12:53:20 +0000
commit86f023fe9da95c7a8a292e91555fb7891d4971a5 (patch)
tree7cfd487443568edd03b6e0400293030fed80a490
parent8cb529a5430b2038a9b66cb5adef90f928da5f94 (diff)
downloadgcc-86f023fe9da95c7a8a292e91555fb7891d4971a5.tar.gz
2005-05-14 Richard Guenther <rguenth@gcc.gnu.org>
* fold-const.c (div_if_zero_remainder): New function. (try_move_mult_to_index): Use it. * g++.dg/tree-ssa/tmmti-2.C: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@99694 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/fold-const.c42
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C22
4 files changed, 65 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 91e30783d84..365ac33f5b3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2005-05-14 Richard Guenther <rguenth@gcc.gnu.org>
+
+ * fold-const.c (div_if_zero_remainder): New function.
+ (try_move_mult_to_index): Use it.
+
2005-05-14 Kazu Hirata <kazu@cs.umass.edu>
* tree-eh.c (leh_tf_state): Change the type of dest_array to
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index a6ed0fa007c..b19dd85ed66 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -831,6 +831,33 @@ div_and_round_double (enum tree_code code, int uns,
add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem);
return overflow;
}
+
+/* If ARG2 divides ARG1 with zero remainder, carries out the division
+ of type CODE and returns the quotient.
+ Otherwise returns NULL_TREE. */
+
+static tree
+div_if_zero_remainder (enum tree_code code, tree arg1, tree arg2)
+{
+ unsigned HOST_WIDE_INT int1l, int2l;
+ HOST_WIDE_INT int1h, int2h;
+ unsigned HOST_WIDE_INT quol, reml;
+ HOST_WIDE_INT quoh, remh;
+ tree type = TREE_TYPE (arg1);
+ int uns = TYPE_UNSIGNED (type);
+
+ int1l = TREE_INT_CST_LOW (arg1);
+ int1h = TREE_INT_CST_HIGH (arg1);
+ int2l = TREE_INT_CST_LOW (arg2);
+ int2h = TREE_INT_CST_HIGH (arg2);
+
+ div_and_round_double (code, uns, int1l, int1h, int2l, int2h,
+ &quol, &quoh, &reml, &remh);
+ if (remh != 0 || reml != 0)
+ return NULL_TREE;
+
+ return build_int_cst_wide (type, quol, quoh);
+}
/* Return true if built-in mathematical function specified by CODE
preserves the sign of it argument, i.e. -f(x) == f(-x). */
@@ -6311,6 +6338,10 @@ try_move_mult_to_index (enum tree_code code, tree addr, tree op1)
{
if (TREE_CODE (ref) == ARRAY_REF)
{
+ itype = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (ref, 0)));
+ if (! itype)
+ continue;
+
step = array_ref_element_size (ref);
if (TREE_CODE (step) != INTEGER_CST)
continue;
@@ -6323,17 +6354,12 @@ try_move_mult_to_index (enum tree_code code, tree addr, tree op1)
else
{
/* Try if delta is a multiple of step. */
- tree mod = int_const_binop (TRUNC_MOD_EXPR, delta, step, 0);
- if (!integer_zerop (mod))
+ tree tmp = div_if_zero_remainder (EXACT_DIV_EXPR, delta, step);
+ if (! tmp)
continue;
-
- delta = int_const_binop (EXACT_DIV_EXPR, delta, step, 0);
+ delta = tmp;
}
- itype = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (ref, 0)));
- if (! itype)
- continue;
-
break;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 47c6771ea86..e3897d580c3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2005-05-14 Richard Guenther <rguenth@gcc.gnu.org>
+
+ * g++.dg/tree-ssa/tmmti-2.C: New testcase.
+
2005-05-13 Julian Brown <julian@codesourcery.com>
* gcc.c-torture/execute/20041218-2.c: Add __attribute__((packed)).
diff --git a/gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C b/gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C
new file mode 100644
index 00000000000..9735adc6c7d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options { -O -fdump-tree-optimized } } */
+
+int a[4][8];
+
+int foo(int i)
+{
+ return *(&a[0][0] + i*8); // a[i][0]
+}
+
+struct Foo { double x, y; };
+
+Foo b[4];
+
+double bar(int i)
+{
+ return *(&b[0].x + i*2); // b[i].x
+}
+
+/* { dg-final { scan-tree-dump "a\\\[.*i.*\\\]\\\[0\\\]" "optimized" } } */
+/* { dg-final { scan-tree-dump "b\\\[.*i.*\\\].x" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */