https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88044
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|WAITING |NEW --- Comment #14 from Jakub Jelinek <jakub at gcc dot gnu.org> --- I've put logging into tree-ssa-loop-niters.c, looking for when before/after r266171 code would make a difference in the returned value, the only case it triggers on is (all types integer(kind=4) i.e. signed 32-bit integer): code LE_EXPR iv0->base 0 iv0->step 0 iv1->base -1 iv1->step 1 every_iteration false The loop starts with: <bb 7> [local count: 8656061039]: # n_63 = PHI <0(6), _28(23)> _19 = n_63 + -1; and ends with _28 = n_63 + 1; if (_28 == 4) goto <bb 21>; [12.36%] else goto <bb 23>; [87.64%] <bb 23> [local count: 7582748748]: goto <bb 7>; [100.00%] and besides the exit at the end has also: <bb 16> [local count: 3548985018]: if (_19 > 0) goto <bb 17>; [0.04%] else goto <bb 28>; [99.96%] <bb 17> [local count: 1419591]: _gfortran_stop_numeric (1, 0); <bb 18> [local count: 5106238449]: if (_19 < 0) goto <bb 19>; [0.04%] else goto <bb 29>; [99.96%] <bb 29> [local count: 5104195957]: goto <bb 20>; [100.00%] <bb 19> [local count: 2042498]: _gfortran_stop_numeric (2, 0); in the middle, so two other loop exits. But, neither bb16, nor bb18 are executed every iteration, if they were, then because _19 is -1 in the first iteration would always stop 2 and not iterate further. We have: /* If the test is not executed every iteration, wrapping may make the test to pass again. TODO: the overflow case can be still used as unreliable estimate of upper bound. But we have no API to pass it down to number of iterations code and, at present, it will not use it anyway. */ if (!every_iteration && (!iv0->no_overflow || !iv1->no_overflow || code == NE_EXPR || code == EQ_EXPR)) return false; at the start, but that doesn't trigger here, because code is not equality comparison and no_overflow is set on both IVs. If there would be an overflow, then maybe it would be right to derive number of iterations from that. But the condition that returns true is that iv0->base code iv1->base is false, if that isn't done in every iteration, it means nothing for the number of iteration analysis. The following patch works for me: 2019-01-18 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/88044 * tree-ssa-loop-niter.c (number_of_iterations_cond): If condition is false in the first iteration, but !every_iteration, return false instead of true with niter->niter zero. --- gcc/tree-ssa-loop-niter.c.jj 2019-01-10 11:43:02.254577008 +0100 +++ gcc/tree-ssa-loop-niter.c 2019-01-18 19:51:00.245504728 +0100 @@ -1824,6 +1824,8 @@ number_of_iterations_cond (struct loop * tree tem = fold_binary (code, boolean_type_node, iv0->base, iv1->base); if (tem && integer_zerop (tem)) { + if (!every_iteration) + return false; niter->niter = build_int_cst (unsigned_type_for (type), 0); niter->max = 0; return true;