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
