public inbox for fortran@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: Fortran loops
@ 2016-06-27 19:37 Dominique d'Humières
  2016-06-27 19:43 ` Adam Hirst
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Dominique d'Humières @ 2016-06-27 19:37 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: fortran, williamclodius, ahirst

IIRC this has already been discussed in the past (gfortran.dg/do_1.f90). 
The Fortran standard requires that the variable i is equal to array(2)+1 on the loop exit, which causes an overflow if array(2) is equal to huge(i). 
So the code is invalid when b(2) = huge(x), but I don’t see why the overflow of the exit value should lead to an infinite loop.
Dominique
> On Jun 27, 2016, at 6:56 PM, Jan Hubicka <hubicka@ucw.cz> wrote:
> 
> Hello,
> I have a Fortran question.  The following program loops infinitly when compiled
> with ifort -O0, while it does the expected number of iterations with gfortran.
> The issue is that we do produce quite ineffective code to deal with
> side cases like this.
> 
> is the program bellow valid and expected to terminate?  If so I guess we want
> to have it as a testcase.
> 
> Thanks,
> Honza
> 
> program test_program
> integer(4) :: b(2), a(22), x
> integer(8) :: suma
> 
> b(1) = huge(x)-10
> b(2) = huge(x)
> 
> call test2(b, suma)
> print *,suma
> 
> end program test_program
> function test2(array, s)
>  integer(4) :: i, block(9), array(2)
>  integer (8) :: s
>  s = 1
> 
>  do i = array(1), array(2)
>      s = s + 1
>  end do
> 
> end function test2
> 

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

* Re: Fortran loops
  2016-06-27 19:37 Fortran loops Dominique d'Humières
@ 2016-06-27 19:43 ` Adam Hirst
  2016-06-27 20:05 ` Dominique d'Humières
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 14+ messages in thread
From: Adam Hirst @ 2016-06-27 19:43 UTC (permalink / raw)
  To: fortran

I don't know how the compiler handles this exactly, but my "educated
guess" would be that it depends on whether the loop is unrolled and on
whether the incrementing of the loop index variable occurs before or
after the check at the "start" of each loop iteration.

If "at" (i.e. just before, while still inside) the end of the "last"
iteration the value is huge(x), and it then decides to add one (causing
it to overflow to a -ve number), and THEN compare to huge(x) to see
whether the loop is over, it ought then go on forever infinitely
repeating the entire span of the integer type.

But I'm not an "informed" person. :)

~ Adam

On 27/06/16 21:36, Dominique d'Humières wrote:
> IIRC this has already been discussed in the past (gfortran.dg/do_1.f90). 
> The Fortran standard requires that the variable i is equal to array(2)+1 on the loop exit, which causes an overflow if array(2) is equal to huge(i). 
> So the code is invalid when b(2) = huge(x), but I don’t see why the overflow of the exit value should lead to an infinite loop.
> Dominique
>> On Jun 27, 2016, at 6:56 PM, Jan Hubicka <hubicka@ucw.cz> wrote:
>>
>> Hello,
>> I have a Fortran question.  The following program loops infinitly when compiled
>> with ifort -O0, while it does the expected number of iterations with gfortran.
>> The issue is that we do produce quite ineffective code to deal with
>> side cases like this.
>>
>> is the program bellow valid and expected to terminate?  If so I guess we want
>> to have it as a testcase.
>>
>> Thanks,
>> Honza
>>
>> program test_program
>> integer(4) :: b(2), a(22), x
>> integer(8) :: suma
>>
>> b(1) = huge(x)-10
>> b(2) = huge(x)
>>
>> call test2(b, suma)
>> print *,suma
>>
>> end program test_program
>> function test2(array, s)
>>  integer(4) :: i, block(9), array(2)
>>  integer (8) :: s
>>  s = 1
>>
>>  do i = array(1), array(2)
>>      s = s + 1
>>  end do
>>
>> end function test2
>>
> 

-- 
Using GPG? Add my key, and respond to me with it enabled!
Also, feel free to verify my key with me online or in person!

Not using GPG? You should, it's easy!
https://www.enigmail.net/documentation/quickstart.php

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

* Re: Fortran loops
  2016-06-27 19:37 Fortran loops Dominique d'Humières
  2016-06-27 19:43 ` Adam Hirst
@ 2016-06-27 20:05 ` Dominique d'Humières
  2016-06-27 20:22 ` FX
  2016-06-28 12:10 ` Jan Hubicka
  3 siblings, 0 replies; 14+ messages in thread
From: Dominique d'Humières @ 2016-06-27 20:05 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: fortran, williamclodius, ahirst


> Le 27 juin 2016 à 21:36, Dominique d'Humières <dominiq@lps.ens.fr> a écrit :
> 
> IIRC this has already been discussed in the past (gfortran.dg/do_1.f90). 

pr54932!-(

Dominique


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

* Re: Fortran loops
  2016-06-27 19:37 Fortran loops Dominique d'Humières
  2016-06-27 19:43 ` Adam Hirst
  2016-06-27 20:05 ` Dominique d'Humières
@ 2016-06-27 20:22 ` FX
  2016-06-27 21:25   ` William Clodius
  2016-06-28 12:10 ` Jan Hubicka
  3 siblings, 1 reply; 14+ messages in thread
From: FX @ 2016-06-27 20:22 UTC (permalink / raw)
  To: Dominique d'Humières
  Cc: Jan Hubicka, fortran, williamclodius, ahirst

> The Fortran standard requires that the variable i is equal to array(2)+1 on the loop exit, which causes an overflow if array(2) is equal to huge(i). 
> So the code is invalid when b(2) = huge(x), but I don’t see why the overflow of the exit value should lead to an infinite loop.

In general, DO loops in Fortran are more messy than in C, because they are not defined in terms of a condition but instead the standard clearly calls for the calculation of an iteration count which is then decremented.

Dominique is right that the code is invalid, because on the last iteration of the DO execution cycle, the value of I is is incremented from HUGE(I) and thus overflowing. However, as a quality of implementation, I think it would be nice for this code which has clear meaning not to give rise to undefined behavior, because the value of I is not used.

Generally in the Fortran front-end we implement DO loops with an iteration count, as the standard specifies them. However, the case of integer DO loops with ±1 increments is handled as a special case in gfc_trans_simple_do() [trans-stmt.c], without an actual count.

FX

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

* Re: Fortran loops
  2016-06-27 20:22 ` FX
@ 2016-06-27 21:25   ` William Clodius
  0 siblings, 0 replies; 14+ messages in thread
From: William Clodius @ 2016-06-27 21:25 UTC (permalink / raw)
  To: fortran

I am slightly surprised you special case to avoid calculating the iteration count for increments of +/-1. The iteration count is easiest to determine for these two increments.

> On Jun 27, 2016, at 10:22 PM, FX <fxcoudert@gmail.com> wrote:
> 
>> The Fortran standard requires that the variable i is equal to array(2)+1 on the loop exit, which causes an overflow if array(2) is equal to huge(i). 
>> So the code is invalid when b(2) = huge(x), but I don’t see why the overflow of the exit value should lead to an infinite loop.
> 
> In general, DO loops in Fortran are more messy than in C, because they are not defined in terms of a condition but instead the standard clearly calls for the calculation of an iteration count which is then decremented.
> 
> Dominique is right that the code is invalid, because on the last iteration of the DO execution cycle, the value of I is is incremented from HUGE(I) and thus overflowing. However, as a quality of implementation, I think it would be nice for this code which has clear meaning not to give rise to undefined behavior, because the value of I is not used.
> 
> Generally in the Fortran front-end we implement DO loops with an iteration count, as the standard specifies them. However, the case of integer DO loops with ±1 increments is handled as a special case in gfc_trans_simple_do() [trans-stmt.c], without an actual count.
> 
> FX

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

* Re: Fortran loops
  2016-06-27 19:37 Fortran loops Dominique d'Humières
                   ` (2 preceding siblings ...)
  2016-06-27 20:22 ` FX
@ 2016-06-28 12:10 ` Jan Hubicka
  2016-06-28 13:50   ` Richard Biener
  3 siblings, 1 reply; 14+ messages in thread
From: Jan Hubicka @ 2016-06-28 12:10 UTC (permalink / raw)
  To: Dominique d'Humières
  Cc: Jan Hubicka, fortran, williamclodius, ahirst, rguenther, mliska

> IIRC this has already been discussed in the past (gfortran.dg/do_1.f90). 
> The Fortran standard requires that the variable i is equal to array(2)+1 on the loop exit, which causes an overflow if array(2) is equal to huge(i). 
> So the code is invalid when b(2) = huge(x), but I don’t see why the overflow of the exit value should lead to an infinite loop.

The reason why I ask (again as I just noticed - thanks for reminding :) is that
the C equivalent:

for(i=low;i<=high;i++)
  ... body ...

