public inbox for fortran@gcc.gnu.org
 help / color / mirror / Atom feed
* [Patch] Fortran: OpenMP 5.0 (in_,task_)reduction clause extensions
@ 2020-11-09 23:40 Tobias Burnus
  2020-11-10 12:16 ` Jakub Jelinek
  0 siblings, 1 reply; 8+ messages in thread
From: Tobias Burnus @ 2020-11-09 23:40 UTC (permalink / raw)
  To: gcc-patches, fortran, Jakub Jelinek

[-- Attachment #1: Type: text/plain, Size: 840 bytes --]

This patch updates the OpenMP handling to support OpenMP 5.0's
reductions changes:
- add task_reduction (for taskgroup)
- add in_reduction (for task, taskloop, target)
- add 'default', 'inscan' and 'task' to 'reduction'
   - only default for teams, taskloop
   - all three for parallel, simd, do, section

When copying + converting testcases from C to Fortran,
I saw that 'schedule(monotonic' can now be mixed with static/runtime/auto,
which is also included in the patch.

OK?

Tobias

PS: I am sure, I missed something, the question is only what ...
A likely place where something might have got wrong is gfc_split_omp_clauses.

-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander Walter

[-- Attachment #2: omp-reduction.diff --]
[-- Type: text/x-patch, Size: 122532 bytes --]

Fortran: OpenMP 5.0 (in_,task_)reduction clause extensions

gcc/fortran/ChangeLog:

	PR fortran/95847
	* dump-parse-tree.c (show_omp_clauses): Handle new reduction enums.
	* gfortran.h (OMP_LIST_REDUCTION_INSCAN, OMP_LIST_REDUCTION_TASK,
	OMP_LIST_IN_REDUCTION, OMP_LIST_TASK_REDUCTION): Add enums.
	* openmp.c (enum omp_mask1): Add OMP_CLAUSE_REDUCTION_DEFAULT,
	OMP_CLAUSE_REDUCTION_MODIFIER, OMP_CLAUSE_IN_REDUCTION,
	and OMP_CLAUSE_TASK_REDUCTION.
	(gfc_match_omp_clause_reduction): Extend reduction handling;
	moved from ...
	(gfc_match_omp_clauses): ... here. Add calls to it.
	(OMP_PARALLEL_CLAUSES, OMP_OMP_DO_CLAUSES, OMP_SECTIONS_CLAUSES,
	OMP_SIMD_CLAUSES): Use OMP_CLAUSE_REDUCTION_MODIFIERS.
	(OMP_TASK_CLAUSES, OMP_TARGET_CLAUSES): Add OMP_CLAUSE_IN_REDUCTION.
	(OMP_TASKLOOP_CLAUSES): Likewise; add OMP_CLAUSE_REDUCTION_DEFAULT.
	(OMP_TEAMS_CLAUSES): Add OMP_CLAUSE_REDUCTION_DEFAULT.
	(gfc_match_omp_taskgroup): Add task_reduction matching.
	(resolve_omp_clauses): Update for new reduction clause changes;
	remove removed nonmonotonic-schedule restrictions.
	(gfc_resolve_omp_parallel_blocks): Add new enums to switch.
	* trans-openmp.c (gfc_omp_clause_default_ctor,
	gfc_trans_omp_reduction_list, gfc_trans_omp_clauses,
	gfc_split_omp_clauses): Handle updated reduction clause.

gcc/ChangeLog:

	PR fortran/95847
	* gimplify.c (gimplify_scan_omp_clauses, gimplify_omp_loop): Use 'do'
	instead of 'for' in error messages for Fortran.
	* omp-low.c (check_omp_nesting_restrictions): Likewise

gcc/testsuite/ChangeLog:

	PR fortran/95847
	* gfortran.dg/gomp/schedule-modifiers-2.f90: Remove some dg-error.
	* gfortran.dg/gomp/reduction4.f90: New test.
	* gfortran.dg/gomp/reduction5.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-1.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-2.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-3.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-4.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-5.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-6.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-7.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-8.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-9.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-10.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-11.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-12.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-13.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-14.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-15.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-16.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-17.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-18.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-19.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-20.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-21.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-22.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-23.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-24.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-25.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-26.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-27.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-28.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-29.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-30.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-31.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-32.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-33.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-34.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-35.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-36.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-37.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-38.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-39.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-40.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-41.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-42.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-43.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-44.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-45.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-46.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-47.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-48.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-49.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-50.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-51.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-52.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-53.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-54.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-55.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-56.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-57.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-58.f90: New test.

 gcc/fortran/dump-parse-tree.c                      |  10 +-
 gcc/fortran/gfortran.h                             |   4 +
 gcc/fortran/openmp.c                               | 401 +++++++++++++--------
 gcc/fortran/trans-openmp.c                         |  71 +++-
 gcc/gimplify.c                                     |   6 +-
 gcc/omp-low.c                                      |   3 +-
 gcc/testsuite/gfortran.dg/gomp/reduction4.f90      | 171 +++++++++
 gcc/testsuite/gfortran.dg/gomp/reduction5.f90      |  41 +++
 .../gfortran.dg/gomp/schedule-modifiers-2.f90      |   8 +-
 .../gfortran.dg/gomp/workshare-reduction-1.f90     |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-10.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-11.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-12.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-13.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-14.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-15.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-16.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-17.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-18.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-19.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-2.f90     |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-20.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-21.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-22.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-23.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-24.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-25.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-26.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-27.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-28.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-29.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-3.f90     |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-30.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-31.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-32.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-33.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-34.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-35.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-36.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-37.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-38.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-39.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-4.f90     |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-40.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-41.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-42.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-43.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-44.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-45.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-46.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-47.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-48.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-49.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-5.f90     |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-50.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-51.f90    |  35 ++
 .../gfortran.dg/gomp/workshare-reduction-52.f90    |  35 ++
 .../gfortran.dg/gomp/workshare-reduction-53.f90    |  35 ++
 .../gfortran.dg/gomp/workshare-reduction-54.f90    |  35 ++
 .../gfortran.dg/gomp/workshare-reduction-55.f90    |  35 ++
 .../gfortran.dg/gomp/workshare-reduction-56.f90    |  35 ++
 .../gfortran.dg/gomp/workshare-reduction-57.f90    |  35 ++
 .../gfortran.dg/gomp/workshare-reduction-58.f90    |  35 ++
 .../gfortran.dg/gomp/workshare-reduction-6.f90     |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-7.f90     |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-8.f90     |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-9.f90     |  31 ++
 67 files changed, 2363 insertions(+), 182 deletions(-)

diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c
index 43b97ba26ff..cab0fb2979f 100644
--- a/gcc/fortran/dump-parse-tree.c
+++ b/gcc/fortran/dump-parse-tree.c
@@ -1587,7 +1587,11 @@ show_omp_clauses (gfc_omp_clauses *omp_clauses)
 	  case OMP_LIST_MAP: type = "MAP"; break;
 	  case OMP_LIST_TO: type = "TO"; break;
 	  case OMP_LIST_FROM: type = "FROM"; break;
-	  case OMP_LIST_REDUCTION: type = "REDUCTION"; break;
+	  case OMP_LIST_REDUCTION:
+	  case OMP_LIST_REDUCTION_INSCAN:
+	  case OMP_LIST_REDUCTION_TASK: type = "REDUCTION"; break;
+	  case OMP_LIST_IN_REDUCTION: type = "IN_REDUCTION"; break;
+	  case OMP_LIST_TASK_REDUCTION: type = "TASK_REDUCTION"; break;
 	  case OMP_LIST_DEVICE_RESIDENT: type = "DEVICE_RESIDENT"; break;
 	  case OMP_LIST_LINK: type = "LINK"; break;
 	  case OMP_LIST_USE_DEVICE: type = "USE_DEVICE"; break;
@@ -1600,6 +1604,10 @@ show_omp_clauses (gfc_omp_clauses *omp_clauses)
 	    gcc_unreachable ();
 	  }
 	fprintf (dumpfile, " %s(", type);
+	if (list_type == OMP_LIST_REDUCTION_INSCAN)
+	  fputs ("inscan, ", dumpfile);
+	if (list_type == OMP_LIST_REDUCTION_TASK)
+	  fputs ("task, ", dumpfile);
 	show_omp_namelist (list_type, omp_clauses->lists[list_type]);
 	fputc (')', dumpfile);
       }
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index dfd7796cce0..6467985ea7f 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1278,6 +1278,10 @@ enum
   OMP_LIST_TO,
   OMP_LIST_FROM,
   OMP_LIST_REDUCTION,
+  OMP_LIST_REDUCTION_INSCAN,
+  OMP_LIST_REDUCTION_TASK,
+  OMP_LIST_IN_REDUCTION,
+  OMP_LIST_TASK_REDUCTION,
   OMP_LIST_DEVICE_RESIDENT,
   OMP_LIST_LINK,
   OMP_LIST_USE_DEVICE,
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 2270c858f39..feb82054b18 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -762,6 +762,10 @@ enum omp_mask1
   OMP_CLAUSE_SHARED,
   OMP_CLAUSE_COPYIN,
   OMP_CLAUSE_REDUCTION,
+  OMP_CLAUSE_REDUCTION_DEFAULT,
+  OMP_CLAUSE_REDUCTION_MODIFIER,
+  OMP_CLAUSE_IN_REDUCTION,
+  OMP_CLAUSE_TASK_REDUCTION,
   OMP_CLAUSE_IF,
   OMP_CLAUSE_NUM_THREADS,
   OMP_CLAUSE_SCHEDULE,
@@ -959,6 +963,172 @@ gfc_match_omp_map_clause (gfc_omp_namelist **list, gfc_omp_map_op map_op,
   return false;
 }
 
+/* reduction ( reduction-modifier, reduction-operator : variable-list )
+   in_reduction ( reduction-operator : variable-list )
+   task_reduction ( reduction-operator : variable-list )  */
+
+static match
+gfc_match_omp_clause_reduction (char pc, const omp_mask mask,
+				gfc_omp_clauses *c, bool openacc,
+				bool allow_derived)
+{
+  if (pc == 'r' && gfc_match ("reduction ( ") != MATCH_YES)
+    return MATCH_NO;
+  else if (pc == 'i' && gfc_match ("in_reduction ( ") != MATCH_YES)
+    return MATCH_NO;
+  else if (pc == 't' && gfc_match ("task_reduction ( ") != MATCH_YES)
+    return MATCH_NO;
+
+  locus old_loc = gfc_current_locus;
+  int list_idx = 0;
+
+  if (pc == 'r' && ((mask & OMP_CLAUSE_REDUCTION_DEFAULT)
+		    || (mask & OMP_CLAUSE_REDUCTION_MODIFIER)))
+    {
+      if (gfc_match ("inscan") == MATCH_YES)
+	list_idx = OMP_LIST_REDUCTION_INSCAN;
+      else if (gfc_match ("task") == MATCH_YES)
+	list_idx = OMP_LIST_REDUCTION_TASK;
+      else if (gfc_match ("default") == MATCH_YES)
+	list_idx = OMP_LIST_REDUCTION;
+      if (list_idx != 0 && gfc_match (", ") != MATCH_YES)
+	{
+	  gfc_error ("Comma expected at %C");
+	  gfc_current_locus = old_loc;
+	  return MATCH_NO;
+	}
+      if (list_idx == 0)
+	list_idx = OMP_LIST_REDUCTION;
+      else if (list_idx != OMP_LIST_REDUCTION
+	       && (mask & OMP_CLAUSE_REDUCTION_DEFAULT))
+	{
+	  gfc_error ("Reduction-modifier shall be %<default%> at %C");
+	  gfc_current_locus = old_loc;
+	  return MATCH_NO;
+	}
+    }
+  else if (pc == 'i')
+    list_idx = OMP_LIST_IN_REDUCTION;
+  else if (pc == 't')
+    list_idx = OMP_LIST_TASK_REDUCTION;
+  else
+    list_idx = OMP_LIST_REDUCTION;
+
+  gfc_omp_reduction_op rop = OMP_REDUCTION_NONE;
+  char buffer[GFC_MAX_SYMBOL_LEN + 3];
+  if (gfc_match_char ('+') == MATCH_YES)
+    rop = OMP_REDUCTION_PLUS;
+  else if (gfc_match_char ('*') == MATCH_YES)
+    rop = OMP_REDUCTION_TIMES;
+  else if (gfc_match_char ('-') == MATCH_YES)
+    rop = OMP_REDUCTION_MINUS;
+  else if (gfc_match (".and.") == MATCH_YES)
+    rop = OMP_REDUCTION_AND;
+  else if (gfc_match (".or.") == MATCH_YES)
+    rop = OMP_REDUCTION_OR;
+  else if (gfc_match (".eqv.") == MATCH_YES)
+    rop = OMP_REDUCTION_EQV;
+  else if (gfc_match (".neqv.") == MATCH_YES)
+    rop = OMP_REDUCTION_NEQV;
+  if (rop != OMP_REDUCTION_NONE)
+    snprintf (buffer, sizeof buffer, "operator %s",
+	      gfc_op2string ((gfc_intrinsic_op) rop));
+  else if (gfc_match_defined_op_name (buffer + 1, 1) == MATCH_YES)
+    {
+      buffer[0] = '.';
+      strcat (buffer, ".");
+    }
+  else if (gfc_match_name (buffer) == MATCH_YES)
+    {
+      gfc_symbol *sym;
+      const char *n = buffer;
+
+      gfc_find_symbol (buffer, NULL, 1, &sym);
+      if (sym != NULL)
+	{
+	  if (sym->attr.intrinsic)
+	    n = sym->name;
+	  else if ((sym->attr.flavor != FL_UNKNOWN
+		    && sym->attr.flavor != FL_PROCEDURE)
+		   || sym->attr.external
+		   || sym->attr.generic
+		   || sym->attr.entry
+		   || sym->attr.result
+		   || sym->attr.dummy
+		   || sym->attr.subroutine
+		   || sym->attr.pointer
+		   || sym->attr.target
+		   || sym->attr.cray_pointer
+		   || sym->attr.cray_pointee
+		   || (sym->attr.proc != PROC_UNKNOWN
+		       && sym->attr.proc != PROC_INTRINSIC)
+		   || sym->attr.if_source != IFSRC_UNKNOWN
+		   || sym == sym->ns->proc_name)
+		{
+		  sym = NULL;
+		  n = NULL;
+		}
+	      else
+		n = sym->name;
+	    }
+	  if (n == NULL)
+	    rop = OMP_REDUCTION_NONE;
+	  else if (strcmp (n, "max") == 0)
+	    rop = OMP_REDUCTION_MAX;
+	  else if (strcmp (n, "min") == 0)
+	    rop = OMP_REDUCTION_MIN;
+	  else if (strcmp (n, "iand") == 0)
+	    rop = OMP_REDUCTION_IAND;
+	  else if (strcmp (n, "ior") == 0)
+	    rop = OMP_REDUCTION_IOR;
+	  else if (strcmp (n, "ieor") == 0)
+	    rop = OMP_REDUCTION_IEOR;
+	  if (rop != OMP_REDUCTION_NONE
+	      && sym != NULL
+	      && ! sym->attr.intrinsic
+	      && ! sym->attr.use_assoc
+	      && ((sym->attr.flavor == FL_UNKNOWN
+		   && !gfc_add_flavor (&sym->attr, FL_PROCEDURE,
+					      sym->name, NULL))
+		  || !gfc_add_intrinsic (&sym->attr, NULL)))
+	    rop = OMP_REDUCTION_NONE;
+    }
+  else
+    buffer[0] = '\0';
+  gfc_omp_udr *udr = (buffer[0] ? gfc_find_omp_udr (gfc_current_ns, buffer, NULL)
+				: NULL);
+  gfc_omp_namelist **head = NULL;
+  if (rop == OMP_REDUCTION_NONE && udr)
+    rop = OMP_REDUCTION_USER;
+
+  if (gfc_match_omp_variable_list (" :", &c->lists[list_idx], false, NULL,
+				   &head, openacc, allow_derived) != MATCH_YES)
+    {
+      gfc_current_locus = old_loc;
+      return MATCH_NO;
+    }
+  gfc_omp_namelist *n;
+  if (rop == OMP_REDUCTION_NONE)
+    {
+      n = *head;
+      *head = NULL;
+      gfc_error_now ("!$OMP DECLARE REDUCTION %s not found at %L",
+		     buffer, &old_loc);
+      gfc_free_omp_namelist (n);
+    }
+  else
+    for (n = *head; n; n = n->next)
+      {
+	n->u.reduction_op = rop;
+	if (udr)
+	  {
+	    n->udr = gfc_get_omp_namelist_udr ();
+	    n->udr->udr = udr;
+	  }
+     }
+  return MATCH_YES;
+}
+
 /* Match OpenMP and OpenACC directive clauses. MASK is a bitmask of
    clauses that are allowed for a particular directive.  */
 
@@ -1379,6 +1549,10 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      needs_space = true;
 	      continue;
 	    }
+	  if ((mask & OMP_CLAUSE_IN_REDUCTION)
+	      && gfc_match_omp_clause_reduction (pc, mask, c, openacc,
+						 allow_derived) == MATCH_YES)
+	    continue;
 	  if ((mask & OMP_CLAUSE_INBRANCH)
 	      && !c->inbranch
 	      && !c->notinbranch
@@ -1716,125 +1890,27 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      needs_space = true;
 	      continue;
 	    }
-	  if ((mask & OMP_CLAUSE_REDUCTION)
-	      && gfc_match ("reduction ( ") == MATCH_YES)
+	  if (((mask & OMP_CLAUSE_REDUCTION)
+	       || (mask & OMP_CLAUSE_REDUCTION_DEFAULT)
+	       || (mask & OMP_CLAUSE_REDUCTION_MODIFIER))
+	      && gfc_match_omp_clause_reduction (pc, mask, c, openacc,
+						 allow_derived) == MATCH_YES)
+	    continue;
+	  if ((mask & OMP_CLAUSE_MEMORDER)
+	      && c->memorder == OMP_MEMORDER_UNSET
+	      && gfc_match ("relaxed") == MATCH_YES)
 	    {
-	      gfc_omp_reduction_op rop = OMP_REDUCTION_NONE;
-	      char buffer[GFC_MAX_SYMBOL_LEN + 3];
-	      if (gfc_match_char ('+') == MATCH_YES)
-		rop = OMP_REDUCTION_PLUS;
-	      else if (gfc_match_char ('*') == MATCH_YES)
-		rop = OMP_REDUCTION_TIMES;
-	      else if (gfc_match_char ('-') == MATCH_YES)
-		rop = OMP_REDUCTION_MINUS;
-	      else if (gfc_match (".and.") == MATCH_YES)
-		rop = OMP_REDUCTION_AND;
-	      else if (gfc_match (".or.") == MATCH_YES)
-		rop = OMP_REDUCTION_OR;
-	      else if (gfc_match (".eqv.") == MATCH_YES)
-		rop = OMP_REDUCTION_EQV;
-	      else if (gfc_match (".neqv.") == MATCH_YES)
-		rop = OMP_REDUCTION_NEQV;
-	      if (rop != OMP_REDUCTION_NONE)
-		snprintf (buffer, sizeof buffer, "operator %s",
-			  gfc_op2string ((gfc_intrinsic_op) rop));
-	      else if (gfc_match_defined_op_name (buffer + 1, 1) == MATCH_YES)
-		{
-		  buffer[0] = '.';
-		  strcat (buffer, ".");
-		}
-	      else if (gfc_match_name (buffer) == MATCH_YES)
-		{
-		  gfc_symbol *sym;
-		  const char *n = buffer;
-
-		  gfc_find_symbol (buffer, NULL, 1, &sym);
-		  if (sym != NULL)
-		    {
-		      if (sym->attr.intrinsic)
-			n = sym->name;
-		      else if ((sym->attr.flavor != FL_UNKNOWN
-				&& sym->attr.flavor != FL_PROCEDURE)
-			       || sym->attr.external
-			       || sym->attr.generic
-			       || sym->attr.entry
-			       || sym->attr.result
-			       || sym->attr.dummy
-			       || sym->attr.subroutine
-			       || sym->attr.pointer
-			       || sym->attr.target
-			       || sym->attr.cray_pointer
-			       || sym->attr.cray_pointee
-			       || (sym->attr.proc != PROC_UNKNOWN
-				   && sym->attr.proc != PROC_INTRINSIC)
-			       || sym->attr.if_source != IFSRC_UNKNOWN
-			       || sym == sym->ns->proc_name)
-			{
-			  sym = NULL;
-			  n = NULL;
-			}
-		      else
-			n = sym->name;
-		    }
-		  if (n == NULL)
-		    rop = OMP_REDUCTION_NONE;
-		  else if (strcmp (n, "max") == 0)
-		    rop = OMP_REDUCTION_MAX;
-		  else if (strcmp (n, "min") == 0)
-		    rop = OMP_REDUCTION_MIN;
-		  else if (strcmp (n, "iand") == 0)
-		    rop = OMP_REDUCTION_IAND;
-		  else if (strcmp (n, "ior") == 0)
-		    rop = OMP_REDUCTION_IOR;
-		  else if (strcmp (n, "ieor") == 0)
-		    rop = OMP_REDUCTION_IEOR;
-		  if (rop != OMP_REDUCTION_NONE
-		      && sym != NULL
-		      && ! sym->attr.intrinsic
-		      && ! sym->attr.use_assoc
-		      && ((sym->attr.flavor == FL_UNKNOWN
-			  && !gfc_add_flavor (&sym->attr, FL_PROCEDURE,
-					      sym->name, NULL))
-			  || !gfc_add_intrinsic (&sym->attr, NULL)))
-		    rop = OMP_REDUCTION_NONE;
-		}
-	      else
-		buffer[0] = '\0';
-	      gfc_omp_udr *udr
-		= (buffer[0]
-		   ? gfc_find_omp_udr (gfc_current_ns, buffer, NULL) : NULL);
-	      gfc_omp_namelist **head = NULL;
-	      if (rop == OMP_REDUCTION_NONE && udr)
-		rop = OMP_REDUCTION_USER;
-
-	      if (gfc_match_omp_variable_list (" :",
-					       &c->lists[OMP_LIST_REDUCTION],
-					       false, NULL, &head, openacc,
-					       allow_derived) == MATCH_YES)
-		{
-		  gfc_omp_namelist *n;
-		  if (rop == OMP_REDUCTION_NONE)
-		    {
-		      n = *head;
-		      *head = NULL;
-		      gfc_error_now ("!$OMP DECLARE REDUCTION %s not found "
-				     "at %L", buffer, &old_loc);
-		      gfc_free_omp_namelist (n);
-		    }
-		  else
-		    for (n = *head; n; n = n->next)
-		      {
-			n->u.reduction_op = rop;
-			if (udr)
-			  {
-			    n->udr = gfc_get_omp_namelist_udr ();
-			    n->udr->udr = udr;
-			  }
-		      }
-		  continue;
-		}
-	      else
-		gfc_current_locus = old_loc;
+	      c->memorder = OMP_MEMORDER_RELAXED;
+	      needs_space = true;
+	      continue;
+	    }
+	  if ((mask & OMP_CLAUSE_MEMORDER)
+	      && c->memorder == OMP_MEMORDER_UNSET
+	      && gfc_match ("release") == MATCH_YES)
+	    {
+	      c->memorder = OMP_MEMORDER_RELEASE;
+	      needs_space = true;
+	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_MEMORDER)
 	      && c->memorder == OMP_MEMORDER_UNSET
@@ -1962,6 +2038,10 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	    }
 	  break;
 	case 't':
+	  if ((mask & OMP_CLAUSE_TASK_REDUCTION)
+	      && gfc_match_omp_clause_reduction (pc, mask, c, openacc,
+						 allow_derived) == MATCH_YES)
+	    continue;
 	  if ((mask & OMP_CLAUSE_THREAD_LIMIT)
 	      && c->thread_limit == NULL
 	      && gfc_match ("thread_limit ( %e )",
@@ -2672,42 +2752,44 @@ cleanup:
 
 #define OMP_PARALLEL_CLAUSES \
   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE		\
-   | OMP_CLAUSE_SHARED | OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION	\
-   | OMP_CLAUSE_IF | OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT	\
-   | OMP_CLAUSE_PROC_BIND)
+   | OMP_CLAUSE_SHARED | OMP_CLAUSE_COPYIN | OMP_CLAUSE_IF		\
+   | OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND \
+   | OMP_CLAUSE_REDUCTION_MODIFIER)
 #define OMP_DECLARE_SIMD_CLAUSES \
   (omp_mask (OMP_CLAUSE_SIMDLEN) | OMP_CLAUSE_LINEAR			\
    | OMP_CLAUSE_UNIFORM	| OMP_CLAUSE_ALIGNED | OMP_CLAUSE_INBRANCH	\
    | OMP_CLAUSE_NOTINBRANCH)
 #define OMP_DO_CLAUSES \
   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE		\
-   | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION			\
+   | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION_MODIFIER		\
    | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED | OMP_CLAUSE_COLLAPSE	\
    | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER)
 #define OMP_SECTIONS_CLAUSES \
   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE		\
-   | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION)
+   | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION_MODIFIER)
 #define OMP_SIMD_CLAUSES \
   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE		\
-   | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN	\
-   | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ALIGNED | OMP_CLAUSE_SIMDLEN	\
-   | OMP_CLAUSE_IF | OMP_CLAUSE_ORDER | OMP_CLAUSE_NOTEMPORAL)
+   | OMP_CLAUSE_REDUCTION_MODIFIER | OMP_CLAUSE_COLLAPSE		\
+   | OMP_CLAUSE_SAFELEN | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ALIGNED	\
+   | OMP_CLAUSE_SIMDLEN	| OMP_CLAUSE_IF | OMP_CLAUSE_ORDER		\
+   | OMP_CLAUSE_NOTEMPORAL)
 #define OMP_TASK_CLAUSES \
   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE		\
    | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT		\
    | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL | OMP_CLAUSE_MERGEABLE	\
-   | OMP_CLAUSE_DEPEND | OMP_CLAUSE_PRIORITY)
+   | OMP_CLAUSE_DEPEND | OMP_CLAUSE_PRIORITY | OMP_CLAUSE_IN_REDUCTION)
 #define OMP_TASKLOOP_CLAUSES \
   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE		\
    | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF		\
    | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL		\
    | OMP_CLAUSE_MERGEABLE | OMP_CLAUSE_PRIORITY | OMP_CLAUSE_GRAINSIZE	\
-   | OMP_CLAUSE_NUM_TASKS | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_NOGROUP)
+   | OMP_CLAUSE_NUM_TASKS | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_NOGROUP	\
+   | OMP_CLAUSE_REDUCTION_DEFAULT | OMP_CLAUSE_IN_REDUCTION)
 #define OMP_TARGET_CLAUSES \
   (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF	\
    | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE		\
    | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP			\
-   | OMP_CLAUSE_IS_DEVICE_PTR)
+   | OMP_CLAUSE_IS_DEVICE_PTR | OMP_CLAUSE_IN_REDUCTION)
 #define OMP_TARGET_DATA_CLAUSES \
   (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF	\
    | OMP_CLAUSE_USE_DEVICE_PTR | OMP_CLAUSE_USE_DEVICE_ADDR)
@@ -2723,7 +2805,7 @@ cleanup:
 #define OMP_TEAMS_CLAUSES \
   (omp_mask (OMP_CLAUSE_NUM_TEAMS) | OMP_CLAUSE_THREAD_LIMIT		\
    | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE	\
-   | OMP_CLAUSE_SHARED | OMP_CLAUSE_REDUCTION)
+   | OMP_CLAUSE_SHARED | OMP_CLAUSE_REDUCTION_DEFAULT)
 #define OMP_DISTRIBUTE_CLAUSES \
   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE		\
    | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_DIST_SCHEDULE)
@@ -4228,12 +4310,12 @@ gfc_match_omp_barrier (void)
 match
 gfc_match_omp_taskgroup (void)
 {
-  if (gfc_match_omp_eos () != MATCH_YES)
-    {
-      gfc_error ("Unexpected junk after $OMP TASKGROUP statement at %C");
-      return MATCH_ERROR;
-    }
+  gfc_omp_clauses *c;
+  if (gfc_match_omp_clauses (&c, OMP_CLAUSE_TASK_REDUCTION, true, true)
+      != MATCH_YES)
+    return MATCH_ERROR;
   new_st.op = EXEC_OMP_TASKGROUP;
+  new_st.ext.omp_clauses = c;
   return MATCH_YES;
 }
 
@@ -4560,7 +4642,9 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
   static const char *clause_names[]
     = { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED",
 	"COPYIN", "UNIFORM", "ALIGNED", "LINEAR", "DEPEND", "MAP",
-	"TO", "FROM", "REDUCTION", "DEVICE_RESIDENT", "LINK", "USE_DEVICE",
+	"TO", "FROM", "REDUCTION", "REDUCTION" /*inscan*/, "REDUCTION" /*task*/,
+	"IN_REDUCTION", "TASK_REDUCTION",
+	"DEVICE_RESIDENT", "LINK", "USE_DEVICE",
 	"CACHE", "IS_DEVICE_PTR", "USE_DEVICE_PTR", "USE_DEVICE_ADDR",
 	"NONTEMPORAL" };
   STATIC_ASSERT (ARRAY_SIZE (clause_names) == OMP_LIST_NUM);
@@ -4727,21 +4811,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
   if (omp_clauses->sched_kind != OMP_SCHED_NONE
       && omp_clauses->sched_nonmonotonic)
     {
-      if (omp_clauses->sched_kind != OMP_SCHED_DYNAMIC
-	  && omp_clauses->sched_kind != OMP_SCHED_GUIDED)
-	{
-	  const char *p;
-	  switch (omp_clauses->sched_kind)
-	    {
-	    case OMP_SCHED_STATIC: p = "STATIC"; break;
-	    case OMP_SCHED_RUNTIME: p = "RUNTIME"; break;
-	    case OMP_SCHED_AUTO: p = "AUTO"; break;
-	    default: gcc_unreachable ();
-	    }
-	  gfc_error ("NONMONOTONIC modifier specified for %s schedule kind "
-		     "at %L", p, &code->loc);
-	}
-      else if (omp_clauses->sched_monotonic)
+      if (omp_clauses->sched_monotonic)
 	gfc_error ("Both MONOTONIC and NONMONOTONIC schedule modifiers "
 		   "specified at %L", &code->loc);
       else if (omp_clauses->ordered)
@@ -4818,7 +4888,11 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 	&& (list != OMP_LIST_MAP || openacc)
 	&& list != OMP_LIST_FROM
 	&& list != OMP_LIST_TO
-	&& (list != OMP_LIST_REDUCTION || !openacc))
+	&& (list != OMP_LIST_REDUCTION || !openacc)
+	&& list != OMP_LIST_REDUCTION_INSCAN
+	&& list != OMP_LIST_REDUCTION_TASK
+	&& list != OMP_LIST_IN_REDUCTION
+	&& list != OMP_LIST_TASK_REDUCTION)
       for (n = omp_clauses->lists[list]; n; n = n->next)
 	{
 	  bool component_ref_p = false;
@@ -5224,6 +5298,11 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 	    for (; n != NULL; n = n->next)
 	      {
 		bool bad = false;
+		bool is_reduction = (list == OMP_LIST_REDUCTION
+				     || list == OMP_LIST_REDUCTION_INSCAN
+				     || list == OMP_LIST_REDUCTION_TASK
+				     || list == OMP_LIST_IN_REDUCTION
+				     || list == OMP_LIST_TASK_REDUCTION);
 		if (n->sym->attr.threadprivate)
 		  gfc_error ("THREADPRIVATE object %qs in %s clause at %L",
 			     n->sym->name, name, &n->where);
@@ -5233,15 +5312,15 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 		if (n->sym->attr.associate_var)
 		  gfc_error ("ASSOCIATE name %qs in %s clause at %L",
 			     n->sym->name, name, &n->where);
-		if (list != OMP_LIST_PRIVATE)
+		if (list != OMP_LIST_PRIVATE && is_reduction)
 		  {
-		    if (n->sym->attr.proc_pointer && list == OMP_LIST_REDUCTION)
+		    if (n->sym->attr.proc_pointer)
 		      gfc_error ("Procedure pointer %qs in %s clause at %L",
 				 n->sym->name, name, &n->where);
-		    if (n->sym->attr.pointer && list == OMP_LIST_REDUCTION)
+		    if (n->sym->attr.pointer)
 		      gfc_error ("POINTER object %qs in %s clause at %L",
 				 n->sym->name, name, &n->where);
-		    if (n->sym->attr.cray_pointer && list == OMP_LIST_REDUCTION)
+		    if (n->sym->attr.cray_pointer)
 		      gfc_error ("Cray pointer %qs in %s clause at %L",
 				 n->sym->name, name, &n->where);
 		  }
@@ -5253,7 +5332,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 		else if (n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE)
 		  gfc_error ("Assumed size array %qs in %s clause at %L",
 			     n->sym->name, name, &n->where);
-		if (n->sym->attr.in_namelist && list != OMP_LIST_REDUCTION)
+		if (n->sym->attr.in_namelist && !is_reduction)
 		  gfc_error ("Variable %qs in %s clause is used in "
 			     "NAMELIST statement at %L",
 			     n->sym->name, name, &n->where);
@@ -5274,6 +5353,10 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 		switch (list)
 		  {
 		  case OMP_LIST_REDUCTION:
+		  case OMP_LIST_REDUCTION_INSCAN:
+		  case OMP_LIST_REDUCTION_TASK:
+		  case OMP_LIST_IN_REDUCTION:
+		  case OMP_LIST_TASK_REDUCTION:
 		    switch (n->u.reduction_op)
 		      {
 		      case OMP_REDUCTION_PLUS:
@@ -6102,6 +6185,10 @@ gfc_resolve_omp_parallel_blocks (gfc_code *code, gfc_namespace *ns)
       case OMP_LIST_FIRSTPRIVATE:
       case OMP_LIST_LASTPRIVATE:
       case OMP_LIST_REDUCTION:
+      case OMP_LIST_REDUCTION_INSCAN:
+      case OMP_LIST_REDUCTION_TASK:
+      case OMP_LIST_IN_REDUCTION:
+      case OMP_LIST_TASK_REDUCTION:
       case OMP_LIST_LINEAR:
 	for (n = omp_clauses->lists[list]; n; n = n->next)
 	  ctx.sharing_clauses->add (n->sym);
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c
index 1d652a09f9d..d2559bd0c0a 100644
--- a/gcc/fortran/trans-openmp.c
+++ b/gcc/fortran/trans-openmp.c
@@ -626,6 +626,8 @@ gfc_omp_clause_default_ctor (tree clause, tree decl, tree outer)
     case OMP_CLAUSE_LASTPRIVATE:
     case OMP_CLAUSE_LINEAR:
     case OMP_CLAUSE_REDUCTION:
+    case OMP_CLAUSE_IN_REDUCTION:
+    case OMP_CLAUSE_TASK_REDUCTION:
       break;
     default:
       gcc_unreachable ();
@@ -699,7 +701,9 @@ gfc_omp_clause_default_ctor (tree clause, tree decl, tree outer)
   then_b = gfc_finish_block (&cond_block);
 
   /* Reduction clause requires allocated ALLOCATABLE.  */
-  if (OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_REDUCTION)
+  if (OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_REDUCTION
+      && OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_IN_REDUCTION
+      && OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_TASK_REDUCTION)
     {
       gfc_init_block (&cond_block);
       if (GFC_DESCRIPTOR_TYPE_P (type))
@@ -2029,9 +2033,25 @@ gfc_trans_omp_array_reduction_or_udr (tree c, gfc_omp_namelist *n, locus where)
 }
 
 static tree
-gfc_trans_omp_reduction_list (gfc_omp_namelist *namelist, tree list,
+gfc_trans_omp_reduction_list (int kind, gfc_omp_namelist *namelist, tree list,
 			      locus where, bool mark_addressable)
 {
+  omp_clause_code clause = OMP_CLAUSE_REDUCTION;
+  switch (kind)
+    {
+    case OMP_LIST_REDUCTION:
+    case OMP_LIST_REDUCTION_INSCAN:
+    case OMP_LIST_REDUCTION_TASK:
+      break;
+    case OMP_LIST_IN_REDUCTION:
+      clause = OMP_CLAUSE_IN_REDUCTION;
+      break;
+    case OMP_LIST_TASK_REDUCTION:
+      clause = OMP_CLAUSE_TASK_REDUCTION;
+      break;
+    default:
+      gcc_unreachable ();
+    }
   for (; namelist != NULL; namelist = namelist->next)
     if (namelist->sym->attr.referenced)
       {
@@ -2039,10 +2059,14 @@ gfc_trans_omp_reduction_list (gfc_omp_namelist *namelist, tree list,
 	if (t != error_mark_node)
 	  {
 	    tree node = build_omp_clause (gfc_get_location (&namelist->where),
-					  OMP_CLAUSE_REDUCTION);
+					  clause);
 	    OMP_CLAUSE_DECL (node) = t;
 	    if (mark_addressable)
 	      TREE_ADDRESSABLE (t) = 1;
+	    if (kind == OMP_LIST_REDUCTION_INSCAN)
+	      OMP_CLAUSE_REDUCTION_INSCAN (node) = 1;
+	    if (kind == OMP_LIST_REDUCTION_TASK)
+	      OMP_CLAUSE_REDUCTION_TASK (node) = 1;
 	    switch (namelist->u.reduction_op)
 	      {
 	      case OMP_REDUCTION_PLUS:
@@ -2267,10 +2291,14 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
       switch (list)
 	{
 	case OMP_LIST_REDUCTION:
+	case OMP_LIST_REDUCTION_INSCAN:
+	case OMP_LIST_REDUCTION_TASK:
+	case OMP_LIST_IN_REDUCTION:
+	case OMP_LIST_TASK_REDUCTION:
 	  /* An OpenACC async clause indicates the need to set reduction
 	     arguments addressable, to allow asynchronous copy-out.  */
-	  omp_clauses = gfc_trans_omp_reduction_list (n, omp_clauses, where,
-						      clauses->async);
+	  omp_clauses = gfc_trans_omp_reduction_list (list, n, omp_clauses,
+						      where, clauses->async);
 	  break;
 	case OMP_LIST_PRIVATE:
 	  clause_code = OMP_CLAUSE_PRIVATE;
@@ -5207,18 +5235,27 @@ gfc_split_omp_clauses (gfc_code *code,
       /* Reduction is allowed on simd, do, parallel and teams.
 	 Duplicate it on all of them, but omit on do if
 	 parallel is present.  */
-      if (mask & GFC_OMP_MASK_TEAMS)
-	clausesa[GFC_OMP_SPLIT_TEAMS].lists[OMP_LIST_REDUCTION]
-	  = code->ext.omp_clauses->lists[OMP_LIST_REDUCTION];
-      if (mask & GFC_OMP_MASK_PARALLEL)
-	clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_REDUCTION]
-	  = code->ext.omp_clauses->lists[OMP_LIST_REDUCTION];
-      else if (mask & GFC_OMP_MASK_DO)
-	clausesa[GFC_OMP_SPLIT_DO].lists[OMP_LIST_REDUCTION]
-	  = code->ext.omp_clauses->lists[OMP_LIST_REDUCTION];
-      if (mask & GFC_OMP_MASK_SIMD)
-	clausesa[GFC_OMP_SPLIT_SIMD].lists[OMP_LIST_REDUCTION]
-	  = code->ext.omp_clauses->lists[OMP_LIST_REDUCTION];
+      for (int i = OMP_LIST_REDUCTION; i <= OMP_LIST_REDUCTION_TASK; i++)
+	{
+	  if (mask & GFC_OMP_MASK_TEAMS)
+	    clausesa[GFC_OMP_SPLIT_TEAMS].lists[i]
+	      = code->ext.omp_clauses->lists[i];
+	  if (mask & GFC_OMP_MASK_PARALLEL)
+	    clausesa[GFC_OMP_SPLIT_PARALLEL].lists[i]
+	      = code->ext.omp_clauses->lists[i];
+	  else if (mask & GFC_OMP_MASK_DO)
+	    clausesa[GFC_OMP_SPLIT_DO].lists[i]
+	      = code->ext.omp_clauses->lists[i];
+	  if (mask & GFC_OMP_MASK_SIMD)
+	    clausesa[GFC_OMP_SPLIT_SIMD].lists[i]
+	      = code->ext.omp_clauses->lists[i];
+	}
+      if (mask & GFC_OMP_MASK_TARGET)
+	clausesa[GFC_OMP_SPLIT_TARGET].lists[OMP_LIST_IN_REDUCTION]
+	  = code->ext.omp_clauses->lists[OMP_LIST_IN_REDUCTION];
+      if (mask & GFC_OMP_MASK_TASKLOOP)
+	clausesa[GFC_OMP_SPLIT_TASKLOOP].lists[OMP_LIST_IN_REDUCTION]
+	  = code->ext.omp_clauses->lists[OMP_LIST_IN_REDUCTION];
       /* Linear clause is supported on do and simd,
 	 put it on the innermost one.  */
       clausesa[innermost].lists[OMP_LIST_LINEAR]
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index aa3b914f6e5..23892d58666 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -8559,7 +8559,8 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
 		{
 		  error_at (OMP_CLAUSE_LOCATION (c),
 			    "invalid %<task%> reduction modifier on construct "
-			    "other than %<parallel%>, %<for%> or %<sections%>");
+			    "other than %<parallel%>, %qs or %<sections%>",
+			    lang_GNU_Fortran () ? "do" : "for");
 		  OMP_CLAUSE_REDUCTION_TASK (c) = 0;
 		}
 	    }
@@ -12521,7 +12522,8 @@ gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
 	  {
 	    error_at (OMP_CLAUSE_LOCATION (*pc),
 		      "invalid %<task%> reduction modifier on construct "
-		      "other than %<parallel%>, %<for%> or %<sections%>");
+		      "other than %<parallel%>, %qs or %<sections%>",
+		      lang_GNU_Fortran () ? "do" : "for");
 	    OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
 	  }
 	pc = &OMP_CLAUSE_CHAIN (*pc);
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index ea9008b61c4..71277968ee3 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -2881,7 +2881,8 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
 		    {
 		      error_at (gimple_location (stmt),
 				"%<ordered simd threads%> must be closely "
-				"nested inside of %<for simd%> region");
+				"nested inside of %<%s simd%> region",
+				lang_GNU_Fortran () ? "do" : "for");
 		      return false;
 		    }
 		  return true;
diff --git a/gcc/testsuite/gfortran.dg/gomp/reduction4.f90 b/gcc/testsuite/gfortran.dg/gomp/reduction4.f90
new file mode 100644
index 00000000000..af8c91b2a87
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/reduction4.f90
@@ -0,0 +1,171 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-original" }
+!
+! (in_)reduction clause
+! Test all in-principle valid combinations, even if
+! not valid in this context (some fail at ME level)
+!
+implicit none
+integer :: a, b, i
+a = 0
+
+! ------------ parallel ------------
+!$omp parallel reduction(+:a)
+do i=1,10
+  a = a + 1
+end do
+!$omp end parallel
+
+!$omp parallel reduction(default,+:a)
+do i=1,10
+  a = a + 1
+end do
+!$omp end parallel
+
+!$omp parallel reduction(task,+:a)
+do i=1,10
+  a = a + 1
+end do
+!$omp end parallel
+
+!$omp parallel reduction(inscan,+:a)  ! { dg-error "'inscan' 'reduction' clause on 'parallel' construct" }
+do i=1,10
+  a = a + 1
+end do
+!$omp end parallel
+
+! ------------ simd ------------
+!$omp simd reduction(+:a)
+do i=1,10
+  a = a + 1
+end do
+
+!$omp simd reduction(default,+:a)
+do i=1,10
+  a = a + 1
+end do
+
+!$omp simd reduction(task,+:a)  ! { dg-error "invalid 'task' reduction modifier on construct other than 'parallel', 'do' or 'sections'" }
+do i=1,10
+  a = a + 1
+end do
+
+!$omp simd reduction(inscan,+:a)  ! { dg-error "'inscan' 'reduction' clause but not in 'scan' directive clause" }
+do i=1,10
+  a = a + 1
+end do
+
+! ------------ do ------------
+!$omp parallel
+!$omp do reduction(+:a)
+do i=1,10
+  a = a + 1
+end do
+!$omp end parallel
+
+!$omp parallel
+!$omp do reduction(default,+:a)
+do i=1,10
+  a = a + 1
+end do
+!$omp end parallel
+
+!$omp parallel
+!$omp do reduction(task,+:a)
+do i=1,10
+  a = a + 1
+end do
+!$omp end parallel
+
+!$omp parallel
+!$omp do reduction(inscan,+:a)  ! { dg-error "'a' specified in 'inscan' 'reduction' clause but not in 'scan' directive clause" }
+do i=1,10
+  a = a + 1
+end do
+!$omp end parallel
+
+! ------------ section ------------
+!$omp parallel
+!$omp sections reduction(+:a)
+  !$omp section
+  a = a + 1
+!$omp end sections
+!$omp end parallel
+
+!$omp parallel
+!$omp sections reduction(default,+:a)
+  !$omp section
+  a = a + 1
+!$omp end sections
+!$omp end parallel
+
+!$omp parallel
+!$omp sections reduction(task,+:a)
+  !$omp section
+  a = a + 1
+!$omp end sections
+!$omp end parallel
+
+!$omp parallel
+!$omp sections reduction(inscan,+:a)  ! { dg-error "'inscan' 'reduction' clause on 'sections' construct" }
+  !$omp section
+  a = a + 1
+!$omp end sections
+!$omp end parallel
+
+! ------------ task ------------
+!$omp task in_reduction(+:a)
+  a = a + 1
+!$omp end task
+
+! ------------ taskloop ------------
+!$omp taskloop reduction(+:a) in_reduction(+:b)
+do i=1,10
+  a = a + 1
+end do
+
+!$omp taskloop reduction(default,+:a) in_reduction(+:b)
+do i=1,10
+  a = a + 1
+end do
+
+! ------------ target ------------
+!$omp target in_reduction(+:b)
+  a = a + 1
+!$omp end target
+
+! ------------ teams ------------
+!$omp teams reduction(+:b)
+  a = a + 1
+!$omp end teams
+
+!$omp teams reduction(default, +:b)
+  a = a + 1
+!$omp end teams
+
+! ------------ taskgroup --------
+
+!$omp taskgroup task_reduction(+:b)
+  a = a + 1
+!$omp end taskgroup
+
+end
+
+! { dg-final { scan-tree-dump-times "#pragma omp for reduction\\(\\\+:a\\)" 2 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp for reduction\\(inscan,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp for reduction\\(task,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel\[\n\r\]" 8 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel private\\(i\\) reduction\\(\\\+:a\\)" 2 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel private\\(i\\) reduction\\(inscan,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel private\\(i\\) reduction\\(task,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp section\[\n\r\]" 4 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp sections reduction\\(\\\+:a\\)" 2 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp sections reduction\\(inscan,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp sections reduction\\(task,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:1\\) reduction\\(\\\+:a\\)" 2 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:1\\) reduction\\(inscan,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:1\\) reduction\\(task,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp target in_reduction\\(\\\+:b\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task in_reduction\\(\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp teams reduction\\(\\\+:b\\)" 2 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp taskloop reduction\\(\\\+:a\\) in_reduction\\(\\\+:b\\)" 2 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/reduction5.f90 b/gcc/testsuite/gfortran.dg/gomp/reduction5.f90
new file mode 100644
index 00000000000..e8c2c5f017d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/reduction5.f90
@@ -0,0 +1,41 @@
+! { dg-do compile }
+!
+implicit none
+integer :: a, b, i
+a = 0
+
+!$omp parallel reduction(foo,+:a)  ! { dg-error "26: Failed to match clause" }
+do i=1,10
+  a = a + 1
+end do
+!$omp end parallel  ! { dg-error "Unexpected !.OMP END PARALLEL statement" }
+
+!$omp parallel reduction(task +:a) ! { dg-error "30: Comma expected at" }
+do i=1,10
+  a = a + 1
+end do
+!$omp end parallel  ! { dg-error "Unexpected !.OMP END PARALLEL statement" }
+
+!$omp task in_reduction(foo,+:a)  ! { dg-error "25: Failed to match clause" }
+  a = a + 1
+!$omp end task  ! { dg-error "Unexpected !.OMP END TASK statement" }
+
+!$omp taskloop reduction(inscan,+:a) in_reduction(+:b) ! { dg-error "33: Reduction-modifier shall be 'default'" }
+do i=1,10
+  a = a + 1
+end do
+
+!$omp taskloop reduction(task,+:a) in_reduction(+:b) ! { dg-error "31: Reduction-modifier shall be 'default'" }
+do i=1,10
+  a = a + 1
+end do
+
+!$omp teams reduction(inscan,+:b) ! { dg-error "30: Reduction-modifier shall be 'default'" }
+  a = a + 1
+!$omp end teams  ! { dg-error "Unexpected !.OMP END TEAMS statement" }
+
+!$omp teams reduction(task, +:b) ! { dg-error "29: Reduction-modifier shall be 'default'" }
+  a = a + 1
+!$omp end teams  ! { dg-error "Unexpected !.OMP END TEAMS statement" }
+
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/schedule-modifiers-2.f90 b/gcc/testsuite/gfortran.dg/gomp/schedule-modifiers-2.f90
index 0be53cc71a5..537fba23c11 100644
--- a/gcc/testsuite/gfortran.dg/gomp/schedule-modifiers-2.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/schedule-modifiers-2.f90
@@ -3,16 +3,16 @@
 
 subroutine foo
   integer :: i
-  !$omp do schedule (nonmonotonic: static, 2)	! { dg-error "NONMONOTONIC modifier specified for STATIC schedule kind" }
+  !$omp do schedule (nonmonotonic: static, 2)
   do i = 0, 64
   end do
-  !$omp do schedule (nonmonotonic : static)	! { dg-error "NONMONOTONIC modifier specified for STATIC schedule kind" }
+  !$omp do schedule (nonmonotonic : static)
   do i = 0, 64
   end do
-  !$omp do schedule (nonmonotonic : runtime)	! { dg-error "NONMONOTONIC modifier specified for RUNTIME schedule kind" }
+  !$omp do schedule (nonmonotonic : runtime)
   do i = 0, 64
   end do
-  !$omp do schedule (nonmonotonic : auto)	! { dg-error "NONMONOTONIC modifier specified for AUTO schedule kind" }
+  !$omp do schedule (nonmonotonic : auto)
   do i = 0, 64
   end do
   !$omp do schedule (nonmonotonic : dynamic) ordered	! { dg-error "NONMONOTONIC schedule modifier specified with ORDERED clause" }
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-1.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-1.f90
new file mode 100644
index 00000000000..3e639d2e74b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-1.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 0, 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_maybe_nonmonotonic_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (runtime)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-10.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-10.f90
new file mode 100644
index 00000000000..e71ac3f41a7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-10.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: static, 2)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-11.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-11.f90
new file mode 100644
index 00000000000..94202200ca1
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-11.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (dynamic)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-12.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-12.f90
new file mode 100644
index 00000000000..66c6eb1cae0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-12.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483650|-2147483646), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: dynamic)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-13.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-13.f90
new file mode 100644
index 00000000000..89782d299fd
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-13.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: dynamic)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-14.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-14.f90
new file mode 100644
index 00000000000..16b3e01b891
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-14.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (dynamic, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-15.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-15.f90
new file mode 100644
index 00000000000..8bf126c5ea7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-15.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483650|-2147483646), 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: dynamic, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-16.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-16.f90
new file mode 100644
index 00000000000..fe8d1ae2124
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-16.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: dynamic, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-17.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-17.f90
new file mode 100644
index 00000000000..1f2823dd724
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-17.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (guided)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-18.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-18.f90
new file mode 100644
index 00000000000..ad0856a6fe7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-18.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483651|-2147483645), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } } 
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: guided)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-19.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-19.f90
new file mode 100644
index 00000000000..e884dbf037c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-19.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: guided)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-2.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-2.f90
new file mode 100644
index 00000000000..2f78c0be4b3
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-2.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483648|-2147483648), 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: runtime)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-20.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-20.f90
new file mode 100644
index 00000000000..8a4d6dfe4df
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-20.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (guided, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-21.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-21.f90
new file mode 100644
index 00000000000..2d9362b751f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-21.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483651|-2147483645), 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: guided, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-22.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-22.f90
new file mode 100644
index 00000000000..485171fd481
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-22.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: guided, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-23.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-23.f90
new file mode 100644
index 00000000000..45dc0002b92
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-23.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (auto)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-24.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-24.f90
new file mode 100644
index 00000000000..e7fbe922f3e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-24.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: auto)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-25.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-25.f90
new file mode 100644
index 00000000000..d5554c49962
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-25.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: auto)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-26.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-26.f90
new file mode 100644
index 00000000000..28267902914
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-26.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 0, 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_maybe_nonmonotonic_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (runtime)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-27.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-27.f90
new file mode 100644
index 00000000000..2ee047d4e8c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-27.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483648|-2147483648), 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: runtime)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-28.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-28.f90
new file mode 100644
index 00000000000..6c9d49be13c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-28.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 4, 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: runtime)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-29.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-29.f90
new file mode 100644
index 00000000000..316b72e1d2e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-29.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-3.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-3.f90
new file mode 100644
index 00000000000..6c9d49be13c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-3.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 4, 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: runtime)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-30.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-30.f90
new file mode 100644
index 00000000000..b9406d6b236
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-30.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (static)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-31.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-31.f90
new file mode 100644
index 00000000000..4a246045c1b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-31.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: static)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-32.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-32.f90
new file mode 100644
index 00000000000..a7062d9eaae
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-32.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: static)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-33.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-33.f90
new file mode 100644
index 00000000000..67c25c82ddd
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-33.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (static, 2)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-34.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-34.f90
new file mode 100644
index 00000000000..f1e4d89adbb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-34.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: static, 2)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-35.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-35.f90
new file mode 100644
index 00000000000..7d7c27118ba
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-35.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: static, 2)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-36.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-36.f90
new file mode 100644
index 00000000000..b190e9ee87b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-36.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (dynamic)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-37.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-37.f90
new file mode 100644
index 00000000000..c541d22d6cf
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-37.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483650|-2147483646), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: dynamic)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-38.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-38.f90
new file mode 100644
index 00000000000..46a27a0386c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-38.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: dynamic)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-39.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-39.f90
new file mode 100644
index 00000000000..6cdd9a8807b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-39.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (dynamic, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-4.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-4.f90
new file mode 100644
index 00000000000..c7744277bc8
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-4.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-40.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-40.f90
new file mode 100644
index 00000000000..29da27abc5a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-40.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483650|-2147483646), 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: dynamic, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-41.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-41.f90
new file mode 100644
index 00000000000..4ed879cdd00
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-41.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: dynamic, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-42.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-42.f90
new file mode 100644
index 00000000000..78d02ef8035
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-42.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (guided)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-43.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-43.f90
new file mode 100644
index 00000000000..16885c84210
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-43.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483651|-2147483645), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: guided)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-44.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-44.f90
new file mode 100644
index 00000000000..0db9be6854c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-44.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: guided)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-45.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-45.f90
new file mode 100644
index 00000000000..40b12755414
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-45.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (guided, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-46.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-46.f90
new file mode 100644
index 00000000000..57c74023d8d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-46.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483651|-2147483645), 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: guided, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-47.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-47.f90
new file mode 100644
index 00000000000..b4564300b50
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-47.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: guided, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-48.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-48.f90
new file mode 100644
index 00000000000..1370010ac60
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-48.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (auto)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-49.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-49.f90
new file mode 100644
index 00000000000..ab2591f3acf
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-49.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: auto)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-5.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-5.f90
new file mode 100644
index 00000000000..ce3db0fa903
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-5.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (static)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-50.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-50.f90
new file mode 100644
index 00000000000..8b8942709a5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-50.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: auto)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-51.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-51.f90
new file mode 100644
index 00000000000..13bde3aabeb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-51.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_start \[^\n\r]*, (?:2147483648|-2147483648), 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_start " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do ordered reduction (task, *: j) schedule (runtime)
+  do i = a, b, c
+    call bar (j)
+    !$omp ordered
+    j = j + 1
+    !$omp end ordered
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-52.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-52.f90
new file mode 100644
index 00000000000..50dce3dccf9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-52.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_start \[^\n\r]*, (?:2147483649|-2147483647), 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_start " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_static_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do ordered reduction (task, *: j)
+  do i = a, b, c
+    call bar (j)
+    !$omp ordered
+    j = j + 1
+    !$omp end ordered
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-53.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-53.f90
new file mode 100644
index 00000000000..018420946cb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-53.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_start \[^\n\r]*, (?:2147483650|-2147483646), 4, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_start " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do ordered reduction (task, *: j) schedule (dynamic, 4)
+  do i = a, b, c
+    call bar (j)
+    !$omp ordered
+    j = j + 1
+    !$omp end ordered
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-54.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-54.f90
new file mode 100644
index 00000000000..0681e43863c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-54.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_start \[^\n\r]*, (?:2147483651|-2147483645), 6, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_start " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do ordered reduction (task, *: j) schedule (guided, 6)
+  do i = a, b, c
+    call bar (j)
+    !$omp ordered
+    j = j + 1
+    !$omp end ordered
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-55.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-55.f90
new file mode 100644
index 00000000000..4d2e1e509ef
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-55.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_doacross_start \[^\n\r]*, (?:2147483648|-2147483648), 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_post " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_wait " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do ordered(1) reduction (task, *: j) schedule (runtime)
+  do i = a, b, c
+    call bar (j)
+    !$omp ordered depend(sink: i - 1)
+    j = j + 1
+    !$omp ordered depend(source)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-56.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-56.f90
new file mode 100644
index 00000000000..dc5ddafa0e5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-56.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_doacross_start \[^\n\r]*, (?:2147483649|-2147483647), 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_post " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_wait " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_static_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do ordered(1) reduction (task, *: j)
+  do i = a, b, c
+    call bar (j)
+    !$omp ordered depend(sink: i - 1)
+    j = j + 1
+    !$omp ordered depend(source)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-57.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-57.f90
new file mode 100644
index 00000000000..80424882d2c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-57.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_doacross_start \[^\n\r]*, (?:2147483650|-2147483646), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_post " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_wait " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do ordered(1) reduction (task, *: j) schedule (dynamic)
+  do i = a, b, c
+    call bar (j)
+    !$omp ordered depend(sink: i - 1)
+    j = j + 1
+    !$omp ordered depend(source)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-58.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-58.f90
new file mode 100644
index 00000000000..ae4f8bc5ef8
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-58.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_doacross_start \[^\n\r]*, (?:2147483651|-2147483645), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_post " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_wait " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do ordered(1) reduction (task, *: j) schedule (guided)
+  do i = a, b, c
+    call bar (j)
+    !$omp ordered depend(sink: i - 1)
+    j = j + 1
+    !$omp ordered depend(source)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-6.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-6.f90
new file mode 100644
index 00000000000..147f14a2a35
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-6.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: static)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-7.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-7.f90
new file mode 100644
index 00000000000..dc99a7512ce
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-7.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: static)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-8.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-8.f90
new file mode 100644
index 00000000000..9d0a1ce95f9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-8.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (static, 2)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-9.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-9.f90
new file mode 100644
index 00000000000..c61374613be
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-9.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: static, 2)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Patch] Fortran: OpenMP 5.0 (in_,task_)reduction clause extensions
  2020-11-09 23:40 [Patch] Fortran: OpenMP 5.0 (in_,task_)reduction clause extensions Tobias Burnus
@ 2020-11-10 12:16 ` Jakub Jelinek
  2020-11-10 16:46   ` Tobias Burnus
  0 siblings, 1 reply; 8+ messages in thread
From: Jakub Jelinek @ 2020-11-10 12:16 UTC (permalink / raw)
  To: Tobias Burnus; +Cc: gcc-patches, fortran

On Tue, Nov 10, 2020 at 12:40:08AM +0100, Tobias Burnus wrote:
> --- a/gcc/fortran/openmp.c
> +++ b/gcc/fortran/openmp.c
> @@ -762,6 +762,10 @@ enum omp_mask1
>    OMP_CLAUSE_SHARED,
>    OMP_CLAUSE_COPYIN,
>    OMP_CLAUSE_REDUCTION,
> +  OMP_CLAUSE_REDUCTION_DEFAULT,
> +  OMP_CLAUSE_REDUCTION_MODIFIER,

I don't understand the need for OMP_CLAUSE_REDUCTION_DEFAULT,
default modifier is allowed in all OpenMP reduction clauses and
your gfc_match_omp_clause_reduction function has the openacc argument.
So why can't you keep using OMP_CLAUSE_REDUCTION in place where
you use OMP_CLAUSE_REDUCTION_DEFAULT now and just decide based on !openacc
whether to parse any reduction modifiers?

One could probably get away even without OMP_CLAUSE_REDUCTION_MODIFIER,
just allow all the modifiers first and during resolving complain if
[OMP_LIST_REDUCTION_INSCAN] and/or [OMP_LIST_REDUCTION_TASK] is non-NULL
on constructs where it shouldn't.

When splitting clauses, OMP_LIST_REDUCTION_TASK applies only on the innermost
construct that accepts it (others should treat it as OMP_LIST_REDUCTION),
and inscan is severely limited to which constructs it can appear on.
For task modifier, do you diagnose somewhere what c_split_omp_clauses
diagnoses?
E.g. if task modifier appears with innermost combined construct simd/loop,
or if task modifier appears and not combined with parallel/do/sections?
Inscan is allowed only on do, simd, do simd, parallel do and parallel do sim.d

Also, I think there should be an error or sorry on the inscan modifier
somewhere until the rest of the scan support is implemented (in particular
the changes in the parsing of do/simd body with inscan reductions
including the parsing of the inclusive/exclusive directives in there).

>  #define OMP_DECLARE_SIMD_CLAUSES \
>    (omp_mask (OMP_CLAUSE_SIMDLEN) | OMP_CLAUSE_LINEAR			\
>     | OMP_CLAUSE_UNIFORM	| OMP_CLAUSE_ALIGNED | OMP_CLAUSE_INBRANCH	\

I wonder why we have the occassional tabs in the middle of the OMP_*_CLAUSES
defines.
> +   | OMP_CLAUSE_SAFELEN | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ALIGNED	\
> +   | OMP_CLAUSE_SIMDLEN	| OMP_CLAUSE_IF | OMP_CLAUSE_ORDER		\

Here too.

> +      for (int i = OMP_LIST_REDUCTION; i <= OMP_LIST_REDUCTION_TASK; i++)
> +	{
> +	  if (mask & GFC_OMP_MASK_TEAMS)
> +	    clausesa[GFC_OMP_SPLIT_TEAMS].lists[i]
> +	      = code->ext.omp_clauses->lists[i];
> +	  if (mask & GFC_OMP_MASK_PARALLEL)
> +	    clausesa[GFC_OMP_SPLIT_PARALLEL].lists[i]
> +	      = code->ext.omp_clauses->lists[i];
> +	  else if (mask & GFC_OMP_MASK_DO)
> +	    clausesa[GFC_OMP_SPLIT_DO].lists[i]
> +	      = code->ext.omp_clauses->lists[i];
> +	  if (mask & GFC_OMP_MASK_SIMD)
> +	    clausesa[GFC_OMP_SPLIT_SIMD].lists[i]
> +	      = code->ext.omp_clauses->lists[i];
> +	}

Seems in the middle-end we just ignore OMP_CLAUSE_REDUCTION_TASK on anything
but parallel/{for,do}/sections, so guess this is ok.

	Jakub


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Patch] Fortran: OpenMP 5.0 (in_,task_)reduction clause extensions
  2020-11-10 12:16 ` Jakub Jelinek
