diff mbox series

Fortran/OpenMP: Add omp loop [PR99928]

Message ID 07fcbbee-93b0-088f-7d6b-ecf06ce2a23c@codesourcery.com
State New
Headers show
Series Fortran/OpenMP: Add omp loop [PR99928] | expand

Commit Message

Tobias Burnus June 2, 2021, 10:30 p.m. UTC
This patch adds support for 'omp loop' to gfortran including the combined
constructs. It also fixes some splitting issues with clauses in
combined constructs.

It does not attempt to clean up all remaining Fortran issues with
clauses in combined constructs (cf. below + PR).

  * * *

Since 'parallel loop' is now supported, using
  !$omp parallel &
  !$acc& loop
no longer gave an error. (Same result before: '!$acc& do'.)

With the current unpatched parser, there is either everything
successfully parsed – and and processed – or it fails with
MATCH_NO and gfortran tries it again with another different
match attempt. The error is cached and only shown, when
still pending and nothing else worked.
Using gfc_error_now prevents the delayed/conditional output
but as several matching attempts are done, the error is show
half a dozen times.

I played around, but I then determined that it
is the simplest to abort with a fatal error in this case.
Hence, I split the testcase into three – and placed it into the
goacc-gomp directory (where it belongs to but which did not
exist for quite some time).
(The early parse errors + the first fatal error can be in one
file, the next fatal error needs an extra file and
resolution-time errors must be yet in another file.)
As the name 'omp*.f*' did not fit any more, I renamed it.


Plus:
   !$omp foo
   !$acc bar
is not a continuation line – which was mishandled in
fixed-form Fortran (cf. mixed-omp-3.f + scanner.c)
- causing a bogus error as no continuation line was involved.

Not in this testcase, but if the first statement is either
an '!$xxx end ...' or a single-statement where nothing
follows, this could prevent valid fixed-form code from
running ...

  * * *

This patch includes all Fortranized pr99928-3.c testcases, except for
pr99928-9.c and pr99928-10.c, which use array sections in 'reduction'.
Additionally, 'defaultmap(none)' is currently commented as it is not yet
supported.

Regarding the xfails: There are some shared() ones and the target map(tofrom),
which I did not attempt to fix in this patch. And I observe the following
fails in pr99928-7.f90:

The check does (for Fortran – and alike for C):
   ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*lastprivate\\(j00\\)" "gimple" } }
   ! { dg-final { scan-tree-dump-not "omp parallel\[^\n\r]*lastprivate\\(j00\\)" "gimple" } }
   ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j00\\)" "gimple" } }
   ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j00:1\\)" "gimple" } }
   !$omp distribute parallel do simd default(none)
   do j00 = 1, 64
   end do

While C generates (original dump)

   #pragma omp distribute
       #pragma omp parallel default(none)
             #pragma omp for nowait
                 #pragma omp simd

Fortran generates the same except for:
                     #pragma omp simd linear(j00:1)

The latter leads to a different result for the gimple dump. Fortran has:
   #pragma omp distribute private(j00.1)
         #pragma omp parallel default(none) lastprivate(j00)
             #pragma omp for nowait private(j00.0)
                   #pragma omp simd linear(j00:1)
while C has the same without 'lastprivate(j00)'.

And the dump checks that 'lastprivate(j00)' does not appear ...

  * * *

OK? – Comments, remarks?

Tobias

-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank Thürauf

Comments

Jakub Jelinek June 3, 2021, 3:07 p.m. UTC | #1
On Thu, Jun 03, 2021 at 12:30:50AM +0200, Tobias Burnus wrote:
> This patch adds support for 'omp loop' to gfortran including the combined
> constructs. It also fixes some splitting issues with clauses in
> combined constructs.
> 
> It does not attempt to clean up all remaining Fortran issues with
> clauses in combined constructs (cf. below + PR).
> 
>  * * *
> 
> Since 'parallel loop' is now supported, using
>  !$omp parallel &
>  !$acc& loop
> no longer gave an error. (Same result before: '!$acc& do'.)

I think best would be just to remove that part of the testcase
in the loop patch and handle the !$omp with !$acc continuations
and vice versa in a separate change.  That seems to be a preexisting
bug not really related to whether we support loop or not.
fatal_error is certainly not ideal, but I can understand fixing
it otherwise might be hard.
Wonder if we just shouldn't treat the incorrect continuations
as if they were simple comments.

> The check does (for Fortran – and alike for C):
>   ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*lastprivate\\(j00\\)" "gimple" } }
>   ! { dg-final { scan-tree-dump-not "omp parallel\[^\n\r]*lastprivate\\(j00\\)" "gimple" } }
>   ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j00\\)" "gimple" } }
>   ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j00:1\\)" "gimple" } }
>   !$omp distribute parallel do simd default(none)
>   do j00 = 1, 64
>   end do
> 
> While C generates (original dump)
> 
>   #pragma omp distribute
>       #pragma omp parallel default(none)
>             #pragma omp for nowait
>                 #pragma omp simd
> 
> Fortran generates the same except for:
>                     #pragma omp simd linear(j00:1)

The *-7 testcase is not appropriate for Fortran, it tests the
IV declared in the construct cases which Fortran has no counterpart for,
even if the IV is first seen within the construct, that would implicitly
declare it outside of the construct.

> +	      if (gfc_match ("teams )") == MATCH_YES)
> +		c->bind = OMP_BIND_TEAMS;
> +	      else if (gfc_match ("parallel )") == MATCH_YES)
> +		c->bind = OMP_BIND_PARALLEL;
> +	      else if (gfc_match ("thread )") == MATCH_YES)
> +		c->bind = OMP_BIND_THREAD;
> +	      else
> +		{
> +		  gfc_error ("Expected TEAMS, PARALLEL or THEAD as binding in "

Typo, s/THEAD/THREAD/

> +      if (clauses->bind == OMP_BIND_TEAMS)
> +        OMP_CLAUSE_BIND_KIND (c) = OMP_CLAUSE_BIND_TEAMS;
> +      else if (clauses->bind == OMP_BIND_PARALLEL)
> +        OMP_CLAUSE_BIND_KIND (c) = OMP_CLAUSE_BIND_PARALLEL;
> +      else if (clauses->bind == OMP_BIND_THREAD)
> +        OMP_CLAUSE_BIND_KIND (c) = OMP_CLAUSE_BIND_THREAD;
> +      else
> +	gcc_unreachable ();

Wouldn't a switch (clauses->bind) be cleaner?

Otherwise LGTM.

	Jakub
Jakub Jelinek June 3, 2021, 10:56 p.m. UTC | #2
On Thu, Jun 03, 2021 at 05:07:22PM +0200, Jakub Jelinek via Gcc-patches wrote:
> I think best would be just to remove that part of the testcase
> in the loop patch and handle the !$omp with !$acc continuations
> and vice versa in a separate change.  That seems to be a preexisting
> bug not really related to whether we support loop or not.
> fatal_error is certainly not ideal, but I can understand fixing
> it otherwise might be hard.
> Wonder if we just shouldn't treat the incorrect continuations
> as if they were simple comments.

Perhaps can't it gfc_error_now for the mixing of OMP and ACC line
continuations and then act as if the incorrect ones were comments
(like for -fopenmp -fno-openacc or -fopenacc -fno-openmp)?

	Jakub
diff mbox series

Patch

Fortran/OpenMP: Add omp loop [PR99928]

	PR middle-end/99928

gcc/fortran/ChangeLog:

	* dump-parse-tree.c (show_omp_clauses): Handle bind clause.
	(show_omp_node): Handle loop directive.
	* frontend-passes.c (gfc_code_walker): Likewise.
	* gfortran.h (enum gfc_statement): Add
	ST_OMP_(END_)(TARGET_)(|PARALLEL_|TEAMS_)LOOP.
	(enum gfc_omp_bind_type): New.
	(gfc_omp_clauses): Use it.
	(enum gfc_exec_op): Add EXEC_OMP_(TARGET_)(|PARALLEL_|TEAMS_)LOOP.
	* match.h (gfc_match_omp_loop, gfc_match_omp_parallel_loop,
	gfc_match_omp_target_parallel_loop, gfc_match_omp_target_teams_loop,
	gfc_match_omp_teams_loop): New.
	* openmp.c (enum omp_mask1): Add OMP_CLAUSE_BIND.
	(gfc_match_omp_clauses): Handle it.
	(OMP_LOOP_CLAUSES, gfc_match_omp_loop, gfc_match_omp_teams_loop,
	gfc_match_omp_target_teams_loop, gfc_match_omp_parallel_loop,
	gfc_match_omp_target_parallel_loop): New.
	(resolve_omp_clauses, resolve_omp_do, omp_code_to_statement,
	gfc_resolve_omp_directive): Handle omp loop.
	* parse.c (decode_omp_directive case_exec_markers, gfc_ascii_statement,
	parse_omp_do, parse_executable): Likewise.
	(parse_omp_structured_block): Remove ST_ which use parse_omp_do.
	* resolve.c (gfc_resolve_blocks): Add omp loop.
	* st.c (gfc_free_statement): Likewise.
	* trans-openmp.c (gfc_trans_omp_clauses): Handle bind clause.
	(gfc_trans_omp_do, gfc_trans_omp_parallel_do, gfc_trans_omp_distribute,
	gfc_trans_omp_teams, gfc_trans_omp_target, gfc_trans_omp_directive):
	Handle loop directive.
	(gfc_split_omp_clauses): Likewise; fix firstprivate/lastprivate
	and (in_)reduction for taskloop.
	* trans.c (trans_code): Handle omp loop directive.
	* scanner.c (gfc_next_char_literal): Fix parsing of !$OMP followed
	by !$ACC and vice versa.

gcc/testsuite/ChangeLog:

	* gfortran.dg/gomp/pr99928-3.f90: Add 'default(none)', following
	C/C++ version of the patch.
	* gfortran.dg/gomp/loop-1.f90: New test.
	* gfortran.dg/gomp/loop-2.f90: New test.
	* gfortran.dg/gomp/pr99928-1.f90: New test; based on C/C++ test.
	* gfortran.dg/gomp/pr99928-11.f90: Likewise.
	* gfortran.dg/gomp/pr99928-2.f90: Likewise.
	* gfortran.dg/gomp/pr99928-4.f90: Likewise.
	* gfortran.dg/gomp/pr99928-5.f90: Likewise.
	* gfortran.dg/gomp/pr99928-6.f90: Likewise.
	* gfortran.dg/gomp/pr99928-7.f90: Likewise.
	* gfortran.dg/gomp/pr99928-8.f90: Likewise.
        * gfortran.dg/goacc/omp.f95: Moved to ...
        * gfortran.dg/goacc-gomp/mixed-1.f95: ... here; parts split off to
        * gfortran.dg/goacc-gomp/mixed-2.f95: ... here and ...
        * gfortran.dg/goacc-gomp/mixed-3.f95: ... here.
        * gfortran.dg/goacc/omp-fixed.f: Moved to ...
        * gfortran.dg/goacc-gomp/mixed-fixed-1.f: ... here; parts split off to
        * gfortran.dg/goacc-gomp/mixed-fixed-2.f: ... here and ...
        * gfortran.dg/goacc-gomp/mixed-fixed-3.f: ... here.

 gcc/fortran/dump-parse-tree.c                      |  23 ++
 gcc/fortran/frontend-passes.c                      |   5 +
 gcc/fortran/gfortran.h                             |  18 +-
 gcc/fortran/match.h                                |   5 +
 gcc/fortran/openmp.c                               |  94 +++++++-
 gcc/fortran/parse.c                                | 104 +++++----
 gcc/fortran/resolve.c                              |  10 +
 gcc/fortran/scanner.c                              |  26 ++-
 gcc/fortran/st.c                                   |   5 +
 gcc/fortran/trans-openmp.c                         | 111 +++++++--
 gcc/fortran/trans.c                                |   5 +
 gcc/testsuite/gfortran.dg/goacc-gomp/mixed-1.f95   |  30 +++
 gcc/testsuite/gfortran.dg/goacc-gomp/mixed-2.f95   |  12 +
 .../{goacc/omp.f95 => goacc-gomp/mixed-3.f95}      |  31 +--
 .../gfortran.dg/goacc-gomp/mixed-fixed-1.f         |  12 +
 .../gfortran.dg/goacc-gomp/mixed-fixed-2.f         |  12 +
 .../gfortran.dg/goacc-gomp/mixed-fixed-3.f         |  16 ++
 gcc/testsuite/gfortran.dg/goacc/omp-fixed.f        |  32 ---
 gcc/testsuite/gfortran.dg/gomp/loop-1.f90          |  56 +++++
 gcc/testsuite/gfortran.dg/gomp/loop-2.f90          |  44 ++++
 gcc/testsuite/gfortran.dg/gomp/pr99928-1.f90       | 238 +++++++++++++++++++
 gcc/testsuite/gfortran.dg/gomp/pr99928-11.f90      |  34 +++
 gcc/testsuite/gfortran.dg/gomp/pr99928-2.f90       | 231 +++++++++++++++++++
 gcc/testsuite/gfortran.dg/gomp/pr99928-3.f90       |  30 +--
 gcc/testsuite/gfortran.dg/gomp/pr99928-4.f90       |  89 ++++++++
 gcc/testsuite/gfortran.dg/gomp/pr99928-5.f90       | 107 +++++++++
 gcc/testsuite/gfortran.dg/gomp/pr99928-6.f90       | 107 +++++++++
 gcc/testsuite/gfortran.dg/gomp/pr99928-7.f90       | 106 +++++++++
 gcc/testsuite/gfortran.dg/gomp/pr99928-8.f90       | 252 +++++++++++++++++++++
 29 files changed, 1695 insertions(+), 150 deletions(-)

diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c
index 0e7fe1cc3f3..8e2df736d8c 100644
--- a/gcc/fortran/dump-parse-tree.c
+++ b/gcc/fortran/dump-parse-tree.c
@@ -1718,6 +1718,19 @@  show_omp_clauses (gfc_omp_clauses *omp_clauses)
 	}
       fprintf (dumpfile, " PROC_BIND(%s)", type);
     }
