https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97741
--- Comment #2 from Andrew Macleod <amacleod at redhat dot com> --- Created attachment 49517 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49517&action=edit don't lose info already in the global range The problem here is the IL being changed by propagation under to covers sometimes loses information. The first thing examined is: e_4 = PHI <0(2), e_8(6)> and the ranger goes off on the backedge to block 6 and eventually determines that the edge 6->2 can never be executed, and thus e_8 is undefined on that edge, which means the range of the PHI can be determined to be [0,0], and can thus be folded. Later on the propagator visits the blocks this originates in and sees e_8 = PHI <e_5(7)> which is fed by the sequence: <bb 7> : b.1_3 = b; if (b.1_3 != 0) goto <bb 6>; [INV] <bb 8> : e_12 = e_5 + 1; <bb 9> : # e_5 = PHI <0(5), e_12(8)> if (e_5 == 20) goto <bb 7>; [INV] The ranger had figured out that although the branch says e_5 must be 20 on the edge from bb5,it can only get to this code if it is 20 AND goes thru the e_12 = e_5 + 1, which means e_12 must only be [21, 21] which makes the whole thing undefined.. and it is. it can never happen. However, when the propagator later visits stmts, and we get to e_12 = e_5 + 1; when this is re-evaluated, e_5 is undefined and rather than propagating e_12 as undefined, we decided a while ago to treat undefined as VARYING when doing math.. we change e_12 to VARYING now, even tho we had earlier decided it was [21,21] This has ripple effects that eventually results in deciding that e_5 must be [20,20] coming from bb 7, it replaces that first PHI: e_8 = PHI <e_5(7)> with e_8 = PHI <20(7)> when we then ask for the range of e_4 again at a use: <bb 4> : _1 = (char) e_4; e_4 = PHI <0(2), e_8(6)> e_8 is now hardwired to [20,20] so it now recalculates e_4 to be [0,0][20,20] instead of 0, and the engine does not fold the statement. which ends up leaving e_4 in the IL with no definition. THe easiest way to fix this sort of thing is to recognize that with the IL changing under the covers in ways not really controlled by the ranger, we should keep the previous value we defined, and refine it as we go along rather than fully recalculating it. I think this will resolve an entire class of issues until we change the way we propagate things, or revisit the slightly schizophrenic interpretation of undefined. The original RVRP pass simply propagated values via the immediate-use chains, so the IL always reflected exactly what it knew. The attached patch is currently being tested.