@ 2020-11-10 16:46   ` Tobias Burnus
  2020-11-10 17:23     ` Jakub Jelinek
  2020-11-11  8:25     ` [committed] gfortran.dg/gomp/workshare-reduction-*.f90: Fix dumps for -m32 (was: Re: [Patch] Fortran: OpenMP 5.0 (in_, task_)reduction clause extensions) Tobias Burnus
  0 siblings, 2 replies; 8+ messages in thread
From: Tobias Burnus @ 2020-11-10 16:46 UTC (permalink / raw)
  To: Jakub Jelinek, gcc-patches, fortran

[-- Attachment #1: Type: text/plain, Size: 1666 bytes --]

Hi Jakub,

thanks for the comments. I have now removed
OMP_CLAUSE_REDUCTION{_DEFAULT,_MODIFIER} and use 'openacc' as flag for OpenACC.
The only 'default:' check is now moved to resolution stage.

If I gathered it correctly, the splitting is complex but the
way it is implemented, it happens to be fine.

We discussed that the _LIST part gets too long (but that's something
for later) and that 'omp scan' best get implemented during stage1.
(Additionally, I believe that the ME always complains about 'inscan'
not being in 'omp scan' – and it can't as 'omp scan' is not yet
supported.)

On 10.11.20 13:16, Jakub Jelinek wrote:

>> +      for (int i = OMP_LIST_REDUCTION; i <= OMP_LIST_REDUCTION_TASK; i++)
>> +    {
>> +      if (mask & GFC_OMP_MASK_TEAMS)
>> +        clausesa[GFC_OMP_SPLIT_TEAMS].lists[i]
>> +          = code->ext.omp_clauses->lists[i];
>> +      if (mask & GFC_OMP_MASK_PARALLEL)
>> +        clausesa[GFC_OMP_SPLIT_PARALLEL].lists[i]
>> +          = code->ext.omp_clauses->lists[i];
>> +      else if (mask & GFC_OMP_MASK_DO)
>> +        clausesa[GFC_OMP_SPLIT_DO].lists[i]
>> +          = code->ext.omp_clauses->lists[i];
>> +      if (mask & GFC_OMP_MASK_SIMD)
>> +        clausesa[GFC_OMP_SPLIT_SIMD].lists[i]
>> +          = code->ext.omp_clauses->lists[i];
>> +    }
> Seems in the middle-end we just ignore OMP_CLAUSE_REDUCTION_TASK on anything
> but parallel/{for,do}/sections, so guess this is ok.


Tobias

-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander Walter

[-- Attachment #2: omp-reduction-v2.diff --]
[-- Type: text/x-patch, Size: 119780 bytes --]

Fortran: OpenMP 5.0 (in_,task_)reduction clause extensions

gcc/fortran/ChangeLog:

	PR fortran/95847
	* dump-parse-tree.c (show_omp_clauses): Handle new reduction enums.
	* gfortran.h (OMP_LIST_REDUCTION_INSCAN, OMP_LIST_REDUCTION_TASK,
	OMP_LIST_IN_REDUCTION, OMP_LIST_TASK_REDUCTION): Add enums.
	* openmp.c (enum omp_mask1): Add OMP_CLAUSE_IN_REDUCTION
	and OMP_CLAUSE_TASK_REDUCTION.
	(gfc_match_omp_clause_reduction): Extend reduction handling;
	moved from ...
	(gfc_match_omp_clauses): ... here. Add calls to it.
	(OMP_TASK_CLAUSES, OMP_TARGET_CLAUSES, OMP_TASKLOOP_CLAUSES):
	Add OMP_CLAUSE_IN_REDUCTION.
	(gfc_match_omp_taskgroup): Add task_reduction matching.
	(resolve_omp_clauses): Update for new reduction clause changes;
	remove removed nonmonotonic-schedule restrictions.
	(gfc_resolve_omp_parallel_blocks): Add new enums to switch.
	* trans-openmp.c (gfc_omp_clause_default_ctor,
	gfc_trans_omp_reduction_list, gfc_trans_omp_clauses,
	gfc_split_omp_clauses): Handle updated reduction clause.

gcc/ChangeLog:

	PR fortran/95847
	* gimplify.c (gimplify_scan_omp_clauses, gimplify_omp_loop): Use 'do'
	instead of 'for' in error messages for Fortran.
	* omp-low.c (check_omp_nesting_restrictions): Likewise

gcc/testsuite/ChangeLog:

	PR fortran/95847
	* gfortran.dg/gomp/schedule-modifiers-2.f90: Remove some dg-error.
	* gfortran.dg/gomp/reduction4.f90: New test.
	* gfortran.dg/gomp/reduction5.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-1.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-2.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-3.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-4.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-5.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-6.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-7.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-8.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-9.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-10.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-11.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-12.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-13.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-14.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-15.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-16.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-17.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-18.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-19.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-20.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-21.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-22.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-23.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-24.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-25.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-26.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-27.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-28.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-29.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-30.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-31.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-32.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-33.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-34.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-35.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-36.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-37.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-38.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-39.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-40.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-41.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-42.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-43.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-44.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-45.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-46.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-47.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-48.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-49.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-50.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-51.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-52.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-53.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-54.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-55.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-56.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-57.f90: New test.
	* gfortran.dg/gomp/workshare-reduction-58.f90: New test.

 gcc/fortran/dump-parse-tree.c                      |  10 +-
 gcc/fortran/gfortran.h                             |   4 +
 gcc/fortran/openmp.c                               | 377 +++++++++++++--------
 gcc/fortran/trans-openmp.c                         |  71 +++-
 gcc/gimplify.c                                     |   6 +-
 gcc/omp-low.c                                      |   3 +-
 gcc/testsuite/gfortran.dg/gomp/reduction4.f90      | 171 ++++++++++
 gcc/testsuite/gfortran.dg/gomp/reduction5.f90      |  41 +++
 .../gfortran.dg/gomp/schedule-modifiers-2.f90      |   8 +-
 .../gfortran.dg/gomp/workshare-reduction-1.f90     |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-10.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-11.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-12.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-13.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-14.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-15.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-16.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-17.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-18.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-19.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-2.f90     |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-20.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-21.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-22.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-23.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-24.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-25.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-26.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-27.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-28.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-29.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-3.f90     |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-30.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-31.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-32.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-33.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-34.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-35.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-36.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-37.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-38.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-39.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-4.f90     |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-40.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-41.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-42.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-43.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-44.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-45.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-46.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-47.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-48.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-49.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-5.f90     |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-50.f90    |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-51.f90    |  35 ++
 .../gfortran.dg/gomp/workshare-reduction-52.f90    |  35 ++
 .../gfortran.dg/gomp/workshare-reduction-53.f90    |  35 ++
 .../gfortran.dg/gomp/workshare-reduction-54.f90    |  35 ++
 .../gfortran.dg/gomp/workshare-reduction-55.f90    |  35 ++
 .../gfortran.dg/gomp/workshare-reduction-56.f90    |  35 ++
 .../gfortran.dg/gomp/workshare-reduction-57.f90    |  35 ++
 .../gfortran.dg/gomp/workshare-reduction-58.f90    |  35 ++
 .../gfortran.dg/gomp/workshare-reduction-6.f90     |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-7.f90     |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-8.f90     |  31 ++
 .../gfortran.dg/gomp/workshare-reduction-9.f90     |  31 ++
 67 files changed, 2349 insertions(+), 172 deletions(-)

diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c
index 43b97ba26ff..cab0fb2979f 100644
--- a/gcc/fortran/dump-parse-tree.c
+++ b/gcc/fortran/dump-parse-tree.c
@@ -1587,7 +1587,11 @@ show_omp_clauses (gfc_omp_clauses *omp_clauses)
 	  case OMP_LIST_MAP: type = "MAP"; break;
 	  case OMP_LIST_TO: type = "TO"; break;
 	  case OMP_LIST_FROM: type = "FROM"; break;
-	  case OMP_LIST_REDUCTION: type = "REDUCTION"; break;
+	  case OMP_LIST_REDUCTION:
+	  case OMP_LIST_REDUCTION_INSCAN:
+	  case OMP_LIST_REDUCTION_TASK: type = "REDUCTION"; break;
+	  case OMP_LIST_IN_REDUCTION: type = "IN_REDUCTION"; break;
+	  case OMP_LIST_TASK_REDUCTION: type = "TASK_REDUCTION"; break;
 	  case OMP_LIST_DEVICE_RESIDENT: type = "DEVICE_RESIDENT"; break;
 	  case OMP_LIST_LINK: type = "LINK"; break;
 	  case OMP_LIST_USE_DEVICE: type = "USE_DEVICE"; break;
@@ -1600,6 +1604,10 @@ show_omp_clauses (gfc_omp_clauses *omp_clauses)
 	    gcc_unreachable ();
 	  }
 	fprintf (dumpfile, " %s(", type);
+	if (list_type == OMP_LIST_REDUCTION_INSCAN)
+	  fputs ("inscan, ", dumpfile);
+	if (list_type == OMP_LIST_REDUCTION_TASK)
+	  fputs ("task, ", dumpfile);
 	show_omp_namelist (list_type, omp_clauses->lists[list_type]);
 	fputc (')', dumpfile);
       }
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index dfd7796cce0..6467985ea7f 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1278,6 +1278,10 @@ enum
   OMP_LIST_TO,
   OMP_LIST_FROM,
   OMP_LIST_REDUCTION,
+  OMP_LIST_REDUCTION_INSCAN,
+  OMP_LIST_REDUCTION_TASK,
+  OMP_LIST_IN_REDUCTION,
+  OMP_LIST_TASK_REDUCTION,
   OMP_LIST_DEVICE_RESIDENT,
   OMP_LIST_LINK,
   OMP_LIST_USE_DEVICE,
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 2270c858f39..68d0b65ff87 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -762,6 +762,8 @@ enum omp_mask1
   OMP_CLAUSE_SHARED,
   OMP_CLAUSE_COPYIN,
   OMP_CLAUSE_REDUCTION,
+  OMP_CLAUSE_IN_REDUCTION,
+  OMP_CLAUSE_TASK_REDUCTION,
   OMP_CLAUSE_IF,
   OMP_CLAUSE_NUM_THREADS,
   OMP_CLAUSE_SCHEDULE,
@@ -959,6 +961,163 @@ gfc_match_omp_map_clause (gfc_omp_namelist **list, gfc_omp_map_op map_op,
   return false;
 }
 
+/* reduction ( reduction-modifier, reduction-operator : variable-list )
+   in_reduction ( reduction-operator : variable-list )
+   task_reduction ( reduction-operator : variable-list )  */
+
+static match
+gfc_match_omp_clause_reduction (char pc, gfc_omp_clauses *c, bool openacc,
+				bool allow_derived)
+{
+  if (pc == 'r' && gfc_match ("reduction ( ") != MATCH_YES)
+    return MATCH_NO;
+  else if (pc == 'i' && gfc_match ("in_reduction ( ") != MATCH_YES)
+    return MATCH_NO;
+  else if (pc == 't' && gfc_match ("task_reduction ( ") != MATCH_YES)
+    return MATCH_NO;
+
+  locus old_loc = gfc_current_locus;
+  int list_idx = 0;
+
+  if (pc == 'r' && !openacc)
+    {
+      if (gfc_match ("inscan") == MATCH_YES)
+	list_idx = OMP_LIST_REDUCTION_INSCAN;
+      else if (gfc_match ("task") == MATCH_YES)
+	list_idx = OMP_LIST_REDUCTION_TASK;
+      else if (gfc_match ("default") == MATCH_YES)
+	list_idx = OMP_LIST_REDUCTION;
+      if (list_idx != 0 && gfc_match (", ") != MATCH_YES)
+	{
+	  gfc_error ("Comma expected at %C");
+	  gfc_current_locus = old_loc;
+	  return MATCH_NO;
+	}
+      if (list_idx == 0)
+	list_idx = OMP_LIST_REDUCTION;
+    }
+  else if (pc == 'i')
+    list_idx = OMP_LIST_IN_REDUCTION;
+  else if (pc == 't')
+    list_idx = OMP_LIST_TASK_REDUCTION;
+  else
+    list_idx = OMP_LIST_REDUCTION;
+
+  gfc_omp_reduction_op rop = OMP_REDUCTION_NONE;
+  char buffer[GFC_MAX_SYMBOL_LEN + 3];
+  if (gfc_match_char ('+') == MATCH_YES)
+    rop = OMP_REDUCTION_PLUS;
+  else if (gfc_match_char ('*') == MATCH_YES)
+    rop = OMP_REDUCTION_TIMES;
+  else if (gfc_match_char ('-') == MATCH_YES)
+    rop = OMP_REDUCTION_MINUS;
+  else if (gfc_match (".and.") == MATCH_YES)
+    rop = OMP_REDUCTION_AND;
+  else if (gfc_match (".or.") == MATCH_YES)
+    rop = OMP_REDUCTION_OR;
+  else if (gfc_match (".eqv.") == MATCH_YES)
+    rop = OMP_REDUCTION_EQV;
+  else if (gfc_match (".neqv.") == MATCH_YES)
+    rop = OMP_REDUCTION_NEQV;
+  if (rop != OMP_REDUCTION_NONE)
+    snprintf (buffer, sizeof buffer, "operator %s",
+	      gfc_op2string ((gfc_intrinsic_op) rop));
+  else if (gfc_match_defined_op_name (buffer + 1, 1) == MATCH_YES)
+    {
+      buffer[0] = '.';
+      strcat (buffer, ".");
+    }
+  else if (gfc_match_name (buffer) == MATCH_YES)
+    {
+      gfc_symbol *sym;
+      const char *n = buffer;
+
+      gfc_find_symbol (buffer, NULL, 1, &sym);
+      if (sym != NULL)
+	{
+	  if (sym->attr.intrinsic)
+	    n = sym->name;
+	  else if ((sym->attr.flavor != FL_UNKNOWN
+		    && sym->attr.flavor != FL_PROCEDURE)
+		   || sym->attr.external
+		   || sym->attr.generic
+		   || sym->attr.entry
+		   || sym->attr.result
+		   || sym->attr.dummy
+		   || sym->attr.subroutine
+		   || sym->attr.pointer
+		   || sym->attr.target
+		   || sym->attr.cray_pointer
+		   || sym->attr.cray_pointee
+		   || (sym->attr.proc != PROC_UNKNOWN
+		       && sym->attr.proc != PROC_INTRINSIC)
+		   || sym->attr.if_source != IFSRC_UNKNOWN
+		   || sym == sym->ns->proc_name)
+		{
+		  sym = NULL;
+		  n = NULL;
+		}
+	      else
+		n = sym->name;
+	    }
+	  if (n == NULL)
+	    rop = OMP_REDUCTION_NONE;
+	  else if (strcmp (n, "max") == 0)
+	    rop = OMP_REDUCTION_MAX;
+	  else if (strcmp (n, "min") == 0)
+	    rop = OMP_REDUCTION_MIN;
+	  else if (strcmp (n, "iand") == 0)
+	    rop = OMP_REDUCTION_IAND;
+	  else if (strcmp (n, "ior") == 0)
+	    rop = OMP_REDUCTION_IOR;
+	  else if (strcmp (n, "ieor") == 0)
+	    rop = OMP_REDUCTION_IEOR;
+	  if (rop != OMP_REDUCTION_NONE
+	      && sym != NULL
+	      && ! sym->attr.intrinsic
+	      && ! sym->attr.use_assoc
+	      && ((sym->attr.flavor == FL_UNKNOWN
+		   && !gfc_add_flavor (&sym->attr, FL_PROCEDURE,
+					      sym->name, NULL))
+		  || !gfc_add_intrinsic (&sym->attr, NULL)))
+	    rop = OMP_REDUCTION_NONE;
+    }
+  else
+    buffer[0] = '\0';
+  gfc_omp_udr *udr = (buffer[0] ? gfc_find_omp_udr (gfc_current_ns, buffer, NULL)
+				: NULL);
+  gfc_omp_namelist **head = NULL;
+  if (rop == OMP_REDUCTION_NONE && udr)
+    rop = OMP_REDUCTION_USER;
+
+  if (gfc_match_omp_variable_list (" :", &c->lists[list_idx], false, NULL,
+				   &head, openacc, allow_derived) != MATCH_YES)
+    {
+      gfc_current_locus = old_loc;
+      return MATCH_NO;
+    }
+  gfc_omp_namelist *n;
+  if (rop == OMP_REDUCTION_NONE)
+    {
+      n = *head;
+      *head = NULL;
+      gfc_error_now ("!$OMP DECLARE REDUCTION %s not found at %L",
+		     buffer, &old_loc);
+      gfc_free_omp_namelist (n);
+    }
+  else
+    for (n = *head; n; n = n->next)
+      {
+	n->u.reduction_op = rop;
+	if (udr)
+	  {
+	    n->udr = gfc_get_omp_namelist_udr ();
+	    n->udr->udr = udr;
+	  }
+     }
+  return MATCH_YES;
+}
+
 /* Match OpenMP and OpenACC directive clauses. MASK is a bitmask of
    clauses that are allowed for a particular directive.  */
 
@@ -1379,6 +1538,10 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      needs_space = true;
 	      continue;
 	    }
+	  if ((mask & OMP_CLAUSE_IN_REDUCTION)
+	      && gfc_match_omp_clause_reduction (pc, c, openacc,
+						 allow_derived) == MATCH_YES)
+	    continue;
 	  if ((mask & OMP_CLAUSE_INBRANCH)
 	      && !c->inbranch
 	      && !c->notinbranch
@@ -1717,124 +1880,24 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_REDUCTION)
-	      && gfc_match ("reduction ( ") == MATCH_YES)
+	      && gfc_match_omp_clause_reduction (pc, c, openacc,
+						 allow_derived) == MATCH_YES)
+	    continue;
+	  if ((mask & OMP_CLAUSE_MEMORDER)
+	      && c->memorder == OMP_MEMORDER_UNSET
+	      && gfc_match ("relaxed") == MATCH_YES)
 	    {
-	      gfc_omp_reduction_op rop = OMP_REDUCTION_NONE;
-	      char buffer[GFC_MAX_SYMBOL_LEN + 3];
-	      if (gfc_match_char ('+') == MATCH_YES)
-		rop = OMP_REDUCTION_PLUS;
-	      else if (gfc_match_char ('*') == MATCH_YES)
-		rop = OMP_REDUCTION_TIMES;
-	      else if (gfc_match_char ('-') == MATCH_YES)
-		rop = OMP_REDUCTION_MINUS;
-	      else if (gfc_match (".and.") == MATCH_YES)
-		rop = OMP_REDUCTION_AND;
-	      else if (gfc_match (".or.") == MATCH_YES)
-		rop = OMP_REDUCTION_OR;
-	      else if (gfc_match (".eqv.") == MATCH_YES)
-		rop = OMP_REDUCTION_EQV;
-	      else if (gfc_match (".neqv.") == MATCH_YES)
-		rop = OMP_REDUCTION_NEQV;
-	      if (rop != OMP_REDUCTION_NONE)
-		snprintf (buffer, sizeof buffer, "operator %s",
-			  gfc_op2string ((gfc_intrinsic_op) rop));
-	      else if (gfc_match_defined_op_name (buffer + 1, 1) == MATCH_YES)
-		{
-		  buffer[0] = '.';
-		  strcat (buffer, ".");
-		}
-	      else if (gfc_match_name (buffer) == MATCH_YES)
-		{
-		  gfc_symbol *sym;
-		  const char *n = buffer;
-
-		  gfc_find_symbol (buffer, NULL, 1, &sym);
-		  if (sym != NULL)
-		    {
-		      if (sym->attr.intrinsic)
-			n = sym->name;
-		      else if ((sym->attr.flavor != FL_UNKNOWN
-				&& sym->attr.flavor != FL_PROCEDURE)
-			       || sym->attr.external
-			       || sym->attr.generic
-			       || sym->attr.entry
-			       || sym->attr.result
-			       || sym->attr.dummy
-			       || sym->attr.subroutine
-			       || sym->attr.pointer
-			       || sym->attr.target
-			       || sym->attr.cray_pointer
-			       || sym->attr.cray_pointee
-			       || (sym->attr.proc != PROC_UNKNOWN
-				   && sym->attr.proc != PROC_INTRINSIC)
-			       || sym->attr.if_source != IFSRC_UNKNOWN
-			       || sym == sym->ns->proc_name)
-			{
-			  sym = NULL;
-			  n = NULL;
-			}
-		      else
-			n = sym->name;
-		    }
-		  if (n == NULL)
-		    rop = OMP_REDUCTION_NONE;
-		  else if (strcmp (n, "max") == 0)
-		    rop = OMP_REDUCTION_MAX;
-		  else if (strcmp (n, "min") == 0)
-		    rop = OMP_REDUCTION_MIN;
-		  else if (strcmp (n, "iand") == 0)
-		    rop = OMP_REDUCTION_IAND;
-		  else if (strcmp (n, "ior") == 0)
-		    rop = OMP_REDUCTION_IOR;
-		  else if (strcmp (n, "ieor") == 0)
-		    rop = OMP_REDUCTION_IEOR;
-		  if (rop != OMP_REDUCTION_NONE
-		      && sym != NULL
-		      && ! sym->attr.intrinsic
-		      && ! sym->attr.use_assoc
-		      && ((sym->attr.flavor == FL_UNKNOWN
-			  && !gfc_add_flavor (&sym->attr, FL_PROCEDURE,
-					      sym->name, NULL))
-			  || !gfc_add_intrinsic (&sym->attr, NULL)))
-		    rop = OMP_REDUCTION_NONE;
-		}
-	      else
-		buffer[0] = '\0';
-	      gfc_omp_udr *udr
-		= (buffer[0]
-		   ? gfc_find_omp_udr (gfc_current_ns, buffer, NULL) : NULL);
-	      gfc_omp_namelist **head = NULL;
-	      if (rop == OMP_REDUCTION_NONE && udr)
-		rop = OMP_REDUCTION_USER;
-
-	      if (gfc_match_omp_variable_list (" :",
-					       &c->lists[OMP_LIST_REDUCTION],
-					       false, NULL, &head, openacc,
-					       allow_derived) == MATCH_YES)
-		{
-		  gfc_omp_namelist *n;
-		  if (rop == OMP_REDUCTION_NONE)
-		    {
-		      n = *head;
-		      *head = NULL;
-		      gfc_error_now ("!$OMP DECLARE REDUCTION %s not found "
-				     "at %L", buffer, &old_loc);
-		      gfc_free_omp_namelist (n);
-		    }
-		  else
-		    for (n = *head; n; n = n->next)
-		      {
-			n->u.reduction_op = rop;
-			if (udr)
-			  {
-			    n->udr = gfc_get_omp_namelist_udr ();
-			    n->udr->udr = udr;
-			  }
-		      }
-		  continue;
-		}
-	      else
-		gfc_current_locus = old_loc;
+	      c->memorder = OMP_MEMORDER_RELAXED;
+	      needs_space = true;
+	      continue;
+	    }
+	  if ((mask & OMP_CLAUSE_MEMORDER)
+	      && c->memorder == OMP_MEMORDER_UNSET
+	      && gfc_match ("release") == MATCH_YES)
+	    {
+	      c->memorder = OMP_MEMORDER_RELEASE;
+	      needs_space = true;
+	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_MEMORDER)
 	      && c->memorder == OMP_MEMORDER_UNSET
@@ -1962,6 +2025,10 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	    }
 	  break;
 	case 't':
+	  if ((mask & OMP_CLAUSE_TASK_REDUCTION)
+	      && gfc_match_omp_clause_reduction (pc, c, openacc,
+						 allow_derived) == MATCH_YES)
+	    continue;
 	  if ((mask & OMP_CLAUSE_THREAD_LIMIT)
 	      && c->thread_limit == NULL
 	      && gfc_match ("thread_limit ( %e )",
@@ -2696,18 +2763,19 @@ cleanup:
   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE		\
    | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT		\
    | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL | OMP_CLAUSE_MERGEABLE	\
-   | OMP_CLAUSE_DEPEND | OMP_CLAUSE_PRIORITY)
+   | OMP_CLAUSE_DEPEND | OMP_CLAUSE_PRIORITY | OMP_CLAUSE_IN_REDUCTION)
 #define OMP_TASKLOOP_CLAUSES \
   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE		\
    | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF		\
    | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL		\
    | OMP_CLAUSE_MERGEABLE | OMP_CLAUSE_PRIORITY | OMP_CLAUSE_GRAINSIZE	\
-   | OMP_CLAUSE_NUM_TASKS | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_NOGROUP)
+   | OMP_CLAUSE_NUM_TASKS | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_NOGROUP	\
+   | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IN_REDUCTION)
 #define OMP_TARGET_CLAUSES \
   (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF	\
    | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE		\
    | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP			\
-   | OMP_CLAUSE_IS_DEVICE_PTR)
+   | OMP_CLAUSE_IS_DEVICE_PTR | OMP_CLAUSE_IN_REDUCTION)
 #define OMP_TARGET_DATA_CLAUSES \
   (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF	\
    | OMP_CLAUSE_USE_DEVICE_PTR | OMP_CLAUSE_USE_DEVICE_ADDR)
@@ -4228,12 +4296,12 @@ gfc_match_omp_barrier (void)
 match
 gfc_match_omp_taskgroup (void)
 {
-  if (gfc_match_omp_eos () != MATCH_YES)
-    {
-      gfc_error ("Unexpected junk after $OMP TASKGROUP statement at %C");
-      return MATCH_ERROR;
-    }
+  gfc_omp_clauses *c;
+  if (gfc_match_omp_clauses (&c, OMP_CLAUSE_TASK_REDUCTION, true, true)
+      != MATCH_YES)
+    return MATCH_ERROR;
   new_st.op = EXEC_OMP_TASKGROUP;
+  new_st.ext.omp_clauses = c;
   return MATCH_YES;
 }
 
@@ -4560,7 +4628,9 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
   static const char *clause_names[]
     = { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED",
 	"COPYIN", "UNIFORM", "ALIGNED", "LINEAR", "DEPEND", "MAP",
-	"TO", "FROM", "REDUCTION", "DEVICE_RESIDENT", "LINK", "USE_DEVICE",
+	"TO", "FROM", "REDUCTION", "REDUCTION" /*inscan*/, "REDUCTION" /*task*/,
+	"IN_REDUCTION", "TASK_REDUCTION",
+	"DEVICE_RESIDENT", "LINK", "USE_DEVICE",
 	"CACHE", "IS_DEVICE_PTR", "USE_DEVICE_PTR", "USE_DEVICE_ADDR",
 	"NONTEMPORAL" };
   STATIC_ASSERT (ARRAY_SIZE (clause_names) == OMP_LIST_NUM);
@@ -4727,21 +4797,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
   if (omp_clauses->sched_kind != OMP_SCHED_NONE
       && omp_clauses->sched_nonmonotonic)
     {
-      if (omp_clauses->sched_kind != OMP_SCHED_DYNAMIC
-	  && omp_clauses->sched_kind != OMP_SCHED_GUIDED)
-	{
-	  const char *p;
-	  switch (omp_clauses->sched_kind)
-	    {
-	    case OMP_SCHED_STATIC: p = "STATIC"; break;
-	    case OMP_SCHED_RUNTIME: p = "RUNTIME"; break;
-	    case OMP_SCHED_AUTO: p = "AUTO"; break;
-	    default: gcc_unreachable ();
-	    }
-	  gfc_error ("NONMONOTONIC modifier specified for %s schedule kind "
-		     "at %L", p, &code->loc);
-	}
-      else if (omp_clauses->sched_monotonic)
+      if (omp_clauses->sched_monotonic)
 	gfc_error ("Both MONOTONIC and NONMONOTONIC schedule modifiers "
 		   "specified at %L", &code->loc);
       else if (omp_clauses->ordered)
@@ -4818,7 +4874,11 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 	&& (list != OMP_LIST_MAP || openacc)
 	&& list != OMP_LIST_FROM
 	&& list != OMP_LIST_TO
-	&& (list != OMP_LIST_REDUCTION || !openacc))
+	&& (list != OMP_LIST_REDUCTION || !openacc)
+	&& list != OMP_LIST_REDUCTION_INSCAN
+	&& list != OMP_LIST_REDUCTION_TASK
+	&& list != OMP_LIST_IN_REDUCTION
+	&& list != OMP_LIST_TASK_REDUCTION)
       for (n = omp_clauses->lists[list]; n; n = n->next)
 	{
 	  bool component_ref_p = false;
@@ -5224,6 +5284,11 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 	    for (; n != NULL; n = n->next)
 	      {
 		bool bad = false;
+		bool is_reduction = (list == OMP_LIST_REDUCTION
+				     || list == OMP_LIST_REDUCTION_INSCAN
+				     || list == OMP_LIST_REDUCTION_TASK
+				     || list == OMP_LIST_IN_REDUCTION
+				     || list == OMP_LIST_TASK_REDUCTION);
 		if (n->sym->attr.threadprivate)
 		  gfc_error ("THREADPRIVATE object %qs in %s clause at %L",
 			     n->sym->name, name, &n->where);
@@ -5233,15 +5298,15 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 		if (n->sym->attr.associate_var)
 		  gfc_error ("ASSOCIATE name %qs in %s clause at %L",
 			     n->sym->name, name, &n->where);
-		if (list != OMP_LIST_PRIVATE)
+		if (list != OMP_LIST_PRIVATE && is_reduction)
 		  {
-		    if (n->sym->attr.proc_pointer && list == OMP_LIST_REDUCTION)
+		    if (n->sym->attr.proc_pointer)
 		      gfc_error ("Procedure pointer %qs in %s clause at %L",
 				 n->sym->name, name, &n->where);
-		    if (n->sym->attr.pointer && list == OMP_LIST_REDUCTION)
+		    if (n->sym->attr.pointer)
 		      gfc_error ("POINTER object %qs in %s clause at %L",
 				 n->sym->name, name, &n->where);
-		    if (n->sym->attr.cray_pointer && list == OMP_LIST_REDUCTION)
+		    if (n->sym->attr.cray_pointer)
 		      gfc_error ("Cray pointer %qs in %s clause at %L",
 				 n->sym->name, name, &n->where);
 		  }
@@ -5253,7 +5318,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 		else if (n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE)
 		  gfc_error ("Assumed size array %qs in %s clause at %L",
 			     n->sym->name, name, &n->where);
-		if (n->sym->attr.in_namelist && list != OMP_LIST_REDUCTION)
+		if (n->sym->attr.in_namelist && !is_reduction)
 		  gfc_error ("Variable %qs in %s clause is used in "
 			     "NAMELIST statement at %L",
 			     n->sym->name, name, &n->where);
@@ -5273,7 +5338,21 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 
 		switch (list)
 		  {
+		  case OMP_LIST_REDUCTION_INSCAN:
+		  case OMP_LIST_REDUCTION_TASK:
+		    if (code && (code->op == EXEC_OMP_TASKLOOP
+				 || code->op == EXEC_OMP_TEAMS
+				 || code->op == EXEC_OMP_TEAMS_DISTRIBUTE))
+		      {
+			gfc_error ("Only DEFAULT permitted as reduction-"
+				   "modifier in REDUCTION clause at %L",
+				   &n->where);
+			break;
+		      }
+		    gcc_fallthrough ();
 		  case OMP_LIST_REDUCTION:
+		  case OMP_LIST_IN_REDUCTION:
+		  case OMP_LIST_TASK_REDUCTION:
 		    switch (n->u.reduction_op)
 		      {
 		      case OMP_REDUCTION_PLUS:
@@ -6102,6 +6181,10 @@ gfc_resolve_omp_parallel_blocks (gfc_code *code, gfc_namespace *ns)
       case OMP_LIST_FIRSTPRIVATE:
       case OMP_LIST_LASTPRIVATE:
       case OMP_LIST_REDUCTION:
+      case OMP_LIST_REDUCTION_INSCAN:
+      case OMP_LIST_REDUCTION_TASK:
+      case OMP_LIST_IN_REDUCTION:
+      case OMP_LIST_TASK_REDUCTION:
       case OMP_LIST_LINEAR:
 	for (n = omp_clauses->lists[list]; n; n = n->next)
 	  ctx.sharing_clauses->add (n->sym);
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c
index 1d652a09f9d..d2559bd0c0a 100644
--- a/gcc/fortran/trans-openmp.c
+++ b/gcc/fortran/trans-openmp.c
@@ -626,6 +626,8 @@ gfc_omp_clause_default_ctor (tree clause, tree decl, tree outer)
     case OMP_CLAUSE_LASTPRIVATE:
     case OMP_CLAUSE_LINEAR:
     case OMP_CLAUSE_REDUCTION:
+    case OMP_CLAUSE_IN_REDUCTION:
+    case OMP_CLAUSE_TASK_REDUCTION:
       break;
     default:
       gcc_unreachable ();
@@ -699,7 +701,9 @@ gfc_omp_clause_default_ctor (tree clause, tree decl, tree outer)
   then_b = gfc_finish_block (&cond_block);
 
   /* Reduction clause requires allocated ALLOCATABLE.  */
-  if (OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_REDUCTION)
+  if (OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_REDUCTION
+      && OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_IN_REDUCTION
+      && OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_TASK_REDUCTION)
     {
       gfc_init_block (&cond_block);
       if (GFC_DESCRIPTOR_TYPE_P (type))
@@ -2029,9 +2033,25 @@ gfc_trans_omp_array_reduction_or_udr (tree c, gfc_omp_namelist *n, locus where)
 }
 
 static tree
-gfc_trans_omp_reduction_list (gfc_omp_namelist *namelist, tree list,
+gfc_trans_omp_reduction_list (int kind, gfc_omp_namelist *namelist, tree list,
 			      locus where, bool mark_addressable)
 {
+  omp_clause_code clause = OMP_CLAUSE_REDUCTION;
+  switch (kind)
+    {
+    case OMP_LIST_REDUCTION:
+    case OMP_LIST_REDUCTION_INSCAN:
+    case OMP_LIST_REDUCTION_TASK:
+      break;
+    case OMP_LIST_IN_REDUCTION:
+      clause = OMP_CLAUSE_IN_REDUCTION;
+      break;
+    case OMP_LIST_TASK_REDUCTION:
+      clause = OMP_CLAUSE_TASK_REDUCTION;
+      break;
+    default:
+      gcc_unreachable ();
+    }
   for (; namelist != NULL; namelist = namelist->next)
     if (namelist->sym->attr.referenced)
       {
@@ -2039,10 +2059,14 @@ gfc_trans_omp_reduction_list (gfc_omp_namelist *namelist, tree list,
 	if (t != error_mark_node)
 	  {
 	    tree node = build_omp_clause (gfc_get_location (&namelist->where),
-					  OMP_CLAUSE_REDUCTION);
+					  clause);
 	    OMP_CLAUSE_DECL (node) = t;
 	    if (mark_addressable)
 	      TREE_ADDRESSABLE (t) = 1;
+	    if (kind == OMP_LIST_REDUCTION_INSCAN)
+	      OMP_CLAUSE_REDUCTION_INSCAN (node) = 1;
+	    if (kind == OMP_LIST_REDUCTION_TASK)
+	      OMP_CLAUSE_REDUCTION_TASK (node) = 1;
 	    switch (namelist->u.reduction_op)
 	      {
 	      case OMP_REDUCTION_PLUS:
@@ -2267,10 +2291,14 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
       switch (list)
 	{
 	case OMP_LIST_REDUCTION:
+	case OMP_LIST_REDUCTION_INSCAN:
+	case OMP_LIST_REDUCTION_TASK:
+	case OMP_LIST_IN_REDUCTION:
+	case OMP_LIST_TASK_REDUCTION:
 	  /* An OpenACC async clause indicates the need to set reduction
 	     arguments addressable, to allow asynchronous copy-out.  */
-	  omp_clauses = gfc_trans_omp_reduction_list (n, omp_clauses, where,
-						      clauses->async);
+	  omp_clauses = gfc_trans_omp_reduction_list (list, n, omp_clauses,
+						      where, clauses->async);
 	  break;
 	case OMP_LIST_PRIVATE:
 	  clause_code = OMP_CLAUSE_PRIVATE;
@@ -5207,18 +5235,27 @@ gfc_split_omp_clauses (gfc_code *code,
       /* Reduction is allowed on simd, do, parallel and teams.
 	 Duplicate it on all of them, but omit on do if
 	 parallel is present.  */
-      if (mask & GFC_OMP_MASK_TEAMS)
-	clausesa[GFC_OMP_SPLIT_TEAMS].lists[OMP_LIST_REDUCTION]
-	  = code->ext.omp_clauses->lists[OMP_LIST_REDUCTION];
-      if (mask & GFC_OMP_MASK_PARALLEL)
-	clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_REDUCTION]
-	  = code->ext.omp_clauses->lists[OMP_LIST_REDUCTION];
-      else if (mask & GFC_OMP_MASK_DO)
-	clausesa[GFC_OMP_SPLIT_DO].lists[OMP_LIST_REDUCTION]
-	  = code->ext.omp_clauses->lists[OMP_LIST_REDUCTION];
-      if (mask & GFC_OMP_MASK_SIMD)
-	clausesa[GFC_OMP_SPLIT_SIMD].lists[OMP_LIST_REDUCTION]
-	  = code->ext.omp_clauses->lists[OMP_LIST_REDUCTION];
+      for (int i = OMP_LIST_REDUCTION; i <= OMP_LIST_REDUCTION_TASK; i++)
+	{
+	  if (mask & GFC_OMP_MASK_TEAMS)
+	    clausesa[GFC_OMP_SPLIT_TEAMS].lists[i]
+	      = code->ext.omp_clauses->lists[i];
+	  if (mask & GFC_OMP_MASK_PARALLEL)
+	    clausesa[GFC_OMP_SPLIT_PARALLEL].lists[i]
+	      = code->ext.omp_clauses->lists[i];
+	  else if (mask & GFC_OMP_MASK_DO)
+	    clausesa[GFC_OMP_SPLIT_DO].lists[i]
+	      = code->ext.omp_clauses->lists[i];
+	  if (mask & GFC_OMP_MASK_SIMD)
+	    clausesa[GFC_OMP_SPLIT_SIMD].lists[i]
+	      = code->ext.omp_clauses->lists[i];
+	}
+      if (mask & GFC_OMP_MASK_TARGET)
+	clausesa[GFC_OMP_SPLIT_TARGET].lists[OMP_LIST_IN_REDUCTION]
+	  = code->ext.omp_clauses->lists[OMP_LIST_IN_REDUCTION];
+      if (mask & GFC_OMP_MASK_TASKLOOP)
+	clausesa[GFC_OMP_SPLIT_TASKLOOP].lists[OMP_LIST_IN_REDUCTION]
+	  = code->ext.omp_clauses->lists[OMP_LIST_IN_REDUCTION];
       /* Linear clause is supported on do and simd,
 	 put it on the innermost one.  */
       clausesa[innermost].lists[OMP_LIST_LINEAR]
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index b2c623be456..d18c43e3e0f 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -8672,7 +8672,8 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
 		{
 		  error_at (OMP_CLAUSE_LOCATION (c),
 			    "invalid %<task%> reduction modifier on construct "
-			    "other than %<parallel%>, %<for%> or %<sections%>");
+			    "other than %<parallel%>, %qs or %<sections%>",
+			    lang_GNU_Fortran () ? "do" : "for");
 		  OMP_CLAUSE_REDUCTION_TASK (c) = 0;
 		}
 	    }
@@ -12703,7 +12704,8 @@ gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
 	  {
 	    error_at (OMP_CLAUSE_LOCATION (*pc),
 		      "invalid %<task%> reduction modifier on construct "
-		      "other than %<parallel%>, %<for%> or %<sections%>");
+		      "other than %<parallel%>, %qs or %<sections%>",
+		      lang_GNU_Fortran () ? "do" : "for");
 	    OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
 	  }
 	pc = &OMP_CLAUSE_CHAIN (*pc);
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 447d7dbc92a..83ca5fc23e0 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -2937,7 +2937,8 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
 		    {
 		      error_at (gimple_location (stmt),
 				"%<ordered simd threads%> must be closely "
-				"nested inside of %<for simd%> region");
+				"nested inside of %<%s simd%> region",
+				lang_GNU_Fortran () ? "do" : "for");
 		      return false;
 		    }
 		  return true;
diff --git a/gcc/testsuite/gfortran.dg/gomp/reduction4.f90 b/gcc/testsuite/gfortran.dg/gomp/reduction4.f90
new file mode 100644
index 00000000000..af8c91b2a87
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/reduction4.f90
@@ -0,0 +1,171 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-original" }
+!
+! (in_)reduction clause
+! Test all in-principle valid combinations, even if
+! not valid in this context (some fail at ME level)
+!
+implicit none
+integer :: a, b, i
+a = 0
+
+! ------------ parallel ------------
+!$omp parallel reduction(+:a)
+do i=1,10
+  a = a + 1
+end do
+!$omp end parallel
+
+!$omp parallel reduction(default,+:a)
+do i=1,10
+  a = a + 1
+end do
+!$omp end parallel
+
+!$omp parallel reduction(task,+:a)
+do i=1,10
+  a = a + 1
+end do
+!$omp end parallel
+
+!$omp parallel reduction(inscan,+:a)  ! { dg-error "'inscan' 'reduction' clause on 'parallel' construct" }
+do i=1,10
+  a = a + 1
+end do
+!$omp end parallel
+
+! ------------ simd ------------
+!$omp simd reduction(+:a)
+do i=1,10
+  a = a + 1
+end do
+
+!$omp simd reduction(default,+:a)
+do i=1,10
+  a = a + 1
+end do
+
+!$omp simd reduction(task,+:a)  ! { dg-error "invalid 'task' reduction modifier on construct other than 'parallel', 'do' or 'sections'" }
+do i=1,10
+  a = a + 1
+end do
+
+!$omp simd reduction(inscan,+:a)  ! { dg-error "'inscan' 'reduction' clause but not in 'scan' directive clause" }
+do i=1,10
+  a = a + 1
+end do
+
+! ------------ do ------------
+!$omp parallel
+!$omp do reduction(+:a)
+do i=1,10
+  a = a + 1
+end do
+!$omp end parallel
+
+!$omp parallel
+!$omp do reduction(default,+:a)
+do i=1,10
+  a = a + 1
+end do
+!$omp end parallel
+
+!$omp parallel
+!$omp do reduction(task,+:a)
+do i=1,10
+  a = a + 1
+end do
+!$omp end parallel
+
+!$omp parallel
+!$omp do reduction(inscan,+:a)  ! { dg-error "'a' specified in 'inscan' 'reduction' clause but not in 'scan' directive clause" }
+do i=1,10
+  a = a + 1
+end do
+!$omp end parallel
+
+! ------------ section ------------
+!$omp parallel
+!$omp sections reduction(+:a)
+  !$omp section
+  a = a + 1
+!$omp end sections
+!$omp end parallel
+
+!$omp parallel
+!$omp sections reduction(default,+:a)
+  !$omp section
+  a = a + 1
+!$omp end sections
+!$omp end parallel
+
+!$omp parallel
+!$omp sections reduction(task,+:a)
+  !$omp section
+  a = a + 1
+!$omp end sections
+!$omp end parallel
+
+!$omp parallel
+!$omp sections reduction(inscan,+:a)  ! { dg-error "'inscan' 'reduction' clause on 'sections' construct" }
+  !$omp section
+  a = a + 1
+!$omp end sections
+!$omp end parallel
+
+! ------------ task ------------
+!$omp task in_reduction(+:a)
+  a = a + 1
+!$omp end task
+
+! ------------ taskloop ------------
+!$omp taskloop reduction(+:a) in_reduction(+:b)
+do i=1,10
+  a = a + 1
+end do
+
+!$omp taskloop reduction(default,+:a) in_reduction(+:b)
+do i=1,10
+  a = a + 1
+end do
+
+! ------------ target ------------
+!$omp target in_reduction(+:b)
+  a = a + 1
+!$omp end target
+
+! ------------ teams ------------
+!$omp teams reduction(+:b)
+  a = a + 1
+!$omp end teams
+
+!$omp teams reduction(default, +:b)
+  a = a + 1
+!$omp end teams
+
+! ------------ taskgroup --------
+
+!$omp taskgroup task_reduction(+:b)
+  a = a + 1
+!$omp end taskgroup
+
+end
+
+! { dg-final { scan-tree-dump-times "#pragma omp for reduction\\(\\\+:a\\)" 2 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp for reduction\\(inscan,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp for reduction\\(task,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel\[\n\r\]" 8 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel private\\(i\\) reduction\\(\\\+:a\\)" 2 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel private\\(i\\) reduction\\(inscan,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel private\\(i\\) reduction\\(task,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp section\[\n\r\]" 4 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp sections reduction\\(\\\+:a\\)" 2 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp sections reduction\\(inscan,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp sections reduction\\(task,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:1\\) reduction\\(\\\+:a\\)" 2 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:1\\) reduction\\(inscan,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:1\\) reduction\\(task,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp target in_reduction\\(\\\+:b\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task in_reduction\\(\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp teams reduction\\(\\\+:b\\)" 2 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp taskloop reduction\\(\\\+:a\\) in_reduction\\(\\\+:b\\)" 2 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/reduction5.f90 b/gcc/testsuite/gfortran.dg/gomp/reduction5.f90
new file mode 100644
index 00000000000..df915f1cad4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/reduction5.f90
@@ -0,0 +1,41 @@
+! { dg-do compile }
+!
+implicit none
+integer :: a, b, i
+a = 0
+
+!$omp parallel reduction(foo,+:a)  ! { dg-error "26: Failed to match clause" }
+do i=1,10
+  a = a + 1
+end do
+!$omp end parallel  ! { dg-error "Unexpected !.OMP END PARALLEL statement" }
+
+!$omp parallel reduction(task +:a) ! { dg-error "30: Comma expected at" }
+do i=1,10
+  a = a + 1
+end do
+!$omp end parallel  ! { dg-error "Unexpected !.OMP END PARALLEL statement" }
+
+!$omp task in_reduction(foo,+:a)  ! { dg-error "25: Failed to match clause" }
+  a = a + 1
+!$omp end task  ! { dg-error "Unexpected !.OMP END TASK statement" }
+
+!$omp taskloop reduction(inscan,+:a) in_reduction(+:b) ! { dg-error "34: Only DEFAULT permitted as reduction-modifier in REDUCTION clause" }
+do i=1,10
+  a = a + 1
+end do
+
+!$omp taskloop reduction(task,+:a) in_reduction(+:b) ! { dg-error "32: Only DEFAULT permitted as reduction-modifier in REDUCTION clause" }
+do i=1,10
+  a = a + 1
+end do
+
+!$omp teams reduction(inscan,+:b) ! { dg-error "31: Only DEFAULT permitted as reduction-modifier in REDUCTION clause" }
+  a = a + 1
+!$omp end teams
+
+!$omp teams reduction(task, +:b) ! { dg-error "30: Only DEFAULT permitted as reduction-modifier in REDUCTION clause" }
+  a = a + 1
+!$omp end teams
+
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/schedule-modifiers-2.f90 b/gcc/testsuite/gfortran.dg/gomp/schedule-modifiers-2.f90
index 0be53cc71a5..537fba23c11 100644
--- a/gcc/testsuite/gfortran.dg/gomp/schedule-modifiers-2.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/schedule-modifiers-2.f90
@@ -3,16 +3,16 @@
 
 subroutine foo
   integer :: i
-  !$omp do schedule (nonmonotonic: static, 2)	! { dg-error "NONMONOTONIC modifier specified for STATIC schedule kind" }
+  !$omp do schedule (nonmonotonic: static, 2)
   do i = 0, 64
   end do
-  !$omp do schedule (nonmonotonic : static)	! { dg-error "NONMONOTONIC modifier specified for STATIC schedule kind" }
+  !$omp do schedule (nonmonotonic : static)
   do i = 0, 64
   end do
-  !$omp do schedule (nonmonotonic : runtime)	! { dg-error "NONMONOTONIC modifier specified for RUNTIME schedule kind" }
+  !$omp do schedule (nonmonotonic : runtime)
   do i = 0, 64
   end do
-  !$omp do schedule (nonmonotonic : auto)	! { dg-error "NONMONOTONIC modifier specified for AUTO schedule kind" }
+  !$omp do schedule (nonmonotonic : auto)
   do i = 0, 64
   end do
   !$omp do schedule (nonmonotonic : dynamic) ordered	! { dg-error "NONMONOTONIC schedule modifier specified with ORDERED clause" }
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-1.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-1.f90
new file mode 100644
index 00000000000..3e639d2e74b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-1.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 0, 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_maybe_nonmonotonic_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (runtime)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-10.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-10.f90
new file mode 100644
index 00000000000..e71ac3f41a7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-10.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: static, 2)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-11.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-11.f90
new file mode 100644
index 00000000000..94202200ca1
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-11.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (dynamic)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-12.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-12.f90
new file mode 100644
index 00000000000..66c6eb1cae0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-12.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483650|-2147483646), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: dynamic)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-13.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-13.f90
new file mode 100644
index 00000000000..89782d299fd
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-13.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: dynamic)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-14.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-14.f90
new file mode 100644
index 00000000000..16b3e01b891
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-14.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (dynamic, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-15.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-15.f90
new file mode 100644
index 00000000000..8bf126c5ea7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-15.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483650|-2147483646), 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: dynamic, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-16.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-16.f90
new file mode 100644
index 00000000000..fe8d1ae2124
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-16.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: dynamic, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-17.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-17.f90
new file mode 100644
index 00000000000..1f2823dd724
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-17.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (guided)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-18.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-18.f90
new file mode 100644
index 00000000000..ad0856a6fe7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-18.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483651|-2147483645), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } } 
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: guided)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-19.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-19.f90
new file mode 100644
index 00000000000..e884dbf037c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-19.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: guided)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-2.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-2.f90
new file mode 100644
index 00000000000..2f78c0be4b3
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-2.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483648|-2147483648), 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: runtime)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-20.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-20.f90
new file mode 100644
index 00000000000..8a4d6dfe4df
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-20.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (guided, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-21.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-21.f90
new file mode 100644
index 00000000000..2d9362b751f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-21.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483651|-2147483645), 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: guided, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-22.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-22.f90
new file mode 100644
index 00000000000..485171fd481
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-22.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: guided, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-23.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-23.f90
new file mode 100644
index 00000000000..45dc0002b92
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-23.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (auto)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-24.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-24.f90
new file mode 100644
index 00000000000..e7fbe922f3e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-24.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: auto)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-25.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-25.f90
new file mode 100644
index 00000000000..d5554c49962
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-25.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: auto)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-26.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-26.f90
new file mode 100644
index 00000000000..28267902914
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-26.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 0, 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_maybe_nonmonotonic_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (runtime)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-27.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-27.f90
new file mode 100644
index 00000000000..2ee047d4e8c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-27.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483648|-2147483648), 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: runtime)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-28.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-28.f90
new file mode 100644
index 00000000000..6c9d49be13c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-28.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 4, 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: runtime)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-29.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-29.f90
new file mode 100644
index 00000000000..316b72e1d2e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-29.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-3.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-3.f90
new file mode 100644
index 00000000000..6c9d49be13c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-3.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 4, 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: runtime)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-30.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-30.f90
new file mode 100644
index 00000000000..b9406d6b236
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-30.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (static)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-31.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-31.f90
new file mode 100644
index 00000000000..4a246045c1b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-31.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: static)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-32.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-32.f90
new file mode 100644
index 00000000000..a7062d9eaae
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-32.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: static)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-33.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-33.f90
new file mode 100644
index 00000000000..67c25c82ddd
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-33.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (static, 2)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-34.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-34.f90
new file mode 100644
index 00000000000..f1e4d89adbb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-34.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: static, 2)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-35.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-35.f90
new file mode 100644
index 00000000000..7d7c27118ba
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-35.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: static, 2)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-36.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-36.f90
new file mode 100644
index 00000000000..b190e9ee87b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-36.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (dynamic)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-37.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-37.f90
new file mode 100644
index 00000000000..c541d22d6cf
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-37.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483650|-2147483646), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: dynamic)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-38.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-38.f90
new file mode 100644
index 00000000000..46a27a0386c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-38.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: dynamic)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-39.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-39.f90
new file mode 100644
index 00000000000..6cdd9a8807b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-39.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (dynamic, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-4.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-4.f90
new file mode 100644
index 00000000000..c7744277bc8
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-4.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-40.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-40.f90
new file mode 100644
index 00000000000..29da27abc5a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-40.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483650|-2147483646), 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: dynamic, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-41.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-41.f90
new file mode 100644
index 00000000000..4ed879cdd00
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-41.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: dynamic, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-42.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-42.f90
new file mode 100644
index 00000000000..78d02ef8035
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-42.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (guided)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-43.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-43.f90
new file mode 100644
index 00000000000..16885c84210
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-43.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483651|-2147483645), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: guided)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-44.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-44.f90
new file mode 100644
index 00000000000..0db9be6854c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-44.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: guided)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-45.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-45.f90
new file mode 100644
index 00000000000..40b12755414
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-45.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (guided, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-46.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-46.f90
new file mode 100644
index 00000000000..57c74023d8d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-46.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483651|-2147483645), 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: guided, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-47.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-47.f90
new file mode 100644
index 00000000000..b4564300b50
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-47.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: guided, 3)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-48.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-48.f90
new file mode 100644
index 00000000000..1370010ac60
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-48.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (auto)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-49.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-49.f90
new file mode 100644
index 00000000000..ab2591f3acf
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-49.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: auto)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-5.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-5.f90
new file mode 100644
index 00000000000..ce3db0fa903
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-5.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (static)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-50.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-50.f90
new file mode 100644
index 00000000000..8b8942709a5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-50.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: auto)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-51.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-51.f90
new file mode 100644
index 00000000000..13bde3aabeb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-51.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_start \[^\n\r]*, (?:2147483648|-2147483648), 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_start " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do ordered reduction (task, *: j) schedule (runtime)
+  do i = a, b, c
+    call bar (j)
+    !$omp ordered
+    j = j + 1
+    !$omp end ordered
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-52.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-52.f90
new file mode 100644
index 00000000000..50dce3dccf9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-52.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_start \[^\n\r]*, (?:2147483649|-2147483647), 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_start " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_static_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do ordered reduction (task, *: j)
+  do i = a, b, c
+    call bar (j)
+    !$omp ordered
+    j = j + 1
+    !$omp end ordered
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-53.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-53.f90
new file mode 100644
index 00000000000..018420946cb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-53.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_start \[^\n\r]*, (?:2147483650|-2147483646), 4, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_start " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do ordered reduction (task, *: j) schedule (dynamic, 4)
+  do i = a, b, c
+    call bar (j)
+    !$omp ordered
+    j = j + 1
+    !$omp end ordered
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-54.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-54.f90
new file mode 100644
index 00000000000..0681e43863c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-54.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_start \[^\n\r]*, (?:2147483651|-2147483645), 6, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_start " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do ordered reduction (task, *: j) schedule (guided, 6)
+  do i = a, b, c
+    call bar (j)
+    !$omp ordered
+    j = j + 1
+    !$omp end ordered
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-55.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-55.f90
new file mode 100644
index 00000000000..4d2e1e509ef
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-55.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_doacross_start \[^\n\r]*, (?:2147483648|-2147483648), 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_post " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_wait " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do ordered(1) reduction (task, *: j) schedule (runtime)
+  do i = a, b, c
+    call bar (j)
+    !$omp ordered depend(sink: i - 1)
+    j = j + 1
+    !$omp ordered depend(source)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-56.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-56.f90
new file mode 100644
index 00000000000..dc5ddafa0e5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-56.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_doacross_start \[^\n\r]*, (?:2147483649|-2147483647), 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_post " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_wait " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_static_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do ordered(1) reduction (task, *: j)
+  do i = a, b, c
+    call bar (j)
+    !$omp ordered depend(sink: i - 1)
+    j = j + 1
+    !$omp ordered depend(source)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-57.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-57.f90
new file mode 100644
index 00000000000..80424882d2c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-57.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_doacross_start \[^\n\r]*, (?:2147483650|-2147483646), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_post " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_wait " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer(8) :: j
+  interface
+    subroutine bar(i)
+      integer(8) :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer(8) :: a, b ,c
+  integer(8) :: i
+  !$omp parallel
+  !$omp do ordered(1) reduction (task, *: j) schedule (dynamic)
+  do i = a, b, c
+    call bar (j)
+    !$omp ordered depend(sink: i - 1)
+    j = j + 1
+    !$omp ordered depend(source)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-58.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-58.f90
new file mode 100644
index 00000000000..ae4f8bc5ef8
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-58.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_doacross_start \[^\n\r]*, (?:2147483651|-2147483645), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_post " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_wait " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do ordered(1) reduction (task, *: j) schedule (guided)
+  do i = a, b, c
+    call bar (j)
+    !$omp ordered depend(sink: i - 1)
+    j = j + 1
+    !$omp ordered depend(source)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-6.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-6.f90
new file mode 100644
index 00000000000..147f14a2a35
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-6.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: static)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-7.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-7.f90
new file mode 100644
index 00000000000..dc99a7512ce
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-7.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (nonmonotonic: static)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-8.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-8.f90
new file mode 100644
index 00000000000..9d0a1ce95f9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-8.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (static, 2)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-9.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-9.f90
new file mode 100644
index 00000000000..c61374613be
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-9.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+  implicit none (type, external)
+  integer :: j
+  interface
+    subroutine bar(i)
+      integer :: i
+    end subroutine
+  end interface
+end module m
+
+subroutine foo(a, b, c)
+  use m
+  implicit none (type, external)
+  integer :: a, b ,c
+  integer :: i
+  !$omp parallel
+  !$omp do reduction (task, *: j) schedule (monotonic: static, 2)
+  do i = a, b, c
+    j = j + 1
+    call bar (j)
+  end do
+  !$omp end parallel
+end

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Patch] Fortran: OpenMP 5.0 (in_,task_)reduction clause extensions
  2020-11-10 16:46   ` Tobias Burnus
