[patch] OpenMP/Fortran: Reject declarations between target + teams (was: [Patch] OpenMP/Fortran: Reject not strictly nested target -> teams [PR110725, PR71065])

2023-07-25 Thread Tobias Burnus

On 24.07.23 21:49, Jakub Jelinek via Fortran wrote:

On Mon, Jul 24, 2023 at 09:43:10PM +0200, Tobias Burnus wrote:

This patch adds diagnostic for additional code alongside a nested teams
in a target region.

Thanks for working on this.  The fuzzy thing on the Fortran side is
if e.g. multiple nested BLOCK statements can appear sandwiched in between
target and teams (of course without declarations in them)


Talking about declarations, I realized that I missed to diagnose them;
the attached patch should handle them as well. (Except for 'omp nothing'
and 'omp error', which return ST_NONE.)

Comments, remarks, suggestions? If none or no changes are required,
I will later commit the attached follow-up patch.

Tobias

-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955
OpenMP/Fortran: Reject declarations between target + teams

While commit r14-2754-g2e31fe431b08b0302e1fa8a1c18ee51adafd41df
detected executable statements, declarations do not show up as
executable statements.  Hence, we now check whether the first
statement after TARGET is TEAMS - such that we can detect data
statements like type or variable declarations.  Fortran semantics
ensures that only executable directives/statemens can come after
'!$omp end teams' such that those can be detected with the
previous check.

Note that statements returning ST_NONE such as 'omp nothing' or
'omp error at(compilation)' will still slip through.

	PR fortran/110725
	PR middle-end/71065

gcc/fortran/ChangeLog:

	* gfortran.h (gfc_omp_clauses): Add target_first_st_is_teams.
	* parse.cc (parse_omp_structured_block): Set it if the first
	statement in the structured block of a TARGET is TEAMS or
	a combined/composite starting with TEAMS.
	* openmp.cc (resolve_omp_target): Also show an error for
	contains_teams_construct without target_first_st_is_teams.

gcc/testsuite/ChangeLog:

	* gfortran.dg/gomp/teams-6.f90: New test.

 gcc/fortran/gfortran.h |  2 +-
 gcc/fortran/openmp.cc  | 13 ++---
 gcc/fortran/parse.cc   | 25 --
 gcc/testsuite/gfortran.dg/gomp/teams-6.f90 | 78 ++
 4 files changed, 108 insertions(+), 10 deletions(-)

diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 577ef807af7..9a00e6dea6f 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1575,7 +1575,7 @@ typedef struct gfc_omp_clauses
   unsigned order_unconstrained:1, order_reproducible:1, capture:1;
   unsigned grainsize_strict:1, num_tasks_strict:1, compare:1, weak:1;
   unsigned non_rectangular:1, order_concurrent:1;
-  unsigned contains_teams_construct:1;
+  unsigned contains_teams_construct:1, target_first_st_is_teams:1;
   ENUM_BITFIELD (gfc_omp_sched_kind) sched_kind:3;
   ENUM_BITFIELD (gfc_omp_device_type) device_type:2;
   ENUM_BITFIELD (gfc_omp_memorder) memorder:3;
diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index 675011a18ce..52eeaf2d4da 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -10666,12 +10666,13 @@ resolve_omp_target (gfc_code *code)
 
   if (!code->ext.omp_clauses->contains_teams_construct)
 return;
-  if ((GFC_IS_TEAMS_CONSTRUCT (code->block->next->op)
-   && code->block->next->next == NULL)
-  || (code->block->next->op == EXEC_BLOCK
-	  && code->block->next->next
-	  && GFC_IS_TEAMS_CONSTRUCT (code->block->next->next->op)
-	  && code->block->next->next->next == NULL))
+  if (code->ext.omp_clauses->target_first_st_is_teams
+  && ((GFC_IS_TEAMS_CONSTRUCT (code->block->next->op)
+	   && code->block->next->next == NULL)
+	  || (code->block->next->op == EXEC_BLOCK
+	  && code->block->next->next
+	  && GFC_IS_TEAMS_CONSTRUCT (code->block->next->next->op)
+	  && code->block->next->next->next == NULL)))
 return;
   gfc_code *c = code->block->next;
   while (c && !GFC_IS_TEAMS_CONSTRUCT (c->op))
diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc
index 011a39c3d04..aa6bb663def 100644
--- a/gcc/fortran/parse.cc
+++ b/gcc/fortran/parse.cc
@@ -5766,7 +5766,7 @@ parse_openmp_allocate_block (gfc_statement omp_st)
 static gfc_statement
 parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only)
 {
-  gfc_statement st, omp_end_st;
+  gfc_statement st, omp_end_st, first_st;
   gfc_code *cp, *np;
   gfc_state_data s;
 
@@ -5857,7 +5857,7 @@ parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only)
   gfc_namespace *my_ns = NULL;
   gfc_namespace *my_parent = NULL;
 
