Fix PR/46200
authorXinliang David Li <davidxl@google.com>
Wed, 3 Nov 2010 22:25:53 +0000 (22:25 +0000)
committerXinliang David Li <davidxl@gcc.gnu.org>
Wed, 3 Nov 2010 22:25:53 +0000 (22:25 +0000)
From-SVN: r166280

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

index cff9dd8aa850a8cda8336f36ebcc0990bc82a16e..a8d12c411914ffb9f483a0e117c631122912b317 100644 (file)
@@ -1,3 +1,9 @@
+2010-11-03  Xinliang David Li  <davidxl@google.com>
+
+       PR target/46200
+       * tree-ssa-loop-ivopts.c (get_computation_cost_at):
+       Adjust cbase if the use stmt is after iv update.
+
 2010-11-03  Kaz Kojima  <kkojima@gcc.gnu.org>
 
        * config.gcc (sh64*) <tm_file>: Add newlib-stdint.h for
index a602ecf6339741f3ef043490f0fdc7b627c68ad9..fb9eb65b846fcda6633f1b951a61dce488f7e112 100644 (file)
@@ -1,3 +1,8 @@
+2010-11-03  Xinliang David Li  <davidxl@google.com>
+
+       PR target/46200
+       * g++.dg/tree-ssa/ivopts-2.C: New test.
+
 2010-11-03  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR target/46295
diff --git a/gcc/testsuite/g++.dg/tree-ssa/ivopts-2.C b/gcc/testsuite/g++.dg/tree-ssa/ivopts-2.C
new file mode 100644 (file)
index 0000000..908299d
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile { target { i?86-*-* x86_64-*-*  } } } */
+/* { dg-options "-O2 -fdump-tree-ivopts-details" } */
+
+void test (int *b, int *e, int stride)
+  {
+    for (int *p = b; p != e; p += stride)
+      *p = 1;
+  }
+
+/* { dg-final { scan-tree-dump-times "PHI <p" 1 "ivopts"} } */
+/* { dg-final { cleanup-tree-dump "ivopts" } } */
index 88fc015ad7f0826842c1654d0a0506cfcdcea3e2..ab2e67af2aea6af0e9621b06141701b2c09d0cb0 100644 (file)
@@ -4027,6 +4027,8 @@ get_computation_cost_at (struct ivopts_data *data,
   STRIP_NOPS (cbase);
   ctype = TREE_TYPE (cbase);
 
+  stmt_is_after_inc = stmt_after_increment (data->current_loop, cand, at);
+
   /* use = ubase + ratio * (var - cbase).  If either cbase is a constant
      or ratio == 1, it is better to handle this like
 
@@ -4045,8 +4047,24 @@ get_computation_cost_at (struct ivopts_data *data,
     }
   else if (ratio == 1)
     {
+      tree real_cbase = cbase;
+
+      /* Check to see if any adjustment is needed.  */
+      if (cstepi == 0 && stmt_is_after_inc)
+        {
+          aff_tree real_cbase_aff;
+          aff_tree cstep_aff;
+
+          tree_to_aff_combination (cbase, TREE_TYPE (real_cbase),
+                                   &real_cbase_aff);
+          tree_to_aff_combination (cstep, TREE_TYPE (cstep), &cstep_aff);
+
+          aff_combination_add (&real_cbase_aff, &cstep_aff);
+          real_cbase = aff_combination_to_tree (&real_cbase_aff);
+        }
+
       cost = difference_cost (data,
-                             ubase, cbase,
+                             ubase, real_cbase,
                              &symbol_present, &var_present, &offset,
                              depends_on);
       cost.cost /= avg_loop_niter (data->current_loop);
@@ -4088,7 +4106,6 @@ get_computation_cost_at (struct ivopts_data *data,
 
   /* If we are after the increment, the value of the candidate is higher by
      one iteration.  */
-  stmt_is_after_inc = stmt_after_increment (data->current_loop, cand, at);
   if (stmt_is_after_inc)
     offset -= ratio * cstepi;