https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68911
--- Comment #4 from amker at gcc dot gnu.org --- (In reply to Jakub Jelinek from comment #2) > This goes wrong during vrp1. > Analyzing # of iterations of loop 2 > exit condition [e_6, + , 1] <= 93 > bounds on difference of bases: -4294967202 ... 93 > result: > zero if e_6 > 94 > # of iterations 94 - e_6, bounded by 94 > looks wrong to me, e_6 as well as the additions and comparison are performed > in unsigned type, therefore 94 - e_6 is I believe not bounded by 94. The > value ranges for e_6 clearly allow (and in the testcase are) some very large > unsigned numbers, so 94 - e_6. If assuming the value of f is arbitrary (it > is not), then the possible values of e before entering the > while (e < 94) > e++; > loop are either 2, 94, 0xffffffffU or 0xfffffffeU (of course f is not > arbitrary and as b and d are both 0, it will be actually 0xffffffffU each > time. > But from those 4 numbers the number of iterations would be bound by 96. The immediate dump of loop before vrp1 is as below: <bb 8>: e_15 = e_1 + 1; <bb 13>: # e_1 = PHI <e_2(3), e_15(8), e_12(7)> if (e_1 <= 93) goto <bb 8>; else goto <bb 10>; The loop niter analyzed before/after r224020 are both like below: Analyzing # of iterations of loop 2 exit condition [e_8, + , 1] <= 93 bounds on difference of bases: -4294967202 ... 93 result: zero if e_8 > 94 # of iterations 94 - e_8, bounded by 94 Analyzing # of iterations of loop 2 exit condition [e_8, + , 1] <= 93 bounds on difference of bases: -4294967202 ... 93 result: zero if e_8 > 94 # of iterations 94 - e_8, bounded by 94 The only difference after patching is now we explicitly record {e_8, 1}_loop as a no-wrap control_iv. Seems to me the bound information is correct because that information must be used when "zero if e_8 > 94" is satisfied, as commented in source code: tree may_be_zero; /* The boolean expression. If it evaluates to true, the loop will exit in the first iteration (i.e. its latch will not be executed), even if the niter field says otherwise. */ tree niter; /* The expression giving the number of iterations of a loop (provided that assumptions == true and may_be_zero == false), more precisely the number of executions of the latch of the loop. */ So no_overflow property of control_iv should also be used only when may_be_zero is false. For now VRP tries to update range information using loop niter bound when the control iv doesn't wrap/overflow, but I think that is not enough. We can not assume any information from loop if the loop exits immediately. So, IMHO, we should only update value range with loop niter bound when may_be_zero is false. This will fix this issue and won't hurt other cases because when the loop exits immediately, there is no useful loop niter bound information anyway.