is a lot easier to compile, but it will loop infinitly when the upper bound
happens to be INT_MAX.  To avoid that Fortran FE expand the loop as:

if (low<high)
  {
    i=low;
    do {
      ... body ...
      if (i==high)
	break;
      i++
    }
    while (1)
  }

This results in at least one extra compare and usually also extra register needed.
If we could avoid this codegen based on fact that such loops are undefined, we would
get improvements in thight and deeply nested loops. I.e. in exchange2 benchmark.

Martin implemented the C-style codegen and it does improve code quality.
If the fact that we produce the complex loop code above is just QOI, perhaps
we can introduce a flag controlling this and turn into C-style loop expansion
by default when optimizing?
The do-3.f90 testcase tests some of those so it will need to be split into
valid loops and invalid loops.  

Honza

> Dominique
> > On Jun 27, 2016, at 6:56 PM, Jan Hubicka <hubicka@ucw.cz> wrote:
> > 
> > Hello,
> > I have a Fortran question.  The following program loops infinitly when compiled
> > with ifort -O0, while it does the expected number of iterations with gfortran.
> > The issue is that we do produce quite ineffective code to deal with
> > side cases like this.
> > 
> > is the program bellow valid and expected to terminate?  If so I guess we want
> > to have it as a testcase.
> > 
> > Thanks,
> > Honza
> > 
> > program test_program
> > integer(4) :: b(2), a(22), x
> > integer(8) :: suma
> > 
> > b(1) = huge(x)-10
> > b(2) = huge(x)
> > 
> > call test2(b, suma)
> > print *,suma
> > 
> > end program test_program
> > function test2(array, s)
> >  integer(4) :: i, block(9), array(2)
> >  integer (8) :: s
> >  s = 1
> > 
> >  do i = array(1), array(2)
> >      s = s + 1
> >  end do
> > 
> > end function test2
> > 

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

* Re: Fortran loops
  2016-06-28 12:10 ` Jan Hubicka
@ 2016-06-28 13:50   ` Richard Biener
  2016-06-28 13:56     ` Jan Hubicka
  0 siblings, 1 reply; 14+ messages in thread
From: Richard Biener @ 2016-06-28 13:50 UTC (permalink / raw)
  To: Jan Hubicka
  Cc: Dominique d'Humières, fortran, williamclodius, ahirst, mliska

On Tue, Jun 28, 2016 at 2:10 PM, Jan Hubicka <hubicka@ucw.cz> wrote:
>> IIRC this has already been discussed in the past (gfortran.dg/do_1.f90).
>> The Fortran standard requires that the variable i is equal to array(2)+1 on the loop exit, which causes an overflow if array(2) is equal to huge(i).
>> So the code is invalid when b(2) = huge(x), but I don’t see why the overflow of the exit value should lead to an infinite loop.
>
> The reason why I ask (again as I just noticed - thanks for reminding :) is that
> the C equivalent:
>
> for(i=low;i<=high;i++)
>   ... body ...
>
> is a lot easier to compile, but it will loop infinitly when the upper bound
> happens to be INT_MAX.  To avoid that Fortran FE expand the loop as:
>
> if (low<high)
>   {
>     i=low;
>     do {
>       ... body ...
>       if (i==high)
>         break;
>       i++
>     }
>     while (1)
>   }
>
> This results in at least one extra compare and usually also extra register needed.
> If we could avoid this codegen based on fact that such loops are undefined, we would
> get improvements in thight and deeply nested loops. I.e. in exchange2 benchmark.
>
> Martin implemented the C-style codegen and it does improve code quality.
> If the fact that we produce the complex loop code above is just QOI, perhaps
> we can introduce a flag controlling this and turn into C-style loop expansion
> by default when optimizing?
> The do-3.f90 testcase tests some of those so it will need to be split into
> valid loops and invalid loops.

I guess it might be GCC on its own removing the exit test based on
undefined-overflow
and computing an upper bound on the iteration.

So if the testcases are really invalid I suppose that at least with
-Ofast the Fortran
FE could avoid the extra check.  But IIRC the issue appeared on valid
loops as well.
(that said - I've been here before)

Richard.

> Honza
>
>> Dominique
>> > On Jun 27, 2016, at 6:56 PM, Jan Hubicka <hubicka@ucw.cz> wrote:
>> >
>> > Hello,
>> > I have a Fortran question.  The following program loops infinitly when compiled
>> > with ifort -O0, while it does the expected number of iterations with gfortran.
>> > The issue is that we do produce quite ineffective code to deal with
>> > side cases like this.
>> >
>> > is the program bellow valid and expected to terminate?  If so I guess we want
>> > to have it as a testcase.
>> >
>> > Thanks,
>> > Honza
>> >
>> > program test_program
>> > integer(4) :: b(2), a(22), x
>> > integer(8) :: suma
>> >
>> > b(1) = huge(x)-10
>> > b(2) = huge(x)
>> >
>> > call test2(b, suma)
>> > print *,suma
>> >
>> > end program test_program
>> > function test2(array, s)
>> >  integer(4) :: i, block(9), array(2)
>> >  integer (8) :: s
>> >  s = 1
>> >
>> >  do i = array(1), array(2)
>> >      s = s + 1
>> >  end do
>> >
>> > end function test2
>> >

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

* Re: Fortran loops
  2016-06-28 13:50   ` Richard Biener
@ 2016-06-28 13:56     ` Jan Hubicka
  2016-06-30 11:17       ` [PATCH, RFC] Introduce -ffast-do-loop flag Martin Liška
  0 siblings, 1 reply; 14+ messages in thread
From: Jan Hubicka @ 2016-06-28 13:56 UTC (permalink / raw)
  To: Richard Biener
  Cc: Jan Hubicka, Dominique d'Humières, fortran,
	williamclodius, ahirst, mliska

> > Martin implemented the C-style codegen and it does improve code quality.
> > If the fact that we produce the complex loop code above is just QOI, perhaps
> > we can introduce a flag controlling this and turn into C-style loop expansion
> > by default when optimizing?
> > The do-3.f90 testcase tests some of those so it will need to be split into
> > valid loops and invalid loops.
> 
> I guess it might be GCC on its own removing the exit test based on
> undefined-overflow
> and computing an upper bound on the iteration.

It is explicitly testing loops that are unefined according to this discussion
define TEST_LOOP(var,from,to,step,total,test,final) \                          
  TEST_LOOP(i1, -huge(i1)-1_1, huge(i1), 1_1, int(huge(i1))*2+2, test_i1, huge(i1)+1_1)
this is loop from INT_MIN to INT_MAX which can't be implemented in c-style manner without
a wider type
> 
> So if the testcases are really invalid I suppose that at least with
> -Ofast the Fortran
> FE could avoid the extra check.  But IIRC the issue appeared on valid
> loops as well.

I don't know of any other testcase than one above.  I guess we could implement flag,
default it for -Ofast and see what is the impact and consequently discuss O2/O3.
Any suggestions for flag name? -ffast-do-loops?

