https://gcc.gnu.org/bugzilla/show_bug.cgi?id=76174
--- Comment #4 from Andrew Macleod <amacleod at redhat dot com> --- I would argue that this isn't a range issue. Looking at the code generated without the c *= 2 I see: <bb 2> : goto <bb 6>; [INV] <bb 3> : if (q_1 == r_6(D)) goto <bb 4>; [INV] else goto <bb 5>; [INV] <bb 4> : m (); <bb 5> : q_11 = q_1 + 1; x_12 = x_2 + 1; <bb 6> : # q_1 = PHI <0(2), q_11(5)> # x_2 = PHI <0(2), x_12(5)> if (x_2 < r_6(D)) goto <bb 3>; [INV] else goto <bb 7>; [INV] <bb 7> : return; we know that x_2<r_6 in in bb3 given the condition on the edge 6->3. What isn't obvious from a range point of view is that x and q are in lockstep and are actually equivalent. There is nothing to indicate they are equivalent other than they execute the same sequence of code. Given that, I would claim that VN or some other pass is required to sort this out, which is exactly what happens now. As we now get this optimization, I think the PR should be closed as this is not something VRP would be planning to get.