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).

Reply via email to