[PATCH] Fix transfer_intrinsic_3.f90 miscompilation on ppc*/s390* (PR tree-optimization/88044)
Richard Biener
rguenther@suse.de
Tue Jan 22 09:39:00 GMT 2019
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 <jakub@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 <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)
More information about the Gcc-patches
mailing list