fold-const.c (div_if_zero_remainder): New function.
authorRichard Guenther <rguenth@gcc.gnu.org>
Sat, 14 May 2005 12:53:20 +0000 (12:53 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Sat, 14 May 2005 12:53:20 +0000 (12:53 +0000)
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.

From-SVN: r99694

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C [new file with mode: 0644]

index 91e30783d84147900b005a4277024ccd7bedb339..365ac33f5b39d5569f48d9a9efb1dd8369b25209 100644 (file)
@@ -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
index a6ed0fa007c71328dc118f8da56c2e063d59403e..b19dd85ed66c8429e761b2702d01c3c1a64bd2cc 100644 (file)
@@ -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);
+}
 \f
 /* 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;
        }
 
index 47c6771ea86b8c7869fd189329271f096676ee18..e3897d580c344590a9726ea7fdb97c1e46b22f26 100644 (file)
@@ -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 (file)
index 0000000..9735adc
--- /dev/null
@@ -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" } } */