http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49039
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |ASSIGNED
AssignedTo|unassigned at gcc dot |jakub at gcc dot gnu.org
|gnu.org |
--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> 2011-05-18
16:46:09 UTC ---
Ok, I think I see the bug. extract_range_from_binary_expr
is called with MIN_EXPR, where vr0 is ~[-1UL, -1UL] and vr1 is ~[0, 0]
and performs:
/* For operations that make the resulting range directly
proportional to the original ranges, apply the operation to
the same end of each range. */
min = vrp_int_const_binop (code, vr0.min, vr1.min);
max = vrp_int_const_binop (code, vr0.max, vr1.max);
which for MIN_EXPR unsurprisingly gives min 0 max 0 and thus returns ~[0, 0]
although it should have been VARYING in this case. For PLUS we already give up
for VR_ANTI_RANGE earlier:
if (code == PLUS_EXPR && vr0.type == VR_ANTI_RANGE)
{
set_value_range_to_varying (vr);
return;
}
but we don't do so for MIN_EXPR/MAX_EXPR. For MAX_EXPR the same ranges will
give similarly incorrect result:
MAX_EXPR <~[-1UL, -1UL], ~[0, 0]> will yield ~[-1UL, -1UL] instead of correct
VARYING. So, either we can just remove "code == PLUS_EXPR && " and give up
with VR_ANTI_RANGE always, or if there is a way to do something better we could
do so. I'll think about it some more. E.g. for MIN_EXPR/MAX_EXPR, if the anti
ranges are the same we can certainly return that anti range instead of VARYING.