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