https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88217
--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
OK, so for -fstrict-enums VRP uses TYPE_MIN/MAX_VALUE in some places but in
others it just uses the underlying precision. This breaks down in
vr_values::extract_range_from_phi_node where
/* Similarly for the maximum value. */
if (cmp_max > 0)
new_max = lhs_vr->max ();
else if (cmp_max < 0
&& !vrp_val_is_max (vr_result->max ()))
new_max = int_const_binop (MINUS_EXPR,
vrp_val_max (vr_result->type ()),
build_int_cst (vr_result->type (), 1));
propagation on the PHI computed vr_result to [0, 4] where 4 is one _above_
vrp_val_max. This causes us to drop down to [0, 2]. The code above
assumes that max is really max.
Elsewhere I stated that VRPs use of TYPE_MIN/MAX_VALUE is fishy
(update_value_range doesn't make use of it either).