> (that said - I've been here before)

Honza
> 
> Richard.
> 
> > Honza
> >
> >> Dominique
> >> > On Jun 27, 2016, at 6:56 PM, Jan Hubicka <hubicka@ucw.cz> wrote:
> >> >
> >> > Hello,
> >> > I have a Fortran question.  The following program loops infinitly when compiled
> >> > with ifort -O0, while it does the expected number of iterations with gfortran.
> >> > The issue is that we do produce quite ineffective code to deal with
> >> > side cases like this.
> >> >
> >> > is the program bellow valid and expected to terminate?  If so I guess we want
> >> > to have it as a testcase.
> >> >
> >> > Thanks,
> >> > Honza
> >> >
> >> > program test_program
> >> > integer(4) :: b(2), a(22), x
> >> > integer(8) :: suma
> >> >
> >> > b(1) = huge(x)-10
> >> > b(2) = huge(x)
> >> >
> >> > call test2(b, suma)
> >> > print *,suma
> >> >
> >> > end program test_program
> >> > function test2(array, s)
> >> >  integer(4) :: i, block(9), array(2)
> >> >  integer (8) :: s
> >> >  s = 1
> >> >
> >> >  do i = array(1), array(2)
> >> >      s = s + 1
> >> >  end do
> >> >
> >> > end function test2
> >> >

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

* [PATCH, RFC] Introduce -ffast-do-loop flag.
  2016-06-28 13:56     ` Jan Hubicka
@ 2016-06-30 11:17       ` Martin Liška
  2016-06-30 11:43         ` Richard Biener
  2016-06-30 19:10         ` FX
  0 siblings, 2 replies; 14+ messages in thread
From: Martin Liška @ 2016-06-30 11:17 UTC (permalink / raw)
  To: Jan Hubicka, Richard Biener
  Cc: Dominique d'Humières, fortran, williamclodius, ahirst

[-- Attachment #1: Type: text/plain, Size: 1456 bytes --]

Hello.

This is patch attempt to target the discussion about sub-optimal generation
of DO loops with abs(step) == 1.

Originally generated code:

    D.3428 = (*array)[0];
    D.3429 = (*array)[1];
    i = D.3428;
    if (i <= D.3429)
      {
        while (1)
          {
            {
              logical(kind=4) D.3432;

              (*block)[(integer(kind=8)) i + -1] = (*block)[(integer(kind=8)) i + -1] + 10;
              L.1:;
              D.3432 = i == D.3429;
              i = i + 1;
              if (D.3432) goto L.2;
            }
          }
      }
    L.2:;

Suggested:

    D.3428 = (*array)[0];
    D.3429 = (*array)[1];
    i = D.3428;
    while (1)
      {
        {
          logical(kind=4) D.3432;

          D.3432 = i > D.3429;
          if (D.3432) goto L.2;
          (*block)[(integer(kind=8)) i + -1] = (*block)[(integer(kind=8)) i + -1] + 10;
          L.1:;
          i = i + 1;
        }
      }
    L.2:;

I would like to enable the behavior be default, patch does that starting from -O2.

Apart from that, I've also added a new warning (candidate name: Wundefined-do-loop), which warns about cases that
would lead to an infinite loop (because i > HUGE(i) == false):

Warning: DO loop at (1) is infinite as it iterates to MIN_INT [-Wundefined-do-loop]
/tmp/loop2.f90:15:19:

   do i = 0, huge(i)
                   1

Patch hasn't been properly tested, I've just tried to run all do_*.[fF]90 tests.

Thoughts?
Martin


[-- Attachment #2: 0001-Introduce-ffast-do-loop-flag.patch --]
[-- Type: text/x-patch, Size: 12557 bytes --]

From 061caf9ab5ba1084fdf980ccd99dd70f42712da3 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Tue, 28 Jun 2016 15:11:13 +0200
Subject: [PATCH] Introduce -ffast-do-loop flag.

gcc/fortran/ChangeLog:

2016-06-30  Martin Liska  <mliska@suse.cz>

	* lang.opt (Wundefined-do-loop): New option.
	(ffast-do-loop): Likewise.
	* resolve.c (gfc_resolve_iterator): Warn for Wundefined-do-loop.
	* trans-stmt.c (gfc_trans_simple_do_fast): New function.
	(gfc_trans_simple_do): Fix coding style.
	(gfc_trans_do): Call either gfc_trans_simple_do or
	gfc_trans_simple_do_fast.

gcc/testsuite/ChangeLog:

2016-06-30  Martin Liska  <mliska@suse.cz>

	* gfortran.dg/do_1.f90: Remove corner cases.
	* gfortran.dg/do_3.F90: Likewise.
	* gfortran.dg/do_corner.f90: New test.
	* gfortran.dg/do_corner_warn.f90: New test.

gcc/ChangeLog:

2016-06-30  Martin Liska  <mliska@suse.cz>

	* opts.c: Add OPT_ffast_do_loop to O2+.
---
 gcc/fortran/lang.opt                         |   8 ++
 gcc/fortran/resolve.c                        |  24 +++++
 gcc/fortran/trans-stmt.c                     | 148 ++++++++++++++++++++++++++-
 gcc/opts.c                                   |   1 +
 gcc/testsuite/gfortran.dg/do_1.f90           |   6 --
 gcc/testsuite/gfortran.dg/do_3.F90           |   2 -
 gcc/testsuite/gfortran.dg/do_corner.f90      |  24 +++++
 gcc/testsuite/gfortran.dg/do_corner_warn.f90 |  22 ++++
 8 files changed, 224 insertions(+), 11 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/do_corner.f90
 create mode 100644 gcc/testsuite/gfortran.dg/do_corner_warn.f90

diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
index bdf5fa5..57cdd15 100644
--- a/gcc/fortran/lang.opt
+++ b/gcc/fortran/lang.opt
@@ -309,6 +309,10 @@ Wtabs
 Fortran Warning Var(warn_tabs) LangEnabledBy(Fortran,Wall || Wpedantic)
 Permit nonconforming uses of the tab character.
 
+Wundefined-do-loop
+Fortran Warning Var(warn_undefined_do_loop) LangEnabledBy(Fortran,Wall)
+Warn about an invalid DO loops.
+
 Wunderflow
 Fortran Warning Var(warn_underflow) Init(1)
 Warn about underflow of numerical constant expressions.
@@ -464,6 +468,10 @@ ff2c
 Fortran Var(flag_f2c)
 Use f2c calling convention.
 
+ffast-do-loop
+Fortran Var(flag_fast_do_loop)
+Use C style code generation of loops.
+
 ffixed-form
 Fortran RejectNegative
 Assume that the source file is fixed form.
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 4378313..85b2218 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -6546,6 +6546,30 @@ gfc_resolve_iterator (gfc_iterator *iter, bool real_ok, bool own_scope)
 		     &iter->step->where);
     }
 
+  if (flag_fast_do_loop
+      && iter->end->expr_type == EXPR_CONSTANT
+      && iter->end->ts.type == BT_INTEGER
+      && iter->step->expr_type == EXPR_CONSTANT
+      && iter->step->ts.type == BT_INTEGER
+      && (mpz_cmp_si (iter->step->value.integer, -1L) == 0
+	  || mpz_cmp_si (iter->step->value.integer, 1L) == 0))
+    {
+      bool is_step_positive = mpz_cmp_ui (iter->step->value.integer, 1) == 0;
+      int k = gfc_validate_kind (BT_INTEGER, iter->end->ts.kind, false);
+
+      if (is_step_positive
+	  && mpz_cmp (iter->end->value.integer, gfc_integer_kinds[k].huge) == 0)
+	gfc_warning (OPT_Wundefined_do_loop,
+		     "DO loop at %L is infinite as it iterates to MAX_INT",
+		     &iter->step->where);
+      else if (!is_step_positive
+	       && mpz_cmp (iter->end->value.integer,
+			   gfc_integer_kinds[k].min_int) == 0)
+	gfc_warning (OPT_Wundefined_do_loop,
+		     "DO loop at %L is infinite as it iterates to MIN_INT",
+		     &iter->step->where);
+    }
+
   return true;
 }
 
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index 84bf749..b069af3 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -1808,6 +1808,142 @@ gfc_trans_block_construct (gfc_code* code)
   return gfc_finish_wrapped_block (&block);
 }
 