@ 2020-11-10 17:23     ` Jakub Jelinek
  2020-11-11  8:25     ` [committed] gfortran.dg/gomp/workshare-reduction-*.f90: Fix dumps for -m32 (was: Re: [Patch] Fortran: OpenMP 5.0 (in_, task_)reduction clause extensions) Tobias Burnus
  1 sibling, 0 replies; 8+ messages in thread
From: Jakub Jelinek @ 2020-11-10 17:23 UTC (permalink / raw)
  To: Tobias Burnus; +Cc: gcc-patches, fortran

On Tue, Nov 10, 2020 at 05:46:17PM +0100, Tobias Burnus wrote:
> Fortran: OpenMP 5.0 (in_,task_)reduction clause extensions
> 
> gcc/fortran/ChangeLog:
> 
> 	PR fortran/95847
> 	* dump-parse-tree.c (show_omp_clauses): Handle new reduction enums.
> 	* gfortran.h (OMP_LIST_REDUCTION_INSCAN, OMP_LIST_REDUCTION_TASK,
> 	OMP_LIST_IN_REDUCTION, OMP_LIST_TASK_REDUCTION): Add enums.
> 	* openmp.c (enum omp_mask1): Add OMP_CLAUSE_IN_REDUCTION
> 	and OMP_CLAUSE_TASK_REDUCTION.
> 	(gfc_match_omp_clause_reduction): Extend reduction handling;
> 	moved from ...
> 	(gfc_match_omp_clauses): ... here. Add calls to it.
> 	(OMP_TASK_CLAUSES, OMP_TARGET_CLAUSES, OMP_TASKLOOP_CLAUSES):
> 	Add OMP_CLAUSE_IN_REDUCTION.
> 	(gfc_match_omp_taskgroup): Add task_reduction matching.
> 	(resolve_omp_clauses): Update for new reduction clause changes;
> 	remove removed nonmonotonic-schedule restrictions.
> 	(gfc_resolve_omp_parallel_blocks): Add new enums to switch.
> 	* trans-openmp.c (gfc_omp_clause_default_ctor,
> 	gfc_trans_omp_reduction_list, gfc_trans_omp_clauses,
> 	gfc_split_omp_clauses): Handle updated reduction clause.
> 
> gcc/ChangeLog:
> 
> 	PR fortran/95847
> 	* gimplify.c (gimplify_scan_omp_clauses, gimplify_omp_loop): Use 'do'
> 	instead of 'for' in error messages for Fortran.
> 	* omp-low.c (check_omp_nesting_restrictions): Likewise
> 
> gcc/testsuite/ChangeLog:
> 
> 	PR fortran/95847
> 	* gfortran.dg/gomp/schedule-modifiers-2.f90: Remove some dg-error.
> 	* gfortran.dg/gomp/reduction4.f90: New test.
> 	* gfortran.dg/gomp/reduction5.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-1.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-2.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-3.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-4.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-5.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-6.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-7.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-8.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-9.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-10.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-11.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-12.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-13.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-14.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-15.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-16.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-17.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-18.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-19.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-20.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-21.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-22.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-23.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-24.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-25.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-26.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-27.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-28.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-29.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-30.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-31.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-32.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-33.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-34.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-35.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-36.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-37.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-38.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-39.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-40.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-41.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-42.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-43.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-44.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-45.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-46.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-47.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-48.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-49.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-50.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-51.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-52.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-53.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-54.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-55.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-56.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-57.f90: New test.
> 	* gfortran.dg/gomp/workshare-reduction-58.f90: New test.