+  if (omp_clauses->bind != OMP_BIND_UNSET)
+    {
+      const char *type;
+      switch (omp_clauses->bind)
+	{
+	case OMP_BIND_TEAMS: type = "TEAMS"; break;
+	case OMP_BIND_PARALLEL: type = "PARALLEL"; break;
+	case OMP_BIND_THREAD: type = "THREAD"; break;
+	default:
+	  gcc_unreachable ();
+	}
+      fprintf (dumpfile, " BIND(%s)", type);
+    }
   if (omp_clauses->num_teams)
     {
       fputs (" NUM_TEAMS(", dumpfile);
@@ -1896,6 +1909,7 @@  show_omp_node (int level, gfc_code *c)
     case EXEC_OMP_DISTRIBUTE_SIMD: name = "DISTRIBUTE SIMD"; break;
     case EXEC_OMP_DO: name = "DO"; break;
     case EXEC_OMP_DO_SIMD: name = "DO SIMD"; break;
+    case EXEC_OMP_LOOP: name = "LOOP"; break;
     case EXEC_OMP_FLUSH: name = "FLUSH"; break;
     case EXEC_OMP_MASTER: name = "MASTER"; break;
     case EXEC_OMP_MASTER_TASKLOOP: name = "MASTER TASKLOOP"; break;
@@ -1905,6 +1919,7 @@  show_omp_node (int level, gfc_code *c)
     case EXEC_OMP_PARALLEL: name = "PARALLEL"; break;
     case EXEC_OMP_PARALLEL_DO: name = "PARALLEL DO"; break;
     case EXEC_OMP_PARALLEL_DO_SIMD: name = "PARALLEL DO SIMD"; break;
+    case EXEC_OMP_PARALLEL_LOOP: name = "PARALLEL LOOP"; break;
     case EXEC_OMP_PARALLEL_MASTER: name = "PARALLEL MASTER"; break;
     case EXEC_OMP_PARALLEL_MASTER_TASKLOOP:
       name = "PARALLEL MASTER TASKLOOP"; break;
@@ -1924,6 +1939,7 @@  show_omp_node (int level, gfc_code *c)
     case EXEC_OMP_TARGET_PARALLEL_DO: name = "TARGET PARALLEL DO"; break;
     case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
       name = "TARGET_PARALLEL_DO_SIMD"; break;
+    case EXEC_OMP_TARGET_PARALLEL_LOOP: name = "TARGET PARALLEL LOOP"; break;
     case EXEC_OMP_TARGET_SIMD: name = "TARGET SIMD"; break;
     case EXEC_OMP_TARGET_TEAMS: name = "TARGET TEAMS"; break;
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
@@ -1934,6 +1950,7 @@  show_omp_node (int level, gfc_code *c)
       name = "TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD"; break;
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
       name = "TARGET TEAMS DISTRIBUTE SIMD"; break;
+    case EXEC_OMP_TARGET_TEAMS_LOOP: name = "TARGET TEAMS LOOP"; break;
     case EXEC_OMP_TARGET_UPDATE: name = "TARGET UPDATE"; break;
     case EXEC_OMP_TASK: name = "TASK"; break;
     case EXEC_OMP_TASKGROUP: name = "TASKGROUP"; break;
@@ -1948,6 +1965,7 @@  show_omp_node (int level, gfc_code *c)
     case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
       name = "TEAMS DISTRIBUTE PARALLEL DO SIMD"; break;
     case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD: name = "TEAMS DISTRIBUTE SIMD"; break;
+    case EXEC_OMP_TEAMS_LOOP: name = "TEAMS LOOP"; break;
     case EXEC_OMP_WORKSHARE: name = "WORKSHARE"; break;
     default:
       gcc_unreachable ();
@@ -1977,10 +1995,12 @@  show_omp_node (int level, gfc_code *c)
     case EXEC_OMP_DISTRIBUTE_SIMD:
     case EXEC_OMP_DO:
     case EXEC_OMP_DO_SIMD:
+    case EXEC_OMP_LOOP:
     case EXEC_OMP_ORDERED:
     case EXEC_OMP_PARALLEL:
     case EXEC_OMP_PARALLEL_DO:
     case EXEC_OMP_PARALLEL_DO_SIMD:
+    case EXEC_OMP_PARALLEL_LOOP:
     case EXEC_OMP_PARALLEL_MASTER:
     case EXEC_OMP_PARALLEL_MASTER_TASKLOOP:
     case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
@@ -1997,12 +2017,14 @@  show_omp_node (int level, gfc_code *c)
     case EXEC_OMP_TARGET_PARALLEL:
     case EXEC_OMP_TARGET_PARALLEL_DO:
     case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
+    case EXEC_OMP_TARGET_PARALLEL_LOOP:
     case EXEC_OMP_TARGET_SIMD:
     case EXEC_OMP_TARGET_TEAMS:
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
+    case EXEC_OMP_TARGET_TEAMS_LOOP:
     case EXEC_OMP_TARGET_UPDATE:
     case EXEC_OMP_TASK:
     case EXEC_OMP_TASKLOOP:
@@ -2012,6 +2034,7 @@  show_omp_node (int level, gfc_code *c)
     case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
     case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
     case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
+    case EXEC_OMP_TEAMS_LOOP:
     case EXEC_OMP_WORKSHARE:
       omp_clauses = c->ext.omp_clauses;
       break;
diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c
index e3b1d1544aa..34fb22c5744 100644
--- a/gcc/fortran/frontend-passes.c
+++ b/gcc/fortran/frontend-passes.c
@@ -5542,6 +5542,7 @@  gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
 	    case EXEC_OMP_PARALLEL:
 	    case EXEC_OMP_PARALLEL_DO:
 	    case EXEC_OMP_PARALLEL_DO_SIMD:
+	    case EXEC_OMP_PARALLEL_LOOP:
 	    case EXEC_OMP_PARALLEL_MASTER:
 	    case EXEC_OMP_PARALLEL_MASTER_TASKLOOP:
 	    case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
@@ -5567,6 +5568,7 @@  gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
 	    case EXEC_OMP_DISTRIBUTE_SIMD:
 	    case EXEC_OMP_DO:
 	    case EXEC_OMP_DO_SIMD:
+	    case EXEC_OMP_LOOP:
 	    case EXEC_OMP_ORDERED:
 	    case EXEC_OMP_SECTIONS:
 	    case EXEC_OMP_SINGLE:
@@ -5581,12 +5583,14 @@  gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
 	    case EXEC_OMP_TARGET_PARALLEL:
 	    case EXEC_OMP_TARGET_PARALLEL_DO:
 	    case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
+	    case EXEC_OMP_TARGET_PARALLEL_LOOP:
 	    case EXEC_OMP_TARGET_SIMD:
 	    case EXEC_OMP_TARGET_TEAMS:
 	    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
 	    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
 	    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
 	    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
+	    case EXEC_OMP_TARGET_TEAMS_LOOP:
 	    case EXEC_OMP_TARGET_UPDATE:
 	    case EXEC_OMP_TASK:
 	    case EXEC_OMP_TEAMS:
@@ -5594,6 +5598,7 @@  gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
 	    case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
 	    case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
 	    case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
+	    case EXEC_OMP_TEAMS_LOOP:
 
 	      /* Come to this label only from the
 		 EXEC_OMP_PARALLEL_* cases above.  */
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 2020ab4a503..cbc95d3726d 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -271,7 +271,11 @@  enum gfc_statement
   ST_OMP_END_PARALLEL_MASTER_TASKLOOP, ST_OMP_PARALLEL_MASTER_TASKLOOP_SIMD,
   ST_OMP_END_PARALLEL_MASTER_TASKLOOP_SIMD, ST_OMP_MASTER_TASKLOOP,
   ST_OMP_END_MASTER_TASKLOOP, ST_OMP_MASTER_TASKLOOP_SIMD,
-  ST_OMP_END_MASTER_TASKLOOP_SIMD, ST_NONE
+  ST_OMP_END_MASTER_TASKLOOP_SIMD, ST_OMP_LOOP, ST_OMP_END_LOOP,
+  ST_OMP_PARALLEL_LOOP, ST_OMP_END_PARALLEL_LOOP, ST_OMP_TEAMS_LOOP,
+  ST_OMP_END_TEAMS_LOOP, ST_OMP_TARGET_PARALLEL_LOOP,
+  ST_OMP_END_TARGET_PARALLEL_LOOP, ST_OMP_TARGET_TEAMS_LOOP,
+  ST_OMP_END_TARGET_TEAMS_LOOP, ST_NONE
 };
 
 /* Types of interfaces that we can have.  Assignment interfaces are
@@ -1401,6 +1405,14 @@  enum gfc_omp_memorder
   OMP_MEMORDER_RELAXED
 };
 
+enum gfc_omp_bind_type
+{
+  OMP_BIND_UNSET,
+  OMP_BIND_TEAMS,
+  OMP_BIND_PARALLEL,
+  OMP_BIND_THREAD
+};
+
 typedef struct gfc_omp_clauses
 {
   struct gfc_expr *if_expr;
@@ -1421,6 +1433,7 @@  typedef struct gfc_omp_clauses
   enum gfc_omp_cancel_kind cancel;
   enum gfc_omp_proc_bind_kind proc_bind;
   enum gfc_omp_depend_op depobj_update;
+  enum gfc_omp_bind_type bind;
   struct gfc_expr *safelen_expr;
   struct gfc_expr *simdlen_expr;
   struct gfc_expr *num_teams;
@@ -2717,7 +2730,8 @@  enum gfc_exec_op
   EXEC_OMP_TASKLOOP, EXEC_OMP_TASKLOOP_SIMD, EXEC_OMP_SCAN, EXEC_OMP_DEPOBJ,
   EXEC_OMP_PARALLEL_MASTER, EXEC_OMP_PARALLEL_MASTER_TASKLOOP,
   EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD, EXEC_OMP_MASTER_TASKLOOP,
-  EXEC_OMP_MASTER_TASKLOOP_SIMD
+  EXEC_OMP_MASTER_TASKLOOP_SIMD, EXEC_OMP_LOOP, EXEC_OMP_PARALLEL_LOOP,
+  EXEC_OMP_TEAMS_LOOP, EXEC_OMP_TARGET_PARALLEL_LOOP, EXEC_OMP_TARGET_TEAMS_LOOP
 };
 
 typedef struct gfc_code
diff --git a/gcc/fortran/match.h b/gcc/fortran/match.h
index bcedf8ef806..bb1f34fc444 100644
--- a/gcc/fortran/match.h
+++ b/gcc/fortran/match.h
@@ -167,6 +167,7 @@  match gfc_match_omp_distribute_parallel_do_simd (void);
 match gfc_match_omp_distribute_simd (void);
 match gfc_match_omp_do (void);
 match gfc_match_omp_do_simd (void);
+match gfc_match_omp_loop (void);
 match gfc_match_omp_flush (void);
 match gfc_match_omp_master (void);
 match gfc_match_omp_master_taskloop (void);
@@ -176,6 +177,7 @@  match gfc_match_omp_ordered_depend (void);
 match gfc_match_omp_parallel (void);
 match gfc_match_omp_parallel_do (void);
 match gfc_match_omp_parallel_do_simd (void);
+match gfc_match_omp_parallel_loop (void);
 match gfc_match_omp_parallel_master (void);
 match gfc_match_omp_parallel_master_taskloop (void);
 match gfc_match_omp_parallel_master_taskloop_simd (void);
@@ -193,12 +195,14 @@  match gfc_match_omp_target_exit_data (void);
 match gfc_match_omp_target_parallel (void);
 match gfc_match_omp_target_parallel_do (void);
 match gfc_match_omp_target_parallel_do_simd (void);
+match gfc_match_omp_target_parallel_loop (void);
 match gfc_match_omp_target_simd (void);
 match gfc_match_omp_target_teams (void);
 match gfc_match_omp_target_teams_distribute (void);
 match gfc_match_omp_target_teams_distribute_parallel_do (void);
 match gfc_match_omp_target_teams_distribute_parallel_do_simd (void);
 match gfc_match_omp_target_teams_distribute_simd (void);
+match gfc_match_omp_target_teams_loop (void);
 match gfc_match_omp_target_update (void);
 match gfc_match_omp_task (void);
 match gfc_match_omp_taskgroup (void);
@@ -211,6 +215,7 @@  match gfc_match_omp_teams_distribute (void);
 match gfc_match_omp_teams_distribute_parallel_do (void);
 match gfc_match_omp_teams_distribute_parallel_do_simd (void);
 match gfc_match_omp_teams_distribute_simd (void);
+match gfc_match_omp_teams_loop (void);
 match gfc_match_omp_threadprivate (void);
 match gfc_match_omp_workshare (void);
 match gfc_match_omp_end_critical (void);
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 9dba165f990..d7136b1e6d7 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -846,6 +846,7 @@  enum omp_mask1
   OMP_CLAUSE_MEMORDER,  /* OpenMP 5.0.  */
   OMP_CLAUSE_DETACH,  /* OpenMP 5.0.  */
   OMP_CLAUSE_AFFINITY,  /* OpenMP 5.0.  */
+  OMP_CLAUSE_BIND,  /* OpenMP 5.0.  */
   OMP_CLAUSE_NOWAIT,
   /* This must come last.  */
   OMP_MASK1_LAST
@@ -1426,6 +1427,26 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 					   allow_derived))
 	    continue;
 	  break;
+	case 'b':
+	  if ((mask & OMP_CLAUSE_BIND)
+	      && c->bind == OMP_BIND_UNSET
+	      && gfc_match ("bind ( ") == MATCH_YES)
+	    {
+	      if (gfc_match ("teams )") == MATCH_YES)
+		c->bind = OMP_BIND_TEAMS;
+	      else if (gfc_match ("parallel )") == MATCH_YES)
+		c->bind = OMP_BIND_PARALLEL;
+	      else if (gfc_match ("thread )") == MATCH_YES)
+		c->bind = OMP_BIND_THREAD;
+	      else
+		{
+		  gfc_error ("Expected TEAMS, PARALLEL or THEAD as binding in "
+			     "BIND at %C");
+		  break;
+		}
+	      continue;
+	    }
+	  break;
 	case 'c':
 	  if ((mask & OMP_CLAUSE_CAPTURE)
 	      && !c->capture
@@ -3016,6 +3037,9 @@  cleanup:
    | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION			\
    | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED | OMP_CLAUSE_COLLAPSE	\
    | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER)
+#define OMP_LOOP_CLAUSES \
+  (omp_mask (OMP_CLAUSE_BIND) | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_ORDER	\
+   | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION)
 #define OMP_SECTIONS_CLAUSES \
   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE		\
    | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION)
@@ -3254,6 +3278,45 @@  gfc_match_omp_do_simd (void)
 }
 
 