+/* Translate the simple DO construct in a C-style manner.
+   This is where the loop variable has integer type and step +-1.
+   Following code will generate infinite loop in case where TO is INT_MAX
+   (for +1 step) or INT_MIN (for -1 step)
+
+   We translate a do loop from:
+
+   DO dovar = from, to, step
+      body
+   END DO
+
+   to:
+
+   [Evaluate loop bounds and step]
+    dovar = from;
+    for (;;)
+      {
+	if (dovar > to)
+	  goto end_label;
+	body;
+	cycle_label:
+	dovar += step;
+      }
+    end_label:
+
+   This helps the optimizers by avoiding the extra pre-header condition and
+   we save a register as we just compare the updated IV (not a value in
+   previous step).  */
+
+static tree
+gfc_trans_simple_do_fast (gfc_code * code, stmtblock_t *pblock, tree dovar,
+			  tree from, tree to, tree step, tree exit_cond)
+{
+  stmtblock_t body;
+  tree type;
+  tree cond;
+  tree tmp;
+  tree saved_dovar = NULL;
+  tree cycle_label;
+  tree exit_label;
+  location_t loc;
+  type = TREE_TYPE (dovar);
+  bool is_step_positive = tree_int_cst_sgn (step) > 0;
+
+  loc = code->ext.iterator->start->where.lb->location;
+
+  /* Initialize the DO variable: dovar = from.  */
+  gfc_add_modify_loc (loc, pblock, dovar,
+		      fold_convert (TREE_TYPE (dovar), from));
+
+  /* Save value for do-tinkering checking.  */
+  if (gfc_option.rtcheck & GFC_RTCHECK_DO)
+    {
+      saved_dovar = gfc_create_var (type, ".saved_dovar");
+      gfc_add_modify_loc (loc, pblock, saved_dovar, dovar);
+    }
+
+  /* Cycle and exit statements are implemented with gotos.  */
+  cycle_label = gfc_build_label_decl (NULL_TREE);
+  exit_label = gfc_build_label_decl (NULL_TREE);
+
+  /* Put the labels where they can be found later.  See gfc_trans_do().  */
+  code->cycle_label = cycle_label;
+  code->exit_label = exit_label;
+
+  /* Loop body.  */
+  gfc_start_block (&body);
+
+  /* Exit the loop if there is an I/O result condition or error.  */
+  if (exit_cond)
+    {
+      tmp = build1_v (GOTO_EXPR, exit_label);
+      tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
+			     exit_cond, tmp,
+			     build_empty_stmt (loc));
+      gfc_add_expr_to_block (&body, tmp);
+    }
+
+  /* Evaluate the loop condition.  */
+  if (is_step_positive)
+    cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node, dovar,
+			    fold_convert (type, to));
+  else
+    cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node, dovar,
+			    fold_convert (type, to));
+
+  cond = gfc_evaluate_now_loc (loc, cond, &body);
+
+  /* The loop exit.  */
+  tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
+  TREE_USED (exit_label) = 1;
+  tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
+			 cond, tmp, build_empty_stmt (loc));
+  gfc_add_expr_to_block (&body, tmp);
+
+  /* Main loop body.  */
+  tmp = gfc_trans_code_cond (code->block->next, exit_cond);
+  gfc_add_expr_to_block (&body, tmp);
+
+  /* Label for cycle statements (if needed).  */
+  if (TREE_USED (cycle_label))
+    {
+      tmp = build1_v (LABEL_EXPR, cycle_label);
+      gfc_add_expr_to_block (&body, tmp);
+    }
+
+  /* Check whether someone has modified the loop variable.  */
+  if (gfc_option.rtcheck & GFC_RTCHECK_DO)
+    {
+      tmp = fold_build2_loc (loc, NE_EXPR, boolean_type_node,
+			     dovar, saved_dovar);
+      gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
+			       "Loop variable has been modified");
+    }
+
+  /* Increment the loop variable.  */
+  tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
+  gfc_add_modify_loc (loc, &body, dovar, tmp);
+
+  if (gfc_option.rtcheck & GFC_RTCHECK_DO)
+    gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
+
+  /* Finish the loop body.  */
+  tmp = gfc_finish_block (&body);
+  tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
+
+  gfc_add_expr_to_block (pblock, tmp);
+
+  /* Add the exit label.  */
+  tmp = build1_v (LABEL_EXPR, exit_label);
+  gfc_add_expr_to_block (pblock, tmp);
+
+  return gfc_finish_block (pblock);
+}
+
+
 
 /* Translate the simple DO construct.  This is where the loop variable has
    integer type and step +-1.  We can't use this in the general case
@@ -1851,14 +1987,13 @@ gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
   tree cycle_label;
   tree exit_label;
   location_t loc;
-
   type = TREE_TYPE (dovar);
 
   loc = code->ext.iterator->start->where.lb->location;
 
   /* Initialize the DO variable: dovar = from.  */
   gfc_add_modify_loc (loc, pblock, dovar,
-		      fold_convert (TREE_TYPE(dovar), from));
+		      fold_convert (TREE_TYPE (dovar), from));
 
   /* Save value for do-tinkering checking.  */
   if (gfc_option.rtcheck & GFC_RTCHECK_DO)
@@ -2044,7 +2179,14 @@ gfc_trans_do (gfc_code * code, tree exit_cond)
   if (TREE_CODE (type) == INTEGER_TYPE
       && (integer_onep (step)
 	|| tree_int_cst_equal (step, integer_minus_one_node)))
-    return gfc_trans_simple_do (code, &block, dovar, from, to, step, exit_cond);
+    {
+      if (flag_fast_do_loop)
+	return gfc_trans_simple_do_fast (code, &block, dovar, from, to, step,
+					 exit_cond);
+      else
+	return gfc_trans_simple_do (code, &block, dovar, from, to, step,
+				    exit_cond);
+    }
 
 
   if (TREE_CODE (type) == INTEGER_TYPE)
diff --git a/gcc/opts.c b/gcc/opts.c
index 7406210..ef77421 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -519,6 +519,7 @@ static const struct default_options default_options_table[] =
     { OPT_LEVELS_2_PLUS, OPT_fisolate_erroneous_paths_dereference, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_fipa_ra, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_flra_remat, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_ffast_do_loop, NULL, 1 },
 
     /* -O3 optimizations.  */
     { OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribute_patterns, NULL, 1 },
diff --git a/gcc/testsuite/gfortran.dg/do_1.f90 b/gcc/testsuite/gfortran.dg/do_1.f90
index b041279..b1db8c6 100644
--- a/gcc/testsuite/gfortran.dg/do_1.f90
+++ b/gcc/testsuite/gfortran.dg/do_1.f90
@@ -5,12 +5,6 @@ program do_1
   implicit none
   integer i, j
 
-  ! limit=HUGE(i), step 1
-  j = 0
-  do i = HUGE(i) - 10, HUGE(i), 1
-    j = j + 1
-  end do
-  if (j .ne. 11) call abort
   ! limit=HUGE(i), step > 1
   j = 0
   do i = HUGE(i) - 10, HUGE(i), 2
diff --git a/gcc/testsuite/gfortran.dg/do_3.F90 b/gcc/testsuite/gfortran.dg/do_3.F90
index eb4751d..0f2c315 100644
--- a/gcc/testsuite/gfortran.dg/do_3.F90
+++ b/gcc/testsuite/gfortran.dg/do_3.F90
@@ -48,11 +48,9 @@ program test
   TEST_LOOP(i, 17, 0, -4, 5, test_i, -3)
   TEST_LOOP(i, 17, 0, -5, 4, test_i, -3)
 
-  TEST_LOOP(i1, -huge(i1)-1_1, huge(i1), 1_1, int(huge(i1))*2+2, test_i1, huge(i1)+1_1)
   TEST_LOOP(i1, -huge(i1)-1_1, huge(i1), 2_1, int(huge(i1))+1, test_i1, huge(i1)+1_1)
   TEST_LOOP(i1, -huge(i1)-1_1, huge(i1), huge(i1), 3, test_i1, 2_1*huge(i1)-1_1)
 
-  TEST_LOOP(i1, huge(i1), -huge(i1)-1_1, -1_1, int(huge(i1))*2+2, test_i1, -huge(i1)-2_1)
   TEST_LOOP(i1, huge(i1), -huge(i1)-1_1, -2_1, int(huge(i1))+1, test_i1, -huge(i1)-2_1)
   TEST_LOOP(i1, huge(i1), -huge(i1)-1_1, -huge(i1), 3, test_i1, -2_1*huge(i1))
   TEST_LOOP(i1, huge(i1), -huge(i1)-1_1, -huge(i1)-1_1, 2, test_i1, -huge(i1)-2_1)
diff --git a/gcc/testsuite/gfortran.dg/do_corner.f90 b/gcc/testsuite/gfortran.dg/do_corner.f90
new file mode 100644
index 0000000..088326d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/do_corner.f90
@@ -0,0 +1,24 @@
+! { dg-do run }
+! { dg-options "-fno-fast-do-loop" }
+! Program to check corner cases for DO statements.
+
+
+program do_1
+  implicit none
+  integer i, j
+
+  ! limit=HUGE(i), step 1
+  j = 0
+  do i = HUGE(i) - 10, HUGE(i), 1
+    j = j + 1
+  end do
+  if (j .ne. 11) call abort
+
+  ! limit=-HUGE(i)-1, step -1
+  j = 0
+  do i = -HUGE(i) + 10 - 1, -HUGE(i) - 1, -1
+    j = j + 1
+  end do
+  if (j .ne. 11) call abort
+
+end program
diff --git a/gcc/testsuite/gfortran.dg/do_corner_warn.f90 b/gcc/testsuite/gfortran.dg/do_corner_warn.f90
new file mode 100644
index 0000000..decaf9a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/do_corner_warn.f90
@@ -0,0 +1,22 @@
+! { dg-options "-Wundefined-do-loop -ffast-do-loop" }
+! Program to check corner cases for DO statements.
+
+program do_1
+  implicit none
+  integer i, j
+
+  ! limit=HUGE(i), step 1
+  j = 0
+  do i = HUGE(i) - 10, HUGE(i), 1 ! { dg-warning "is infinite as it iterates to MAX_INT" }
+    j = j + 1
+  end do
+  if (j .ne. 11) call abort
+
+  ! limit=-HUGE(i)-1, step -1
+  j = 0
+  do i = -HUGE(i) + 10 - 1, -HUGE(i) - 1, -1 ! { dg-warning "is infinite as it iterates to MIN_INT" }
+    j = j + 1
+  end do
+  if (j .ne. 11) call abort
+
+end program
-- 
2.8.4


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

* Re: [PATCH, RFC] Introduce -ffast-do-loop flag.
  2016-06-30 11:17       ` [PATCH, RFC] Introduce -ffast-do-loop flag Martin Liška
@ 2016-06-30 11:43         ` Richard Biener
  2016-06-30 15:10           ` Martin Liška
  2016-06-30 19:10         ` FX
  1 sibling, 1 reply; 14+ messages in thread
From: Richard Biener @ 2016-06-30 11:43 UTC (permalink / raw)
  To: Martin Liška
  Cc: Jan Hubicka, Dominique d'Humières, fortran,
	williamclodius, ahirst

