On Fri, 18 Jan 2019, Jakub Jelinek wrote: > 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?
OK. Richard. > 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 > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)