diff mbox series

[Fortran,committed] OpenACC tile clause – apply exit/cycle checks (PR 93552)

Message ID 5fe46ee6-7c43-7256-a238-c04836d5e7a9@codesourcery.com
State New
Headers show
Series [Fortran,committed] OpenACC tile clause – apply exit/cycle checks (PR 93552) | expand

Commit Message

Tobias Burnus Feb. 24, 2020, 11:21 a.m. UTC
All is about OpenACC. First, when testing, I found out that "kernels 
loop" wasn't checked for – only serial/parallel loop and an "acc loop".

For nested loops, besides using the "collapse" clause also the "tile" 
clause can be used. Internally, those are processed identically (on the 
FE side) but "tile" wins if both are specified. Hence:

NOTE: I only do check of "tile" – if tile is for a nest level of n while 
collapse is for a nest level > n, invalid use related to collapse, only, 
are not detected. That's in line with the later implementation where 
"tile" has a higher priority.

For "collapse" exits from the loop and "cycle" to any but the innermost 
loop was ready rejected – for "tile" this was not checked for – and, 
hence, accepted. As the rest of the code wasn't prepared for it, it lead 
to an ICE.

In my understanding of the OpenACC spec ("tightly nested loop", 
semantic) "tile" and "collapse" have the same restriction such that the 
attached test case is invalid. (However, the bug reported marked it as 
'ice-on-valid-code'.)

Committed as Rev. r10-6808-g2bd8c3ff3511df8781dd9f3777efab20572d29ab

Cheers,

Tobias
diff mbox series

Patch

commit 2bd8c3ff3511df8781dd9f3777efab20572d29ab
Author: Tobias Burnus <tobias@codesourcery.com>
Date:   Mon Feb 24 12:18:04 2020 +0100

    OpenACC tile clause – apply exit/cycle checks (PR 93552)
    
            PR fortran/93552
            * match.c (match_exit_cycle): With OpenACC, check the kernels loop
            directive and tile clause as well.
    
            PR fortran/93552
            * gfortran.dg/goacc/tile-4.f90: New.
---
 gcc/fortran/ChangeLog                      |  6 ++++++
 gcc/fortran/match.c                        | 25 ++++++++++++++++++++-----
 gcc/testsuite/ChangeLog                    |  7 ++++++-
 gcc/testsuite/gfortran.dg/goacc/tile-4.f90 | 27 +++++++++++++++++++++++++++
 4 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 1ed6a97366e..94ceb5c8aa3 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,9 @@ 
+2020-02-24  Tobias Burnus  <tobias@codesourcery.com>
+
+	PR fortran/93552
+	* match.c (match_exit_cycle): With OpenACC, check the kernels loop
+	directive and tile clause as well.
+
 2020-02-23  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
 	PR fortran/93889
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index e4d52245976..17196eb1ae6 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -2878,6 +2878,7 @@  match_exit_cycle (gfc_statement st, gfc_exec_op op)
       && o != NULL
       && o->state == COMP_OMP_STRUCTURED_BLOCK
       && (o->head->op == EXEC_OACC_LOOP
+	  || o->head->op == EXEC_OACC_KERNELS_LOOP
 	  || o->head->op == EXEC_OACC_PARALLEL_LOOP
 	  || o->head->op == EXEC_OACC_SERIAL_LOOP))
     {
@@ -2887,9 +2888,20 @@  match_exit_cycle (gfc_statement st, gfc_exec_op op)
 		      || o->head->next->op == EXEC_DO_WHILE)
 		  && o->previous != NULL
 		  && o->previous->tail->op == o->head->op);
-      if (o->previous->tail->ext.omp_clauses != NULL
-	  && o->previous->tail->ext.omp_clauses->collapse > 1)
-	collapse = o->previous->tail->ext.omp_clauses->collapse;
+      if (o->previous->tail->ext.omp_clauses != NULL)
+	{
+	  /* Both collapsed and tiled loops are lowered the same way, but are not
+	     compatible.  In gfc_trans_omp_do, the tile is prioritized.  */
+	  if (o->previous->tail->ext.omp_clauses->tile_list)
+	    {
+	      collapse = 0;
+	      gfc_expr_list *el = o->previous->tail->ext.omp_clauses->tile_list;
+	      for ( ; el; el = el->next)
+		++collapse;
+	    }
+	  else if (o->previous->tail->ext.omp_clauses->collapse > 1)
+	    collapse = o->previous->tail->ext.omp_clauses->collapse;
+	}
       if (st == ST_EXIT && cnt <= collapse)
 	{
 	  gfc_error ("EXIT statement at %C terminating !$ACC LOOP loop");
@@ -2897,8 +2909,11 @@  match_exit_cycle (gfc_statement st, gfc_exec_op op)
 	}
       if (st == ST_CYCLE && cnt < collapse)
 	{
-	  gfc_error ("CYCLE statement at %C to non-innermost collapsed"
-		     " !$ACC LOOP loop");
+	  gfc_error (o->previous->tail->ext.omp_clauses->tile_list
+		     ? G_("CYCLE statement at %C to non-innermost tiled"
+			  " !$ACC LOOP loop")
+		     : G_("CYCLE statement at %C to non-innermost collapsed"
+			  " !$ACC LOOP loop"));
 	  return MATCH_ERROR;
 	}
     }
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 13c1a132cc1..bd50ffdbd68 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@ 
+2020-02-24  Tobias Burnus  <tobias@codesourcery.com>
+
+	PR fortran/93552
+	* gfortran.dg/goacc/tile-4.f90: New.
+
 2020-02-24  Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>
 	    Kugan Vivekandarajah  <kugan.vivekanandarajah@linaro.org>
 
@@ -43,7 +48,7 @@ 
 2020-02-21  Jan Hubicka  <hubicka@ucw.cz>
 	    Richard Biener  <rguenther@suse.de>
 
-  	PR tree-optimization/93586
+	PR tree-optimization/93586
 	* gcc.dg/torture/pr93586.c: New testcase.
 
 2020-02-21  Martin Jambor  <mjambor@suse.cz>
diff --git a/gcc/testsuite/gfortran.dg/goacc/tile-4.f90 b/gcc/testsuite/gfortran.dg/goacc/tile-4.f90
new file mode 100644
index 00000000000..86c22df9b66
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/tile-4.f90
@@ -0,0 +1,27 @@ 
+! { dg-do compile }
+!
+! Contributed by  G. Steinmetz
+!
+! PR fortran/93552
+! only collapsed an not tile was checked:
+program p
+   integer :: i, j
+   !$acc parallel loop tile(2,2)
+   outer: do i = 1, 8
+      do j = 1, 8
+         exit  ! { dg-error "statement at .1. terminating ..ACC LOOP loop" }
+         cycle outer ! { dg-error "to non-innermost tiled" }
+      end do
+   end do outer
+end
+
+! Kernels loop was missing the check:
+subroutine test
+  !$acc kernels loop collapse(2)
+  outer: do i = 1, 4
+    do j = 1, 4
+      exit  ! { dg-error "statement at .1. terminating ..ACC LOOP loop" }
+      cycle outer ! { dg-error "to non-innermost collapsed" }
+    end do
+  end do outer
+end