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
