https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68911

amker at gcc dot gnu.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|2016-01-04 00:00:00         |2015-12-15 0:00

--- Comment #6 from amker at gcc dot gnu.org ---
Here is the situation:
  scev_probably_wraps_p returns:
     A) true, in this case there is nothing to do;
     B) false.  since this information only indicates no-overflow when
may_be_zero is false.  We then have three sub-cases:
        B.1) may_be_zero is false.  The current code logic works.
        B.2) may_be_zero is true, and scev will overflow after nit(bound)
iterations.
        B.3) may_be_zero is true, and scev doesn't overflow after nit(bound)
iterations.

So simply bypass and return when loop may exit at its first iteration is not
optimal.  Because case B.3) will be missed.

I think the right fix is add overflow check in below code:

      /* We are only entering here for loop header PHI nodes, so using
         the number of latch executions is the correct thing to use.  */
      if (max_loop_iterations (loop, &nit))
        {
          value_range maxvr = VR_INITIALIZER;
          signop sgn = TYPE_SIGN (TREE_TYPE (step));
          bool overflow;

          widest_int wtmp = wi::mul (wi::to_widest (step), nit, sgn,
                                     &overflow);
          /* If the multiplication overflowed we can't do a meaningful
             adjustment.  Likewise if the result doesn't fit in the type
             of the induction variable.  For a signed type we have to
             check whether the result has the expected signedness which
             is that of the step as number of iterations is unsigned.  */
          if (!overflow
              && wi::fits_to_tree_p (wtmp, TREE_TYPE (init))
              && (sgn == UNSIGNED
                  || wi::gts_p (wtmp, 0) == wi::gts_p (step, 0)))
            {
              tem = wide_int_to_tree (TREE_TYPE (init), wtmp);
              extract_range_from_binary_expr (&maxvr, PLUS_EXPR,
                                              TREE_TYPE (init), init, tem);
              /* Likewise if the addition did.  */
              if (maxvr.type == VR_RANGE)
                {

                  //  <-----------HERE

                  tmin = maxvr.min;
                  tmax = maxvr.max;
                }
            }
        }

This overflow check is specifically for scev when may_be_zero is true. 
Actually I think it might be possible for us to remove the call to
scev_probably_wraps_p, since this new check together with the variable
"overflow" can cover the case when scev does overflow when may_be_zero is
false.

I am testing a patch for this.

Reply via email to