[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