https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71031
--- Comment #10 from Marek Polacek <mpolacek at gcc dot gnu.org> --- (In reply to Eric Botcazou from comment #9) > > The situation (+ UINT_MAX) is equal to [1, od_5] - 1 which would mean > > a result range of ideally [0, od_5 - 1]. > > Right. > > > I think Eric added this code so he may want to have a look here to see > > what general solution is appropriate. > > > > But yes, instead of asserting we can always drop to VR_VARYING ... > > That's what the block of code just above was added for: > > /* If we have overflow for the constant part and the resulting > range will be symbolic, drop to VR_VARYING. */ > if ((min_ovf && sym_min_op0 != sym_min_op1) > || (max_ovf && sym_max_op0 != sym_max_op1)) > { > set_value_range_to_varying (vr); > return; > } > > so a safe fix is to extend it to catch this case: > > /* If we have overflow for the constant part and the resulting > range will be symbolic, drop to VR_VARYING. */ > if ((min_ovf || max_ovf) > && (sym_min_op0 != sym_min_op1 || sym_max_op0 != sym_max_op1)) > { > set_value_range_to_varying (vr); > return; > } That makes sense. I'll do that. > If we want to compute the above expected range, we need to enter the > business of symbolic ranges with TYPE_OVERFLOW_WRAPS, which is rather > delicate. And we also need to short circuit the final call to > compare_values, which will drop to VR_VARYING if I'm not mistaken. Yea, it is (at least for me ;). Thanks Eric & Richi!