-  st = next_statement ();
+  first_st = st = next_statement ();
 
   if (st == ST_BLOCK)
 {
@@ -5876,9 +5876,28 @@ parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only)
   new_st.ext.block.ns = my_ns;
   new_st.ext.block.assoc = NULL;
   accept_statement 

Re: [Patch] OpenMP/Fortran: Reject not strictly nested target -> teams [PR110725, PR71065]

2023-07-25 Thread Tobias Burnus

Now committed as r14-2754-g2e31fe431b08b0 with a minor addition:

On 24.07.23 22:05, Tobias Burnus wrote:

The current patch rejects nested blocks, be it 'omp target; block;
block; omp teams;'

which was before in the testcase. But now also

or be it 'omp target; block; block;end block; omp teams'.

is tested for.

Somehow, the second dg-error line in an modified testcase did not make
it in the first commit; now fixed in r14-2759-g50656980497d77

Tobias.
-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955
commit 50656980497d77ac12a5e7179013a6af09ba32f7
Author: Tobias Burnus 
Date:   Tue Jul 25 09:28:43 2023 +0200

gfortran.dg/gomp/pr99226.f90: Add missing dg-error

Follow up to r14-2754-g2e31fe431b08b0302e1fa8a1c18ee51adafd41df
which added a check that a target region with teams does not
have anything anything else strictly nested in the target.

When changing the dg-error for this PR, somehow the addition of a
dg-error in a second line was lost (the message uses (1) and (2) as
location, showing two lines, both need a dg-error with the same message).

gcc/testsuite/ChangeLog:

* gfortran.dg/gomp/pr99226.f90: Update dg-error.
---
 gcc/testsuite/gfortran.dg/gomp/pr99226.f90 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gfortran.dg/gomp/pr99226.f90 b/gcc/testsuite/gfortran.dg/gomp/pr99226.f90
index 2aea0c15585..d1b35076dd0 100644
--- a/gcc/testsuite/gfortran.dg/gomp/pr99226.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/pr99226.f90
@@ -3,7 +3,7 @@
 subroutine sub (n)
integer :: n, i
!$omp target	! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" }
-   !$omp teams distribute dist_schedule (static,n+4)
+   !$omp teams distribute dist_schedule (static,n+4)	! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" }
do i = 1, 8
end do
!$omp teams distribute dist_schedule (static,n+4)
commit 2e31fe431b08b0302e1fa8a1c18ee51adafd41df
Author: Tobias Burnus 
Date:   Mon Jul 24 22:57:07 2023 +0200

OpenMP/Fortran: Reject not strictly nested target -> teams [PR110725, PR71065]

OpenMP requires: "If a teams region is nested inside a target region, the
corresponding target construct must not contain any statements, declarations
or directives outside of the corresponding teams construct."

This commit checks now for this restriction.

PR fortran/110725
PR middle-end/71065

gcc/fortran/ChangeLog:

* gfortran.h (gfc_omp_clauses): Add contains_teams_construct.
* openmp.cc (resolve_omp_target): New; check for teams nesting.
(gfc_resolve_omp_directive): Call it.
* parse.cc (decode_omp_directive): Set contains_teams_construct
on enclosing ST_OMP_TARGET.

gcc/testsuite/ChangeLog:

* gfortran.dg/gomp/pr99226.f90: Update dg-error.
* gfortran.dg/gomp/teams-5.f90: New test.
---
 gcc/fortran/gfortran.h |   1 +
 gcc/fortran/openmp.cc  |  39 +++-
 gcc/fortran/parse.cc   |  33 +++
 gcc/testsuite/gfortran.dg/gomp/pr99226.f90 |   2 +-
 gcc/testsuite/gfortran.dg/gomp/teams-5.f90 | 150 +
 5 files changed, 223 insertions(+), 2 deletions(-)

diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 6482a885211..577ef807af7 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1575,6 +1575,7 @@ typedef struct gfc_omp_clauses
   unsigned order_unconstrained:1, order_reproducible:1, capture:1;
   unsigned grainsize_strict:1, num_tasks_strict:1, compare:1, weak:1;
   unsigned non_rectangular:1, order_concurrent:1;
+  unsigned contains_teams_construct:1;
   ENUM_BITFIELD (gfc_omp_sched_kind) sched_kind:3;
   ENUM_BITFIELD (gfc_omp_device_type) device_type:2;
   ENUM_BITFIELD (gfc_omp_memorder) memorder:3;
diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index 05a697da071..675011a18ce 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -10653,6 +10653,41 @@ gfc_resolve_oacc_directive (gfc_code *code, gfc_namespace *ns ATTRIBUTE_UNUSED)
 }
 
 
+static void
+resolve_omp_target (gfc_code *code)
+{
+#define GFC_IS_TEAMS_CONSTRUCT(op)			\
+  (op == EXEC_OMP_TEAMS	\
+   || op == EXEC_OMP_TEAMS_DISTRIBUTE			\
+   || op == EXEC_OMP_TEAMS_DISTRIBUTE_SIMD		\
+   || op == EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO	\
+   || op == EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD	\
+   || op == EXEC_OMP_TEAMS_LOOP)
+
+  if