Ok, thanks.

	Jakub


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [committed] gfortran.dg/gomp/workshare-reduction-*.f90: Fix dumps for -m32 (was: Re: [Patch] Fortran: OpenMP 5.0 (in_, task_)reduction clause extensions)
  2020-11-10 16:46   ` Tobias Burnus
  2020-11-10 17:23     ` Jakub Jelinek
@ 2020-11-11  8:25     ` Tobias Burnus
  2020-11-11  9:39       ` Jakub Jelinek
  2020-11-11 13:40       ` Thomas Schwinge
  1 sibling, 2 replies; 8+ messages in thread
From: Tobias Burnus @ 2020-11-11  8:25 UTC (permalink / raw)
  To: Jakub Jelinek, gcc-patches, fortran

[-- Attachment #1: Type: text/plain, Size: 573 bytes --]

As Sunil's regression tester pointed out, the testcases fail on x86-64 with -m32.

The reason is that then the _ull_ variants of the GOMP functions are called;
in the C equivalent, those are always called – I assume that's because the C
testcase uses 'unsigned' which does not exist with Fortran.

Committed as r11-4903-g1644ab9917ca6b96e9e683c422f1793258b9a3db

Tobias

-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander Walter

[-- Attachment #2: committed.diff --]
[-- Type: text/x-patch, Size: 15919 bytes --]

commit 1644ab9917ca6b96e9e683c422f1793258b9a3db
Author: Tobias Burnus <tobias@codesourcery.com>
Date:   Wed Nov 11 09:23:07 2020 +0100

    gfortran.dg/gomp/workshare-reduction-*.f90: Fix dumps for -m32
    
    gcc/testsuite/ChangeLog:
    
            * gfortran.dg/gomp/workshare-reduction-26.f90: Add (?:_ull) to
            scan-tree-dump-times regex for -m32.
            * gfortran.dg/gomp/workshare-reduction-27.f90: Likewise.
            * gfortran.dg/gomp/workshare-reduction-28.f90: Likewise.
            * gfortran.dg/gomp/workshare-reduction-3.f90: Likewise.
            * gfortran.dg/gomp/workshare-reduction-36.f90: Likewise.
            * gfortran.dg/gomp/workshare-reduction-37.f90: Likewise.
            * gfortran.dg/gomp/workshare-reduction-38.f90: Likewise.
            * gfortran.dg/gomp/workshare-reduction-39.f90: Likewise.
            * gfortran.dg/gomp/workshare-reduction-40.f90: Likewise.
            * gfortran.dg/gomp/workshare-reduction-41.f90: Likewise.
            * gfortran.dg/gomp/workshare-reduction-42.f90: Likewise.
            * gfortran.dg/gomp/workshare-reduction-43.f90: Likewise.
            * gfortran.dg/gomp/workshare-reduction-44.f90: Likewise.
            * gfortran.dg/gomp/workshare-reduction-45.f90: Likewise.
            * gfortran.dg/gomp/workshare-reduction-46.f90: Likewise.
            * gfortran.dg/gomp/workshare-reduction-47.f90: Likewise.
            * gfortran.dg/gomp/workshare-reduction-56.f90: Likewise.
            * gfortran.dg/gomp/workshare-reduction-57.f90: Likewise.

diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-26.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-26.f90
index 28267902914..d8633b66045 100644
--- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-26.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-26.f90
@@ -3 +3 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 0, 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 0, 0, " 1 "optimized" } }
@@ -5 +5 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_maybe_nonmonotonic_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_maybe_nonmonotonic_runtime_next " 1 "optimized" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-27.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-27.f90
index 2ee047d4e8c..aada4d7a23b 100644
--- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-27.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-27.f90
@@ -3 +3 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483648|-2147483648), 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, (?:2147483648|-2147483648), 0, " 1 "optimized" } }
@@ -5 +5 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_runtime_next " 1 "optimized" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-28.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-28.f90
index 6c9d49be13c..e67e24b1aa2 100644
--- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-28.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-28.f90
@@ -3 +3 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 4, 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 4, 0, " 1 "optimized" } }
@@ -5 +5 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_runtime_next " 1 "optimized" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-3.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-3.f90
index 6c9d49be13c..e67e24b1aa2 100644
--- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-3.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-3.f90
@@ -3 +3 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 4, 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 4, 0, " 1 "optimized" } }
@@ -5 +5 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_runtime_next " 1 "optimized" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-36.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-36.f90
index b190e9ee87b..82dc063545e 100644
--- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-36.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-36.f90
@@ -3 +3 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
@@ -5 +5 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_dynamic_next " 1 "optimized" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-37.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-37.f90
index c541d22d6cf..4fb64cf3133 100644
--- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-37.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-37.f90
@@ -3 +3 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483650|-2147483646), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, (?:2147483650|-2147483646), 1, " 1 "optimized" } }
@@ -5 +5 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_dynamic_next " 1 "optimized" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-38.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-38.f90
index 46a27a0386c..08eaef082d5 100644
--- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-38.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-38.f90
@@ -3 +3 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
@@ -5 +5 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_dynamic_next " 1 "optimized" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-39.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-39.f90
index 6cdd9a8807b..732753cac47 100644
--- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-39.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-39.f90
@@ -3 +3 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
@@ -5 +5 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_dynamic_next " 1 "optimized" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-40.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-40.f90
index 29da27abc5a..44ecfa86f0f 100644
--- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-40.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-40.f90
@@ -3 +3 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483650|-2147483646), 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, (?:2147483650|-2147483646), 3, " 1 "optimized" } }
@@ -5 +5 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_dynamic_next " 1 "optimized" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-41.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-41.f90
index 4ed879cdd00..a8b99120c0d 100644
--- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-41.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-41.f90
@@ -3 +3 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
@@ -5 +5 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_dynamic_next " 1 "optimized" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-42.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-42.f90
index 78d02ef8035..c6709e3f39e 100644
--- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-42.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-42.f90
@@ -3 +3 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
@@ -5 +5 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_guided_next " 1 "optimized" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-43.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-43.f90
index 16885c84210..3cb0a661824 100644
--- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-43.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-43.f90
@@ -3 +3 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483651|-2147483645), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, (?:2147483651|-2147483645), 1, " 1 "optimized" } }
@@ -5 +5 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_guided_next " 1 "optimized" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-44.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-44.f90
index 0db9be6854c..3a4867f8cf0 100644
--- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-44.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-44.f90
@@ -3 +3 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
@@ -5 +5 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_guided_next " 1 "optimized" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-45.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-45.f90
index 40b12755414..1252ffc5980 100644
--- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-45.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-45.f90
@@ -3 +3 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
@@ -5 +5 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_guided_next " 1 "optimized" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-46.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-46.f90
index 57c74023d8d..bf191984138 100644
--- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-46.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-46.f90
@@ -3 +3 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483651|-2147483645), 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, (?:2147483651|-2147483645), 3, " 1 "optimized" } }
@@ -5 +5 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_guided_next " 1 "optimized" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-47.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-47.f90
index b4564300b50..d2b03f6ec9b 100644
--- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-47.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-47.f90
@@ -3 +3 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
@@ -5 +5 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_guided_next " 1 "optimized" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-56.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-56.f90
index dc5ddafa0e5..fb6175c6172 100644
--- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-56.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-56.f90
@@ -3 +3 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_doacross_start \[^\n\r]*, (?:2147483649|-2147483647), 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_doacross_start \[^\n\r]*, (?:2147483649|-2147483647), 0, " 1 "optimized" } }
@@ -5,3 +5,3 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_post " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_wait " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_static_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross(?:_ull)_post " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross(?:_ull)_wait " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_static_next " 1 "optimized" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-57.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-57.f90
index 80424882d2c..41b55eae786 100644
--- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-57.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-57.f90
@@ -3 +3 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_doacross_start \[^\n\r]*, (?:2147483650|-2147483646), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_doacross_start \[^\n\r]*, (?:2147483650|-2147483646), 1, " 1 "optimized" } }
@@ -5,3 +5,3 @@
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_post " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_wait " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross(?:_ull)_post " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross(?:_ull)_wait " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_dynamic_next " 1 "optimized" } }

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [committed] gfortran.dg/gomp/workshare-reduction-*.f90: Fix dumps for -m32 (was: Re: [Patch] Fortran: OpenMP 5.0 (in_, task_)reduction clause extensions)
  2020-11-11  8:25     ` [committed] gfortran.dg/gomp/workshare-reduction-*.f90: Fix dumps for -m32 (was: Re: [Patch] Fortran: OpenMP 5.0 (in_, task_)reduction clause extensions) Tobias Burnus
