Fortran: OpenMP 5.0 (in_,task_)reduction clause extensions
authorTobias Burnus <tobias@codesourcery.com>
Tue, 10 Nov 2020 17:28:18 +0000 (18:28 +0100)
committerTobias Burnus <tobias@codesourcery.com>
Tue, 10 Nov 2020 17:28:18 +0000 (18:28 +0100)
gcc/fortran/ChangeLog:

* 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:

* 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:

* 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.

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

index 43b97ba26ff916a578b7529eb8a5395a54f83626..cab0fb2979f50279fb07a6e7baae04548a9c2124 100644 (file)
@@ -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);
       }
index dfd7796cce0b3e3c872c1c359d18302acb241cc5..6467985ea7f080ccf009e536ac782bd692b8719f 100644 (file)
@@ -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,
index 2270c858f394167f6206ca78ec43295b1e1324ae..68d0b65ff87f082b4a28a9be6a0a68f96d0cf8c3 100644 (file)
@@ -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);
index 1d652a09f9d23b6cf0380fd829d349dbbdedbb1f..d2559bd0c0a4476b5c541d00fe1b43e0aba3dd9b 100644 (file)
@@ -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]
index b2c623be456e74ec968794fda348be2e5df13f6a..d18c43e3e0fe2648a722f18bea8f3afb45897fd8 100644 (file)
@@ -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);
index 447d7dbc92a5e15545c87710c9bbed71289a948d..83ca5fc23e0471da5a5776c0871203e5726c0732 100644 (file)
@@ -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 (file)
index 0000000..af8c91b
--- /dev/null
@@ -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 (file)
index 0000000..df915f1
--- /dev/null
@@ -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
index 0be53cc71a5d339dbb2c10e34ff6f9b739e11c17..537fba23c11199c8f926f165a23d3cea3faaa0b3 100644 (file)
@@ -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 (file)
index 0000000..3e639d2
--- /dev/null
@@ -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 (file)
index 0000000..e71ac3f
--- /dev/null
@@ -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 (file)
index 0000000..9420220
--- /dev/null
@@ -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 (file)
index 0000000..66c6eb1
--- /dev/null
@@ -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 (file)
index 0000000..89782d2
--- /dev/null
@@ -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 (file)
index 0000000..16b3e01
--- /dev/null
@@ -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 (file)
index 0000000..8bf126c
--- /dev/null
@@ -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 (file)
index 0000000..fe8d1ae
--- /dev/null
@@ -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 (file)
index 0000000..1f2823d
--- /dev/null
@@ -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 (file)
index 0000000..ad0856a
--- /dev/null
@@ -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 (file)
index 0000000..e884dbf
--- /dev/null
@@ -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 (file)
index 0000000..2f78c0b
--- /dev/null
@@ -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 (file)
index 0000000..8a4d6df
--- /dev/null
@@ -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 (file)
index 0000000..2d9362b
--- /dev/null
@@ -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 (file)
index 0000000..485171f
--- /dev/null
@@ -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 (file)
index 0000000..45dc000
--- /dev/null
@@ -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 (file)
index 0000000..e7fbe92
--- /dev/null
@@ -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 (file)
index 0000000..d5554c4
--- /dev/null
@@ -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 (file)
index 0000000..2826790
--- /dev/null
@@ -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 (file)
index 0000000..2ee047d
--- /dev/null
@@ -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 (file)
index 0000000..6c9d49b
--- /dev/null
@@ -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 (file)
index 0000000..316b72e
--- /dev/null
@@ -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 (file)
index 0000000..6c9d49b
--- /dev/null
@@ -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 (file)
index 0000000..b9406d6
--- /dev/null
@@ -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 (file)
index 0000000..4a24604
--- /dev/null
@@ -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 (file)
index 0000000..a7062d9
--- /dev/null
@@ -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 (file)
index 0000000..67c25c8
--- /dev/null
@@ -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 (file)
index 0000000..f1e4d89
--- /dev/null
@@ -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 (file)
index 0000000..7d7c271
--- /dev/null
@@ -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 (file)
index 0000000..b190e9e
--- /dev/null
@@ -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 (file)
index 0000000..c541d22
--- /dev/null
@@ -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 (file)
index 0000000..46a27a0
--- /dev/null
@@ -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 (file)
index 0000000..6cdd9a8
--- /dev/null
@@ -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 (file)
index 0000000..c774427
--- /dev/null
@@ -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 (file)
index 0000000..29da27a
--- /dev/null
@@ -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 (file)
index 0000000..4ed879c
--- /dev/null
@@ -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 (file)
index 0000000..78d02ef
--- /dev/null
@@ -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 (file)
index 0000000..16885c8
--- /dev/null
@@ -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 (file)
index 0000000..0db9be6
--- /dev/null
@@ -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 (file)
index 0000000..40b1275
--- /dev/null
@@ -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 (file)
index 0000000..57c7402
--- /dev/null
@@ -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 (file)
index 0000000..b456430
--- /dev/null
@@ -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 (file)
index 0000000..1370010
--- /dev/null
@@ -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 (file)
index 0000000..ab2591f
--- /dev/null
@@ -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 (file)
index 0000000..ce3db0f
--- /dev/null
@@ -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 (file)
index 0000000..8b89427
--- /dev/null
@@ -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 (file)
index 0000000..13bde3a
--- /dev/null
@@ -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 (file)
index 0000000..50dce3d
--- /dev/null
@@ -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 (file)
index 0000000..0184209
--- /dev/null
@@ -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 (file)
index 0000000..0681e43
--- /dev/null
@@ -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 (file)
index 0000000..4d2e1e5
--- /dev/null
@@ -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 (file)
index 0000000..dc5ddaf
--- /dev/null
@@ -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 (file)
index 0000000..8042488
--- /dev/null
@@ -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 (file)
index 0000000..ae4f8bc
--- /dev/null
@@ -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 (file)
index 0000000..147f14a
--- /dev/null
@@ -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 (file)
index 0000000..dc99a75
--- /dev/null
@@ -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 (file)
index 0000000..9d0a1ce
--- /dev/null
@@ -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 (file)
index 0000000..c613746
--- /dev/null
@@ -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