https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78327
--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> ---
Well, the issue is that we don't always use the "nice" unsigned rep
for anti-range tests but "simplify" the special case
(unsigned char) n + 125 <= 127
to a cheaper signed comparison against zero via
/* Non-equality compare simplifications from fold_binary */
(for cmp (lt gt le ge)
/* Comparisons with the highest or lowest possible integer of
the specified precision will have known values. */
(simplify
(cmp (convert?@2 @0) INTEGER_CST@1)
(if ((INTEGRAL_TYPE_P (TREE_TYPE (@1)) || POINTER_TYPE_P (TREE_TYPE (@1)))
&& tree_nop_conversion_p (TREE_TYPE (@2), TREE_TYPE (@0)))
...
(if (wi::eq_p (@1, signed_max)
&& TYPE_UNSIGNED (arg1_type)
/* We will flip the signedness of the comparison operator
associated with the mode of @1, so the sign bit is
specified by this mode. Check that @1 is the signed
max associated with this sign bit. */
&& prec == GET_MODE_PRECISION (TYPE_MODE (arg1_type))
/* signed_type does not work on pointer types. */
&& INTEGRAL_TYPE_P (arg1_type))
/* The following case also applies to X < signed_max+1
and X >= signed_max+1 because previous transformations. */
(if (cmp == LE_EXPR || cmp == GT_EXPR)
(with { tree st = signed_type_for (arg1_type); }
(if (cmp == LE_EXPR)
(ge (convert:st @0) { build_zero_cst (st); })
(lt (convert:st @0) { build_zero_cst (st); }))))))))))
so yes, we should add handling of (signed)X < / >= 0 to VRP. Note that
early VRP doesn't handle any of these cases yet (it requires back-propagation
to be implemented or of course the pattern matchings be generalized so they
are usable from early VRP).