@ 2020-11-11  9:39       ` Jakub Jelinek
  2020-11-11 13:40       ` Thomas Schwinge
  1 sibling, 0 replies; 8+ messages in thread
From: Jakub Jelinek @ 2020-11-11  9:39 UTC (permalink / raw)
  To: Tobias Burnus; +Cc: gcc-patches, fortran

On Wed, Nov 11, 2020 at 09:25:25AM +0100, Tobias Burnus wrote:
> As Sunil's regression tester pointed out, the testcases fail on x86-64 with -m32.
> 
> The reason is that then the _ull_ variants of the GOMP functions are called;
> in the C equivalent, those are always called – I assume that's because the C
> testcase uses 'unsigned' which does not exist with Fortran.

Yes, I didn't want to have 4 variants of everything, so we have just two.
One handles what fits into signed long, another handles what fits into
unsigned long long.

	Jakub


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [committed] gfortran.dg/gomp/workshare-reduction-*.f90: Fix dumps for -m32 (was: Re: [Patch] Fortran: OpenMP 5.0 (in_, task_)reduction clause extensions)
  2020-11-11  8:25     ` [committed] gfortran.dg/gomp/workshare-reduction-*.f90: Fix dumps for -m32 (was: Re: [Patch] Fortran: OpenMP 5.0 (in_, task_)reduction clause extensions) Tobias Burnus
  2020-11-11  9:39       ` Jakub Jelinek