+match
+gfc_match_omp_loop (void)
+{
+  return match_omp (EXEC_OMP_LOOP, OMP_LOOP_CLAUSES);
+}
+
+
+match
+gfc_match_omp_teams_loop (void)
+{
+  return match_omp (EXEC_OMP_TEAMS_LOOP, OMP_TEAMS_CLAUSES | OMP_LOOP_CLAUSES);
+}
+
+
+match
+gfc_match_omp_target_teams_loop (void)
+{
+  return match_omp (EXEC_OMP_TARGET_TEAMS_LOOP,
+		    OMP_TARGET_CLAUSES | OMP_TEAMS_CLAUSES | OMP_LOOP_CLAUSES);
+}
+
+
+match
+gfc_match_omp_parallel_loop (void)
+{
+  return match_omp (EXEC_OMP_PARALLEL_LOOP,
+		    OMP_PARALLEL_CLAUSES | OMP_LOOP_CLAUSES);
+}
+
+
+match
+gfc_match_omp_target_parallel_loop (void)
+{
+  return match_omp (EXEC_OMP_TARGET_PARALLEL_LOOP,
+		    (OMP_TARGET_CLAUSES | OMP_PARALLEL_CLAUSES
+		     | OMP_LOOP_CLAUSES));
+}
+
+
 match
 gfc_match_omp_flush (void)
 {
@@ -5889,14 +5952,19 @@  resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 		  {
 		  case OMP_LIST_REDUCTION_TASK:
 		    if (code
-			&& (code->op == EXEC_OMP_TASKLOOP
+			&& (code->op == EXEC_OMP_LOOP
+			    || code->op == EXEC_OMP_TASKLOOP
 			    || code->op == EXEC_OMP_TASKLOOP_SIMD
 			    || code->op == EXEC_OMP_MASTER_TASKLOOP
 			    || code->op == EXEC_OMP_MASTER_TASKLOOP_SIMD
+			    || code->op == EXEC_OMP_PARALLEL_LOOP
 			    || code->op == EXEC_OMP_PARALLEL_MASTER_TASKLOOP
 			    || code->op == EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD
+			    || code->op == EXEC_OMP_TARGET_PARALLEL_LOOP
+			    || code->op == EXEC_OMP_TARGET_TEAMS_LOOP
 			    || code->op == EXEC_OMP_TEAMS
-			    || code->op == EXEC_OMP_TEAMS_DISTRIBUTE))
+			    || code->op == EXEC_OMP_TEAMS_DISTRIBUTE
+			    || code->op == EXEC_OMP_TEAMS_LOOP))
 		      {
 			gfc_error ("Only DEFAULT permitted as reduction-"
 				   "modifier in REDUCTION clause at %L",
@@ -6953,11 +7021,13 @@  resolve_omp_do (gfc_code *code)
       break;
     case EXEC_OMP_DO: name = "!$OMP DO"; break;
     case EXEC_OMP_DO_SIMD: name = "!$OMP DO SIMD"; is_simd = true; break;
+    case EXEC_OMP_LOOP: name = "!$OMP LOOP"; break;
     case EXEC_OMP_PARALLEL_DO: name = "!$OMP PARALLEL DO"; break;
     case EXEC_OMP_PARALLEL_DO_SIMD:
       name = "!$OMP PARALLEL DO SIMD";
       is_simd = true;
       break;
+    case EXEC_OMP_PARALLEL_LOOP: name = "!$OMP PARALLEL LOOP"; break;
     case EXEC_OMP_PARALLEL_MASTER_TASKLOOP:
       name = "!$OMP PARALLEL MASTER TASKLOOP";
       break;
@@ -6976,6 +7046,9 @@  resolve_omp_do (gfc_code *code)
       name = "!$OMP TARGET PARALLEL DO SIMD";
       is_simd = true;
       break;
+    case EXEC_OMP_TARGET_PARALLEL_LOOP:
+      name = "!$OMP TARGET PARALLEL LOOP";
+      break;
     case EXEC_OMP_TARGET_SIMD:
       name = "!$OMP TARGET SIMD";
       is_simd = true;
@@ -6994,6 +7067,7 @@  resolve_omp_do (gfc_code *code)
       name = "!$OMP TARGET TEAMS DISTRIBUTE SIMD";
       is_simd = true;
       break;
+    case EXEC_OMP_TARGET_TEAMS_LOOP: name = "!$OMP TARGET TEAMS LOOP"; break;
     case EXEC_OMP_TASKLOOP: name = "!$OMP TASKLOOP"; break;
     case EXEC_OMP_TASKLOOP_SIMD:
       name = "!$OMP TASKLOOP SIMD";
@@ -7011,6 +7085,7 @@  resolve_omp_do (gfc_code *code)
       name = "!$OMP TEAMS DISTRIBUTE SIMD";
       is_simd = true;
       break;
+    case EXEC_OMP_TEAMS_LOOP: name = "!$OMP TEAMS LOOP"; break;
     default: gcc_unreachable ();
     }
 
@@ -7152,6 +7227,8 @@  omp_code_to_statement (gfc_code *code)
       return ST_OMP_PARALLEL_WORKSHARE;
     case EXEC_OMP_DO:
       return ST_OMP_DO;
+    case EXEC_OMP_LOOP:
+      return ST_OMP_LOOP;
     case EXEC_OMP_ATOMIC:
       return ST_OMP_ATOMIC;
     case EXEC_OMP_BARRIER:
@@ -7190,6 +7267,8 @@  omp_code_to_statement (gfc_code *code)
       return ST_OMP_TARGET_PARALLEL_DO;
     case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
       return ST_OMP_TARGET_PARALLEL_DO_SIMD;
+    case EXEC_OMP_TARGET_PARALLEL_LOOP:
+      return ST_OMP_TARGET_PARALLEL_LOOP;
     case EXEC_OMP_TARGET_SIMD:
       return ST_OMP_TARGET_SIMD;
     case EXEC_OMP_TARGET_TEAMS:
@@ -7202,6 +7281,8 @@  omp_code_to_statement (gfc_code *code)
       return ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD;
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
       return ST_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD;
+    case EXEC_OMP_TARGET_TEAMS_LOOP:
+      return ST_OMP_TARGET_TEAMS_LOOP;
     case EXEC_OMP_TARGET_UPDATE:
       return ST_OMP_TARGET_UPDATE;
     case EXEC_OMP_TASKGROUP:
@@ -7224,10 +7305,14 @@  omp_code_to_statement (gfc_code *code)
       return ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD;
     case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
       return ST_OMP_TEAMS_DISTRIBUTE_SIMD;
+    case EXEC_OMP_TEAMS_LOOP:
+      return ST_OMP_TEAMS_LOOP;
     case EXEC_OMP_PARALLEL_DO:
       return ST_OMP_PARALLEL_DO;
     case EXEC_OMP_PARALLEL_DO_SIMD:
       return ST_OMP_PARALLEL_DO_SIMD;
+    case EXEC_OMP_PARALLEL_LOOP:
+      return ST_OMP_PARALLEL_LOOP;
     case EXEC_OMP_DEPOBJ:
       return ST_OMP_DEPOBJ;
     default:
@@ -7628,8 +7713,10 @@  gfc_resolve_omp_directive (gfc_code *code, gfc_namespace *ns)
     case EXEC_OMP_DISTRIBUTE_SIMD:
     case EXEC_OMP_DO:
     case EXEC_OMP_DO_SIMD:
+    case EXEC_OMP_LOOP:
     case EXEC_OMP_PARALLEL_DO:
     case EXEC_OMP_PARALLEL_DO_SIMD:
+    case EXEC_OMP_PARALLEL_LOOP:
     case EXEC_OMP_PARALLEL_MASTER_TASKLOOP:
     case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
     case EXEC_OMP_MASTER_TASKLOOP:
@@ -7637,17 +7724,20 @@  gfc_resolve_omp_directive (gfc_code *code, gfc_namespace *ns)
     case EXEC_OMP_SIMD:
     case EXEC_OMP_TARGET_PARALLEL_DO:
     case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
+    case EXEC_OMP_TARGET_PARALLEL_LOOP:
     case EXEC_OMP_TARGET_SIMD:
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
+    case EXEC_OMP_TARGET_TEAMS_LOOP:
     case EXEC_OMP_TASKLOOP:
     case EXEC_OMP_TASKLOOP_SIMD:
     case EXEC_OMP_TEAMS_DISTRIBUTE:
     case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
     case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
     case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
+    case EXEC_OMP_TEAMS_LOOP:
       resolve_omp_do (code);
       break;
     case EXEC_OMP_CANCEL:
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index c44e23ccb62..0522b391393 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -988,6 +988,9 @@  decode_omp_directive (void)
 	      ST_OMP_MASTER_TASKLOOP);
       matcho ("master", gfc_match_omp_master, ST_OMP_MASTER);
       break;
+    case 'l':
+      matcho ("loop", gfc_match_omp_loop, ST_OMP_LOOP);
+      break;
     case 'o':
       if (gfc_match ("ordered depend (") == MATCH_YES)
 	{
@@ -1004,6 +1007,8 @@  decode_omp_directive (void)
       matchs ("parallel do simd", gfc_match_omp_parallel_do_simd,
 	      ST_OMP_PARALLEL_DO_SIMD);
       matcho ("parallel do", gfc_match_omp_parallel_do, ST_OMP_PARALLEL_DO);
+      matcho ("parallel loop", gfc_match_omp_parallel_loop,
+	      ST_OMP_PARALLEL_LOOP);
       matcho ("parallel master taskloop simd",
 	      gfc_match_omp_parallel_master_taskloop_simd,
 	      ST_OMP_PARALLEL_MASTER_TASKLOOP_SIMD);
@@ -1037,6 +1042,8 @@  decode_omp_directive (void)
 	      ST_OMP_TARGET_PARALLEL_DO_SIMD);
       matcho ("target parallel do", gfc_match_omp_target_parallel_do,
 	      ST_OMP_TARGET_PARALLEL_DO);
+      matcho ("target parallel loop", gfc_match_omp_target_parallel_loop,
+	      ST_OMP_TARGET_PARALLEL_LOOP);
       matcho ("target parallel", gfc_match_omp_target_parallel,
 	      ST_OMP_TARGET_PARALLEL);
       matchs ("target simd", gfc_match_omp_target_simd, ST_OMP_TARGET_SIMD);
@@ -1051,6 +1058,8 @@  decode_omp_directive (void)
 	      ST_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD);
       matcho ("target teams distribute", gfc_match_omp_target_teams_distribute,
 	      ST_OMP_TARGET_TEAMS_DISTRIBUTE);
+      matcho ("target teams loop", gfc_match_omp_target_teams_loop,
+	      ST_OMP_TARGET_TEAMS_LOOP);
       matcho ("target teams", gfc_match_omp_target_teams, ST_OMP_TARGET_TEAMS);
       matcho ("target update", gfc_match_omp_target_update,
 	      ST_OMP_TARGET_UPDATE);
@@ -1072,6 +1081,7 @@  decode_omp_directive (void)
 	      ST_OMP_TEAMS_DISTRIBUTE_SIMD);
       matcho ("teams distribute", gfc_match_omp_teams_distribute,
 	      ST_OMP_TEAMS_DISTRIBUTE);
+      matcho ("teams loop", gfc_match_omp_teams_loop, ST_OMP_TEAMS_LOOP);
       matcho ("teams", gfc_match_omp_teams, ST_OMP_TEAMS);
       matchdo ("threadprivate", gfc_match_omp_threadprivate,
 	       ST_OMP_THREADPRIVATE);
@@ -1125,9 +1135,11 @@  decode_omp_directive (void)
     case ST_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
     case ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
     case ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
+    case ST_OMP_TARGET_TEAMS_LOOP:
     case ST_OMP_TARGET_PARALLEL:
     case ST_OMP_TARGET_PARALLEL_DO:
     case ST_OMP_TARGET_PARALLEL_DO_SIMD:
+    case ST_OMP_TARGET_PARALLEL_LOOP:
     case ST_OMP_TARGET_SIMD:
     case ST_OMP_TARGET_UPDATE:
       {
@@ -1650,6 +1662,8 @@  next_statement (void)
   case ST_OMP_DISTRIBUTE_PARALLEL_DO_SIMD: case ST_OMP_TARGET_PARALLEL: \
   case ST_OMP_TARGET_PARALLEL_DO: case ST_OMP_TARGET_PARALLEL_DO_SIMD: \
   case ST_OMP_TARGET_SIMD: case ST_OMP_TASKLOOP: case ST_OMP_TASKLOOP_SIMD: \
+  case ST_OMP_LOOP: case ST_OMP_PARALLEL_LOOP: case ST_OMP_TEAMS_LOOP: \
+  case ST_OMP_TARGET_PARALLEL_LOOP: case ST_OMP_TARGET_TEAMS_LOOP: \
   case ST_CRITICAL: \
   case ST_OACC_PARALLEL_LOOP: case ST_OACC_PARALLEL: case ST_OACC_KERNELS: \
   case ST_OACC_DATA: case ST_OACC_HOST_DATA: case ST_OACC_LOOP: \
@@ -2359,6 +2373,9 @@  gfc_ascii_statement (gfc_statement st)
     case ST_OMP_END_SIMD:
       p = "!$OMP END SIMD";
       break;
+    case ST_OMP_END_LOOP:
+      p = "!$OMP END LOOP";
+      break;
     case ST_OMP_END_MASTER:
       p = "!$OMP END MASTER";
       break;
@@ -2380,6 +2397,9 @@  gfc_ascii_statement (gfc_statement st)
     case ST_OMP_END_PARALLEL_DO_SIMD:
       p = "!$OMP END PARALLEL DO SIMD";
       break;
+    case ST_OMP_END_PARALLEL_LOOP:
+      p = "!$OMP END PARALLEL LOOP";
+      break;
     case ST_OMP_END_PARALLEL_MASTER:
       p = "!$OMP END PARALLEL MASTER";
       break;
@@ -2419,6 +2439,9 @@  gfc_ascii_statement (gfc_statement st)
     case ST_OMP_END_TARGET_PARALLEL_DO_SIMD:
       p = "!$OMP END TARGET PARALLEL DO SIMD";
       break;
+    case ST_OMP_END_TARGET_PARALLEL_LOOP:
+      p = "!$OMP END TARGET PARALLEL LOOP";
+      break;
     case ST_OMP_END_TARGET_SIMD:
       p = "!$OMP END TARGET SIMD";
       break;
@@ -2437,6 +2460,9 @@  gfc_ascii_statement (gfc_statement st)
     case ST_OMP_END_TARGET_TEAMS_DISTRIBUTE_SIMD:
       p = "!$OMP END TARGET TEAMS DISTRIBUTE SIMD";
       break;
+    case ST_OMP_END_TARGET_TEAMS_LOOP:
+      p = "!$OMP END TARGET TEAMS LOOP";
+      break;
     case ST_OMP_END_TASKGROUP:
       p = "!$OMP END TASKGROUP";
       break;
@@ -2461,12 +2487,18 @@  gfc_ascii_statement (gfc_statement st)
     case ST_OMP_END_TEAMS_DISTRIBUTE_SIMD:
       p = "!$OMP END TEAMS DISTRIBUTE SIMD";
       break;
+    case ST_OMP_END_TEAMS_LOOP:
+      p = "!$OMP END TEAMS LOP";
+      break;
     case ST_OMP_END_WORKSHARE:
       p = "!$OMP END WORKSHARE";
       break;
     case ST_OMP_FLUSH:
       p = "!$OMP FLUSH";
       break;
+    case ST_OMP_LOOP:
+      p = "!$OMP LOOP";
+      break;
     case ST_OMP_MASTER:
       p = "!$OMP MASTER";
       break;
@@ -2486,6 +2518,9 @@  gfc_ascii_statement (gfc_statement st)
     case ST_OMP_PARALLEL_DO:
       p = "!$OMP PARALLEL DO";
       break;
+    case ST_OMP_PARALLEL_LOOP:
+      p = "!$OMP PARALLEL LOOP";
+      break;
     case ST_OMP_PARALLEL_DO_SIMD:
       p = "!$OMP PARALLEL DO SIMD";
       break;
@@ -2543,6 +2578,9 @@  gfc_ascii_statement (gfc_statement st)
     case ST_OMP_TARGET_PARALLEL_DO_SIMD:
       p = "!$OMP TARGET PARALLEL DO SIMD";
       break;
+    case ST_OMP_TARGET_PARALLEL_LOOP:
+      p = "!$OMP TARGET PARALLEL LOOP";
+      break;
     case ST_OMP_TARGET_SIMD:
       p = "!$OMP TARGET SIMD";
       break;
@@ -2561,6 +2599,9 @@  gfc_ascii_statement (gfc_statement st)
     case ST_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
       p = "!$OMP TARGET TEAMS DISTRIBUTE SIMD";
       break;
+    case ST_OMP_TARGET_TEAMS_LOOP:
+      p = "!$OMP TARGET TEAMS LOOP";
+      break;
     case ST_OMP_TARGET_UPDATE:
       p = "!$OMP TARGET UPDATE";
       break;
@@ -2597,6 +2638,9 @@  gfc_ascii_statement (gfc_statement st)
     case ST_OMP_TEAMS_DISTRIBUTE_SIMD:
       p = "!$OMP TEAMS DISTRIBUTE SIMD";
       break;
+    case ST_OMP_TEAMS_LOOP:
+      p = "!$OMP TEAMS LOOP";
+      break;
     case ST_OMP_THREADPRIVATE:
       p = "!$OMP THREADPRIVATE";
       break;
@@ -5044,10 +5088,14 @@  parse_omp_do (gfc_statement omp_st)
       break;
     case ST_OMP_DO: omp_end_st = ST_OMP_END_DO; break;
     case ST_OMP_DO_SIMD: omp_end_st = ST_OMP_END_DO_SIMD; break;
+    case ST_OMP_LOOP: omp_end_st = ST_OMP_END_LOOP; break;
     case ST_OMP_PARALLEL_DO: omp_end_st = ST_OMP_END_PARALLEL_DO; break;
     case ST_OMP_PARALLEL_DO_SIMD:
       omp_end_st = ST_OMP_END_PARALLEL_DO_SIMD;
       break;
+    case ST_OMP_PARALLEL_LOOP:
+      omp_end_st = ST_OMP_END_PARALLEL_LOOP;
+      break;
     case ST_OMP_SIMD: omp_end_st = ST_OMP_END_SIMD; break;
     case ST_OMP_TARGET_PARALLEL_DO:
       omp_end_st = ST_OMP_END_TARGET_PARALLEL_DO;
@@ -5055,6 +5103,9 @@  parse_omp_do (gfc_statement omp_st)
     case ST_OMP_TARGET_PARALLEL_DO_SIMD:
       omp_end_st = ST_OMP_END_TARGET_PARALLEL_DO_SIMD;
       break;
+    case ST_OMP_TARGET_PARALLEL_LOOP:
+      omp_end_st = ST_OMP_END_TARGET_PARALLEL_LOOP;
+      break;
     case ST_OMP_TARGET_SIMD: omp_end_st = ST_OMP_END_TARGET_SIMD; break;
     case ST_OMP_TARGET_TEAMS_DISTRIBUTE:
       omp_end_st = ST_OMP_END_TARGET_TEAMS_DISTRIBUTE;
@@ -5068,6 +5119,9 @@  parse_omp_do (gfc_statement omp_st)
     case ST_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
       omp_end_st = ST_OMP_END_TARGET_TEAMS_DISTRIBUTE_SIMD;
       break;
+    case ST_OMP_TARGET_TEAMS_LOOP:
+      omp_end_st = ST_OMP_END_TARGET_TEAMS_LOOP;
+      break;
     case ST_OMP_TASKLOOP: omp_end_st = ST_OMP_END_TASKLOOP; break;
     case ST_OMP_TASKLOOP_SIMD: omp_end_st = ST_OMP_END_TASKLOOP_SIMD; break;
     case ST_OMP_MASTER_TASKLOOP: omp_end_st = ST_OMP_END_MASTER_TASKLOOP; break;
@@ -5092,6 +5146,9 @@  parse_omp_do (gfc_statement omp_st)
     case ST_OMP_TEAMS_DISTRIBUTE_SIMD:
       omp_end_st = ST_OMP_END_TEAMS_DISTRIBUTE_SIMD;
       break;
+    case ST_OMP_TEAMS_LOOP:
+      omp_end_st = ST_OMP_END_TEAMS_LOOP;
+      break;
     default: gcc_unreachable ();
     }
   if (st == omp_end_st)
@@ -5323,12 +5380,6 @@  parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only)
     case ST_OMP_PARALLEL_MASTER:
       omp_end_st = ST_OMP_END_PARALLEL_MASTER;
       break;
-    case ST_OMP_PARALLEL_MASTER_TASKLOOP:
-      omp_end_st = ST_OMP_END_PARALLEL_MASTER_TASKLOOP;
-      break;
-    case ST_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
-      omp_end_st = ST_OMP_END_PARALLEL_MASTER_TASKLOOP_SIMD;
-      break;
     case ST_OMP_PARALLEL_SECTIONS:
       omp_end_st = ST_OMP_END_PARALLEL_SECTIONS;
       break;
@@ -5344,12 +5395,6 @@  parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only)
     case ST_OMP_MASTER:
       omp_end_st = ST_OMP_END_MASTER;
       break;
