https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104356
--- Comment #37 from Andrew Macleod <amacleod at redhat dot com> --- (In reply to Jakub Jelinek from comment #35) > I meant something like: > return Z / X; > and there evrp does with -O2 -gnatp optimize away the division. > Though that is likely the X / boolean_range_Y case which you've disabled. > In any case, I think you want to hear from Andrew/Aldy where exactly does > VRP/ranger assume UB on integer division by zero. That divide is remove by the simplifier because it determines that X has a range of [0,1] and I believe the simplifer chooses to ignore the 0 under various circumstances. As for ranger, range-ops will return UNDEFINED for the range if x is known to be [0,0]. This can be propagated around, and depending on how it ends up being used as to what happens with it. This happens in range-ops.cc in operator_div::wi_fold() // If we're definitely dividing by zero, there's nothing to do. if (wi_zero_p (type, divisor_min, divisor_max)) { r.set_undefined (); return; } likewise the MOD operator does the same: void operator_trunc_mod::wi_fold (irange &r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, const wide_int &rh_lb, const wide_int &rh_ub) const { wide_int new_lb, new_ub, tmp; signop sign = TYPE_SIGN (type); unsigned prec = TYPE_PRECISION (type); // Mod 0 is undefined. if (wi_zero_p (type, rh_lb, rh_ub)) { r.set_undefined (); return; }