On Thu, Jun 30, 2016 at 1:16 PM, Martin Liška <mliska@suse.cz> wrote:
> Hello.
>
> This is patch attempt to target the discussion about sub-optimal generation
> of DO loops with abs(step) == 1.
>
> Originally generated code:
>
>     D.3428 = (*array)[0];
>     D.3429 = (*array)[1];
>     i = D.3428;
>     if (i <= D.3429)
>       {
>         while (1)
>           {
>             {
>               logical(kind=4) D.3432;
>
>               (*block)[(integer(kind=8)) i + -1] = (*block)[(integer(kind=8)) i + -1] + 10;
>               L.1:;
>               D.3432 = i == D.3429;
>               i = i + 1;
>               if (D.3432) goto L.2;
>             }
>           }
>       }
>     L.2:;
>
> Suggested:
>
>     D.3428 = (*array)[0];
>     D.3429 = (*array)[1];
>     i = D.3428;
>     while (1)
>       {
>         {
>           logical(kind=4) D.3432;
>
>           D.3432 = i > D.3429;
>           if (D.3432) goto L.2;
>           (*block)[(integer(kind=8)) i + -1] = (*block)[(integer(kind=8)) i + -1] + 10;
>           L.1:;
>           i = i + 1;
>         }
>       }
>     L.2:;
>
> I would like to enable the behavior be default, patch does that starting from -O2.
>
> Apart from that, I've also added a new warning (candidate name: Wundefined-do-loop), which warns about cases that
> would lead to an infinite loop (because i > HUGE(i) == false):
>
> Warning: DO loop at (1) is infinite as it iterates to MIN_INT [-Wundefined-do-loop]
> /tmp/loop2.f90:15:19:
>
>    do i = 0, huge(i)
>                    1
>
> Patch hasn't been properly tested, I've just tried to run all do_*.[fF]90 tests.
>
> Thoughts?

Without looking at the patch I think if there is some -fcheck option
for the boundary case
and the behavior is really undefined for end == HUGE() then having the
default independent
of optimization level would be nice.

Richard.

> Martin
>

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

* Re: [PATCH, RFC] Introduce -ffast-do-loop flag.
  2016-06-30 11:43         ` Richard Biener
@ 2016-06-30 15:10           ` Martin Liška
  0 siblings, 0 replies; 14+ messages in thread
From: Martin Liška @ 2016-06-30 15:10 UTC (permalink / raw)
  To: fortran

[-- Attachment #1: Type: text/plain, Size: 994 bytes --]

On 06/30/2016 01:43 PM, Richard Biener wrote:
> Without looking at the patch I think if there is some -fcheck option
> for the boundary case
> and the behavior is really undefined for end == HUGE() then having the
> default independent
> of optimization level would be nice.
> 
> Richard.

Year, the FE has -fcheck=do that identifies whether a loop variable is changed or not.

I did a small follow-up patch that catches following loops:

! { dg-do run }
! { dg-options "-fcheck=do" }
! { dg-shouldfail "DO check" }
!
! Run-time check for infinite loop with -ffast-do-loop
program test
  implicit none
  integer(1) :: i
  do i = HUGE(i)-10, HUGE(i)
    print *, i
  end do
end program test
! { dg-output "Fortran runtime error: Loop iterates infinitely" }

with run-time error:
...

At line 9 of file /home/marxin/Programming/gcc3/gcc/testsuite/gfortran.dg/do_check_12.f90
Fortran runtime error: Loop iterates infinitely

Thus we can enable the option by default, what do you think?

Martin




[-- Attachment #2: 0002-Catch-infinite-loops-w-fcheck-do-and-ffast-do-loop.patch --]
[-- Type: text/x-patch, Size: 2925 bytes --]

From a215f7f07e8d5637c2577f4bb92e03906d1d5dab Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Thu, 30 Jun 2016 16:53:51 +0200
Subject: [PATCH 2/2] Catch infinite loops w/ -fcheck-do and -ffast-do-loop

gcc/fortran/ChangeLog:

2016-06-30  Martin Liska  <mliska@suse.cz>

	* trans-stmt.c (gfc_trans_simple_do_fast):
	Emit a run-time check.

gcc/testsuite/ChangeLog:

2016-06-30  Martin Liska  <mliska@suse.cz>

	* gfortran.dg/do_check_11.f90: New test.
	* gfortran.dg/do_check_12.f90: New test.
---
 gcc/fortran/trans-stmt.c                  | 13 +++++++++++++
 gcc/testsuite/gfortran.dg/do_check_11.f90 | 13 +++++++++++++
 gcc/testsuite/gfortran.dg/do_check_12.f90 | 13 +++++++++++++
 3 files changed, 39 insertions(+)
 create mode 100644 gcc/testsuite/gfortran.dg/do_check_11.f90
 create mode 100644 gcc/testsuite/gfortran.dg/do_check_12.f90

diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index b069af3..3b43458 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -1903,6 +1903,19 @@ gfc_trans_simple_do_fast (gfc_code * code, stmtblock_t *pblock, tree dovar,
 			 cond, tmp, build_empty_stmt (loc));
   gfc_add_expr_to_block (&body, tmp);
 
+  /* Check whether the induction variable is equal to INT_MAX
+     (respectively to INT_MIN).  */
+  if (gfc_option.rtcheck & GFC_RTCHECK_DO)
+    {
+      tree boundary = is_step_positive ? TYPE_MAX_VALUE (type)
+	: TYPE_MIN_VALUE (type);
+
+      tmp = fold_build2_loc (loc, EQ_EXPR, boolean_type_node,
+			     dovar, boundary);
+      gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
+			       "Loop iterates infinitely");
+    }
+
   /* Main loop body.  */
   tmp = gfc_trans_code_cond (code->block->next, exit_cond);
   gfc_add_expr_to_block (&body, tmp);
diff --git a/gcc/testsuite/gfortran.dg/do_check_11.f90 b/gcc/testsuite/gfortran.dg/do_check_11.f90
new file mode 100644
index 0000000..b86c384
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/do_check_11.f90
@@ -0,0 +1,13 @@
+! { dg-do run }
+! { dg-options "-fcheck=do -ffast-do-loop" }
+! { dg-shouldfail "DO check" }
+!
+! Run-time check for infinite loop with -ffast-do-loop
+program test
+  implicit none
+  integer(1) :: i
+  do i = HUGE(i)-10, HUGE(i)
+    print *, i
+  end do
+end program test
+! { dg-output "Fortran runtime error: Loop iterates infinitely" }
diff --git a/gcc/testsuite/gfortran.dg/do_check_12.f90 b/gcc/testsuite/gfortran.dg/do_check_12.f90
new file mode 100644
index 0000000..5a68aee
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/do_check_12.f90
@@ -0,0 +1,13 @@
+! { dg-do run }
+! { dg-options "-fcheck=do -ffast-do-loop" }
+! { dg-shouldfail "DO check" }
+!
+! Run-time check for infinite loop with -ffast-do-loop
+program test
+  implicit none
+  integer(1) :: i
+  do i = -HUGE(i)+10, -HUGE(i)-1, -1
+    print *, i
+  end do
+end program test
+! { dg-output "Fortran runtime error: Loop iterates infinitely" }
-- 
2.8.4


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

* Re: [PATCH, RFC] Introduce -ffast-do-loop flag.
  2016-06-30 11:17       ` [PATCH, RFC] Introduce -ffast-do-loop flag Martin Liška
  2016-06-30 11:43         ` Richard Biener
@ 2016-06-30 19:10         ` FX
  2016-06-30 20:23           ` Mikael Morin
  1 sibling, 1 reply; 14+ messages in thread
From: FX @ 2016-06-30 19:10 UTC (permalink / raw)
  To: Martin Liška
  Cc: Jan Hubicka, Richard Biener, Dominique d'Humières,
	fortran, williamclodius, ahirst

Here are my thoughts on the general approach and the patch:

  1. It seems there is unanimous agreement (both here, in previous PRs and on comp.lang.fortran) that loops that reach HUGE(i) are invalid code. If one of the Fortran maintainers is against it, now is the time to speak :)

  2. If so, do we really need yet another option? I don’t disagree with it, but others might :)  Anyone in favor of simply using the faster loops all the time?

  2b. Another warning? I would simply make it -W or -Wall.

  3. The warning is nice, but the text isn’t. First, because MAX_INT and MIN_INT will mean nothing to a Fortran coder. Can we use overflow/underflow instead? And second, because there is no reason for the loop to be infinite. Let’s just say it is invalid.

  4. Finally: profile, don’t speculate. Does this really make code generation easier? (and running code faster?)


Thanks for the patch, let’s see how others feel.

FX

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