-    case ST_OMP_MASTER_TASKLOOP:
-      omp_end_st = ST_OMP_END_MASTER_TASKLOOP;
-      break;
-    case ST_OMP_MASTER_TASKLOOP_SIMD:
-      omp_end_st = ST_OMP_END_MASTER_TASKLOOP_SIMD;
-      break;
     case ST_OMP_SINGLE:
       omp_end_st = ST_OMP_END_SINGLE;
       break;
@@ -5365,18 +5410,6 @@  parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only)
     case ST_OMP_TARGET_TEAMS:
       omp_end_st = ST_OMP_END_TARGET_TEAMS;
       break;
-    case ST_OMP_TARGET_TEAMS_DISTRIBUTE:
-      omp_end_st = ST_OMP_END_TARGET_TEAMS_DISTRIBUTE;
-      break;
-    case ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
-      omp_end_st = ST_OMP_END_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO;
-      break;
-    case ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
-      omp_end_st = ST_OMP_END_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD;
-      break;
-    case ST_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
-      omp_end_st = ST_OMP_END_TARGET_TEAMS_DISTRIBUTE_SIMD;
-      break;
     case ST_OMP_TASK:
       omp_end_st = ST_OMP_END_TASK;
       break;
@@ -5389,27 +5422,9 @@  parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only)
     case ST_OMP_TEAMS_DISTRIBUTE:
       omp_end_st = ST_OMP_END_TEAMS_DISTRIBUTE;
       break;
-    case ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
-      omp_end_st = ST_OMP_END_TEAMS_DISTRIBUTE_PARALLEL_DO;
-      break;
-    case ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
-      omp_end_st = ST_OMP_END_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD;
-      break;
-    case ST_OMP_TEAMS_DISTRIBUTE_SIMD:
-      omp_end_st = ST_OMP_END_TEAMS_DISTRIBUTE_SIMD;
-      break;
     case ST_OMP_DISTRIBUTE:
       omp_end_st = ST_OMP_END_DISTRIBUTE;
       break;
-    case ST_OMP_DISTRIBUTE_PARALLEL_DO:
-      omp_end_st = ST_OMP_END_DISTRIBUTE_PARALLEL_DO;
-      break;
-    case ST_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
-      omp_end_st = ST_OMP_END_DISTRIBUTE_PARALLEL_DO_SIMD;
-      break;
-    case ST_OMP_DISTRIBUTE_SIMD:
-      omp_end_st = ST_OMP_END_DISTRIBUTE_SIMD;
-      break;
     case ST_OMP_WORKSHARE:
       omp_end_st = ST_OMP_END_WORKSHARE;
       break;
@@ -5689,8 +5704,10 @@  parse_executable (gfc_statement st)
 	case ST_OMP_DISTRIBUTE_SIMD:
 	case ST_OMP_DO:
 	case ST_OMP_DO_SIMD:
+	case ST_OMP_LOOP:
 	case ST_OMP_PARALLEL_DO:
 	case ST_OMP_PARALLEL_DO_SIMD:
+	case ST_OMP_PARALLEL_LOOP:
 	case ST_OMP_PARALLEL_MASTER_TASKLOOP:
 	case ST_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
 	case ST_OMP_MASTER_TASKLOOP:
@@ -5698,17 +5715,20 @@  parse_executable (gfc_statement st)
 	case ST_OMP_SIMD:
 	case ST_OMP_TARGET_PARALLEL_DO:
 	case ST_OMP_TARGET_PARALLEL_DO_SIMD:
+	case ST_OMP_TARGET_PARALLEL_LOOP:
 	case ST_OMP_TARGET_SIMD:
 	case ST_OMP_TARGET_TEAMS_DISTRIBUTE:
 	case ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
 	case ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
 	case ST_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
+	case ST_OMP_TARGET_TEAMS_LOOP:
 	case ST_OMP_TASKLOOP:
 	case ST_OMP_TASKLOOP_SIMD:
 	case ST_OMP_TEAMS_DISTRIBUTE:
 	case ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
 	case ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
 	case ST_OMP_TEAMS_DISTRIBUTE_SIMD:
+	case ST_OMP_TEAMS_LOOP:
 	  st = parse_omp_do (st);
 	  if (st == ST_IMPLIED_ENDDO)
 	    return st;
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index fed6dce3d98..a37ad665645 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -10797,6 +10797,7 @@  gfc_resolve_blocks (gfc_code *b, gfc_namespace *ns)
 	case EXEC_OMP_DISTRIBUTE_SIMD:
 	case EXEC_OMP_DO:
 	case EXEC_OMP_DO_SIMD:
+	case EXEC_OMP_LOOP:
 	case EXEC_OMP_MASTER:
 	case EXEC_OMP_MASTER_TASKLOOP:
 	case EXEC_OMP_MASTER_TASKLOOP_SIMD:
@@ -10804,6 +10805,7 @@  gfc_resolve_blocks (gfc_code *b, gfc_namespace *ns)
 	case EXEC_OMP_PARALLEL:
 	case EXEC_OMP_PARALLEL_DO:
 	case EXEC_OMP_PARALLEL_DO_SIMD:
+	case EXEC_OMP_PARALLEL_LOOP:
 	case EXEC_OMP_PARALLEL_MASTER:
 	case EXEC_OMP_PARALLEL_MASTER_TASKLOOP:
 	case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
@@ -10819,12 +10821,14 @@  gfc_resolve_blocks (gfc_code *b, gfc_namespace *ns)
 	case EXEC_OMP_TARGET_PARALLEL:
 	case EXEC_OMP_TARGET_PARALLEL_DO:
 	case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
+	case EXEC_OMP_TARGET_PARALLEL_LOOP:
 	case EXEC_OMP_TARGET_SIMD:
 	case EXEC_OMP_TARGET_TEAMS:
 	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
 	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
 	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
 	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
+	case EXEC_OMP_TARGET_TEAMS_LOOP:
 	case EXEC_OMP_TARGET_UPDATE:
 	case EXEC_OMP_TASK:
 	case EXEC_OMP_TASKGROUP:
@@ -10836,6 +10840,7 @@  gfc_resolve_blocks (gfc_code *b, gfc_namespace *ns)
 	case EXEC_OMP_TEAMS_DISTRIBUTE:
 	case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
 	case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
+	case EXEC_OMP_TEAMS_LOOP:
 	case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
 	case EXEC_OMP_WORKSHARE:
 	  break;
@@ -12219,6 +12224,7 @@  start:
 	case EXEC_OMP_DISTRIBUTE_SIMD:
 	case EXEC_OMP_DO:
 	case EXEC_OMP_DO_SIMD:
+	case EXEC_OMP_LOOP:
 	case EXEC_OMP_MASTER:
 	case EXEC_OMP_MASTER_TASKLOOP:
 	case EXEC_OMP_MASTER_TASKLOOP_SIMD:
@@ -12234,12 +12240,14 @@  start:
 	case EXEC_OMP_TARGET_PARALLEL:
 	case EXEC_OMP_TARGET_PARALLEL_DO:
 	case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
+	case EXEC_OMP_TARGET_PARALLEL_LOOP:
 	case EXEC_OMP_TARGET_SIMD:
 	case EXEC_OMP_TARGET_TEAMS:
 	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
 	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
 	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
 	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
+	case EXEC_OMP_TARGET_TEAMS_LOOP:
 	case EXEC_OMP_TARGET_UPDATE:
 	case EXEC_OMP_TASK:
 	case EXEC_OMP_TASKGROUP:
@@ -12252,6 +12260,7 @@  start:
 	case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
 	case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
 	case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
+	case EXEC_OMP_TEAMS_LOOP:
 	case EXEC_OMP_WORKSHARE:
 	  gfc_resolve_omp_directive (code, ns);
 	  break;
@@ -12259,6 +12268,7 @@  start:
 	case EXEC_OMP_PARALLEL:
 	case EXEC_OMP_PARALLEL_DO:
 	case EXEC_OMP_PARALLEL_DO_SIMD:
+	case EXEC_OMP_PARALLEL_LOOP:
 	case EXEC_OMP_PARALLEL_MASTER:
 	case EXEC_OMP_PARALLEL_MASTER_TASKLOOP:
 	case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
diff --git a/gcc/fortran/scanner.c b/gcc/fortran/scanner.c
index 74c5461ed6f..a04076d9c41 100644
--- a/gcc/fortran/scanner.c
+++ b/gcc/fortran/scanner.c
@@ -1406,11 +1406,11 @@  restart:
 	      if (i == 4)
 		old_loc = gfc_current_locus;
 	    }
-	  gfc_error (is_openmp
-		     ? G_("Wrong OpenACC continuation at %C: "
-			  "expected !$ACC, got !$OMP")
-		     : G_("Wrong OpenMP continuation at %C: "
-			  "expected !$OMP, got !$ACC"));
+	  gfc_fatal_error (is_openmp
+			   ? G_("Wrong OpenACC continuation at %C: "
+				"expected !$ACC, got !$OMP")
+			   : G_("Wrong OpenMP continuation at %C: "
+				"expected !$OMP, got !$ACC"));
 	}
 
       if (c != '&')
@@ -1511,11 +1511,17 @@  restart:
 	      if (gfc_wide_tolower (c) != (unsigned char) "*$acc"[i])
 		is_openmp = 1;
 	    }
-	  gfc_error (is_openmp
-		     ? G_("Wrong OpenACC continuation at %C: "
-			  "expected !$ACC, got !$OMP")
-		     : G_("Wrong OpenMP continuation at %C: "
-			  "expected !$OMP, got !$ACC"));
+	  c = next_char ();
+	  if (c == '0' || c == ' ' || c == '\n')
+	    {
+	      openacc_flag = openmp_flag = 0;
+	      goto not_continuation;  /* Not continued. */
+	    }
+	  gfc_fatal_error (is_openmp
+			   ? G_("Wrong OpenACC continuation at %C: "
+				"expected !$ACC, got !$OMP")
+			   : G_("Wrong OpenMP continuation at %C: "
+				"expected !$OMP, got !$ACC"));
 	}
       else if (!openmp_flag && !openacc_flag)
 	for (i = 0; i < 5; i++)
diff --git a/gcc/fortran/st.c b/gcc/fortran/st.c
index 9f6fe49db02..6ae1df612a7 100644
--- a/gcc/fortran/st.c
+++ b/gcc/fortran/st.c
@@ -225,6 +225,7 @@  gfc_free_statement (gfc_code *p)
     case EXEC_OMP_DISTRIBUTE_SIMD:
     case EXEC_OMP_DO:
     case EXEC_OMP_DO_SIMD:
+    case EXEC_OMP_LOOP:
     case EXEC_OMP_END_SINGLE:
     case EXEC_OMP_MASTER_TASKLOOP:
     case EXEC_OMP_MASTER_TASKLOOP_SIMD:
@@ -232,6 +233,7 @@  gfc_free_statement (gfc_code *p)
     case EXEC_OMP_PARALLEL:
     case EXEC_OMP_PARALLEL_DO:
     case EXEC_OMP_PARALLEL_DO_SIMD:
+    case EXEC_OMP_PARALLEL_LOOP:
     case EXEC_OMP_PARALLEL_MASTER:
     case EXEC_OMP_PARALLEL_MASTER_TASKLOOP:
     case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
@@ -248,12 +250,14 @@  gfc_free_statement (gfc_code *p)
     case EXEC_OMP_TARGET_PARALLEL:
     case EXEC_OMP_TARGET_PARALLEL_DO:
     case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
+    case EXEC_OMP_TARGET_PARALLEL_LOOP:
     case EXEC_OMP_TARGET_SIMD:
     case EXEC_OMP_TARGET_TEAMS:
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
+    case EXEC_OMP_TARGET_TEAMS_LOOP:
     case EXEC_OMP_TARGET_UPDATE:
     case EXEC_OMP_TASK:
     case EXEC_OMP_TASKLOOP:
@@ -263,6 +267,7 @@  gfc_free_statement (gfc_code *p)
     case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
     case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
     case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
+    case EXEC_OMP_TEAMS_LOOP:
     case EXEC_OMP_WORKSHARE:
       gfc_free_omp_clauses (p->ext.omp_clauses);
       break;
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c
index 2917d3d058b..93a98048818 100644
--- a/gcc/fortran/trans-openmp.c
+++ b/gcc/fortran/trans-openmp.c
@@ -4195,6 +4195,19 @@  gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
 	  OMP_CLAUSE_GANG_STATIC_EXPR (c) = arg;
 	}
     }
+  if (clauses->bind != OMP_BIND_UNSET)
+    {
+      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_BIND);
+      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
+      if (clauses->bind == OMP_BIND_TEAMS)
+        OMP_CLAUSE_BIND_KIND (c) = OMP_CLAUSE_BIND_TEAMS;
+      else if (clauses->bind == OMP_BIND_PARALLEL)
+        OMP_CLAUSE_BIND_KIND (c) = OMP_CLAUSE_BIND_PARALLEL;
+      else if (clauses->bind == OMP_BIND_THREAD)
+        OMP_CLAUSE_BIND_KIND (c) = OMP_CLAUSE_BIND_THREAD;
+      else
+	gcc_unreachable ();
+    }
 
   return nreverse (omp_clauses);
 }
@@ -5083,6 +5096,7 @@  gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock,
     case EXEC_OMP_SIMD: stmt = make_node (OMP_SIMD); break;
     case EXEC_OMP_DO: stmt = make_node (OMP_FOR); break;
     case EXEC_OMP_DISTRIBUTE: stmt = make_node (OMP_DISTRIBUTE); break;
+    case EXEC_OMP_LOOP: stmt = make_node (OMP_LOOP); break;
     case EXEC_OMP_TASKLOOP: stmt = make_node (OMP_TASKLOOP); break;
     case EXEC_OACC_LOOP: stmt = make_node (OACC_LOOP); break;
     default: gcc_unreachable ();
