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;
}