@ 2020-11-11 13:40       ` Thomas Schwinge
  2020-11-11 15:16         ` [committed] testsuite: Fix up scan-tree-dump-times regexps for 64-bit targets Jakub Jelinek
  1 sibling, 1 reply; 8+ messages in thread
From: Thomas Schwinge @ 2020-11-11 13:40 UTC (permalink / raw)
  To: Tobias Burnus; +Cc: Jakub Jelinek, gcc-patches, fortran

Hi Tobias!

On 2020-11-11T09:25:25+0100, Tobias Burnus <tobias@codesourcery.com> wrote:
> As Sunil's regression tester pointed out, the testcases fail on x86-64 with -m32.
>
> The reason is that then the _ull_ variants of the GOMP functions are called;
> in the C equivalent, those are always called – I assume that's because the C
> testcase uses 'unsigned' which does not exist with Fortran.
>
> Committed as r11-4903-g1644ab9917ca6b96e9e683c422f1793258b9a3db

I'm confirming this fixes things for '-m32' -- but it also broke '-m64'.
;-)


Grüße
 Thomas


> commit 1644ab9917ca6b96e9e683c422f1793258b9a3db
> Author: Tobias Burnus <tobias@codesourcery.com>
> Date:   Wed Nov 11 09:23:07 2020 +0100
>
>     gfortran.dg/gomp/workshare-reduction-*.f90: Fix dumps for -m32
>
>     gcc/testsuite/ChangeLog:
>
>             * gfortran.dg/gomp/workshare-reduction-26.f90: Add (?:_ull) to
>             scan-tree-dump-times regex for -m32.
>             * gfortran.dg/gomp/workshare-reduction-27.f90: Likewise.
>             * gfortran.dg/gomp/workshare-reduction-28.f90: Likewise.
>             * gfortran.dg/gomp/workshare-reduction-3.f90: Likewise.
>             * gfortran.dg/gomp/workshare-reduction-36.f90: Likewise.
>             * gfortran.dg/gomp/workshare-reduction-37.f90: Likewise.
>             * gfortran.dg/gomp/workshare-reduction-38.f90: Likewise.
>             * gfortran.dg/gomp/workshare-reduction-39.f90: Likewise.
>             * gfortran.dg/gomp/workshare-reduction-40.f90: Likewise.
>             * gfortran.dg/gomp/workshare-reduction-41.f90: Likewise.
>             * gfortran.dg/gomp/workshare-reduction-42.f90: Likewise.
>             * gfortran.dg/gomp/workshare-reduction-43.f90: Likewise.
>             * gfortran.dg/gomp/workshare-reduction-44.f90: Likewise.
>             * gfortran.dg/gomp/workshare-reduction-45.f90: Likewise.
>             * gfortran.dg/gomp/workshare-reduction-46.f90: Likewise.
>             * gfortran.dg/gomp/workshare-reduction-47.f90: Likewise.
>             * gfortran.dg/gomp/workshare-reduction-56.f90: Likewise.
>             * gfortran.dg/gomp/workshare-reduction-57.f90: Likewise.
>
> diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-26.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-26.f90
> index 28267902914..d8633b66045 100644
> --- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-26.f90
> +++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-26.f90
> @@ -3 +3 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 0, 0, " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 0, 0, " 1 "optimized" } }
> @@ -5 +5 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_maybe_nonmonotonic_runtime_next " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_maybe_nonmonotonic_runtime_next " 1 "optimized" } }
> diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-27.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-27.f90
> index 2ee047d4e8c..aada4d7a23b 100644
> --- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-27.f90
> +++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-27.f90
> @@ -3 +3 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483648|-2147483648), 0, " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, (?:2147483648|-2147483648), 0, " 1 "optimized" } }
> @@ -5 +5 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_runtime_next " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_runtime_next " 1 "optimized" } }
> diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-28.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-28.f90
> index 6c9d49be13c..e67e24b1aa2 100644
> --- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-28.f90
> +++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-28.f90
> @@ -3 +3 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 4, 0, " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 4, 0, " 1 "optimized" } }
> @@ -5 +5 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_runtime_next " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_runtime_next " 1 "optimized" } }
> diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-3.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-3.f90
> index 6c9d49be13c..e67e24b1aa2 100644
> --- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-3.f90
> +++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-3.f90
> @@ -3 +3 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 4, 0, " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 4, 0, " 1 "optimized" } }
> @@ -5 +5 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_runtime_next " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_runtime_next " 1 "optimized" } }
> diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-36.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-36.f90
> index b190e9ee87b..82dc063545e 100644
> --- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-36.f90
> +++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-36.f90
> @@ -3 +3 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
> @@ -5 +5 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_dynamic_next " 1 "optimized" } }
> diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-37.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-37.f90
> index c541d22d6cf..4fb64cf3133 100644
> --- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-37.f90
> +++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-37.f90
> @@ -3 +3 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483650|-2147483646), 1, " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, (?:2147483650|-2147483646), 1, " 1 "optimized" } }
> @@ -5 +5 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_dynamic_next " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_dynamic_next " 1 "optimized" } }
> diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-38.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-38.f90
> index 46a27a0386c..08eaef082d5 100644
> --- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-38.f90
> +++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-38.f90
> @@ -3 +3 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
> @@ -5 +5 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_dynamic_next " 1 "optimized" } }
> diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-39.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-39.f90
> index 6cdd9a8807b..732753cac47 100644
> --- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-39.f90
> +++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-39.f90
> @@ -3 +3 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
> @@ -5 +5 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_dynamic_next " 1 "optimized" } }
> diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-40.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-40.f90
> index 29da27abc5a..44ecfa86f0f 100644
> --- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-40.f90
> +++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-40.f90
> @@ -3 +3 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483650|-2147483646), 3, " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, (?:2147483650|-2147483646), 3, " 1 "optimized" } }
> @@ -5 +5 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_dynamic_next " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_dynamic_next " 1 "optimized" } }
> diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-41.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-41.f90
> index 4ed879cdd00..a8b99120c0d 100644
> --- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-41.f90
> +++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-41.f90
> @@ -3 +3 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
> @@ -5 +5 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_dynamic_next " 1 "optimized" } }
> diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-42.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-42.f90
> index 78d02ef8035..c6709e3f39e 100644
> --- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-42.f90
> +++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-42.f90
> @@ -3 +3 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
> @@ -5 +5 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_guided_next " 1 "optimized" } }
> diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-43.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-43.f90
> index 16885c84210..3cb0a661824 100644
> --- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-43.f90
> +++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-43.f90
> @@ -3 +3 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483651|-2147483645), 1, " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, (?:2147483651|-2147483645), 1, " 1 "optimized" } }
> @@ -5 +5 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_guided_next " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_guided_next " 1 "optimized" } }
> diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-44.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-44.f90
> index 0db9be6854c..3a4867f8cf0 100644
> --- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-44.f90
> +++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-44.f90
> @@ -3 +3 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
> @@ -5 +5 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_guided_next " 1 "optimized" } }
> diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-45.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-45.f90
> index 40b12755414..1252ffc5980 100644
> --- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-45.f90
> +++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-45.f90
> @@ -3 +3 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
> @@ -5 +5 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_guided_next " 1 "optimized" } }
> diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-46.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-46.f90
> index 57c74023d8d..bf191984138 100644
> --- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-46.f90
> +++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-46.f90
> @@ -3 +3 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483651|-2147483645), 3, " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, (?:2147483651|-2147483645), 3, " 1 "optimized" } }
> @@ -5 +5 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_guided_next " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_guided_next " 1 "optimized" } }
> diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-47.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-47.f90
> index b4564300b50..d2b03f6ec9b 100644
> --- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-47.f90
> +++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-47.f90
> @@ -3 +3 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
> @@ -5 +5 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_guided_next " 1 "optimized" } }
> diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-56.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-56.f90
> index dc5ddafa0e5..fb6175c6172 100644
> --- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-56.f90
> +++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-56.f90
> @@ -3 +3 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_doacross_start \[^\n\r]*, (?:2147483649|-2147483647), 0, " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_doacross_start \[^\n\r]*, (?:2147483649|-2147483647), 0, " 1 "optimized" } }
> @@ -5,3 +5,3 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_post " 1 "optimized" } }
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_wait " 1 "optimized" } }
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_static_next " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross(?:_ull)_post " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross(?:_ull)_wait " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_static_next " 1 "optimized" } }
> diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-57.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-57.f90
> index 80424882d2c..41b55eae786 100644
> --- a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-57.f90
> +++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-57.f90
> @@ -3 +3 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_doacross_start \[^\n\r]*, (?:2147483650|-2147483646), 1, " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_doacross_start \[^\n\r]*, (?:2147483650|-2147483646), 1, " 1 "optimized" } }
> @@ -5,3 +5,3 @@
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_post " 1 "optimized" } }
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_wait " 1 "optimized" } }
> -! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_dynamic_next " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross(?:_ull)_post " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross(?:_ull)_wait " 1 "optimized" } }
> +! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_dynamic_next " 1 "optimized" } }
-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander Walter

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [committed] testsuite: Fix up scan-tree-dump-times regexps for 64-bit targets
  2020-11-11 13:40       ` Thomas Schwinge
@ 2020-11-11 15:16         ` Jakub Jelinek
  0 siblings, 0 replies; 8+ messages in thread