@@ -5343,6 +5357,7 @@  gfc_split_omp_clauses (gfc_code *code,
 		       gfc_omp_clauses clausesa[GFC_OMP_SPLIT_NUM])
 {
   int mask = 0, innermost = 0;
+  bool is_loop = false;
   memset (clausesa, 0, GFC_OMP_SPLIT_NUM * sizeof (gfc_omp_clauses));
   switch (code->op)
     {
@@ -5363,6 +5378,7 @@  gfc_split_omp_clauses (gfc_code *code,
       innermost = GFC_OMP_SPLIT_SIMD;
       break;
     case EXEC_OMP_DO:
+    case EXEC_OMP_LOOP:
       innermost = GFC_OMP_SPLIT_DO;
       break;
     case EXEC_OMP_DO_SIMD:
@@ -5373,6 +5389,7 @@  gfc_split_omp_clauses (gfc_code *code,
       innermost = GFC_OMP_SPLIT_PARALLEL;
       break;
     case EXEC_OMP_PARALLEL_DO:
+    case EXEC_OMP_PARALLEL_LOOP:
       mask = GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO;
       innermost = GFC_OMP_SPLIT_DO;
       break;
@@ -5399,6 +5416,7 @@  gfc_split_omp_clauses (gfc_code *code,
       innermost = GFC_OMP_SPLIT_PARALLEL;
       break;
     case EXEC_OMP_TARGET_PARALLEL_DO:
+    case EXEC_OMP_TARGET_PARALLEL_LOOP:
       mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO;
       innermost = GFC_OMP_SPLIT_DO;
       break;
@@ -5435,6 +5453,10 @@  gfc_split_omp_clauses (gfc_code *code,
 	     | GFC_OMP_MASK_DISTRIBUTE | GFC_OMP_MASK_SIMD;
       innermost = GFC_OMP_SPLIT_SIMD;
       break;
+    case EXEC_OMP_TARGET_TEAMS_LOOP:
+      mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DO;
+      innermost = GFC_OMP_SPLIT_DO;
+      break;
     case EXEC_OMP_MASTER_TASKLOOP:
     case EXEC_OMP_TASKLOOP:
       innermost = GFC_OMP_SPLIT_TASKLOOP;
@@ -5465,6 +5487,10 @@  gfc_split_omp_clauses (gfc_code *code,
       mask = GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DISTRIBUTE | GFC_OMP_MASK_SIMD;
       innermost = GFC_OMP_SPLIT_SIMD;
       break;
+    case EXEC_OMP_TEAMS_LOOP:
+      mask = GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DO;
+      innermost = GFC_OMP_SPLIT_DO;
+      break;
     default:
       gcc_unreachable ();
     }
@@ -5473,6 +5499,18 @@  gfc_split_omp_clauses (gfc_code *code,
       clausesa[innermost] = *code->ext.omp_clauses;
       return;
     }
+  /* Loops are similar to DO but still a bit different.  */
+  switch (code->op)
+    {
+    case EXEC_OMP_LOOP:
+    case EXEC_OMP_PARALLEL_LOOP:
+    case EXEC_OMP_TEAMS_LOOP:
+    case EXEC_OMP_TARGET_PARALLEL_LOOP:
+    case EXEC_OMP_TARGET_TEAMS_LOOP:
+      is_loop = true;
+    default:
+      break;
+    }
   if (code->ext.omp_clauses != NULL)
     {
       if (mask & GFC_OMP_MASK_TARGET)
@@ -5540,7 +5578,7 @@  gfc_split_omp_clauses (gfc_code *code,
 	  clausesa[GFC_OMP_SPLIT_PARALLEL].if_expr
 	    = code->ext.omp_clauses->if_expr;
 	}
-      if (mask & GFC_OMP_MASK_DO)
+      if ((mask & GFC_OMP_MASK_DO) && !is_loop)
 	{
 	  /* First the clauses that are unique to some constructs.  */
 	  clausesa[GFC_OMP_SPLIT_DO].ordered
@@ -5560,6 +5598,11 @@  gfc_split_omp_clauses (gfc_code *code,
 	    = code->ext.omp_clauses->chunk_size;
 	  clausesa[GFC_OMP_SPLIT_DO].nowait
 	    = code->ext.omp_clauses->nowait;
+	}
+      if (mask & GFC_OMP_MASK_DO)
+	{
+	  clausesa[GFC_OMP_SPLIT_DO].bind
+	    = code->ext.omp_clauses->bind;
 	  /* Duplicate collapse.  */
 	  clausesa[GFC_OMP_SPLIT_DO].collapse
 	    = code->ext.omp_clauses->collapse;
@@ -5621,7 +5664,7 @@  gfc_split_omp_clauses (gfc_code *code,
 	 it is enough to put it on the innermost one.  For
 	 !$ omp parallel do put it on parallel though,
 	 as that's what we did for OpenMP 3.1.  */
-      clausesa[innermost == GFC_OMP_SPLIT_DO
+      clausesa[innermost == GFC_OMP_SPLIT_DO && !is_loop
 	       ? (int) GFC_OMP_SPLIT_PARALLEL
 	       : innermost].lists[OMP_LIST_PRIVATE]
 	= code->ext.omp_clauses->lists[OMP_LIST_PRIVATE];
@@ -5637,19 +5680,25 @@  gfc_split_omp_clauses (gfc_code *code,
       else if (mask & GFC_OMP_MASK_DISTRIBUTE)
 	clausesa[GFC_OMP_SPLIT_DISTRIBUTE].lists[OMP_LIST_FIRSTPRIVATE]
 	  = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
+      if (mask & GFC_OMP_MASK_TASKLOOP)
+	clausesa[GFC_OMP_SPLIT_TASKLOOP].lists[OMP_LIST_FIRSTPRIVATE]
+	  = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
       if (mask & GFC_OMP_MASK_PARALLEL)
 	clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_FIRSTPRIVATE]
 	  = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
-      else if (mask & GFC_OMP_MASK_DO)
+      else if ((mask & GFC_OMP_MASK_DO) && !is_loop)
 	clausesa[GFC_OMP_SPLIT_DO].lists[OMP_LIST_FIRSTPRIVATE]
 	  = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
-      /* Lastprivate is allowed on distribute, do and simd.
+      /* Lastprivate is allowed on distribute, do, simd, taskloop and loop.
          In parallel do{, simd} we actually want to put it on
 	 parallel rather than do.  */
       if (mask & GFC_OMP_MASK_DISTRIBUTE)
 	clausesa[GFC_OMP_SPLIT_DISTRIBUTE].lists[OMP_LIST_LASTPRIVATE]
 	  = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
-      if (mask & GFC_OMP_MASK_PARALLEL)
+      if (mask & GFC_OMP_MASK_TASKLOOP)
+	clausesa[GFC_OMP_SPLIT_TASKLOOP].lists[OMP_LIST_LASTPRIVATE]
+	  = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
+      if ((mask & GFC_OMP_MASK_PARALLEL) && !is_loop)
 	clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_LASTPRIVATE]
 	  = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
       else if (mask & GFC_OMP_MASK_DO)
@@ -5658,17 +5707,25 @@  gfc_split_omp_clauses (gfc_code *code,
       if (mask & GFC_OMP_MASK_SIMD)
 	clausesa[GFC_OMP_SPLIT_SIMD].lists[OMP_LIST_LASTPRIVATE]
 	  = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
-      /* Reduction is allowed on simd, do, parallel and teams.
-	 Duplicate it on all of them, but omit on do if
-	 parallel is present; additionally, inscan applies to do/simd only.  */
+      /* Reduction is allowed on simd, do, parallel, teams, taskloop, and loop.
+	 Duplicate it on all of them, but
+	 - omit on do if parallel is present;
+	 - omit on task and parallel if loop is present;
+	 additionally, inscan applies to do/simd only.  */
       for (int i = OMP_LIST_REDUCTION; i <= OMP_LIST_REDUCTION_TASK; i++)
 	{
-	  if (mask & GFC_OMP_MASK_TEAMS
+	  if (mask & GFC_OMP_MASK_TASKLOOP
 	      && i != OMP_LIST_REDUCTION_INSCAN)
+	    clausesa[GFC_OMP_SPLIT_TASKLOOP].lists[i]
+	      = code->ext.omp_clauses->lists[i];
+	  if (mask & GFC_OMP_MASK_TEAMS
+	      && i != OMP_LIST_REDUCTION_INSCAN
+	      && !is_loop)
 	    clausesa[GFC_OMP_SPLIT_TEAMS].lists[i]
 	      = code->ext.omp_clauses->lists[i];
 	  if (mask & GFC_OMP_MASK_PARALLEL
-	      && i != OMP_LIST_REDUCTION_INSCAN)
+	      && i != OMP_LIST_REDUCTION_INSCAN
+	      && !is_loop)
 	    clausesa[GFC_OMP_SPLIT_PARALLEL].lists[i]
 	      = code->ext.omp_clauses->lists[i];
 	  else if (mask & GFC_OMP_MASK_DO)
@@ -5689,8 +5746,9 @@  gfc_split_omp_clauses (gfc_code *code,
       clausesa[innermost].lists[OMP_LIST_LINEAR]
 	= code->ext.omp_clauses->lists[OMP_LIST_LINEAR];
     }
-  if ((mask & (GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO))
-      == (GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO))
+   if (((mask & (GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO))
+	== (GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO))
+       && !is_loop)
     clausesa[GFC_OMP_SPLIT_DO].nowait = true;
 }
 
@@ -5740,7 +5798,7 @@  gfc_trans_omp_do_simd (gfc_code *code, stmtblock_t *pblock,
 }
 
 static tree
-gfc_trans_omp_parallel_do (gfc_code *code, stmtblock_t *pblock,
+gfc_trans_omp_parallel_do (gfc_code *code, bool is_loop, stmtblock_t *pblock,
 			   gfc_omp_clauses *clausesa)
 {
   stmtblock_t block, *new_pblock = pblock;
@@ -5768,8 +5826,9 @@  gfc_trans_omp_parallel_do (gfc_code *code, stmtblock_t *pblock,
       else
 	pushlevel ();
     }
-  stmt = gfc_trans_omp_do (code, EXEC_OMP_DO, new_pblock,
-			   &clausesa[GFC_OMP_SPLIT_DO], omp_clauses);
+  stmt = gfc_trans_omp_do (code, is_loop ? EXEC_OMP_LOOP : EXEC_OMP_DO,
+			   new_pblock, &clausesa[GFC_OMP_SPLIT_DO],
+			   omp_clauses);
   if (pblock == NULL)
     {
       if (TREE_CODE (stmt) != BIND_EXPR)
@@ -6006,7 +6065,7 @@  gfc_trans_omp_distribute (gfc_code *code, gfc_omp_clauses *clausesa)
     case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
     case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
-      stmt = gfc_trans_omp_parallel_do (code, &block, clausesa);
+      stmt = gfc_trans_omp_parallel_do (code, false, &block, clausesa);
       if (TREE_CODE (stmt) != BIND_EXPR)
 	stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
       else
@@ -6083,6 +6142,12 @@  gfc_trans_omp_teams (gfc_code *code, gfc_omp_clauses *clausesa,
 			       &clausesa[GFC_OMP_SPLIT_DISTRIBUTE],
 			       NULL);
       break;
+    case EXEC_OMP_TARGET_TEAMS_LOOP:
+    case EXEC_OMP_TEAMS_LOOP:
+      stmt = gfc_trans_omp_do (code, EXEC_OMP_LOOP, NULL,
+			       &clausesa[GFC_OMP_SPLIT_DO],
+			       NULL);
+      break;
     default:
       stmt = gfc_trans_omp_distribute (code, clausesa);
       break;
@@ -6140,7 +6205,11 @@  gfc_trans_omp_target (gfc_code *code)
       }
       break;
     case EXEC_OMP_TARGET_PARALLEL_DO:
-      stmt = gfc_trans_omp_parallel_do (code, &block, clausesa);
+    case EXEC_OMP_TARGET_PARALLEL_LOOP:
+      stmt = gfc_trans_omp_parallel_do (code,
+					(code->op
+					 == EXEC_OMP_TARGET_PARALLEL_LOOP),
+					&block, clausesa);
       if (TREE_CODE (stmt) != BIND_EXPR)
 	stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
       else
@@ -6611,6 +6680,7 @@  gfc_trans_omp_directive (gfc_code *code)
       return gfc_trans_omp_depobj (code);
     case EXEC_OMP_DISTRIBUTE:
     case EXEC_OMP_DO:
+    case EXEC_OMP_LOOP:
     case EXEC_OMP_SIMD:
     case EXEC_OMP_TASKLOOP:
       return gfc_trans_omp_do (code, code->op, NULL, code->ext.omp_clauses,
@@ -6633,7 +6703,9 @@  gfc_trans_omp_directive (gfc_code *code)
     case EXEC_OMP_PARALLEL:
       return gfc_trans_omp_parallel (code);
     case EXEC_OMP_PARALLEL_DO:
-      return gfc_trans_omp_parallel_do (code, NULL, NULL);
+      return gfc_trans_omp_parallel_do (code, false, NULL, NULL);
+    case EXEC_OMP_PARALLEL_LOOP:
+      return gfc_trans_omp_parallel_do (code, true, NULL, NULL);
     case EXEC_OMP_PARALLEL_DO_SIMD:
       return gfc_trans_omp_parallel_do_simd (code, NULL, NULL);
     case EXEC_OMP_PARALLEL_MASTER:
@@ -6652,12 +6724,14 @@  gfc_trans_omp_directive (gfc_code *code)
     case EXEC_OMP_TARGET_PARALLEL:
     case EXEC_OMP_TARGET_PARALLEL_DO:
     case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
+    case EXEC_OMP_TARGET_PARALLEL_LOOP:
     case EXEC_OMP_TARGET_SIMD:
     case EXEC_OMP_TARGET_TEAMS:
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
+    case EXEC_OMP_TARGET_TEAMS_LOOP:
       return gfc_trans_omp_target (code);
     case EXEC_OMP_TARGET_DATA:
       return gfc_trans_omp_target_data (code);
@@ -6682,6 +6756,7 @@  gfc_trans_omp_directive (gfc_code *code)
     case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
     case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
     case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
+    case EXEC_OMP_TEAMS_LOOP:
       return gfc_trans_omp_teams (code, NULL, NULL_TREE);
     case EXEC_OMP_WORKSHARE:
       return gfc_trans_omp_workshare (code, code->ext.omp_clauses);
diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c
index cbbfcd9d1bc..3ffa394d406 100644
--- a/gcc/fortran/trans.c
+++ b/gcc/fortran/trans.c
@@ -2168,6 +2168,7 @@  trans_code (gfc_code * code, tree cond)
 	case EXEC_OMP_DISTRIBUTE_SIMD:
 	case EXEC_OMP_DO:
 	case EXEC_OMP_DO_SIMD:
+	case EXEC_OMP_LOOP:
 	case EXEC_OMP_FLUSH:
 	case EXEC_OMP_MASTER:
 	case EXEC_OMP_MASTER_TASKLOOP:
@@ -2176,6 +2177,7 @@  trans_code (gfc_code * code, tree cond)
 	case EXEC_OMP_PARALLEL:
 	case EXEC_OMP_PARALLEL_DO:
 	case EXEC_OMP_PARALLEL_DO_SIMD:
+	case EXEC_OMP_PARALLEL_LOOP:
 	case EXEC_OMP_PARALLEL_MASTER:
 	case EXEC_OMP_PARALLEL_MASTER_TASKLOOP:
 	case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
@@ -2191,12 +2193,14 @@  trans_code (gfc_code * code, tree cond)
 	case EXEC_OMP_TARGET_PARALLEL:
 	case EXEC_OMP_TARGET_PARALLEL_DO:
 	case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
+	case EXEC_OMP_TARGET_PARALLEL_LOOP:
 	case EXEC_OMP_TARGET_SIMD:
 	case EXEC_OMP_TARGET_TEAMS:
 	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
 	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
 	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
 	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
+	case EXEC_OMP_TARGET_TEAMS_LOOP:
 	case EXEC_OMP_TARGET_UPDATE:
 	case EXEC_OMP_TASK:
 	case EXEC_OMP_TASKGROUP:
@@ -2209,6 +2213,7 @@  trans_code (gfc_code * code, tree cond)
 	case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
 	case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
 	case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
+	case EXEC_OMP_TEAMS_LOOP:
 	case EXEC_OMP_WORKSHARE:
 	  res = gfc_trans_omp_directive (code);
 	  break;
diff --git a/gcc/testsuite/gfortran.dg/goacc-gomp/mixed-1.f95 b/gcc/testsuite/gfortran.dg/goacc-gomp/mixed-1.f95
new file mode 100644
index 00000000000..685522695e0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc-gomp/mixed-1.f95
@@ -0,0 +1,30 @@ 
+! { dg-do compile } 
+
+module test
+contains
+  subroutine san
+    implicit none
+    integer :: i
+    !$omp do
+    !$acc loop ! { dg-error "Unexpected" }
+    do i = 1,5
+    enddo
+   end subroutine san
+
+   subroutine yon
+     implicit none
+     integer :: i
+     !$acc loop
+     !$omp do ! { dg-error "Expected DO loop" }
+     do i = 1,5
+     enddo
+   end subroutine yon
+
+   subroutine nana
+     !$acc parallel &
+     !$omp do ! { dg-error "Wrong OpenACC continuation" }
+     do i = 1, 5
+     end do
+   end subroutine nana
+end module test
+! { dg-prune-output "compilation terminated." }
diff --git a/gcc/testsuite/gfortran.dg/goacc-gomp/mixed-2.f95 b/gcc/testsuite/gfortran.dg/goacc-gomp/mixed-2.f95
new file mode 100644
index 00000000000..4c17334bea9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc-gomp/mixed-2.f95
@@ -0,0 +1,12 @@ 
+! { dg-do compile } 
+
+module test
+contains
+   subroutine nana
+     !$omp parallel &
+     !$acc loop ! { dg-error "Wrong OpenMP continuation" }
+     do i = 1, 5
+     end do
+   end subroutine nana
+end module test
+! { dg-prune-output "compilation terminated." }
diff --git a/gcc/testsuite/gfortran.dg/goacc/omp.f95 b/gcc/testsuite/gfortran.dg/goacc-gomp/mixed-3.f95
similarity index 58%
rename from gcc/testsuite/gfortran.dg/goacc/omp.f95
rename to gcc/testsuite/gfortran.dg/goacc-gomp/mixed-3.f95
index 339438ab772..4b9150806aa 100644
--- a/gcc/testsuite/gfortran.dg/goacc/omp.f95
+++ b/gcc/testsuite/gfortran.dg/goacc-gomp/mixed-3.f95
@@ -1,9 +1,8 @@ 
-! { dg-do compile } 
-! { dg-additional-options "-fopenmp" } 
+  ! { dg-do compile } 
 
 module test
 contains
-  subroutine ichi
+subroutine ichi
     implicit none
     integer :: i
     !$acc parallel
@@ -23,24 +22,6 @@  contains
     !$omp end parallel
   end subroutine ni
 
-  subroutine san
-    implicit none
-    integer :: i
-    !$omp do
-    !$acc loop ! { dg-error "Unexpected" }
-    do i = 1,5
-    enddo
-   end subroutine san
-
-   subroutine yon
-     implicit none
-     integer :: i
-     !$acc loop
-     !$omp do ! { dg-error "Expected DO loop" }
-     do i = 1,5
-     enddo
-   end subroutine yon
-
    subroutine go
      implicit none
      integer :: i, j
@@ -63,12 +44,4 @@  contains
      !$omp end parallel
      !$acc end data
    end subroutine roku
-
-   subroutine nana
-     !$acc parallel &
-     !$omp do ! { dg-error "Wrong OpenACC continuation" }
-
-     !$omp parallel &
-     !$acc loop ! { dg-error "Wrong OpenMP continuation" }
-   end subroutine nana
 end module test
diff --git a/gcc/testsuite/gfortran.dg/goacc-gomp/mixed-fixed-1.f b/gcc/testsuite/gfortran.dg/goacc-gomp/mixed-fixed-1.f
new file mode 100644
index 00000000000..de77c913220
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc-gomp/mixed-fixed-1.f
@@ -0,0 +1,12 @@ 
+! { dg-do compile }
+      SUBROUTINE NI
+      IMPLICIT NONE
+      INTEGER :: I
+
+!$ACC PARALLEL                                                          &
+!$OMP& DO ! { dg-error "Wrong OpenACC continuation" }
+      DO I = 1, 10
+      ENDDO
+
+      END SUBROUTINE NI
+! { dg-prune-output "compilation terminated." }
diff --git a/gcc/testsuite/gfortran.dg/goacc-gomp/mixed-fixed-2.f b/gcc/testsuite/gfortran.dg/goacc-gomp/mixed-fixed-2.f
new file mode 100644
index 00000000000..0f77848fa90
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc-gomp/mixed-fixed-2.f
@@ -0,0 +1,12 @@ 
+! { dg-do compile }
+
+      SUBROUTINE NI
+      IMPLICIT NONE
+      INTEGER :: I
+
+!$OMP PARALLEL                                                          &
+!$ACC& LOOP ! { dg-error "Wrong OpenMP continuation" }
+      DO I = 1, 10
+      ENDDO
+      END SUBROUTINE NI
+! { dg-prune-output "compilation terminated." }
diff --git a/gcc/testsuite/gfortran.dg/goacc-gomp/mixed-fixed-3.f b/gcc/testsuite/gfortran.dg/goacc-gomp/mixed-fixed-3.f
new file mode 100644
index 00000000000..1f9d728218c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc-gomp/mixed-fixed-3.f
@@ -0,0 +1,16 @@ 
+! { dg-do compile }
+
+      SUBROUTINE ICHI
+      INTEGER :: ARGC
+      ARGC = COMMAND_ARGUMENT_COUNT ()
+
+!$OMP PARALLEL
+!$ACC PARALLEL                                                          &
+!$ACC& COPYIN(ARGC) ! { dg-error "directive cannot be specified within" }
+      IF (ARGC .NE. 0) THEN
+         STOP 1
+      END IF
+!$ACC END PARALLEL
+!$OMP END PARALLEL
+
+      END SUBROUTINE ICHI
diff --git a/gcc/testsuite/gfortran.dg/goacc/omp-fixed.f b/gcc/testsuite/gfortran.dg/goacc/omp-fixed.f
deleted file mode 100644
index c6206e71773..00000000000
--- a/gcc/testsuite/gfortran.dg/goacc/omp-fixed.f
+++ /dev/null
@@ -1,32 +0,0 @@ 
-! { dg-do compile }
-! { dg-additional-options "-fopenmp" }
-      SUBROUTINE ICHI
-      INTEGER :: ARGC
-      ARGC = COMMAND_ARGUMENT_COUNT ()
-
-!$OMP PARALLEL
-!$ACC PARALLEL                                                          &
-!$ACC& COPYIN(ARGC) ! { dg-error "directive cannot be specified within" }
-      IF (ARGC .NE. 0) THEN
-         STOP 1
-      END IF
-!$ACC END PARALLEL
-!$OMP END PARALLEL
-
-      END SUBROUTINE ICHI
-
-
-      SUBROUTINE NI
-      IMPLICIT NONE
-      INTEGER :: I
-
-!$ACC PARALLEL                                                          &
-!$OMP& DO ! { dg-error "Wrong OpenACC continuation" }
-      DO I = 1, 10
-      ENDDO
-
-!$OMP PARALLEL                                                          &
-!$ACC& LOOP ! { dg-error "Wrong OpenMP continuation" }
-      DO I = 1, 10
-      ENDDO
-      END SUBROUTINE NI
diff --git a/gcc/testsuite/gfortran.dg/gomp/loop-1.f90 b/gcc/testsuite/gfortran.dg/gomp/loop-1.f90
new file mode 100644
index 00000000000..c112030a32c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/loop-1.f90
@@ -0,0 +1,56 @@ 
+! { dg-additional-options "-fdump-tree-original" }
+
+implicit none
+integer :: q, i, j
+integer :: r
+r = 0
+!$omp loop bind(thread) reduction(default,+: r) collapse(2) order(concurrent), private(q) lastprivate(i)
+do i = 1,4
+do j = 1,4
+  r = r + 1
+  q = 5
+end do
+end do
+
+!$omp teams loop bind(teams) collapse(2) order(concurrent), private(q) lastprivate(i) reduction(default,+: r) 
+do i = 1,4
+do j = 1,4
+  r = r + 1
+  q = 5
+end do
+end do
+
+!$omp target teams loop bind(thread) reduction(+: r) collapse(2) order(concurrent), private(q) lastprivate(i)
+do i = 1,4
+do j = 1,4
+  r = r + 1
+  q = 5
+end do
+end do
+
+!$omp parallel loop bind(thread) collapse(2) order(concurrent), private(q) lastprivate(i) reduction(default,+: r) 
+do i = 1,4
+do j = 1,4
+  r = r + 1
+  q = 5
+end do
+end do
+
+!$omp target parallel loop bind(parallel) collapse(2) order(concurrent), private(q) lastprivate(i) reduction(default,+: r) 
+do i = 1,4
+do j = 1,4
+  r = r + 1
+  q = 5
+end do
+end do
+
+end
+ 
+! TODO: xfailed due to PR99928: 
+! { dg-final { scan-tree-dump-times "#pragma omp target map\\(tofrom:r\\)\[\r\n\]" 2 "original" { xfail *-*-* } } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel\[\r\n\]" 2 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp teams\[\r\n\]" 2 "original" } }
+
+! { dg-final { scan-tree-dump-times "#pragma omp loop private\\(q\\) lastprivate\\(i\\) reduction\\(\\+:r\\) order\\(concurrent\\) collapse\\(2\\) bind\\(parallel\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp loop private\\(q\\) lastprivate\\(i\\) reduction\\(\\+:r\\) order\\(concurrent\\) collapse\\(2\\) bind\\(teams\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp loop private\\(q\\) lastprivate\\(i\\) reduction\\(\\+:r\\) order\\(concurrent\\) collapse\\(2\\) bind\\(thread\\)" 3 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/loop-2.f90 b/gcc/testsuite/gfortran.dg/gomp/loop-2.f90
new file mode 100644
index 00000000000..b2a0d1589e1
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/loop-2.f90
@@ -0,0 +1,44 @@ 
+subroutine foo()
+implicit none
+integer :: i, r
+!$omp loop reduction(task, +: r)  ! { dg-error "Only DEFAULT permitted as reduction-modifier in REDUCTION clause" }
+do i = 1, 64
+end do
+!$omp teams loop reduction(task, +: r)  ! { dg-error "Only DEFAULT permitted as reduction-modifier in REDUCTION clause" }
+do i = 1, 64
+end do
+!$omp parallel loop reduction(task, +: r)  ! { dg-error "Only DEFAULT permitted as reduction-modifier in REDUCTION clause" }
+do i = 1, 64
+end do
+!$omp target teams loop reduction(task, +: r)  ! { dg-error "Only DEFAULT permitted as reduction-modifier in REDUCTION clause" }
+do i = 1, 64
+end do
+!$omp target parallel loop reduction(task, +: r)  ! { dg-error "Only DEFAULT permitted as reduction-modifier in REDUCTION clause" }
+do i = 1, 64
+end do
+
+!$omp loop reduction(inscan, +: r)  ! { dg-error "'inscan' REDUCTION clause on construct other than DO, SIMD, DO SIMD, PARALLEL DO, PARALLEL DO SIMD" }
+do i = 1, 64
+end do
+!$omp teams loop reduction(inscan, +: r)  ! { dg-error "'inscan' REDUCTION clause on construct other than DO, SIMD, DO SIMD, PARALLEL DO, PARALLEL DO SIMD" }
+do i = 1, 64
+end do
+!$omp parallel loop reduction(inscan, +: r) ! { dg-error "'inscan' REDUCTION clause on construct other than DO, SIMD, DO SIMD, PARALLEL DO, PARALLEL DO SIMD" }
+do i = 1, 64
+end do
+!$omp target teams loop reduction(inscan, +: r)  ! { dg-error "'inscan' REDUCTION clause on construct other than DO, SIMD, DO SIMD, PARALLEL DO, PARALLEL DO SIMD" }
+do i = 1, 64
+end do
+!$omp target parallel loop reduction(inscan, +: r)  ! { dg-error "'inscan' REDUCTION clause on construct other than DO, SIMD, DO SIMD, PARALLEL DO, PARALLEL DO SIMD" }
+do i = 1, 64
+end do
+
+!$omp loop bind(target)  ! { dg-error "17: Expected TEAMS, PARALLEL or THEAD as binding in BIND" }
+do i = 1, 64
+end do
+
+!$omp loop bind(teams) bind(teams)  ! { dg-error "24: Failed to match clause" }
+do i = 1, 64
+end do
+
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr99928-1.f90 b/gcc/testsuite/gfortran.dg/gomp/pr99928-1.f90
new file mode 100644
index 00000000000..5cbffb09b3f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/pr99928-1.f90
@@ -0,0 +1,238 @@ 
+! PR middle-end/99928
+! { dg-do compile }
+! { dg-options "-fopenmp -fdump-tree-gimple" }
+
+module m
+  integer :: f00, f01, f02, f03, f04, f05, f06, f07, f08, f09
+  integer :: f12, f13, f14, f15, f16, f17, f18, f19
+  integer :: f20, f21, f22, f23, f24, f25, f26, f27, f28, f29
+
+contains
+
+subroutine foo ()
+  integer :: i
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*firstprivate\\(f00\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f00\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f00\\)" "gimple" } } ! FIXME. 
+  !$omp distribute parallel do firstprivate (f00) default(none)
+  do i = 1, 64
+    f00 = f00 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*firstprivate\\(f01\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f01\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f01\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f01\\)" "gimple" } }
+  !$omp distribute parallel do simd firstprivate (f01) default(none)
+  do i = 1, 64
+    f01 = f01 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*firstprivate\\(f02\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f02\\)" "gimple" } }
+  !$omp distribute simd firstprivate (f02)
+  do i = 1, 64
+    f02 = f02 + 1
+  end do
+end
+
+subroutine bar ()
+  integer :: f10, f11
+  integer :: i
+  f10 = 0; f11 = 0
+  ! { dg-final { scan-tree-dump "omp for\[^\n\r]*firstprivate\\(f03\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f03\\)" "gimple" } }
+  !$omp do simd firstprivate (f03)
+  do i = 1, 64
+    f03 = f03 + 1
+  end do
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(f04\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(f04\\)" "gimple" } }
+  !$omp master taskloop firstprivate (f04) default(none)
+  do i = 1, 64
+    f04 = f04 + 1
+  end do
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(f05\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(f05\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f05\\)" "gimple" } }
+  !$omp master taskloop simd firstprivate (f05) default(none)
+  do i = 1, 64
+    f05 = f05 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f06\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f06\\)" "gimple" } } ! FIXME. 
+  !$omp parallel do firstprivate (f06) default(none)
+  do i = 1, 64
+    f06 = f06 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f07\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f07\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f07\\)" "gimple" } }
+  !$omp parallel do simd firstprivate (f07) default(none)
+  do i = 1, 64
+    f07 = f07 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f08\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f08\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f08\\)" "gimple" } }
+  !$omp parallel loop firstprivate (f08) default(none)
+  do i = 1, 64
+    f08 = f08 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f09\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(f09\\)" "gimple" } }
+  !$omp parallel master firstprivate (f09) default(none)
+  f09 = f09 + 1
+  !$omp end parallel master
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(f10\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(f10\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(f10\\)" "gimple" } }
+  !$omp parallel master taskloop firstprivate (f10) default(none)
+  do i = 1, 64
+    f10 = f10 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(f11\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(f11\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(f11\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f11\\)" "gimple" } }
+  !$omp parallel master taskloop simd firstprivate (f11) default(none)
+  do i = 1, 64
+    f11 = f11 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f12\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp sections\[^\n\r]*firstprivate\\(f12\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp section \[^\n\r]*firstprivate\\(f12\\)" "gimple" } }
+  !$omp parallel sections firstprivate (f12) default(none)
+    f12 = f12 + 1
+    !$omp section
+    f12 = f12 + 1
+  !$omp end parallel sections
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*firstprivate\\(f13\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f13\\)" "gimple" } }
+  !$omp target parallel firstprivate (f13) default(none) ! defaultmap(none)
+  f13 = f13 + 1
+  !$omp end target parallel
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*firstprivate\\(f14\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f14\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f14\\)" "gimple" } } ! FIXME. 
+  !$omp target parallel do firstprivate (f14) default(none) ! defaultmap(none)
+  do i = 1, 64
+    f14 = f14 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*firstprivate\\(f15\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f15\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f15\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f15\\)" "gimple" } }
+  !$omp target parallel do simd firstprivate (f15) default(none) ! defaultmap(none)
+  do i = 1, 64
+    f15 = f15 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*firstprivate\\(f16\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f16\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f16\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f16\\)" "gimple" } }
+  !$omp target parallel loop firstprivate (f16) default(none) ! defaultmap(none)
+  do i = 1, 64
+    f16 = f16 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*firstprivate\\(f17\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(f17\\)" "gimple" } }
+  !$omp target teams firstprivate (f17) default(none) ! defaultmap(none)
+  f17 = f17 + 1
+  !$omp end target teams
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*firstprivate\\(f18\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(f18\\)" "gimple" } } ! FIXME: This should be on distribute instead. 
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*firstprivate\\(f18\\)" "gimple" } } ! FIXME. 
+  !$omp target teams distribute firstprivate (f18) default(none) ! defaultmap(none)
+  do i = 1, 64
+    f18 = f18 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*firstprivate\\(f19\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(f19\\)" "gimple" } } ! FIXME: This should be on distribute instead. 
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*firstprivate\\(f19\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f19\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f19\\)" "gimple" } } ! FIXME. 
+  !$omp target teams distribute parallel do firstprivate (f19) default(none) ! defaultmap(none)
+  do i = 1, 64
+    f19 = f19 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*firstprivate\\(f20\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(f20\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*firstprivate\\(f20\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f20\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f20\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f20\\)" "gimple" } }
+  !$omp target teams distribute parallel do simd firstprivate (f20) default(none) ! defaultmap(none)
+  do i = 1, 64
+    f20 = f20 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*firstprivate\\(f21\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(f21\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*firstprivate\\(f21\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f21\\)" "gimple" } }
+  !$omp target teams distribute simd firstprivate (f21) default(none) ! defaultmap(none)
+  do i = 1, 64
+    f21 = f21 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*firstprivate\\(f22\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(f22\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*firstprivate\\(f22\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(f22\\)" "gimple" } } ! NOTE: This is an implementation detail. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f22\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f22\\)" "gimple" } }
+  !$omp target teams loop firstprivate (f22) default(none) ! defaultmap(none)
+  do i = 1, 64
+    f22 = f22 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*firstprivate\\(f23\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f23\\)" "gimple" } }
+  !$omp target simd firstprivate (f23) ! defaultmap(none)
+  do i = 1, 64
+    f23 = f23 + 1
+  end do
+  !$omp end target simd
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(f24\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f24\\)" "gimple" } }
+  !$omp taskloop simd firstprivate (f24) default(none)
+  do i = 1, 64
+    f24 = f24 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(f25\\)" "gimple" } } ! FIXME: This should be on distribute instead. 
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*firstprivate\\(f25\\)" "gimple" } } ! FIXME. 
+  !$omp teams distribute firstprivate (f25) default(none)
+  do i = 1, 64
+    f25 = f25 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(f26\\)" "gimple" } } ! FIXME: This should be on distribute instead. 
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*firstprivate\\(f26\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f26\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f26\\)" "gimple" } } ! FIXME. 
+  !$omp teams distribute parallel do firstprivate (f26) default(none)
+  do i = 1, 64
+    f26 = f26 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(f27\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*firstprivate\\(f27\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(f27\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f27\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f27\\)" "gimple" } }
+  !$omp teams distribute parallel do simd firstprivate (f27) default(none)
+  do i = 1, 64
+    f27 = f27 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(f28\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*firstprivate\\(f28\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f28\\)" "gimple" } }
+  !$omp teams distribute simd firstprivate (f28) default(none)
+  do i = 1, 64
+    f28 = f28 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(f29\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*firstprivate\\(f29\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(f29\\)" "gimple" } } ! NOTE: This is an implementation detail. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(f29\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(f29\\)" "gimple" } }
+  !$omp teams loop firstprivate (f29) default(none)
+  do i = 1, 64
+    f29 = f29 + 1
+  end do
+end
+end module m
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr99928-11.f90 b/gcc/testsuite/gfortran.dg/gomp/pr99928-11.f90
new file mode 100644
index 00000000000..864ae4b6c99
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/pr99928-11.f90
@@ -0,0 +1,34 @@ 
+! PR middle-end/99928
+! { dg-do compile }
+! { dg-options "-fopenmp -fdump-tree-gimple" }
+
+module m
+  integer :: r00, r01, r02
+
+contains
+
+subroutine bar ()
+  integer :: i
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*in_reduction\\(\\+:r00\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*in_reduction\\(\\+:r00\\)" "gimple" } }
+  !$omp master taskloop in_reduction(+:r00)
+  do i = 1, 64
+    r00 = r00 + 1
+  end do
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*in_reduction\\(\\+:r01\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*in_reduction\\(\\+:r01\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*in_reduction\\(\\+:r01\\)" "gimple" } }
+  !$omp master taskloop simd in_reduction(+:r01)
+  do i = 1, 64
+    r01 = r01 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*in_reduction\\(\\+:r02\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*in_reduction\\(\\+:r02\\)" "gimple" } }
+  !$omp taskloop simd in_reduction(+:r02)
+  do i = 1, 64
+    r02 = r02 + 1
+  end do
+  ! FIXME: We don't support in_reduction clause on target yet, once we do, should
+  ! add testcase coverage for all combined/composite constructs with target as leaf construct. 
+end
+end module m
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr99928-2.f90 b/gcc/testsuite/gfortran.dg/gomp/pr99928-2.f90
new file mode 100644
index 00000000000..5dbf78ba291
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/pr99928-2.f90
@@ -0,0 +1,231 @@ 
+! PR middle-end/99928
+! { dg-do compile }
+! { dg-options "-fopenmp -fdump-tree-gimple" }
+
+module m
+  integer :: l00, l01, l02, l03, l04, l05, l06, l07
+  integer :: l10, l11, l12, l13, l14, l15, l16, l17, l18
+
+contains
+
+subroutine foo ()
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l00\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l00\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l00\\)" "gimple" } } ! FIXME. 
+  !$omp distribute parallel do lastprivate (l00) default(none)
+  do i = 1, 64
+    l00 = i
+  end do
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l01\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l01\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l01\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l01\\)" "gimple" } }
+  !$omp distribute parallel do simd lastprivate (l01) default(none)
+  do i = 1, 64
+    l01 = i
+  end do
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l02\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l02\\)" "gimple" } }
+  !$omp distribute simd lastprivate (l02)
+  do i = 1, 64
+    l02 = i
+  end do
+end
+
+subroutine bar ()
+  integer :: j00, j01, j02, j03
+  integer :: l08, l09, l19, l20, l21, l22
+  integer :: i
+  l08 = 0; l09 = 0; l19 = 0; l20 = 0; l21 = 0; l22 = 0
+  ! { dg-final { scan-tree-dump "omp for\[^\n\r]*lastprivate\\(l03\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l03\\)" "gimple" } }
+  !$omp do simd lastprivate (l03)
+  do i = 1, 64
+    l03 = i
+  end do
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l04\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*shared\\(l04\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l04\\)" "gimple" } }
+  !$omp master taskloop lastprivate (l04) default(none)
+  do i = 1, 64
+    l04 = i
+  end do
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l05\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*shared\\(l05\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l05\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l05\\)" "gimple" } }
+  !$omp master taskloop simd lastprivate (l05) default(none)
+  do i = 1, 64
+    l05 = i
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l06\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l06\\)" "gimple" } } ! FIXME. 
+  !$omp parallel do lastprivate (l06) default(none)
+  do i = 1, 64
+    l06 = i
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l07\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l07\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l07\\)" "gimple" } }
+  !$omp parallel do simd lastprivate (l07) default(none)
+  do i = 1, 64
+    l07 = i
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(j00\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp for\[^\n\r]*lastprivate\\(j00\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(j00\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  !$omp parallel loop lastprivate (j00) default(none)
+  do j00 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(l08\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l08\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*shared\\(l08\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l08\\)" "gimple" } }
+  !$omp parallel master taskloop lastprivate (l08) default(none)
+  do i = 1, 64
+    l08 = i
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(l09\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l09\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*shared\\(l09\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l09\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l09\\)" "gimple" } }
+  !$omp parallel master taskloop simd lastprivate (l09) default(none)
+  do i = 1, 64
+    l09 = i
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l10\\)" "gimple" } } ! FIXME: This should be on sections instead. 
+  ! { dg-final { scan-tree-dump-not "omp sections\[^\n\r]*lastprivate\\(l10\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump-not "omp section \[^\n\r]*lastprivate\\(l10\\)" "gimple" } }
+  !$omp parallel sections lastprivate (l10) default(none)
+    l10 = 1
+    !$omp section
+    l10 = 2
+  !$omp end parallel sections
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l11" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l11\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l11\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l11\\)" "gimple" } } ! FIXME. 
+  !$omp target parallel do lastprivate (l11) default(none) ! defaultmap(none)
+  do i = 1, 64
+    l11 = i
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l12" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l12\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l12\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l12\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l12\\)" "gimple" } }
+  !$omp target parallel do simd lastprivate (l12) default(none) ! defaultmap(none)
+  do i = 1, 64
+    l12 = i
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j01" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j01\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(j01\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp for\[^\n\r]*lastprivate\\(j01\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(j01\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  !$omp target parallel loop lastprivate (j01) default(none) ! defaultmap(none)
+  do j01 = 0, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l13" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l13\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(l13\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l13\\)" "gimple" } }
+  !$omp target teams distribute lastprivate (l13) default(none) ! defaultmap(none)
+  do i = 1, 64
+    l13 = i
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l14" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l14\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(l14\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l14\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l14\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l14\\)" "gimple" } } ! FIXME. 
+  !$omp target teams distribute parallel do lastprivate (l14) default(none) ! defaultmap(none)
+  do i = 1, 64
+    l14 = i
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l15" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l15\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(l15\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l15\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l15\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l15\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l15\\)" "gimple" } }
+  !$omp target teams distribute parallel do simd lastprivate (l15) default(none) ! defaultmap(none)
+  do i = 1, 64
+    l15 = i
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l16" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l16\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(l16\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l16\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l16\\)" "gimple" } }
+  !$omp target teams distribute simd lastprivate (l16) default(none) ! defaultmap(none)
+  do i = 1, 64
+    l16 = i
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j02" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j02\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(j02\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j02\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(j02\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp for\[^\n\r]*lastprivate\\(j02\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(j02\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  !$omp target teams loop lastprivate (j02) default(none) ! defaultmap(none)
+  do j02 = 0, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l17" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l17\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l17\\)" "gimple" } }
+  !$omp target simd lastprivate (l17) ! defaultmap(none)
+  do i = 1, 64
+    l17 = i
+  end do
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*shared\\(l18\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l18\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l18\\)" "gimple" } }
+  !$omp taskloop simd lastprivate (l18) default(none)
+  do i = 1, 64
+    l18 = i
+  end do
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(l19\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l19\\)" "gimple" } }
+  !$omp teams distribute lastprivate (l19) default(none)
+  do i = 1, 64
+    l19 = i
+  end do
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(l20\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l20\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l20\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l20\\)" "gimple" } } ! FIXME. 
+ !$omp teams distribute parallel do lastprivate (l20) default(none)
+  do i = 1, 64
+    l20 = i
+  end do
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(l21\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l21\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l21\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l21\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l21\\)" "gimple" } }
+ !$omp teams distribute parallel do simd lastprivate (l21) default(none)
+  do i = 1, 64
+    l21 = i
+  end do
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(l22\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l22\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l22\\)" "gimple" } }
+  !$omp teams distribute simd lastprivate (l22) default(none)
+  do i = 1, 64
+    l22 = i
+  end do
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(j03\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j03\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(j03\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp for\[^\n\r]*lastprivate\\(j03\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(j03\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  !$omp teams loop lastprivate (j03) default(none)
+  do j03 = 1, 64
+  end do
+end
+end module m
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr99928-3.f90 b/gcc/testsuite/gfortran.dg/gomp/pr99928-3.f90
index ce43dfb8ccd..854b9d6f2e1 100644
--- a/gcc/testsuite/gfortran.dg/gomp/pr99928-3.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/pr99928-3.f90
@@ -25,17 +25,17 @@  subroutine bar ()
   ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l01\\)" "gimple" } }
   ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l01\\)" "gimple" } }
   ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l01\\)" "gimple" } }
-  !$omp master taskloop firstprivate (l01) lastprivate (l01)
+  !$omp master taskloop firstprivate (l01) lastprivate (l01) default(none)
   do i = 1, 64
     l01 = i
   end do
   ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(l02\\)" "gimple" } }
   ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l02\\)" "gimple" } }
-  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l02\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l02\\)" "gimple" } }
   ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l02\\)" "gimple" } }
   ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(l02\\)" "gimple" } }
   ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l02\\)" "gimple" } }
-  !$omp master taskloop simd firstprivate (l02) lastprivate (l02)
+  !$omp master taskloop simd firstprivate (l02) lastprivate (l02) default(none)
   do i = 1, 64
     l02 = i
   end do
@@ -43,7 +43,7 @@  subroutine bar ()
   ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l03\\)" "gimple" } } ! FIXME: This should be on for instead. 
   ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(l03\\)" "gimple" } } ! FIXME. 
   ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l03\\)" "gimple" } } ! FIXME. 
-  !$omp parallel do firstprivate (l03) lastprivate (l03)
+  !$omp parallel do firstprivate (l03) lastprivate (l03) default(none)
   do i = 1, 64
     l03 = i
   end do
@@ -54,7 +54,7 @@  subroutine bar ()
   ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l04\\)" "gimple" } } ! FIXME. 
   ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(l04\\)" "gimple" } }
   ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l04\\)" "gimple" } }
-  !$omp parallel do simd firstprivate (l04) lastprivate (l04)
+  !$omp parallel do simd firstprivate (l04) lastprivate (l04) default(none)
   do i = 1, 64
     l04 = i
   end do
@@ -63,19 +63,19 @@  subroutine bar ()
   ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(l05\\)" "gimple" } }
   ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l05\\)" "gimple" } }
   ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l05\\)" "gimple" } }
-  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l05\\)" "gimple" { xfail *-*-* } } }
-  !$omp parallel master taskloop firstprivate (l05) lastprivate (l05)
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l05\\)" "gimple" } }
+  !$omp parallel master taskloop firstprivate (l05) lastprivate (l05) default(none)
   do i = 1, 64
     l05 = i
   end do
   ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(l06\\)" "gimple" { xfail *-*-* } } }
   ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(l06\\)" "gimple" } }
   ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l06\\)" "gimple" } }
-  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l06\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l06\\)" "gimple" } }
   ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l06\\)" "gimple" } }
   ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(l06\\)" "gimple" } }
   ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l06\\)" "gimple" } }
-  !$omp parallel master taskloop simd firstprivate (l06) lastprivate (l06)
+  !$omp parallel master taskloop simd firstprivate (l06) lastprivate (l06) default(none)
   do i = 1, 64
     l06 = i
   end do
@@ -90,7 +90,7 @@  subroutine bar ()
   ! { dg-final { scan-tree-dump-not "omp sections\[^\n\r]*lastprivate\\(l07\\)" "gimple" } }
   ! { dg-final { scan-tree-dump-not "omp section \[^\n\r]*firstprivate\\(l07\\)" "gimple" } }
   ! { dg-final { scan-tree-dump-not "omp section \[^\n\r]*lastprivate\\(l07\\)" "gimple" } }
-  !$omp parallel sections firstprivate (l07) lastprivate (l07)
+  !$omp parallel sections firstprivate (l07) lastprivate (l07) default(none)
     l07 = 1
     !$omp section
     l07 = 2
@@ -101,7 +101,7 @@  subroutine bar ()
   ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l08\\)" "gimple" } } ! FIXME: This should be on for instead. 
   ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(l08\\)" "gimple" } } ! FIXME. 
   ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l08\\)" "gimple" } } ! FIXME. 
-  !$omp target parallel do firstprivate (l08) lastprivate (l08)
+  !$omp target parallel do firstprivate (l08) lastprivate (l08) default(none) ! defaultmap(none)
   do i = 1, 64
     l08 = i
   end do
@@ -114,7 +114,7 @@  subroutine bar ()
   ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l09\\)" "gimple" } } ! FIXME. 
   ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(l09\\)" "gimple" } }
   ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l09\\)" "gimple" } }
-  !$omp target parallel do simd firstprivate (l09) lastprivate (l09)
+  !$omp target parallel do simd firstprivate (l09) lastprivate (l09) default(none) ! defaultmap(none)
   do i = 1, 64
     l09 = i
   end do
@@ -122,15 +122,15 @@  subroutine bar ()
   ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l10\\)" "gimple" { xfail *-*-* } } }
   ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(l10\\)" "gimple" } }
   ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l10\\)" "gimple" } }
