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.

Reply via email to