public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix transfer_intrinsic_3.f90 miscompilation on ppc*/s390* (PR tree-optimization/88044)
@ 2019-01-18 22:52 Jakub Jelinek
  2019-01-22  9:39 ` Richard Biener
  0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2019-01-18 22:52 UTC (permalink / raw)
  To: Richard Biener, Jan Hubicka; +Cc: gcc-patches

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  <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

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Fix transfer_intrinsic_3.f90 miscompilation on ppc*/s390* (PR tree-optimization/88044)
  2019-01-18 22:52 [PATCH] Fix transfer_intrinsic_3.f90 miscompilation on ppc*/s390* (PR tree-optimization/88044) Jakub Jelinek
@ 2019-01-22  9:39 ` Richard Biener
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Biener @ 2019-01-22  9:39 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Jan Hubicka, gcc-patches

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)

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-01-22  9:39 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-18 22:52 [PATCH] Fix transfer_intrinsic_3.f90 miscompilation on ppc*/s390* (PR tree-optimization/88044) Jakub Jelinek
2019-01-22  9:39 ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).