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