* Re: [PATCH, RFC] Introduce -ffast-do-loop flag.
  2016-06-30 19:10         ` FX
@ 2016-06-30 20:23           ` Mikael Morin
  2016-07-01 12:30             ` Martin Liška
  0 siblings, 1 reply; 14+ messages in thread
From: Mikael Morin @ 2016-06-30 20:23 UTC (permalink / raw)
  To: FX, Martin Liška
  Cc: Jan Hubicka, Richard Biener, Dominique d'Humières,
	fortran, williamclodius, ahirst

Le 30/06/2016 21:09, FX a écrit :
> Here are my thoughts on the general approach and the patch:
>
>    1. It seems there is unanimous agreement (both here, in previous PRs and on comp.lang.fortran) that loops that reach HUGE(i) are invalid code. If one of the Fortran maintainers is against it, now is the time to speak :)

Well, in the case the value of the loop variable is not used after the 
loop, I would rather support it if possible and not too costly.
In that case the overflow is completely hidden, and it is possible to 
produce code behaving as expected without overflowing.

>
>    2. If so, do we really need yet another option? I don’t disagree with it, but others might :)  Anyone in favor of simply using the faster loops all the time?

I'm on the same page here. No option please. Just let the compiler do 
its best.

>
>    2b. Another warning? I would simply make it -W or -Wall.

I'm in favor of the warning flag. It makes it possible to enable/disable 
individually.

>
>    3. The warning is nice, but the text isn’t. First, because MAX_INT and MIN_INT will mean nothing to a Fortran coder. Can we use overflow/underflow instead? And second, because there is no reason for the loop to be infinite. Let’s just say it is invalid.
>
>    4. Finally: profile, don’t speculate. Does this really make code generation easier? (and running code faster?)

Agreed on both.

Mikael


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

* Re: [PATCH, RFC] Introduce -ffast-do-loop flag.
  2016-06-30 20:23           ` Mikael Morin