From: Jakub Jelinek @ 2020-11-11 15:16 UTC (permalink / raw)
  To: Thomas Schwinge; +Cc: Tobias Burnus, gcc-patches, fortran

On Wed, Nov 11, 2020 at 02:40:20PM +0100, Thomas Schwinge wrote:
> On 2020-11-11T09:25:25+0100, Tobias Burnus <tobias@codesourcery.com> wrote:
> > As Sunil's regression tester pointed out, the testcases fail on x86-64 with -m32.
> >
> > The reason is that then the _ull_ variants of the GOMP functions are called;
> > in the C equivalent, those are always called – I assume that's because the C
> > testcase uses 'unsigned' which does not exist with Fortran.
> >
> > Committed as r11-4903-g1644ab9917ca6b96e9e683c422f1793258b9a3db
> 
> I'm confirming this fixes things for '-m32' -- but it also broke '-m64'.
> ;-)

The added (?:_ull) match on 32-bit targets, but are equivalent to just
adding _ull into the strings, i.e. require the _ull substrings, while
the intent is that they are optional, so we should use (?:_ull)? instead.

Tested on x86_64-linux with -m32/-m64, committed to trunk.

2020-11-11  Jakub Jelinek  <jakub@redhat.com>

	* gfortran.dg/gomp/workshare-reduction-3.f90: Use (?:_ull)? instead
	of (?:_ull) in the scan-tree-dump-times directives.
	* gfortran.dg/gomp/workshare-reduction-26.f90: Likewise.
	* gfortran.dg/gomp/workshare-reduction-27.f90: Likewise.
	* gfortran.dg/gomp/workshare-reduction-28.f90: Likewise.
	* gfortran.dg/gomp/workshare-reduction-36.f90: Likewise.
	* gfortran.dg/gomp/workshare-reduction-37.f90: Likewise.
	* gfortran.dg/gomp/workshare-reduction-38.f90: Likewise.
	* gfortran.dg/gomp/workshare-reduction-39.f90: Likewise.
	* gfortran.dg/gomp/workshare-reduction-40.f90: Likewise.
	* gfortran.dg/gomp/workshare-reduction-41.f90: Likewise.
	* gfortran.dg/gomp/workshare-reduction-42.f90: Likewise.
	* gfortran.dg/gomp/workshare-reduction-43.f90: Likewise.
	* gfortran.dg/gomp/workshare-reduction-44.f90: Likewise.
	* gfortran.dg/gomp/workshare-reduction-45.f90: Likewise.
	* gfortran.dg/gomp/workshare-reduction-46.f90: Likewise.
	* gfortran.dg/gomp/workshare-reduction-47.f90: Likewise.
	* gfortran.dg/gomp/workshare-reduction-56.f90: Likewise.
	* gfortran.dg/gomp/workshare-reduction-57.f90: Likewise.

