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

--- Comment #3 from Andrew Macleod <amacleod at redhat dot com> ---
Created attachment 49512
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49512&action=edit
Use a multirange value in value_query::value_of_*

This was triggered by a new call into range_of_stmt to reevaluate

_3 = e_15 != 0;

we already knew it was [1,1], and had folded some stuff away.  however, e_15
had been further refined so _3 was out of date.

mostly harmless, except e_15 now has a range of
long int [-1, -1][4294967294, 4294967295]

obviously that will still evaluate to [1,1]... except it didn't :-P  it came
back VARYING.

!= checks if the intersection of the 2 operands is empty... which it should be, 
but the code reuses the result range passed in as the temporary.. and that
turns out of be a value_range.  so when we copy  [-1, -1][4294967294,
4294967295] into the value_range, it cant be fully represented, and we end up
with
 long int [-1, 4294967295]
and can no longer tell it is not equal to [0,0].

doh.

First, the range-ops code for not_equal and equal should be adjusted to not use
the range passed in as a temporary.. the consumer may well know this is a
boolean and only pass in an int_range<1> on purpose.

second, the true root is that the 3 value_of_* routines actually pass in a 
value_range rather than a multirange... Original thinking was we are looking
for a single value result.  But there are other range_ops routines that build
into the value passed, like multiply and others, so its better to simple pass
in an int_range_max or something similar could happen elsewhere.

testing the attached patch

Reply via email to