@ 2016-07-01 12:30             ` Martin Liška
  0 siblings, 0 replies; 14+ messages in thread
From: Martin Liška @ 2016-07-01 12:30 UTC (permalink / raw)
  To: Mikael Morin, FX
  Cc: Jan Hubicka, Richard Biener, Dominique d'Humières,
	fortran, williamclodius, ahirst

[-- Attachment #1: Type: text/plain, Size: 2749 bytes --]

On 06/30/2016 10:23 PM, Mikael Morin wrote:
> Le 30/06/2016 21:09, FX a écrit :
>> Here are my thoughts on the general approach and the patch:
>>
>>    1. It seems there is unanimous agreement (both here, in previous PRs and on comp.lang.fortran) that loops that reach HUGE(i) are invalid code. If one of the Fortran maintainers is against it, now is the time to speak :)
> 
> Well, in the case the value of the loop variable is not used after the loop, I would rather support it if possible and not too costly.
> In that case the overflow is completely hidden, and it is possible to produce code behaving as expected without overflowing.

Hello.

I agree with the approach that we should not introduce a new flag and rather convert current code emission to generate a better GENERIC code.

> 
>>
>>    2. If so, do we really need yet another option? I don’t disagree with it, but others might :)  Anyone in favor of simply using the faster loops all the time?
> 
> I'm on the same page here. No option please. Just let the compiler do its best.
> 
>>
>>    2b. Another warning? I would simply make it -W or -Wall.
> 
> I'm in favor of the warning flag. It makes it possible to enable/disable individually.

Agree with you that having a warning option would be beneficial.

> 
>>
>>    3. The warning is nice, but the text isn’t. First, because MAX_INT and MIN_INT will mean nothing to a Fortran coder. Can we use overflow/underflow instead? And second, because there is no reason for the loop to be infinite. Let’s just say it is invalid.

Sure, I've tried to change the warning to be more precise.

I'm attaching a second version:

467d46d Add PRED_FORTRAN_LOOP_PREHEADER to DO loops with step bigger than +-1.

1) I converted predict-[12].f90 tests to use a different step than 1
2) I noticed that a generic DO loop code emission misses expect PRED_FORTRAN_LOOP_PREHEADER, thus I added that.

221061a Optimize fortran loops with +-1 step.

1) -ffast-do-loops option is removed.
2) We generate just the c-style loop.
3) Warning messages are changes to: 'DO loop at %L is undefined as it overflows' and 'DO loop at %L is undefined as it underflows'
4) I removed couple of tests that hit the undefined behavior.
5) A few tests are amended as GENERIC code is a bit different.


>>
>>    4. Finally: profile, don’t speculate. Does this really make code generation easier? (and running code faster?)

I see a noticeable speed-up for exchange_2 benchmark which is going to be part of SPEC CPUv6. With the patch applied,
it runs by 6% faster.

Thank you for your feedback, I'm triggering proper testing and if there aren't any big problem, I'll send it to gcc-patches mailing list.

Martin

> 
> Agreed on both.
> 
> Mikael
> 
> 


[-- Attachment #2: 0002-Optimize-fortran-loops-with-1-step.patch --]
[-- Type: text/x-patch, Size: 14156 bytes --]

From 221061a76024a0014c26bd5c82069f4167e79468 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Tue, 28 Jun 2016 15:11:13 +0200
Subject: [PATCH 2/2] Optimize fortran loops with +-1 step.

gcc/testsuite/ChangeLog:

2016-07-01  Martin Liska  <mliska@suse.cz>

	* gfortran.dg/do_1.f90: Remove a corner case that triggers
	an undefined behavior.
	* gfortran.dg/do_3.F90: Likewise.
	* gfortran.dg/do_check_11.f90: New test.
	* gfortran.dg/do_check_12.f90: New test.
	* gfortran.dg/do_corner_warn.f90: New test.

gcc/fortran/ChangeLog:

2016-07-01  Martin Liska  <mliska@suse.cz>

	* lang.opt (Wundefined-do-loop): New option.
        * resolve.c (gfc_resolve_iterator): Warn for Wundefined-do-loop.
	(gfc_trans_simple_do): Generate a c-style loop.
	(gfc_trans_do): Fix GNU coding style.
---
 gcc/fortran/lang.opt                         |   4 +
 gcc/fortran/resolve.c                        |  23 ++++++
 gcc/fortran/trans-stmt.c                     | 117 ++++++++++++++-------------
 gcc/testsuite/gfortran.dg/do_1.f90           |   6 --
 gcc/testsuite/gfortran.dg/do_3.F90           |   2 -
 gcc/testsuite/gfortran.dg/do_check_11.f90    |  12 +++
 gcc/testsuite/gfortran.dg/do_check_12.f90    |  12 +++
 gcc/testsuite/gfortran.dg/do_corner_warn.f90 |  22 +++++
 gcc/testsuite/gfortran.dg/ldist-1.f90        |   2 +-
 gcc/testsuite/gfortran.dg/pr48636.f90        |   2 +-
 10 files changed, 136 insertions(+), 66 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/do_check_11.f90
 create mode 100644 gcc/testsuite/gfortran.dg/do_check_12.f90
 create mode 100644 gcc/testsuite/gfortran.dg/do_corner_warn.f90

diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
index bdf5fa5..8f8b299 100644
--- a/gcc/fortran/lang.opt
+++ b/gcc/fortran/lang.opt
@@ -309,6 +309,10 @@ Wtabs
 Fortran Warning Var(warn_tabs) LangEnabledBy(Fortran,Wall || Wpedantic)
 Permit nonconforming uses of the tab character.
 
+Wundefined-do-loop
+Fortran Warning Var(warn_undefined_do_loop) LangEnabledBy(Fortran,Wall)
+Warn about an invalid DO loop.
+
 Wunderflow
 Fortran Warning Var(warn_underflow) Init(1)
 Warn about underflow of numerical constant expressions.
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 4378313..1fc540a 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -6546,6 +6546,29 @@ gfc_resolve_iterator (gfc_iterator *iter, bool real_ok, bool own_scope)
 		     &iter->step->where);
     }
 
+  if (iter->end->expr_type == EXPR_CONSTANT
+      && iter->end->ts.type == BT_INTEGER
+      && iter->step->expr_type == EXPR_CONSTANT
+      && iter->step->ts.type == BT_INTEGER
+      && (mpz_cmp_si (iter->step->value.integer, -1L) == 0
+	  || mpz_cmp_si (iter->step->value.integer, 1L) == 0))
+    {
+      bool is_step_positive = mpz_cmp_ui (iter->step->value.integer, 1) == 0;
+      int k = gfc_validate_kind (BT_INTEGER, iter->end->ts.kind, false);
+
+      if (is_step_positive
+	  && mpz_cmp (iter->end->value.integer, gfc_integer_kinds[k].huge) == 0)
+	gfc_warning (OPT_Wundefined_do_loop,
+		     "DO loop at %L is undefined as it overflows",
+		     &iter->step->where);
+      else if (!is_step_positive
+	       && mpz_cmp (iter->end->value.integer,
+			   gfc_integer_kinds[k].min_int) == 0)
+	gfc_warning (OPT_Wundefined_do_loop,
+		     "DO loop at %L is undefined as it underflows",
+		     &iter->step->where);
+    }
+
   return true;
 }
 
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index 389fa5e..d6fb620 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -1808,11 +1808,11 @@ gfc_trans_block_construct (gfc_code* code)
   return gfc_finish_wrapped_block (&block);
 }
 
+/* Translate the simple DO construct in a C-style manner.
+   This is where the loop variable has integer type and step +-1.
+   Following code will generate infinite loop in case where TO is INT_MAX
+   (for +1 step) or INT_MIN (for -1 step)
 
-/* Translate the simple DO construct.  This is where the loop variable has
-   integer type and step +-1.  We can't use this in the general case
-   because integer overflow and floating point errors could give incorrect
-   results.
    We translate a do loop from:
 
    DO dovar = from, to, step
@@ -1822,22 +1822,20 @@ gfc_trans_block_construct (gfc_code* code)
    to:
 
    [Evaluate loop bounds and step]
-   dovar = from;
-   if ((step > 0) ? (dovar <= to) : (dovar => to))
-    {
-      for (;;)
-        {
-	  body;
-   cycle_label:
-	  cond = (dovar == to);
-	  dovar += step;
-	  if (cond) goto end_label;
-	}
+    dovar = from;
+    for (;;)
+      {
+	if (dovar > to)
+	  goto end_label;
+	body;
+	cycle_label:
+	dovar += step;
       }
-   end_label:
+    end_label:
 
-   This helps the optimizers by avoiding the extra induction variable
-   used in the general case.  */
+   This helps the optimizers by avoiding the extra pre-header condition and
+   we save a register as we just compare the updated IV (not a value in
+   previous step).  */
 
 static tree
 gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
@@ -1851,14 +1849,14 @@ gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
   tree cycle_label;
   tree exit_label;
   location_t loc;
-
   type = TREE_TYPE (dovar);
+  bool is_step_positive = tree_int_cst_sgn (step) > 0;
 
   loc = code->ext.iterator->start->where.lb->location;
 
   /* Initialize the DO variable: dovar = from.  */
   gfc_add_modify_loc (loc, pblock, dovar,
-		      fold_convert (TREE_TYPE(dovar), from));
+		      fold_convert (TREE_TYPE (dovar), from));
 
   /* Save value for do-tinkering checking.  */
   if (gfc_option.rtcheck & GFC_RTCHECK_DO)
@@ -1871,13 +1869,53 @@ gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
   cycle_label = gfc_build_label_decl (NULL_TREE);
   exit_label = gfc_build_label_decl (NULL_TREE);
 
-  /* Put the labels where they can be found later. See gfc_trans_do().  */
+  /* Put the labels where they can be found later.  See gfc_trans_do().  */
   code->cycle_label = cycle_label;
   code->exit_label = exit_label;
 
   /* Loop body.  */
   gfc_start_block (&body);
 
+  /* Exit the loop if there is an I/O result condition or error.  */
+  if (exit_cond)
+    {
+      tmp = build1_v (GOTO_EXPR, exit_label);
+      tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
+			     exit_cond, tmp,
+			     build_empty_stmt (loc));
+      gfc_add_expr_to_block (&body, tmp);
+    }
+
+  /* Evaluate the loop condition.  */
+  if (is_step_positive)
+    cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node, dovar,
+			    fold_convert (type, to));
+  else
+    cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node, dovar,
+			    fold_convert (type, to));
+
+  cond = gfc_evaluate_now_loc (loc, cond, &body);
+
+  /* The loop exit.  */
+  tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
+  TREE_USED (exit_label) = 1;
+  tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
+			 cond, tmp, build_empty_stmt (loc));
+  gfc_add_expr_to_block (&body, tmp);
+
+  /* Check whether the induction variable is equal to INT_MAX
+     (respectively to INT_MIN).  */
+  if (gfc_option.rtcheck & GFC_RTCHECK_DO)
+    {
+      tree boundary = is_step_positive ? TYPE_MAX_VALUE (type)
+	: TYPE_MIN_VALUE (type);
+
+      tmp = fold_build2_loc (loc, EQ_EXPR, boolean_type_node,
+			     dovar, boundary);
+      gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
+			       "Loop iterates infinitely");
+    }
+
   /* Main loop body.  */
   tmp = gfc_trans_code_cond (code->block->next, exit_cond);
   gfc_add_expr_to_block (&body, tmp);
@@ -1898,21 +1936,6 @@ gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
 			       "Loop variable has been modified");
     }
 
-  /* Exit the loop if there is an I/O result condition or error.  */
-  if (exit_cond)
-    {
-      tmp = build1_v (GOTO_EXPR, exit_label);
-      tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
-			     exit_cond, tmp,
-			     build_empty_stmt (loc));
-      gfc_add_expr_to_block (&body, tmp);
-    }
-
-  /* Evaluate the loop condition.  */
-  cond = fold_build2_loc (loc, EQ_EXPR, boolean_type_node, dovar,
-			  to);
-  cond = gfc_evaluate_now_loc (loc, cond, &body);
-
   /* Increment the loop variable.  */
   tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
   gfc_add_modify_loc (loc, &body, dovar, tmp);
@@ -1920,28 +1943,10 @@ gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
   if (gfc_option.rtcheck & GFC_RTCHECK_DO)
     gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
 
-  /* The loop exit.  */
-  tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
-  TREE_USED (exit_label) = 1;
-  tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
-			 cond, tmp, build_empty_stmt (loc));
-  gfc_add_expr_to_block (&body, tmp);
-
   /* Finish the loop body.  */
   tmp = gfc_finish_block (&body);
   tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
 
-  /* Only execute the loop if the number of iterations is positive.  */
-  if (tree_int_cst_sgn (step) > 0)
-    cond = fold_build2_loc (loc, LE_EXPR, boolean_type_node, dovar,
-			    to);
-  else
-    cond = fold_build2_loc (loc, GE_EXPR, boolean_type_node, dovar,
-			    to);
-
-  tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
-			 gfc_likely (cond, PRED_FORTRAN_LOOP_PREHEADER), tmp,
-			 build_empty_stmt (loc));
   gfc_add_expr_to_block (pblock, tmp);
 
   /* Add the exit label.  */
@@ -2044,8 +2049,8 @@ gfc_trans_do (gfc_code * code, tree exit_cond)
   if (TREE_CODE (type) == INTEGER_TYPE
       && (integer_onep (step)
 	|| tree_int_cst_equal (step, integer_minus_one_node)))
-    return gfc_trans_simple_do (code, &block, dovar, from, to, step, exit_cond);
-
+    return gfc_trans_simple_do (code, &block, dovar, from, to, step,
+				exit_cond);
 
   if (TREE_CODE (type) == INTEGER_TYPE)
     utype = unsigned_type_for (type);
diff --git a/gcc/testsuite/gfortran.dg/do_1.f90 b/gcc/testsuite/gfortran.dg/do_1.f90
index b041279..b1db8c6 100644
--- a/gcc/testsuite/gfortran.dg/do_1.f90
+++ b/gcc/testsuite/gfortran.dg/do_1.f90
@@ -5,12 +5,6 @@ program do_1
   implicit none
   integer i, j
 
-  ! limit=HUGE(i), step 1
-  j = 0
-  do i = HUGE(i) - 10, HUGE(i), 1
-    j = j + 1
-  end do
-  if (j .ne. 11) call abort
   ! limit=HUGE(i), step > 1
   j = 0
   do i = HUGE(i) - 10, HUGE(i), 2
diff --git a/gcc/testsuite/gfortran.dg/do_3.F90 b/gcc/testsuite/gfortran.dg/do_3.F90
index eb4751d..0f2c315 100644
--- a/gcc/testsuite/gfortran.dg/do_3.F90
+++ b/gcc/testsuite/gfortran.dg/do_3.F90
@@ -48,11 +48,9 @@ program test
   TEST_LOOP(i, 17, 0, -4, 5, test_i, -3)
   TEST_LOOP(i, 17, 0, -5, 4, test_i, -3)
 
-  TEST_LOOP(i1, -huge(i1)-1_1, huge(i1), 1_1, int(huge(i1))*2+2, test_i1, huge(i1)+1_1)
   TEST_LOOP(i1, -huge(i1)-1_1, huge(i1), 2_1, int(huge(i1))+1, test_i1, huge(i1)+1_1)
   TEST_LOOP(i1, -huge(i1)-1_1, huge(i1), huge(i1), 3, test_i1, 2_1*huge(i1)-1_1)
 
-  TEST_LOOP(i1, huge(i1), -huge(i1)-1_1, -1_1, int(huge(i1))*2+2, test_i1, -huge(i1)-2_1)
   TEST_LOOP(i1, huge(i1), -huge(i1)-1_1, -2_1, int(huge(i1))+1, test_i1, -huge(i1)-2_1)
   TEST_LOOP(i1, huge(i1), -huge(i1)-1_1, -huge(i1), 3, test_i1, -2_1*huge(i1))
   TEST_LOOP(i1, huge(i1), -huge(i1)-1_1, -huge(i1)-1_1, 2, test_i1, -huge(i1)-2_1)
diff --git a/gcc/testsuite/gfortran.dg/do_check_11.f90 b/gcc/testsuite/gfortran.dg/do_check_11.f90
new file mode 100644
index 0000000..87850cf
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/do_check_11.f90
@@ -0,0 +1,12 @@
+! { dg-do run }
+! { dg-options "-fcheck=do" }
+! { dg-shouldfail "DO check" }
+!
+program test
+  implicit none
+  integer(1) :: i
+  do i = HUGE(i)-10, HUGE(i)
+    print *, i
+  end do
+end program test
+! { dg-output "Fortran runtime error: Loop iterates infinitely" }
diff --git a/gcc/testsuite/gfortran.dg/do_check_12.f90 b/gcc/testsuite/gfortran.dg/do_check_12.f90
new file mode 100644
index 0000000..71edace
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/do_check_12.f90
@@ -0,0 +1,12 @@
+! { dg-do run }
+! { dg-options "-fcheck=do" }
+! { dg-shouldfail "DO check" }
+!
+program test
+  implicit none
+  integer(1) :: i
+  do i = -HUGE(i)+10, -HUGE(i)-1, -1
+    print *, i
+  end do
+end program test
+! { dg-output "Fortran runtime error: Loop iterates infinitely" }
diff --git a/gcc/testsuite/gfortran.dg/do_corner_warn.f90 b/gcc/testsuite/gfortran.dg/do_corner_warn.f90
new file mode 100644
index 0000000..07484d3
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/do_corner_warn.f90
@@ -0,0 +1,22 @@
+! { dg-options "-Wundefined-do-loop" }
+! Program to check corner cases for DO statements.
+
+program do_1
+  implicit none
+  integer i, j
+
+  ! limit=HUGE(i), step 1
+  j = 0
+  do i = HUGE(i) - 10, HUGE(i), 1 ! { dg-warning "is undefined as it overflows" }
+    j = j + 1
+  end do
+  if (j .ne. 11) call abort
+
+  ! limit=-HUGE(i)-1, step -1
+  j = 0
+  do i = -HUGE(i) + 10 - 1, -HUGE(i) - 1, -1 ! { dg-warning "is undefined as it underflows" }
+    j = j + 1
+  end do
+  if (j .ne. 11) call abort
+
+end program
diff --git a/gcc/testsuite/gfortran.dg/ldist-1.f90 b/gcc/testsuite/gfortran.dg/ldist-1.f90
index ea3990d..2030328 100644
--- a/gcc/testsuite/gfortran.dg/ldist-1.f90
+++ b/gcc/testsuite/gfortran.dg/ldist-1.f90
@@ -32,4 +32,4 @@ end Subroutine PADEC
 ! There are 5 legal partitions in this code.  Based on the data
 ! locality heuristic, this loop should not be split.
 
-! { dg-final { scan-tree-dump-not "distributed: split to" "ldist" } }
+! { dg-final { scan-tree-dump "distributed: split to" "ldist" } }
diff --git a/gcc/testsuite/gfortran.dg/pr48636.f90 b/gcc/testsuite/gfortran.dg/pr48636.f90
index 94826fa..926d8f3 100644
--- a/gcc/testsuite/gfortran.dg/pr48636.f90
+++ b/gcc/testsuite/gfortran.dg/pr48636.f90
@@ -34,5 +34,5 @@ program main
 end program main
 
 ! { dg-final { scan-ipa-dump "bar\[^\\n\]*inline copy in MAIN" "inline" } }
-! { dg-final { scan-ipa-dump-times "phi predicate:" 5 "inline" } }
+! { dg-final { scan-ipa-dump-times "phi predicate:" 3 "inline" } }
 ! { dg-final { scan-ipa-dump "inline hints: loop_iterations" "inline" } }
-- 
2.8.4


[-- Attachment #3: 0001-Add-PRED_FORTRAN_LOOP_PREHEADER-to-DO-loops-with-ste.patch --]
[-- Type: text/x-patch, Size: 3278 bytes --]

From 467d46dfc9da3f4205abc953b8529b99acd0f7eb Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Fri, 1 Jul 2016 14:11:04 +0200
Subject: [PATCH 1/2] Add PRED_FORTRAN_LOOP_PREHEADER to DO loops with step
 bigger than +-1.

gcc/fortran/ChangeLog:

2016-07-01  Martin Liska  <mliska@suse.cz>

	* trans-stmt.c (gfc_trans_do): Add expect builtin for DO
	loops with step bigger than +-1.

gcc/testsuite/ChangeLog:

2016-07-01  Martin Liska  <mliska@suse.cz>

	* gfortran.dg/predict-1.f90: Ammend the test.
	* gfortran.dg/predict-2.f90: Likewise.
---
 gcc/fortran/trans-stmt.c                | 6 ++++--
 gcc/testsuite/gfortran.dg/predict-1.f90 | 9 +++++++--
 gcc/testsuite/gfortran.dg/predict-2.f90 | 6 +++---
 3 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index 84bf749..389fa5e 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -2109,7 +2109,8 @@ gfc_trans_do (gfc_code * code, tree exit_cond)
       pos = build2 (COMPOUND_EXPR, void_type_node,
 		    fold_build2 (MODIFY_EXPR, void_type_node,
 				 countm1, tmp2),
-		    build3_loc (loc, COND_EXPR, void_type_node, tmp,
+		    build3_loc (loc, COND_EXPR, void_type_node,
+				gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
 				build1_loc (loc, GOTO_EXPR, void_type_node,
 					    exit_label), NULL_TREE));
 
@@ -2123,7 +2124,8 @@ gfc_trans_do (gfc_code * code, tree exit_cond)
       neg = build2 (COMPOUND_EXPR, void_type_node,
 		    fold_build2 (MODIFY_EXPR, void_type_node,
 				 countm1, tmp2),
-		    build3_loc (loc, COND_EXPR, void_type_node, tmp,
+		    build3_loc (loc, COND_EXPR, void_type_node,
+				gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
 				build1_loc (loc, GOTO_EXPR, void_type_node,
 					    exit_label), NULL_TREE));
 
diff --git a/gcc/testsuite/gfortran.dg/predict-1.f90 b/gcc/testsuite/gfortran.dg/predict-1.f90
index 81f0436..a3feea9 100644
--- a/gcc/testsuite/gfortran.dg/predict-1.f90
+++ b/gcc/testsuite/gfortran.dg/predict-1.f90
@@ -4,9 +4,14 @@
 subroutine test(block, array)
 integer :: i, block(9), array(2)
 
-do i = array(1), array(2)
+do i = array(1), array(2), 2
     block(i) = i
 end do
+
+do i = array(1), array(2), -2
+    block(i) = block(i) + i
+end do
+
 end subroutine test
 
-! { dg-final { scan-tree-dump-times "Fortran loop preheader heuristics of edge\[^:\]*: 99.0%" 1 "profile_estimate" } }
+! { dg-final { scan-tree-dump-times "Fortran loop preheader heuristics of edge\[^:\]*: 1.0%" 2 "profile_estimate" } }
diff --git a/gcc/testsuite/gfortran.dg/predict-2.f90 b/gcc/testsuite/gfortran.dg/predict-2.f90
index 4ae5c3a..11a9ec5 100644
--- a/gcc/testsuite/gfortran.dg/predict-2.f90
+++ b/gcc/testsuite/gfortran.dg/predict-2.f90
@@ -4,12 +4,12 @@
 subroutine test(block, array)
 integer :: i,j, block(9), array(2)
 
-do i = array(1), array(2)
-    do j = array(1), array(2)
+do i = array(1), array(2), 2
+    do j = array(1), array(2), 3
        block(i) = j
     end do
 end do
 end subroutine test
 
 ! { dg-final { scan-tree-dump-times "Fortran loop preheader heuristics of edge" 2 "profile_estimate" } }
-! { dg-final { scan-tree-dump-times "loop gueard" 0 "profile_estimate" } }
+! { dg-final { scan-tree-dump-times "loop guard" 0 "profile_estimate" } }
-- 
2.8.4


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

end of thread, other threads:[~2016-07-01 12:30 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-27 19:37 Fortran loops Dominique d'Humières
2016-06-27 19:43 ` Adam Hirst
2016-06-27 20:05 ` Dominique d'Humières
2016-06-27 20:22 ` FX
2016-06-27 21:25   ` William Clodius
2016-06-28 12:10 ` Jan Hubicka
2016-06-28 13:50   ` Richard Biener
2016-06-28 13:56     ` Jan Hubicka
2016-06-30 11:17       ` [PATCH, RFC] Introduce -ffast-do-loop flag Martin Liška
2016-06-30 11:43         ` Richard Biener
2016-06-30 15:10           ` Martin Liška
2016-06-30 19:10         ` FX
2016-06-30 20:23           ` Mikael Morin
2016-07-01 12:30             ` Martin Liška

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