[Bug tree-optimization/68911] [6 Regression] wrong code with -O1 -ftree-vrp
amker at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Jan 6 18:04:00 GMT 2016
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.
More information about the Gcc-bugs
mailing list