re PR tree-optimization/57343 (wrong code on x86_64-linux at -Os and above)
authorRichard Biener <rguenther@suse.de>
Mon, 27 May 2013 13:02:24 +0000 (13:02 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 27 May 2013 13:02:24 +0000 (13:02 +0000)
2013-05-27  Richard Biener  <rguenther@suse.de>

PR tree-optimization/57343
* tree-ssa-loop-niter.c (number_of_iterations_ne_max): Do not
use multiple_of_p if not TYPE_OVERFLOW_UNDEFINED.
(number_of_iterations_cond): Do not build the folded tree.

* gcc.dg/torture/pr57343.c: New testcase.

From-SVN: r199357

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr57343.c [new file with mode: 0644]
gcc/tree-ssa-loop-niter.c

index 8b7bed89d4b05ca2c8565a1429e0ba457847c594..7d6d31e01a22fc71602971119d1f78b32ddb86a2 100644 (file)
@@ -1,3 +1,10 @@
+2013-05-27  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/57343
+       * tree-ssa-loop-niter.c (number_of_iterations_ne_max): Do not
+       use multiple_of_p if not TYPE_OVERFLOW_UNDEFINED.
+       (number_of_iterations_cond): Do not build the folded tree.
+
 2013-05-27  Richard Biener  <rguenther@suse.de>
 
        Revert
index 7cf47c4f51410ba07dd1a3234d75fa08df68c2d9..40c213fc2515b7d39d5be4ad4dd56bfd45339132 100644 (file)
@@ -1,3 +1,8 @@
+2013-05-27  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/57343
+       * gcc.dg/torture/pr57343.c: New testcase.
+
 2013-05-27  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/57417
diff --git a/gcc/testsuite/gcc.dg/torture/pr57343.c b/gcc/testsuite/gcc.dg/torture/pr57343.c
new file mode 100644 (file)
index 0000000..b05bad5
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+
+int c = 0;
+
+int
+main ()
+{
+  int i, f = 1;
+  for (i = 0; i < 5; i++)
+    {
+      --c;
+      unsigned char h = c * 100;
+      if (h == 0)
+       {
+         f = 0;
+         break;
+       }
+    }
+  if (f != 1)
+    __builtin_abort ();
+  return 0;
+}
index 090e114c36d89c24ff14502e8f6fb096e471bf07..f5629306e4bb20ffc0d6e97632a2194dd0cabfef 100644 (file)
@@ -552,10 +552,18 @@ number_of_iterations_ne_max (mpz_t bnd, bool no_overflow, tree c, tree s,
 {
   double_int max;
   mpz_t d;
+  tree type = TREE_TYPE (c);
   bool bnds_u_valid = ((no_overflow && exit_must_be_taken)
                       || mpz_sgn (bnds->below) >= 0);
 
-  if (multiple_of_p (TREE_TYPE (c), c, s))
+  if (integer_onep (s)
+      || (TREE_CODE (c) == INTEGER_CST
+         && TREE_CODE (s) == INTEGER_CST
+         && tree_to_double_int (c).mod (tree_to_double_int (s),
+                                        TYPE_UNSIGNED (type),
+                                        EXACT_DIV_EXPR).is_zero ())
+      || (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (c))
+         && multiple_of_p (type, c, s)))
     {
       /* If C is an exact multiple of S, then its value will be reached before
         the induction variable overflows (unless the loop is exited in some
@@ -572,16 +580,15 @@ number_of_iterations_ne_max (mpz_t bnd, bool no_overflow, tree c, tree s,
      the whole # of iterations analysis will fail).  */
   if (!no_overflow)
     {
-      max = double_int::mask (TYPE_PRECISION (TREE_TYPE (c))
-                            - tree_low_cst (num_ending_zeros (s), 1));
+      max = double_int::mask (TYPE_PRECISION (type)
+                             - tree_low_cst (num_ending_zeros (s), 1));
       mpz_set_double_int (bnd, max, true);
       return;
     }
 
   /* Now we know that the induction variable does not overflow, so the loop
      iterates at most (range of type / S) times.  */
-  mpz_set_double_int (bnd, double_int::mask (TYPE_PRECISION (TREE_TYPE (c))),
-                     true);
+  mpz_set_double_int (bnd, double_int::mask (TYPE_PRECISION (type)), true);
 
   /* If the induction variable is guaranteed to reach the value of C before
      overflow, ... */
@@ -1311,7 +1318,8 @@ number_of_iterations_cond (struct loop *loop,
     }
 
   /* If the loop exits immediately, there is nothing to do.  */
-  if (integer_zerop (fold_build2 (code, boolean_type_node, iv0->base, iv1->base)))
+  tree tem = fold_binary (code, boolean_type_node, iv0->base, iv1->base);
+  if (tem && integer_zerop (tem))
     {
       niter->niter = build_int_cst (unsigned_type_for (type), 0);
       niter->max = double_int_zero;