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

--- Comment #1 from Patrick Palka <ppalka at gcc dot gnu.org> ---
(In reply to Patrick Palka from comment #0)
> Test case:
> 
> void
> test (int x)
> {
>   if (x < 5 || x > 10)
>     {
>       int y;
>       foo (x);
>       y = x + 1;
>       bar (y);
>     }
> }
> 
> The range for x is ~[5, 10] and so one would expect the range for y to be
> ~[6, 11].  Yet what's actually derived for y is:
> 
> Visiting statement:
> y_7 = x_9 + 1;
> Meeting
>   [-2147483647, 5]
> and
>   [12, +INF(OVF)]
> to
>   [-2147483647, +INF(OVF)]
> Found new range for y_7: [-2147483647, +INF(OVF)]
> 
> which is a less useful range than the expected ~[6, 11].
> 
> This range for y is derived by splitting the anti-range of x_9 into two
> nonintersecting ranges, adjusting them both (by +1 in this case), and then
> vrp_meet()ing them.  But vrp_meet() turns two non-intersecting ranges into
> an anti-range only if the lower bound is -INF (which is not the case here)
> and the upper is +INF.
> 
> A possible solution is to also allow vrp_meet() to turn two ranges into an
> anti-range if either the upper or lower bound is an INF(OVF).  Maybe the
> number of restricted elements within the corresponding anti-range vs the
> number within the corresponding union of the two ranges should be considered
> too in deciding which representation to pick?

Regarding the last point, for example the number of restricted elements in the
expected anti range for y is 11-6 = 5 whereas the number of restricted elements
in the union is 1 (just INT_MIN).

Reply via email to