PR 23386
authorspop <spop@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 15 Aug 2005 07:51:42 +0000 (07:51 +0000)
committerspop <spop@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 15 Aug 2005 07:51:42 +0000 (07:51 +0000)
  * tree-data-ref.c (estimate_niter_from_size_of_data): When
  step is negative compute the estimation from init downwards to
  zero.

* testsuite/gcc.dg/tree-ssa/pr23386.c: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@103106 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr23386.c [new file with mode: 0644]
gcc/tree-data-ref.c

index ae35c9f..e8c8594 100644 (file)
@@ -1,3 +1,9 @@
+2005-08-15  Sebastian Pop  <pop@cri.ensmp.fr>
+
+       PR 23386
+       * tree-data-ref.c (estimate_niter_from_size_of_data): When
+       step is negative compute the estimation from init downwards to zero.
+       
 2005-08-14  James A. Morrison  <phython@gcc.gnu.org>
 
        * fold-const (fold_binary): Call fold_build2 instead of fold (build.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr23386.c b/gcc/testsuite/gcc.dg/tree-ssa/pr23386.c
new file mode 100644 (file)
index 0000000..d322f99
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+int f[100];
+int g[100];
+unsigned char
+f1 (int a, int b)
+{
+  __SIZE_TYPE__ ix;
+  if (a)
+    return 1;
+  for (ix = 4; ix--;)
+      if (f[ix] != g[ix])
+         return 0;
+  return 1;
+}
+
+int main(void)
+{
+  if (!f1 (0, 2))
+    __builtin_abort();
+  return 0;
+}
+
index 24856ed..1848128 100644 (file)
@@ -751,7 +751,7 @@ estimate_niter_from_size_of_data (struct loop *loop,
                                  tree access_fn, 
                                  tree stmt)
 {
-  tree estimation;
+  tree estimation = NULL_TREE;
   tree array_size, data_size, element_size;
   tree init, step;
 
@@ -773,11 +773,28 @@ estimate_niter_from_size_of_data (struct loop *loop,
       && TREE_CODE (init) == INTEGER_CST
       && TREE_CODE (step) == INTEGER_CST)
     {
-      estimation = fold_build2 (CEIL_DIV_EXPR, integer_type_node,
-                               fold_build2 (MINUS_EXPR, integer_type_node,
-                                            data_size, init), step);
-
-      record_estimate (loop, estimation, boolean_true_node, stmt);
+      tree i_plus_s = fold_build2 (PLUS_EXPR, integer_type_node, init, step);
+      tree sign = fold_build2 (GT_EXPR, boolean_type_node, i_plus_s, init);
+
+      if (sign == boolean_true_node)
+       estimation = fold_build2 (CEIL_DIV_EXPR, integer_type_node,
+                                 fold_build2 (MINUS_EXPR, integer_type_node,
+                                              data_size, init), step);
+
+      /* When the step is negative, as in PR23386: (init = 3, step =
+        0ffffffff, data_size = 100), we have to compute the
+        estimation as ceil_div (init, 0 - step) + 1.  */
+      else if (sign == boolean_false_node)
+       estimation = 
+         fold_build2 (PLUS_EXPR, integer_type_node,
+                      fold_build2 (CEIL_DIV_EXPR, integer_type_node,
+                                   init,
+                                   fold_build2 (MINUS_EXPR, unsigned_type_node,
+                                                integer_zero_node, step)),
+                      integer_one_node);
+
+      if (estimation)
+       record_estimate (loop, estimation, boolean_true_node, stmt);
     }
 }