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

--- Comment #1 from Aldy Hernandez <aldyh at gcc dot gnu.org> ---
We are calculating ranges for the following:

(gdb) dd stmt
_18 = .UBSAN_CHECK_SUB (_58, _57);

which gets turned into a MINUS_EXPR.  Then we call
extract_range_from_binary_expr on the MINUS_EXPR:

      /* Pretend the arithmetics is wrapping.  If there is
         any overflow, we'll complain, but will actually do
         wrapping operation.  */
      flag_wrapv = 1;
      extract_range_from_binary_expr (vr, subcode, type,
                                      gimple_call_arg (stmt, 0),
                                      gimple_call_arg (stmt, 1));
      flag_wrapv = saved_flag_wrapv;

In extract_range_from_binary_expr, we calculate the range for _58 and _57
respectively as:

(gdb) dd vr0
integer(kind=8) [-INF, _57 - 1]
(gdb) dd vr1
integer(kind=8) [_58 + 1, +INF]

Which extract_range_from_binary_expr can then use to reduce the MINUS_EXPR to
~[0,0]:

 /* If we didn't derive a range for MINUS_EXPR, and
     op1's range is ~[op0,op0] or vice-versa, then we
     can derive a non-null range.  This happens often for
     pointer subtraction.  */
  if (vr->varying_p ()
      && (code == MINUS_EXPR || code == POINTER_DIFF_EXPR)
      && TREE_CODE (op0) == SSA_NAME
      && ((vr0.kind () == VR_ANTI_RANGE
           && vr0.min () == op1
           && vr0.min () == vr0.max ())
          || (vr1.kind () == VR_ANTI_RANGE
              && vr1.min () == op0
              && vr1.min () == vr1.max ())))
    {
      vr->set_nonzero (expr_type);
      vr->equiv_clear ();
    }

The ranger version is not handling these symbolics.

Reply via email to