Hi! As mentioned in the PR, on the transfer_intrinsic_3.f90 testcase at -O3 on a few targets we have in number_of_iterations_cond: 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. Fixed thusly, bootstrapped/regtested on x86_64-linux, i686-linux, powerpc64{,le}-linux, ok for trunk? 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; Jakub