Determine more IVs to be non-overflowing

Jan Hubicka hubicka@ucw.cz
Wed Jun 29 10:53:00 GMT 2016


Hi,
after some exprimentation I am re-testing the following version.  wide_int variant
seemed ugly. Here I simply cap nit to be in range of the type and then the
widest_int calculation ought to be safe.

What do you think? Perhaps I need to use signs of STEP and BASE type just in
the case some casts was dropped?
Honza

/* Return true if the IV calculation in TYPE can overflow based on the knowledge
   of the upper bound on the number of iterations of LOOP, the BASE and STEP
   of IV.

   We do not use information whether TYPE can overflow so it is safe to
   use this test even for derived IVs not computed every iteration or
   hypotetical IVs to be inserted into code.  */

bool
iv_can_overflow_p (struct loop *loop, tree type, tree base, tree step)
{
  widest_int nit;
  wide_int base_min, base_max, step_min, step_max, type_min, type_max;
  signop sgn = TYPE_SIGN (type);

  if (step == 0)
    return false;

  if (TREE_CODE (base) == INTEGER_CST)
    base_min = base_max = base;
  else if (TREE_CODE (base) == SSA_NAME && !POINTER_TYPE_P (TREE_TYPE (base))
	   && get_range_info (base, &base_min, &base_max) == VR_RANGE)
    ;
  else
    return true;

  if (TREE_CODE (step) == INTEGER_CST)
    step_min = step_max = step;
  else if (TREE_CODE (step) == SSA_NAME && !POINTER_TYPE_P (TREE_TYPE (base))
	   && get_range_info (step, &step_min, &step_max) == VR_RANGE)
    ;
  else
    return true;

  if (!get_max_loop_iterations (loop, &nit))
    return false;

  type_min = wi::max_value (type);
  type_max = wi::min_value (type);
  /* Watch overflow.  */
  if ((widest_int)1 << TYPE_PRECISION (type) <= nit)
    return true;
  if ((widest_int::from (base_max, sgn)
       + widest_int::from (step_max, sgn) * (nit + 1))
       > widest_int::from (type_max, sgn)
      || (widest_int::from (type_min, sgn)
	  > (widest_int::from (base_min, sgn)
	     + widest_int::from (step_min, sgn) * (nit + 1))))
    return true;
  return false;
}



More information about the Gcc-patches mailing list