--- gcc/testsuite/gfortran.dg/gomp/workshare-reduction-26.f90.jj	2020-11-11 14:11:07.924006064 +0100
+++ gcc/testsuite/gfortran.dg/gomp/workshare-reduction-26.f90	2020-11-11 16:08:18.865674174 +0100
@@ -1,8 +1,8 @@
 ! { dg-do compile }
 ! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 0, 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, 0, 0, " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_maybe_nonmonotonic_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_maybe_nonmonotonic_runtime_next " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
 
--- gcc/testsuite/gfortran.dg/gomp/workshare-reduction-28.f90.jj	2020-11-11 14:11:07.924006064 +0100
+++ gcc/testsuite/gfortran.dg/gomp/workshare-reduction-28.f90	2020-11-11 16:08:18.871674108 +0100
@@ -1,8 +1,8 @@
 ! { dg-do compile }
 ! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 4, 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, 4, 0, " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_nonmonotonic_runtime_next " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
 
--- gcc/testsuite/gfortran.dg/gomp/workshare-reduction-44.f90.jj	2020-11-11 14:11:07.924006064 +0100
+++ gcc/testsuite/gfortran.dg/gomp/workshare-reduction-44.f90	2020-11-11 16:08:18.895673844 +0100
@@ -1,8 +1,8 @@
 ! { dg-do compile }
 ! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_nonmonotonic_guided_next " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
 
--- gcc/testsuite/gfortran.dg/gomp/workshare-reduction-57.f90.jj	2020-11-11 14:11:07.924006064 +0100
+++ gcc/testsuite/gfortran.dg/gomp/workshare-reduction-57.f90	2020-11-11 16:08:18.907673712 +0100
@@ -1,10 +1,10 @@
 ! { dg-do compile }
 ! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_doacross_start \[^\n\r]*, (?:2147483650|-2147483646), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_doacross_start \[^\n\r]*, (?:2147483650|-2147483646), 1, " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross(?:_ull)_post " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross(?:_ull)_wait " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross(?:_ull)?_post " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross(?:_ull)?_wait " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_dynamic_next " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
 
--- gcc/testsuite/gfortran.dg/gomp/workshare-reduction-43.f90.jj	2020-11-11 14:11:07.924006064 +0100
+++ gcc/testsuite/gfortran.dg/gomp/workshare-reduction-43.f90	2020-11-11 16:08:18.893673866 +0100
@@ -1,8 +1,8 @@
 ! { dg-do compile }
 ! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, (?:2147483651|-2147483645), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, (?:2147483651|-2147483645), 1, " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_guided_next " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
 
--- gcc/testsuite/gfortran.dg/gomp/workshare-reduction-56.f90.jj	2020-11-11 14:11:07.924006064 +0100
+++ gcc/testsuite/gfortran.dg/gomp/workshare-reduction-56.f90	2020-11-11 16:08:18.904673745 +0100
@@ -1,10 +1,10 @@
 ! { dg-do compile }
 ! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_doacross_start \[^\n\r]*, (?:2147483649|-2147483647), 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_doacross_start \[^\n\r]*, (?:2147483649|-2147483647), 0, " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross(?:_ull)_post " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross(?:_ull)_wait " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_static_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross(?:_ull)?_post " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross(?:_ull)?_wait " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_static_next " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
 
--- gcc/testsuite/gfortran.dg/gomp/workshare-reduction-39.f90.jj	2020-11-11 14:11:07.924006064 +0100
+++ gcc/testsuite/gfortran.dg/gomp/workshare-reduction-39.f90	2020-11-11 16:08:18.881673998 +0100
@@ -1,8 +1,8 @@
 ! { dg-do compile }
 ! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_nonmonotonic_dynamic_next " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
 
--- gcc/testsuite/gfortran.dg/gomp/workshare-reduction-36.f90.jj	2020-11-11 14:11:07.924006064 +0100
+++ gcc/testsuite/gfortran.dg/gomp/workshare-reduction-36.f90	2020-11-11 16:08:18.873674086 +0100
@@ -1,8 +1,8 @@
 ! { dg-do compile }
 ! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_nonmonotonic_dynamic_next " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
 
--- gcc/testsuite/gfortran.dg/gomp/workshare-reduction-47.f90.jj	2020-11-11 14:11:07.924006064 +0100
+++ gcc/testsuite/gfortran.dg/gomp/workshare-reduction-47.f90	2020-11-11 16:08:18.902673767 +0100
@@ -1,8 +1,8 @@
 ! { dg-do compile }
 ! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_nonmonotonic_guided_next " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
 
--- gcc/testsuite/gfortran.dg/gomp/workshare-reduction-38.f90.jj	2020-11-11 14:11:07.924006064 +0100
+++ gcc/testsuite/gfortran.dg/gomp/workshare-reduction-38.f90	2020-11-11 16:08:18.878674031 +0100
@@ -1,8 +1,8 @@
 ! { dg-do compile }
 ! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_nonmonotonic_dynamic_next " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
 
--- gcc/testsuite/gfortran.dg/gomp/workshare-reduction-46.f90.jj	2020-11-11 14:11:07.924006064 +0100
+++ gcc/testsuite/gfortran.dg/gomp/workshare-reduction-46.f90	2020-11-11 16:08:18.900673789 +0100
@@ -1,8 +1,8 @@
 ! { dg-do compile }
 ! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, (?:2147483651|-2147483645), 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, (?:2147483651|-2147483645), 3, " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_guided_next " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
 
--- gcc/testsuite/gfortran.dg/gomp/workshare-reduction-27.f90.jj	2020-11-11 14:11:07.924006064 +0100
+++ gcc/testsuite/gfortran.dg/gomp/workshare-reduction-27.f90	2020-11-11 16:08:18.868674141 +0100
@@ -1,8 +1,8 @@
 ! { dg-do compile }
 ! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, (?:2147483648|-2147483648), 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, (?:2147483648|-2147483648), 0, " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_runtime_next " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
 
--- gcc/testsuite/gfortran.dg/gomp/workshare-reduction-40.f90.jj	2020-11-11 14:11:07.924006064 +0100
+++ gcc/testsuite/gfortran.dg/gomp/workshare-reduction-40.f90	2020-11-11 16:08:18.885673954 +0100
@@ -1,8 +1,8 @@
 ! { dg-do compile }
 ! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, (?:2147483650|-2147483646), 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, (?:2147483650|-2147483646), 3, " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_dynamic_next " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
 
--- gcc/testsuite/gfortran.dg/gomp/workshare-reduction-37.f90.jj	2020-11-11 14:11:07.924006064 +0100
+++ gcc/testsuite/gfortran.dg/gomp/workshare-reduction-37.f90	2020-11-11 16:08:18.876674053 +0100
@@ -1,8 +1,8 @@
 ! { dg-do compile }
 ! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, (?:2147483650|-2147483646), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, (?:2147483650|-2147483646), 1, " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_dynamic_next " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
 
--- gcc/testsuite/gfortran.dg/gomp/workshare-reduction-41.f90.jj	2020-11-11 14:11:07.924006064 +0100
+++ gcc/testsuite/gfortran.dg/gomp/workshare-reduction-41.f90	2020-11-11 16:08:18.888673921 +0100
@@ -1,8 +1,8 @@
 ! { dg-do compile }
 ! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_nonmonotonic_dynamic_next " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
 
--- gcc/testsuite/gfortran.dg/gomp/workshare-reduction-42.f90.jj	2020-11-11 14:11:07.924006064 +0100
+++ gcc/testsuite/gfortran.dg/gomp/workshare-reduction-42.f90	2020-11-11 16:08:18.890673899 +0100
@@ -1,8 +1,8 @@
 ! { dg-do compile }
 ! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_nonmonotonic_guided_next " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
 
--- gcc/testsuite/gfortran.dg/gomp/workshare-reduction-45.f90.jj	2020-11-11 14:11:07.924006064 +0100
+++ gcc/testsuite/gfortran.dg/gomp/workshare-reduction-45.f90	2020-11-11 16:08:18.898673811 +0100
@@ -1,8 +1,8 @@
 ! { dg-do compile }
 ! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_nonmonotonic_guided_next " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
 
--- gcc/testsuite/gfortran.dg/gomp/workshare-reduction-3.f90.jj	2020-11-11 14:11:07.924006064 +0100
+++ gcc/testsuite/gfortran.dg/gomp/workshare-reduction-3.f90	2020-11-11 16:08:18.883673976 +0100
@@ -1,8 +1,8 @@
 ! { dg-do compile }
 ! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_start \[^\n\r]*, 4, 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, 4, 0, " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
-! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)_nonmonotonic_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_nonmonotonic_runtime_next " 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
 


	Jakub


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2020-11-11 15:16 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-09 23:40 [Patch] Fortran: OpenMP 5.0 (in_,task_)reduction clause extensions Tobias Burnus
2020-11-10 12:16 ` Jakub Jelinek
2020-11-10 16:46   ` Tobias Burnus
2020-11-10 17:23     ` Jakub Jelinek
2020-11-11  8:25     ` [committed] gfortran.dg/gomp/workshare-reduction-*.f90: Fix dumps for -m32 (was: Re: [Patch] Fortran: OpenMP 5.0 (in_, task_)reduction clause extensions) Tobias Burnus
2020-11-11  9:39       ` Jakub Jelinek
2020-11-11 13:40       ` Thomas Schwinge
2020-11-11 15:16         ` [committed] testsuite: Fix up scan-tree-dump-times regexps for 64-bit targets Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).