This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug middle-end/36691] [4.2/4.3/4.4 Regression] wrong value left in induction variable



------- Comment #8 from rguenth at gcc dot gnu dot org  2008-08-04 13:36 -------
Because somehow we get into

  /* If we can determine the final value of the control iv exactly, we can
     transform the condition to != comparison.  In particular, this will be
     the case if DELTA is constant.  */
  if (number_of_iterations_lt_to_ne (type, iv0, iv1, niter, &delta, step,
                                     bnds))
    {
      affine_iv zps;

and that figures it can just use [0, 5] - but number_of_iterations_lt_to_ne
didn't add any assumptions...  why does it take the "absolute value of
the step", and why do we compute that (unconditionally) by negating the
step?

It looks like at least

      /* The final value of the iv is iv0->base - MOD, assuming that this
         computation does not overflow, and that
         iv0->base - MOD <= iv1->base. */
      if (!iv0->no_overflow && !integer_zerop (mod))

is wrong, as iv0 is just { 3, 0, true } (mod == 4), so certainly the
assumption computed (if we would compute it) is false.

So, with

Index: tree-ssa-loop-niter.c
===================================================================
--- tree-ssa-loop-niter.c       (revision 138620)
+++ tree-ssa-loop-niter.c       (working copy)
@@ -677,7 +677,7 @@ number_of_iterations_lt_to_ne (tree type
   tree tmod;
   mpz_t mmod;
   tree assumption = boolean_true_node, bound, noloop;
-  bool ret = false;
+  bool no_overflow, ret = false;
   tree type1 = type;
   if (POINTER_TYPE_P (type))
     type1 = sizetype;
@@ -692,12 +692,13 @@ number_of_iterations_lt_to_ne (tree type
   mpz_set_double_int (mmod, tree_to_double_int (mod), true);
   mpz_neg (mmod, mmod);

+  no_overflow = iv0->no_overflow && iv1->no_overflow;
   if (integer_nonzerop (iv0->step))
     {
       /* The final value of the iv is iv1->base + MOD, assuming that this
         computation does not overflow, and that
         iv0->base <= iv1->base + MOD.  */
-      if (!iv1->no_overflow && !integer_zerop (mod))
+      if (!no_overflow && !integer_zerop (mod))
        {
          bound = fold_build2 (MINUS_EXPR, type,
                               TYPE_MAX_VALUE (type1), tmod);
@@ -719,7 +720,7 @@ number_of_iterations_lt_to_ne (tree type
       /* The final value of the iv is iv0->base - MOD, assuming that this
         computation does not overflow, and that
         iv0->base - MOD <= iv1->base. */
-      if (!iv0->no_overflow && !integer_zerop (mod))
+      if (!no_overflow && !integer_zerop (mod))
        {
          bound = fold_build2 (PLUS_EXPR, type1,
                               TYPE_MIN_VALUE (type1), tmod);


we make the testcase work.


-- 

rguenth at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |rakdver at gcc dot gnu dot
                   |                            |org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36691


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]