https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104356
--- Comment #39 from Andrew Macleod <amacleod at redhat dot com> --- (In reply to Jakub Jelinek from comment #38) > (In reply to Andrew Macleod from comment #37) > > 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. > > Yeah, so e.g. with Eric's patch to disable the X / boolean_range_Y simplifier > in match.pd, won't the ranger perform the same optimization? > I mean with the wi_fold_in_parts, if range of the divisor has 2 values and > one of them is 0, won't it try to union range of X / 1 (range of X) and > range of X / 0 (undefined) and yield range of X? So say won't 7 / > Y_with_bool_range yield > [7,7] ? It will... but ranger wont remove the divide unless the simplifier or folding does it. ie: if (x == 7 || x == 0) return y/x; Produces: x_5(D) int [0, 0][7, 7] <bb 3> : _8 = y_7(D) / x_5(D); // predicted unlikely by early return (on trees) predictor. _8 : int [-306783378, 306783378] Change it to: if (y != 7) return 1; if (x == 7 || x == 0) return y/x; and ranger will provide [7,7] / [0,0][7,7] then go thru folding and remove the statement: Folding statement: _8 = y_5(D) / x_6(D); Queued stmt for removal. Folds to: 1 however ranger will indeed calculate this range as [1,1]. _8 will be registered as [1,1] and some follow on code may get eliminated as a result... Even if the folder didn't remove this, Its possible that if we propagate the value of [1,1] it could make the divide dead code, and it could then be removed by some other passes. If we have states where divide by zero cannot possibly ever be eliminated like this, then we could have the / 0 case return VARYING instead... we just need to decide in rangeops what behaviour you want. In fact, I think it did in GCC11... yeah, here it is. // If we're definitely dividing by zero, there's nothing to do. if (wi_zero_p (type, divisor_min, divisor_max)) { r.set_varying (type); return; }