-  !$omp target simd firstprivate (l10) lastprivate (l10)
+  !$omp target simd firstprivate (l10) lastprivate (l10) ! defaultmap(none)
   do i = 1, 64
     l10 = i
   end do
-  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l11\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l11\\)" "gimple" } }
   ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l11\\)" "gimple" } }
   ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(l11\\)" "gimple" } }
   ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l11\\)" "gimple" } }
- !$omp taskloop simd firstprivate (l11) lastprivate (l11)
+ !$omp taskloop simd firstprivate (l11) lastprivate (l11) default(none)
   do i = 1, 64
     l11 = i
   end do
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr99928-4.f90 b/gcc/testsuite/gfortran.dg/gomp/pr99928-4.f90
new file mode 100644
index 00000000000..5b82dd6581c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/pr99928-4.f90
@@ -0,0 +1,89 @@ 
+! PR middle-end/99928
+! { dg-do compile }
+! { dg-options "-fopenmp -fdump-tree-gimple" }
+
+module m
+  integer :: l00, l01, l05, l06, l07, l08
+
+contains
+
+subroutine bar ()
+  integer :: l02, l03, l04
+  integer :: i
+  l02 = 0; l03 = 0; l04 = 0
+  ! { dg-final { scan-tree-dump "omp for\[^\n\r]*firstprivate\\(l00\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp for\[^\n\r]*lastprivate\\(l00\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(l00:1\\)" "gimple" } }
+  !$omp do simd linear (l00)
+  do i = 1, 64
+    l00 = l00 + 1
+  end do
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(l01\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l01\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l01\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l01\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(l01:1\\)" "gimple" } }
+  !$omp master taskloop simd linear (l01) default(none)
+  do i = 1, 64
+    l01 = l01 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(l02\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp for\[^\n\r]*linear\\(l02:1\\)" "gimple" } }
+  !$omp parallel do linear (l02) default(none)
+  do i = 1, 64
+    l02 = l02 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(l03\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l03\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(l03\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l03\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(l03:1\\)" "gimple" } }
+  !$omp parallel do simd linear (l03) default(none)
+  do i = 1, 64
+    l03 = l03 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(l04\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(l04\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l04\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l04\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l04\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(l04:1\\)" "gimple" } }
+  !$omp parallel master taskloop simd linear (l04) default(none)
+  do i = 1, 64
+    l04 = l04 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l05" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l05\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(l05\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp for\[^\n\r]*linear\\(l05:1\\)" "gimple" } }
+  !$omp target parallel do linear (l05) default(none) ! defaultmap(none)
+  do i = 1, 64
+    l05 = l05 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l06" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l06\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(l06\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l06\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(l06\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l06\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(l06:1\\)" "gimple" } }
+  !$omp target parallel do simd linear (l06) default(none) ! defaultmap(none)
+  do i = 1, 64
+    l06 = l06 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l07" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l07\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(l07:1\\)" "gimple" } }
+  !$omp target simd linear (l07) ! defaultmap(none)
+  do i = 1, 64
+    l07 = l07 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l08\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l08\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(l08:1\\)" "gimple" } }
+  !$omp taskloop simd linear (l08) default(none)
+  do i = 1, 64
+    l08 = l08 + 1
+  end do
+end
+end module m
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr99928-5.f90 b/gcc/testsuite/gfortran.dg/gomp/pr99928-5.f90
new file mode 100644
index 00000000000..9f45e48feb4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/pr99928-5.f90
@@ -0,0 +1,107 @@ 
+! PR middle-end/99928
+! { dg-do compile }
+! { dg-options "-fopenmp -fdump-tree-gimple" }
+
+module m
+  integer :: j00, j01, j02, j03, j04, j06, j07, j08, j09
+  integer :: j10
+
+contains
+
+subroutine foo ()
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j00\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(j00\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j00\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j00:1\\)" "gimple" } }
+  !$omp distribute parallel do simd linear (j00) default(none)
+  do j00 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j01\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j01:1\\)" "gimple" } }
+  !$omp distribute simd linear (j01)
+  do j01 = 1, 64
+  end do
+end
+
+subroutine bar ()
+  integer :: j05, j11, j12
+  ! { dg-final { scan-tree-dump "omp for\[^\n\r]*lastprivate\\(j02\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j02:1\\)" "gimple" } }
+  !$omp do simd linear (j02)
+  do j02 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(j03\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*shared\\(j03\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(j03\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j03:1\\)" "gimple" } }
+  !$omp master taskloop simd linear (j03) default(none)
+  do j03 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(j04\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j04\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j04:1\\)" "gimple" } }
+  !$omp parallel do simd linear (j04) default(none)
+  do j04 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(j05\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(j05\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*shared\\(j05\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(j05\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j05:1\\)" "gimple" } }
+  !$omp parallel master taskloop simd linear (j05) default(none)
+  do j05 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j06" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j06\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(j06\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j06\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j06:1\\)" "gimple" } }
+  !$omp target parallel do simd linear (j06) default(none) ! defaultmap(none)
+  do j06 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j07" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j07\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j07:1\\)" "gimple" } }
+  !$omp target simd linear (j07) ! defaultmap(none)
+  do j07 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j08" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j08\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(j08\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j08\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(j08\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j08\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j08:1\\)" "gimple" } }
+  !$omp target teams distribute parallel do simd linear (j08) default(none) ! defaultmap(none)
+  do j08 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j09" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j09\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(j09\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j09\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j09:1\\)" "gimple" } }
+  !$omp target teams distribute simd linear (j09) default(none) ! defaultmap(none)
+  do j09 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*shared\\(j10\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(j10\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j10:1\\)" "gimple" { xfail *-*-* } } }
+  !$omp taskloop simd linear (j10) default(none)
+  do j010 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(j11\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j11\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(j11\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j11\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j11:1\\)" "gimple" } }
+  !$omp teams distribute parallel do simd linear (j11) default(none)
+  do j11 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(j12\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j12\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j12:1\\)" "gimple" } }
+  !$omp teams distribute simd linear (j12) default(none)
+  do j12 = 1, 64
+  end do
+end
+end module m
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr99928-6.f90 b/gcc/testsuite/gfortran.dg/gomp/pr99928-6.f90
new file mode 100644
index 00000000000..37a93e6b1ac
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/pr99928-6.f90
@@ -0,0 +1,107 @@ 
+! PR middle-end/99928
+! { dg-do compile }
+! { dg-options "-fopenmp -fdump-tree-gimple" }
+
+module m
+  integer :: j00, j01, j02, j03, j04, j06, j07, j08, j09
+  integer :: j10
+
+contains
+
+subroutine foo ()
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j00\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(j00\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j00\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j00:1\\)" "gimple" } }
+  !$omp distribute parallel do simd default(none)
+  do j00 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j01\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j01:1\\)" "gimple" } }
+  !$omp distribute simd
+  do j01 = 1, 64
+  end do
+end
+
+subroutine bar ()
+  integer :: j05, j11, j12;
+  ! { dg-final { scan-tree-dump "omp for\[^\n\r]*lastprivate\\(j02\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j02:1\\)" "gimple" } }
+  !$omp do simd
+  do j02 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(j03\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*shared\\(j03\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(j03\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j03:1\\)" "gimple" } }
+  !$omp master taskloop simd default(none)
+  do j03 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(j04\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j04\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j04:1\\)" "gimple" } }
+  !$omp parallel do simd default(none)
+  do j04 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(j05\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(j05\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*shared\\(j05\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(j05\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j05:1\\)" "gimple" } }
+  !$omp parallel master taskloop simd default(none)
+  do j05 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j06" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j06\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(j06\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j06\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j06:1\\)" "gimple" } }
+  !$omp target parallel do simd default(none) ! defaultmap(none)
+  do j06 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j07" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j07\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j07:1\\)" "gimple" } }
+  !$omp target simd ! defaultmap(none)
+  do j07 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j08" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j08\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(j08\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j08\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(j08\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j08\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j08:1\\)" "gimple" } }
+  !$omp target teams distribute parallel do simd default(none) ! defaultmap(none)
+  do j08 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j09" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j09\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(j09\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j09\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j09:1\\)" "gimple" } }
+  !$omp target teams distribute simd default(none) ! defaultmap(none)
+  do j09 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*shared\\(j10\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(j10\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j10:1\\)" "gimple" } }
+  !$omp taskloop simd default(none)
+  do j10 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(j11\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j11\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(j11\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j11\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j11:1\\)" "gimple" } }
+  !$omp teams distribute parallel do simd default(none)
+  do j11 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(j12\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j12\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j12:1\\)" "gimple" } }
+  !$omp teams distribute simd default(none)
+  do j12 = 1, 64
+  end do
+end
+end module m
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr99928-7.f90 b/gcc/testsuite/gfortran.dg/gomp/pr99928-7.f90
new file mode 100644
index 00000000000..8443ed504ee
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/pr99928-7.f90
@@ -0,0 +1,106 @@ 
+! PR middle-end/99928
+! { dg-do compile }
+! { dg-options "-fopenmp -fdump-tree-gimple" }
+
+module m
+ implicit none
+contains
+
+subroutine foo ()
+  integer :: j00, j01
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*lastprivate\\(j00\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp parallel\[^\n\r]*lastprivate\\(j00\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j00\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j00:1\\)" "gimple" } }
+  !$omp distribute parallel do simd default(none)
+  do j00 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*lastprivate\\(j01\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j01:1\\)" "gimple" } }
+  !$omp distribute simd
+  do j01 = 1, 64
+  end do
+end
+
+subroutine bar ()
+  integer :: j02, j03, j04, j05, j06, j07, j08, j09, j10, j11, j12
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j02\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j02:1\\)" "gimple" } }
+  !$omp do simd
+  do j02 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(j03\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp taskloop\[^\n\r]*lastprivate\\(j03\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j03:1\\)" "gimple" } }
+  !$omp master taskloop simd default(none)
+  do j03 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump-not "omp parallel\[^\n\r]*lastprivate\\(j04\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j04\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j04:1\\)" "gimple" } }
+  !$omp parallel do simd default(none)
+  do j04 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump-not "omp parallel\[^\n\r]*shared\\(j05\\)" "gimple" { xfail *-*-* }  } }
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(j05\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp taskloop\[^\n\r]*lastprivate\\(j05\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j05:1\\)" "gimple" } }
+  !$omp parallel master taskloop simd default(none)
+  do j05 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*map\\(tofrom:j06" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j06\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp parallel\[^\n\r]*shared\\(j06\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp parallel\[^\n\r]*lastprivate\\(j06\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j06\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j06:1\\)" "gimple" } }
+  !$omp target parallel do simd default(none) ! defaultmap(none)
+  do j06 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*map\\(tofrom:j07" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j07\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j07:1\\)" "gimple" } }
+  !$omp target simd ! defaultmap(none)
+  do j07 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*map\\(tofrom:j08" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j08\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp teams\[^\n\r]*shared\\(j08\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*lastprivate\\(j08\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp parallel\[^\n\r]*shared\\(j08\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp parallel\[^\n\r]*lastprivate\\(j08\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j08\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j08:1\\)" "gimple" } }
+  !$omp target teams distribute parallel do simd default(none) ! defaultmap(none)
+  do j08 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*map\\(tofrom:j09" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(j09\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp teams\[^\n\r]*shared\\(j09\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*lastprivate\\(j09\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j09:1\\)" "gimple" } }
+  !$omp target teams distribute simd default(none) ! defaultmap(none)
+  do j09 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump-not "omp taskloop\[^\n\r]*lastprivate\\(j10\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j10:1\\)" "gimple" } }
+  !$omp taskloop simd default(none)
+  do j10 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump-not "omp teams\[^\n\r]*shared\\(j11\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*lastprivate\\(j11\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp parallel\[^\n\r]*shared\\(j11\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp parallel\[^\n\r]*lastprivate\\(j11\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(j11\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j11:1\\)" "gimple" } }
+  !$omp teams distribute parallel do simd default(none)
+  do j11 = 1, 64
+  end do
+  ! { dg-final { scan-tree-dump-not "omp teams\[^\n\r]*shared\\(j12\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*lastprivate\\(j12\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*linear\\(j12:1\\)" "gimple" } }
+  !$omp teams distribute simd default(none)
+  do j12 = 1, 64
+  end do
+end
+end module m
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr99928-8.f90 b/gcc/testsuite/gfortran.dg/gomp/pr99928-8.f90
new file mode 100644
index 00000000000..de27ffed629
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/pr99928-8.f90
@@ -0,0 +1,252 @@ 
+! PR middle-end/99928
+! { dg-do compile }
+! { dg-options "-fopenmp -fdump-tree-gimple" }
+
+module m
+  integer :: r00, r01, r02, r03, r04, r05
+  integer :: r13, r14, r15, r16, r17, r18, r19
+  integer :: r20, r21, r22, r23, r24
+
+contains
+
+subroutine foo ()
+  integer :: i
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r00\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r00\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:r00\\)" "gimple" } } ! FIXME. 
+  !$omp distribute parallel do reduction(+:r00) default(none)
+  do i = 1, 64
+    r00 = r00 + 1
+  end do
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r01\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r01\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:r01\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r01\\)" "gimple" } }
+  !$omp distribute parallel do simd reduction(+:r01) default(none)
+  do i = 1, 64
+    r01 = r01 + 1
+  end do
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r02\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r02\\)" "gimple" } }
+  !$omp distribute simd reduction(+:r02)
+  do i = 1, 64
+    r02 = r02 + 1
+  end do
+end
+
+subroutine bar ()
+  integer :: r06, r07, r08, r09
+  integer :: r10, r11, r12
+  integer :: r25, r26, r27, r28, r29
+  integer :: i
+  r06 = 0; r07 = 0; r08 = 0; r09 = 0
+  r10 = 0; r11 = 0; r12 = 0
+  r25 = 0; r26 = 0; r27 = 0; r28 = 0; r29 = 0
+  ! { dg-final { scan-tree-dump "omp for\[^\n\r]*reduction\\(\\+:r03\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r03\\)" "gimple" } }
+  !$omp do simd reduction(+:r03)
+  do i = 1, 64
+    r03 = r03 + 1
+  end do
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*reduction\\(\\+:r04\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*reduction\\(\\+:r04\\)" "gimple" } }
+  !$omp master taskloop reduction(+:r04) default(none)
+  do i = 1, 64
+    r04 = r04 + 1
+  end do
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*reduction\\(\\+:r05\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*reduction\\(\\+:r05\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r05\\)" "gimple" } }
+  !$omp master taskloop simd reduction(+:r05) default(none)
+  do i = 1, 64
+    r05 = r05 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r06\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:r06\\)" "gimple" } } ! FIXME. 
+  !$omp parallel do reduction(+:r06) default(none)
+  do i = 1, 64
+    r06 = r06 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r07\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:r07\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r07\\)" "gimple" } }
+  !$omp parallel do simd reduction(+:r07) default(none)
+  do i = 1, 64
+    r07 = r07 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(r08\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp for\[^\n\r]*reduction\\(\\+:r08\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r08\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  !$omp parallel loop reduction(+:r08) default(none)
+  do i = 1, 64
+    r08 = r08 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r09\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*reduction\\(\\+:r09\\)" "gimple" } }
+  !$omp parallel master reduction(+:r09) default(none)
+  r09 = r09 + 1
+  !$omp end parallel master
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(r10\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*reduction\\(\\+:r10\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*reduction\\(\\+:r10\\)" "gimple" } }
+  !$omp parallel master taskloop reduction(+:r10) default(none)
+  do i = 1, 64
+    r10 = r10 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(r11\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*reduction\\(\\+:r11\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*reduction\\(\\+:r11\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r11\\)" "gimple" } }
+  !$omp parallel master taskloop simd reduction(+:r11) default(none)
+  do i = 1, 64
+    r11 = r11 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r12\\)" "gimple" } } ! FIXME: This should be on sections instead. 
+  ! { dg-final { scan-tree-dump-not "omp sections\[^\n\r]*reduction\\(\\+:r12\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump-not "omp section \[^\n\r]*reduction\\(\\+:r12\\)" "gimple" } }
+  !$omp parallel sections reduction(+:r12) default(none)
+    r12 = r12 + 1
+    !$omp section
+    r12 = r12 + 1
+  !$omp end parallel sections
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r13" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r13\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r13\\)" "gimple" } }
+  !$omp target parallel reduction(+:r13) default(none) ! defaultmap(none)
+  r13 = r13 + 1
+  !$omp end target parallel
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r14" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r14\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r14\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:r14\\)" "gimple" } } ! FIXME. 
+  !$omp target parallel do reduction(+:r14) default(none) ! defaultmap(none)
+  do i = 1, 64
+    r14 = r14 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r15" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r15\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r15\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:r15\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r15\\)" "gimple" } }
+  !$omp target parallel do simd reduction(+:r15) default(none) ! defaultmap(none)
+  do i = 1, 64
+    r15 = r15 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r16" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r16\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(r16\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp for\[^\n\r]*reduction\\(\\+:r16\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r16\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  !$omp target parallel loop reduction(+:r16) default(none) ! defaultmap(none)
+  do i = 1, 64
+    r16 = r16 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r17" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r17\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r17\\)" "gimple" } }
+  !$omp target teams reduction(+:r17) default(none) ! defaultmap(none)
+  r17 = r17 + 1
+  !$omp end target teams
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r18" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r18\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r18\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r18\\)" "gimple" } }
+  !$omp target teams distribute reduction(+:r18) default(none) ! defaultmap(none)
+  do i = 1, 64
+    r18 = r18 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r19" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r19\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r19\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r19\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r19\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:r19\\)" "gimple" } } ! FIXME. 
+  !$omp target teams distribute parallel do reduction(+:r19) default(none) ! defaultmap(none)
+  do i = 1, 64
+    r19 = r19 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r20" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r20\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r20\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r20\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r20\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:r20\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r20\\)" "gimple" } }
+  !$omp target teams distribute parallel do simd reduction(+:r20) default(none) ! defaultmap(none)
+  do i = 1, 64
+    r20 = r20 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r21" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r21\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r21\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r21\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r21\\)" "gimple" } }
+  !$omp target teams distribute simd reduction(+:r21) default(none) ! defaultmap(none)
+  do i = 1, 64
+    r21 = r21 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r22" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r22\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(r22\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*reduction\\(\\+:r22\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(r22\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp for\[^\n\r]*reduction\\(\\+:r22\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r22\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  !$omp target teams loop reduction(+:r22) default(none) ! defaultmap(none)
+  do i = 1, 64
+    r22 = r22 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r23" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r23\\)" "gimple" { xfail *-*-* } } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r23\\)" "gimple" } }
+  !$omp target simd reduction(+:r23) ! defaultmap(none)
+  do i = 1, 64
+    r23 = r23 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*reduction\\(\\+:r24\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r24\\)" "gimple" } }
+  !$omp taskloop simd reduction(+:r24) default(none)
+  do i = 1, 64
+    r24 = r24 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r25\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r25\\)" "gimple" } }
+  !$omp teams distribute reduction(+:r25) default(none)
+  do i = 1, 64
+    r25 = r25 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r26\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r26\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r26\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:r26\\)" "gimple" } } ! FIXME. 
+  !$omp teams distribute parallel do reduction(+:r26) default(none)
+  do i = 1, 64
+    r26 = r26 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r27\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r27\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r27\\)" "gimple" } } ! FIXME: This should be on for instead. 
+  ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:r27\\)" "gimple" } } ! FIXME. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r27\\)" "gimple" } }
+  !$omp teams distribute parallel do simd reduction(+:r27) default(none)
+  do i = 1, 64
+    r27 = r27 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r28\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r28\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r28\\)" "gimple" } }
+  !$omp teams distribute simd reduction(+:r28) default(none)
+  do i = 1, 64
+    r28 = r28 + 1
+  end do
+  ! { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(r29\\)" "gimple" } }
+  ! { dg-final { scan-tree-dump "omp distribute\[^\n\r]*reduction\\(\\+:r29\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(r29\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp for\[^\n\r]*reduction\\(\\+:r29\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r29\\)" "gimple" } } ! NOTE: This is implementation detail. 
+  !$omp teams loop reduction(+:r29) default(none)
+  do i = 1, 64
+    r29 = r29 + 1
+  end do
+end
+end module m