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.