https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97378
--- Comment #6 from Andrew Macleod <amacleod at redhat dot com> --- (In reply to Aldy Hernandez from comment #2) > (In reply to David Binderman from comment #1) > > > > The division by zero was product of various transformations. Basically we > know that a.0_1 is 0, so we _7 is 0, which means _9 is also 0, which means > that final conditional can't happen: > > <bb 3> : > c.3_6 = c; > _7 = a.0_1 * c.3_6; > a = _7; > _9 = (long int) _7; > _10 = f_33(D) % _9; > if (_10 != 0) > > Andrew can take it from here, but it looks like the substitute_and_fold > engine must be able to remove *ALL* references to an LHS whose definition > was folded away, even if said references appear in unreachable code. The issue was a residue of the conflict between the old meaning of undefined (which was unprocessed, and could be treated as VARYING in a calculation) and the original ranger design in which undefined means an empty range and is not reachable. as such, range-ops was returning undefined for _10 = f_33 % 0 and when processing UNDEFINED != 0 ranger was assuming neither edge could be taken because it wouldn't arrive at this statement in the first place, and well, bad things happened. The current meaning of UNDEFINED in ranger world is still that a value cant be resolved but use as UNDEFINED is primarily triggered on edge calculations when combining ranges to indicate an edge isnt taken. When its used in a calculation that can/will happen, it should be treated as a VARYING value since we dont actually know what the value will be and can't draw conclusions. Its still slightly schizophrenic, and I will work to resolve the consistency of it.