]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
openmp: Add support for OpenMP 5.1 masked construct
authorJakub Jelinek <jakub@redhat.com>
Mon, 16 Aug 2021 10:35:25 +0000 (12:35 +0200)
committerTobias Burnus <tobias@codesourcery.com>
Mon, 16 Aug 2021 10:36:33 +0000 (12:36 +0200)
This construct has been introduced as a replacement for master
construct, but unlike that construct is slightly more general,
has an optional clause which allows to choose which thread
will be the one running the region, it can be some other thread
than the master (primary) thread with number 0, or it could be no
threads or multiple threads (then of course one needs to be careful
about data races).

It is way too early to deprecate the master construct though, we don't
even have OpenMP 5.0 fully implemented, it has been deprecated in 5.1,
will be also in 5.2 and removed in 6.0.  But even then it will likely
be a good idea to just -Wdeprecated warn about it and still accept it.

The patch also contains something I should have done much earlier,
for clauses that accept some integral expression where we only care
about the value, forces during gimplification that value into
either a min invariant (as before), SSA_NAME or a fresh temporary,
but never e.g. a user VAR_DECL, so that for those clauses we don't
need to worry about adjusting it.

2021-08-12  Jakub Jelinek  <jakub@redhat.com>

gcc/
* tree.def (OMP_MASKED): New tree code.
* tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_FILTER.
* tree.h (OMP_MASKED_BODY, OMP_MASKED_CLAUSES, OMP_MASKED_COMBINED,
OMP_CLAUSE_FILTER_EXPR): Define.
* tree.c (omp_clause_num_ops): Add OMP_CLAUSE_FILTER entry.
(omp_clause_code_name): Likewise.
(walk_tree_1): Handle OMP_CLAUSE_FILTER.
* tree-nested.c (convert_nonlocal_omp_clauses,
convert_local_omp_clauses): Handle OMP_CLAUSE_FILTER.
(convert_nonlocal_reference_stmt, convert_local_reference_stmt,
convert_gimple_call): Handle GIMPLE_OMP_MASTER.
* tree-pretty-print.c (dump_omp_clause): Handle OMP_CLAUSE_FILTER.
(dump_generic_node): Handle OMP_MASTER.
* gimple.def (GIMPLE_OMP_MASKED): New gimple code.
* gimple.c (gimple_build_omp_masked): New function.
(gimple_copy): Handle GIMPLE_OMP_MASKED.
* gimple.h (gimple_build_omp_masked): Declare.
(gimple_has_substatements): Handle GIMPLE_OMP_MASKED.
(gimple_omp_masked_clauses, gimple_omp_masked_clauses_ptr,
gimple_omp_masked_set_clauses): New inline functions.
(CASE_GIMPLE_OMP): Add GIMPLE_OMP_MASKED.
* gimple-pretty-print.c (dump_gimple_omp_masked): New function.
(pp_gimple_stmt_1): Handle GIMPLE_OMP_MASKED.
* gimple-walk.c (walk_gimple_stmt): Likewise.
* gimple-low.c (lower_stmt): Likewise.
* gimplify.c (is_gimple_stmt): Handle OMP_MASTER.
(gimplify_scan_omp_clauses): Handle OMP_CLAUSE_FILTER.  For clauses
that take one expression rather than decl or constant, force
gimplification of that into a SSA_NAME or temporary unless min
invariant.
(gimplify_adjust_omp_clauses): Handle OMP_CLAUSE_FILTER.
(gimplify_expr): Handle OMP_MASKED.
* tree-inline.c (remap_gimple_stmt): Handle GIMPLE_OMP_MASKED.
(estimate_num_insns): Likewise.
* omp-low.c (scan_sharing_clauses): Handle OMP_CLAUSE_FILTER.
(check_omp_nesting_restrictions): Handle GIMPLE_OMP_MASKED.  Adjust
diagnostics for existence of masked construct.
(scan_omp_1_stmt, lower_omp_master, lower_omp_1, diagnose_sb_1,
diagnose_sb_2): Handle GIMPLE_OMP_MASKED.
* omp-expand.c (expand_omp_synch, expand_omp, omp_make_gimple_edges):
Likewise.
gcc/c-family/
* c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_MASKED.
(enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_FILTER.
* c-pragma.c (omp_pragmas_simd): Add masked construct.
* c-common.h (enum c_omp_clause_split): Add C_OMP_CLAUSE_SPLIT_MASKED
enumerator.
(c_finish_omp_masked): Declare.
* c-omp.c (c_finish_omp_masked): New function.
(c_omp_split_clauses): Handle combined masked constructs.
gcc/c/
* c-parser.c (c_parser_omp_clause_name): Parse filter clause name.
(c_parser_omp_clause_filter): New function.
(c_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_FILTER.
(OMP_MASKED_CLAUSE_MASK): Define.
(c_parser_omp_masked): New function.
(c_parser_omp_parallel): Handle parallel masked.
(c_parser_omp_construct): Handle PRAGMA_OMP_MASKED.
* c-typeck.c (c_finish_omp_clauses): Handle OMP_CLAUSE_FILTER.
gcc/cp/
* parser.c (cp_parser_omp_clause_name): Parse filter clause name.
(cp_parser_omp_clause_filter): New function.
(cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_FILTER.
(OMP_MASKED_CLAUSE_MASK): Define.
(cp_parser_omp_masked): New function.
(cp_parser_omp_parallel): Handle parallel masked.
(cp_parser_omp_construct, cp_parser_pragma): Handle PRAGMA_OMP_MASKED.
* semantics.c (finish_omp_clauses): Handle OMP_CLAUSE_FILTER.
* pt.c (tsubst_omp_clauses): Likewise.
(tsubst_expr): Handle OMP_MASKED.
gcc/testsuite/
* c-c++-common/gomp/clauses-1.c (bar): Add tests for combined masked
constructs with clauses.
* c-c++-common/gomp/clauses-5.c (foo): Add testcase for filter clause.
* c-c++-common/gomp/clause-dups-1.c (f1): Likewise.
* c-c++-common/gomp/masked-1.c: New test.
* c-c++-common/gomp/masked-2.c: New test.
* c-c++-common/gomp/masked-combined-1.c: New test.
* c-c++-common/gomp/masked-combined-2.c: New test.
* c-c++-common/goacc/uninit-if-clause.c: Remove xfails.
* g++.dg/gomp/block-11.C: New test.
* g++.dg/gomp/tpl-masked-1.C: New test.
* g++.dg/gomp/attrs-1.C (bar): Add tests for masked construct and
combined masked constructs with clauses in attribute syntax.
* g++.dg/gomp/attrs-2.C (bar): Likewise.
* gcc.dg/gomp/nesting-1.c (f1, f2): Add tests for masked construct
nesting.
* gfortran.dg/goacc/host_data-tree.f95: Allow also SSA_NAMEs in if
clause.
* gfortran.dg/goacc/kernels-tree.f95: Likewise.
libgomp/
* testsuite/libgomp.c-c++-common/masked-1.c: New test.

(cherry picked from commit d0befed793b94f3f407be44e6f69f81a02f5f073)

47 files changed:
gcc/ChangeLog.omp
gcc/c-family/ChangeLog.omp
gcc/c-family/c-common.h
gcc/c-family/c-omp.c
gcc/c-family/c-pragma.c
gcc/c-family/c-pragma.h
gcc/c/ChangeLog.omp
gcc/c/c-parser.c
gcc/c/c-typeck.c
gcc/cp/ChangeLog.omp
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/gimple-low.c
gcc/gimple-pretty-print.c
gcc/gimple-walk.c
gcc/gimple.c
gcc/gimple.def
gcc/gimple.h
gcc/gimplify.c
gcc/omp-expand.c
gcc/omp-low.c
gcc/testsuite/ChangeLog.omp
gcc/testsuite/c-c++-common/goacc/uninit-if-clause.c
gcc/testsuite/c-c++-common/gomp/clause-dups-1.c
gcc/testsuite/c-c++-common/gomp/clauses-1.c
gcc/testsuite/c-c++-common/gomp/clauses-5.c
gcc/testsuite/c-c++-common/gomp/masked-1.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/gomp/masked-2.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/gomp/masked-combined-1.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/gomp/masked-combined-2.c [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/attrs-1.C
gcc/testsuite/g++.dg/gomp/attrs-2.C
gcc/testsuite/g++.dg/gomp/block-11.C
gcc/testsuite/g++.dg/gomp/tpl-masked-1.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/nesting-1.c
gcc/testsuite/gfortran.dg/goacc/host_data-tree.f95
gcc/testsuite/gfortran.dg/goacc/kernels-tree.f95
gcc/tree-core.h
gcc/tree-inline.c
gcc/tree-nested.c
gcc/tree-pretty-print.c
gcc/tree.c
gcc/tree.def
gcc/tree.h
libgomp/ChangeLog.omp
libgomp/testsuite/libgomp.c-c++-common/masked-1.c [new file with mode: 0644]

index cb4be9369306d0ecff0861d1aa062adea3ed3a39..97c0143fd07a2cb6502f3c182f2d4da257d81b77 100644 (file)
@@ -1,3 +1,50 @@
+2021-08-16  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backported from master:
+       2021-08-12  Jakub Jelinek  <jakub@redhat.com>
+
+       * tree.def (OMP_MASKED): New tree code.
+       * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_FILTER.
+       * tree.h (OMP_MASKED_BODY, OMP_MASKED_CLAUSES, OMP_MASKED_COMBINED,
+       OMP_CLAUSE_FILTER_EXPR): Define.
+       * tree.c (omp_clause_num_ops): Add OMP_CLAUSE_FILTER entry.
+       (omp_clause_code_name): Likewise.
+       (walk_tree_1): Handle OMP_CLAUSE_FILTER.
+       * tree-nested.c (convert_nonlocal_omp_clauses,
+       convert_local_omp_clauses): Handle OMP_CLAUSE_FILTER.
+       (convert_nonlocal_reference_stmt, convert_local_reference_stmt,
+       convert_gimple_call): Handle GIMPLE_OMP_MASTER.
+       * tree-pretty-print.c (dump_omp_clause): Handle OMP_CLAUSE_FILTER.
+       (dump_generic_node): Handle OMP_MASTER.
+       * gimple.def (GIMPLE_OMP_MASKED): New gimple code.
+       * gimple.c (gimple_build_omp_masked): New function.
+       (gimple_copy): Handle GIMPLE_OMP_MASKED.
+       * gimple.h (gimple_build_omp_masked): Declare.
+       (gimple_has_substatements): Handle GIMPLE_OMP_MASKED.
+       (gimple_omp_masked_clauses, gimple_omp_masked_clauses_ptr,
+       gimple_omp_masked_set_clauses): New inline functions.
+       (CASE_GIMPLE_OMP): Add GIMPLE_OMP_MASKED.
+       * gimple-pretty-print.c (dump_gimple_omp_masked): New function.
+       (pp_gimple_stmt_1): Handle GIMPLE_OMP_MASKED.
+       * gimple-walk.c (walk_gimple_stmt): Likewise.
+       * gimple-low.c (lower_stmt): Likewise.
+       * gimplify.c (is_gimple_stmt): Handle OMP_MASTER.
+       (gimplify_scan_omp_clauses): Handle OMP_CLAUSE_FILTER.  For clauses
+       that take one expression rather than decl or constant, force
+       gimplification of that into a SSA_NAME or temporary unless min
+       invariant.
+       (gimplify_adjust_omp_clauses): Handle OMP_CLAUSE_FILTER.
+       (gimplify_expr): Handle OMP_MASKED.
+       * tree-inline.c (remap_gimple_stmt): Handle GIMPLE_OMP_MASKED.
+       (estimate_num_insns): Likewise.
+       * omp-low.c (scan_sharing_clauses): Handle OMP_CLAUSE_FILTER.
+       (check_omp_nesting_restrictions): Handle GIMPLE_OMP_MASKED.  Adjust
+       diagnostics for existence of masked construct.
+       (scan_omp_1_stmt, lower_omp_master, lower_omp_1, diagnose_sb_1,
+       diagnose_sb_2): Handle GIMPLE_OMP_MASKED.
+       * omp-expand.c (expand_omp_synch, expand_omp, omp_make_gimple_edges):
+       Likewise.
+
 2021-08-16  Tobias Burnus  <tobias@codesourcery.com>
 
        Backported from master:
        function to...
        (gcn_goacc_create_propagation_record): This.  Adjust comment.
        * config/gcn/gcn.c (gcn_init_builtins): Override decls for
-        BUILT_IN_GOACC_SINGLE_START, BUILT_IN_GOACC_SINGLE_COPY_START,
-        BUILT_IN_GOACC_SINGLE_COPY_END and BUILT_IN_GOACC_BARRIER.
+       BUILT_IN_GOACC_SINGLE_START, BUILT_IN_GOACC_SINGLE_COPY_START,
+       BUILT_IN_GOACC_SINGLE_COPY_END and BUILT_IN_GOACC_BARRIER.
        (gcn_fork_join): Remove inaccurate comment.
        (TARGET_GOACC_ADJUST_PROPAGATION_RECORD): Rename to...
        (TARGET_GOACC_CREATE_PROPAGATION_RECORD): This.
 
        * Makefile.in (OBJS): Add omp-sese.o.
        * omp-builtins.def (BUILT_IN_GOACC_BARRIER, BUILT_IN_GOACC_SINGLE_START,
-        BUILT_IN_GOACC_SINGLE_COPY_START, BUILT_IN_GOACC_SINGLE_COPY_END): New
+       BUILT_IN_GOACC_SINGLE_COPY_START, BUILT_IN_GOACC_SINGLE_COPY_END): New
        builtins.
        * omp-offload.c (omp-sese.h): Include header.
        (oacc_loop_xform_head_tail): Call update_stmt for modified builtin
index e27c421eba94601f0e9e00108ffdf03bc453bb76..31b8534d8f2e16be9f8da8c33e960fcafb9e3846 100644 (file)
@@ -1,3 +1,17 @@
+2021-08-16  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backported from master:
+       2021-08-12  Jakub Jelinek  <jakub@redhat.com>
+
+       * c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_MASKED.
+       (enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_FILTER.
+       * c-pragma.c (omp_pragmas_simd): Add masked construct.
+       * c-common.h (enum c_omp_clause_split): Add C_OMP_CLAUSE_SPLIT_MASKED
+       enumerator.
+       (c_finish_omp_masked): Declare.
+       * c-omp.c (c_finish_omp_masked): New function.
+       (c_omp_split_clauses): Handle combined masked constructs.
+
 2021-07-23  Tobias Burnus  <tobias@codesourcery.com>
 
        Backported from master:
index c188e5f7627101b737af30992565c99761ff1d09..0043fc47ea27ad5e5f08b68e4896d5a21ddb843f 100644 (file)
@@ -1198,7 +1198,8 @@ enum c_omp_clause_split
   C_OMP_CLAUSE_SPLIT_COUNT,
   C_OMP_CLAUSE_SPLIT_SECTIONS = C_OMP_CLAUSE_SPLIT_FOR,
   C_OMP_CLAUSE_SPLIT_TASKLOOP = C_OMP_CLAUSE_SPLIT_FOR,
-  C_OMP_CLAUSE_SPLIT_LOOP = C_OMP_CLAUSE_SPLIT_FOR
+  C_OMP_CLAUSE_SPLIT_LOOP = C_OMP_CLAUSE_SPLIT_FOR,
+  C_OMP_CLAUSE_SPLIT_MASKED = C_OMP_CLAUSE_SPLIT_DISTRIBUTE
 };
 
 enum c_omp_region_type
@@ -1210,6 +1211,7 @@ enum c_omp_region_type
 };
 
 extern tree c_finish_omp_master (location_t, tree);
+extern tree c_finish_omp_masked (location_t, tree, tree);
 extern tree c_finish_omp_taskgroup (location_t, tree, tree);
 extern tree c_finish_omp_critical (location_t, tree, tree, tree);
 extern tree c_finish_omp_ordered (location_t, tree, tree);
index b07db9e7dc977a68be350689062c035df2e9c5e4..a70aec9f151f41d8a854e675283cd763300af41b 100644 (file)
@@ -86,6 +86,20 @@ c_finish_omp_master (location_t loc, tree stmt)
   return t;
 }
 
+/* Complete a #pragma omp masked construct.  BODY is the structured-block
+   that follows the pragma.  LOC is the location of the #pragma.  */
+
+tree
+c_finish_omp_masked (location_t loc, tree body, tree clauses)
+{
+  tree stmt = make_node (OMP_MASKED);
+  TREE_TYPE (stmt) = void_type_node;
+  OMP_MASKED_BODY (stmt) = body;
+  OMP_MASKED_CLAUSES (stmt) = clauses;
+  SET_EXPR_LOCATION (stmt, loc);
+  return add_stmt (stmt);
+}
+
 /* Complete a #pragma omp taskgroup construct.  BODY is the structured-block
    that follows the pragma.  LOC is the location of the #pragma.  */
 
@@ -1686,11 +1700,16 @@ c_oacc_split_loop_clauses (tree clauses, tree *not_loop_clauses,
    #pragma omp distribute parallel for simd
    #pragma omp distribute simd
    #pragma omp for simd
+   #pragma omp masked taskloop
+   #pragma omp masked taskloop simd
    #pragma omp master taskloop
    #pragma omp master taskloop simd
    #pragma omp parallel for
    #pragma omp parallel for simd
    #pragma omp parallel loop
+   #pragma omp parallel masked
+   #pragma omp parallel masked taskloop
+   #pragma omp parallel masked taskloop simd
    #pragma omp parallel master
    #pragma omp parallel master taskloop
    #pragma omp parallel master taskloop simd
@@ -1795,6 +1814,9 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
        case OMP_CLAUSE_BIND:
          s = C_OMP_CLAUSE_SPLIT_LOOP;
          break;
+       case OMP_CLAUSE_FILTER:
+         s = C_OMP_CLAUSE_SPLIT_MASKED;
+         break;
        /* Duplicate this to all of taskloop, distribute, for, simd and
           loop.  */
        case OMP_CLAUSE_COLLAPSE:
@@ -1844,10 +1866,10 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
          else
            s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
          break;
-       /* Private clause is supported on all constructs but master,
-          it is enough to put it on the innermost one other than master.  For
-          #pragma omp {for,sections} put it on parallel though,
-          as that's what we did for OpenMP 3.1.  */
+       /* Private clause is supported on all constructs but master/masked,
+          it is enough to put it on the innermost one other than
+          master/masked.  For #pragma omp {for,sections} put it on parallel
+          though, as that's what we did for OpenMP 3.1.  */
        case OMP_CLAUSE_PRIVATE:
          switch (code)
            {
@@ -1857,14 +1879,15 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
            case OMP_DISTRIBUTE: s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE; break;
            case OMP_TEAMS: s = C_OMP_CLAUSE_SPLIT_TEAMS; break;
            case OMP_MASTER: s = C_OMP_CLAUSE_SPLIT_PARALLEL; break;
+           case OMP_MASKED: s = C_OMP_CLAUSE_SPLIT_PARALLEL; break;
            case OMP_TASKLOOP: s = C_OMP_CLAUSE_SPLIT_TASKLOOP; break;
            case OMP_LOOP: s = C_OMP_CLAUSE_SPLIT_LOOP; break;
            default: gcc_unreachable ();
            }
          break;
        /* Firstprivate clause is supported on all constructs but
-          simd, master and loop.  Put it on the outermost of those and
-          duplicate on teams and parallel.  */
+          simd, master, masked and loop.  Put it on the outermost of those
+          and duplicate on teams and parallel.  */
        case OMP_CLAUSE_FIRSTPRIVATE:
          if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP))
              != 0)
@@ -1917,7 +1940,7 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
              else if ((mask & (OMP_CLAUSE_MASK_1
                                << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0)
                /* This must be
-                  #pragma omp parallel master taskloop{, simd}.  */
+                  #pragma omp parallel mas{ked,ter} taskloop{, simd}.  */
                s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
              else
                /* This must be
@@ -1949,9 +1972,10 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
          else if ((mask & (OMP_CLAUSE_MASK_1
                            << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0)
            {
-             /* This must be #pragma omp {,{,parallel }master }taskloop simd
+             /* This must be
+                #pragma omp {,{,parallel }mas{ked,ter} }taskloop simd
                 or
-                #pragma omp {,parallel }master taskloop.  */
+                #pragma omp {,parallel }mas{ked,ter} taskloop.  */
              gcc_assert (code == OMP_SIMD || code == OMP_TASKLOOP);
              s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
            }
@@ -2188,7 +2212,8 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
            }
          else if (code == OMP_SECTIONS
                   || code == OMP_PARALLEL
-                  || code == OMP_MASTER)
+                  || code == OMP_MASTER
+                  || code == OMP_MASKED)
            s = C_OMP_CLAUSE_SPLIT_PARALLEL;
          else if (code == OMP_TASKLOOP)
            s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
@@ -2586,7 +2611,8 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
     gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_TARGET] == NULL_TREE);
   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)) == 0)
     gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_TEAMS] == NULL_TREE);
-  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
+  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0
+      && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)) == 0)
     gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE] == NULL_TREE);
   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) == 0)
     gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] == NULL_TREE);
@@ -3759,8 +3785,8 @@ static const struct c_omp_directive omp_directives[] = {
     C_OMP_DIR_STANDALONE, false },  */
   { "loop", nullptr, nullptr, PRAGMA_OMP_LOOP,
     C_OMP_DIR_CONSTRUCT, true },
-  /* { "masked", nullptr, nullptr, PRAGMA_OMP_MASKED,
-    C_OMP_DIR_CONSTRUCT, true },  */
+  { "masked", nullptr, nullptr, PRAGMA_OMP_MASKED,
+    C_OMP_DIR_CONSTRUCT, true },
   { "master", nullptr, nullptr, PRAGMA_OMP_MASTER,
     C_OMP_DIR_CONSTRUCT, true },
   /* { "metadirective", nullptr, nullptr, PRAGMA_OMP_METADIRECTIVE,
index 4f8e8e0128c3ddb77450a0d4976d00ad03c6a4c6..338c56fbd3a6839d5128073c1cff6525c3de1f87 100644 (file)
@@ -1333,6 +1333,7 @@ static const struct omp_pragma_def omp_pragmas_simd[] = {
   { "distribute", PRAGMA_OMP_DISTRIBUTE },
   { "for", PRAGMA_OMP_FOR },
   { "loop", PRAGMA_OMP_LOOP },
+  { "masked", PRAGMA_OMP_MASKED },
   { "master", PRAGMA_OMP_MASTER },
   { "ordered", PRAGMA_OMP_ORDERED },
   { "parallel", PRAGMA_OMP_PARALLEL },
index abd66672f527fb5d4bbc4e6143fbd3b39914e9d7..b7ec6e5d5474f11fcd9c34ff6c645babda11ad9d 100644 (file)
@@ -57,6 +57,7 @@ enum pragma_kind {
   PRAGMA_OMP_FLUSH,
   PRAGMA_OMP_FOR,
   PRAGMA_OMP_LOOP,
+  PRAGMA_OMP_MASKED,
   PRAGMA_OMP_MASTER,
   PRAGMA_OMP_ORDERED,
   PRAGMA_OMP_PARALLEL,
@@ -104,6 +105,7 @@ enum pragma_omp_clause {
   PRAGMA_OMP_CLAUSE_DEVICE,
   PRAGMA_OMP_CLAUSE_DEVICE_TYPE,
   PRAGMA_OMP_CLAUSE_DIST_SCHEDULE,
+  PRAGMA_OMP_CLAUSE_FILTER,
   PRAGMA_OMP_CLAUSE_FINAL,
   PRAGMA_OMP_CLAUSE_FIRSTPRIVATE,
   PRAGMA_OMP_CLAUSE_FOR,
index db3dff6e8b7740ff3e93d4a791d52e4e1a475bd2..56004986d44ba1ab7818250df40e18a182372568 100644 (file)
@@ -1,3 +1,17 @@
+2021-08-16  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backported from master:
+       2021-08-12  Jakub Jelinek  <jakub@redhat.com>
+
+       * c-parser.c (c_parser_omp_clause_name): Parse filter clause name.
+       (c_parser_omp_clause_filter): New function.
+       (c_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_FILTER.
+       (OMP_MASKED_CLAUSE_MASK): Define.
+       (c_parser_omp_masked): New function.
+       (c_parser_omp_parallel): Handle parallel masked.
+       (c_parser_omp_construct): Handle PRAGMA_OMP_MASKED.
+       * c-typeck.c (c_finish_omp_clauses): Handle OMP_CLAUSE_FILTER.
+
 2021-08-16  Tobias Burnus  <tobias@codesourcery.com>
 
        Backported from master:
index c028095fc24115eeb6fb885c20009e6e211a6831..c4dc5f83c12223a4d3b9591a65eaeacad1bab426 100644 (file)
@@ -12660,7 +12660,9 @@ c_parser_omp_clause_name (c_parser *parser)
            result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
          break;
        case 'f':
-         if (!strcmp ("final", p))
+         if (!strcmp ("filter", p))
+           result = PRAGMA_OMP_CLAUSE_FILTER;
+         else if (!strcmp ("final", p))
            result = PRAGMA_OMP_CLAUSE_FINAL;
          else if (!strcmp ("finalize", p))
            result = PRAGMA_OACC_CLAUSE_FINALIZE;
@@ -13964,6 +13966,38 @@ c_parser_omp_clause_hint (c_parser *parser, tree list)
   return list;
 }
 
+/* OpenMP 5.1:
+   filter ( integer-expression ) */
+
+static tree
+c_parser_omp_clause_filter (c_parser *parser, tree list)
+{
+  location_t hint_loc = c_parser_peek_token (parser)->location;
+  matching_parens parens;
+  if (parens.require_open (parser))
+    {
+      location_t expr_loc = c_parser_peek_token (parser)->location;
+      c_expr expr = c_parser_expr_no_commas (parser, NULL);
+      expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
+      tree c, t = expr.value;
+      t = c_fully_fold (t, false, NULL);
+      if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
+       {
+         c_parser_error (parser, "expected integer expression");
+         return list;
+       }
+      parens.skip_until_found_close (parser);
+      check_no_duplicate_clause (list, OMP_CLAUSE_FILTER, "filter");
+
+      c = build_omp_clause (hint_loc, OMP_CLAUSE_FILTER);
+      OMP_CLAUSE_FILTER_EXPR (c) = t;
+      OMP_CLAUSE_CHAIN (c) = list;
+      list = c;
+    }
+
+  return list;
+}
+
 /* OpenMP 4.5:
    defaultmap ( tofrom : scalar )
 
@@ -16430,6 +16464,10 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
          clauses = c_parser_omp_clause_detach (parser, clauses);
          c_name = "detach";
          break;
+       case PRAGMA_OMP_CLAUSE_FILTER:
+         clauses = c_parser_omp_clause_filter (parser, clauses);
+         c_name = "filter";
+         break;
        case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
          clauses = c_parser_omp_clause_firstprivate (parser, clauses);
          c_name = "firstprivate";
@@ -18998,6 +19036,70 @@ c_parser_omp_master (location_t loc, c_parser *parser,
                                                                  if_p));
 }
 
+/* OpenMP 5.1:
+   # pragma omp masked masked-clauses new-line
+     structured-block
+
+   LOC is the location of the #pragma token.
+*/
+
+#define OMP_MASKED_CLAUSE_MASK                                 \
+       (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
+
+static tree
+c_parser_omp_masked (location_t loc, c_parser *parser,
+                    char *p_name, omp_clause_mask mask, tree *cclauses,
+                    bool *if_p)
+{
+  tree block, clauses, ret;
+
+  strcat (p_name, " masked");
+  mask |= OMP_MASKED_CLAUSE_MASK;
+
+  if (c_parser_next_token_is (parser, CPP_NAME))
+    {
+      const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+
+      if (strcmp (p, "taskloop") == 0)
+       {
+         tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
+         if (cclauses == NULL)
+           cclauses = cclauses_buf;
+
+         c_parser_consume_token (parser);
+         if (!flag_openmp)  /* flag_openmp_simd  */
+           return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
+                                         if_p);
+         block = c_begin_compound_stmt (true);
+         ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
+                                      if_p);
+         block = c_end_compound_stmt (loc, block, true);
+         if (ret == NULL_TREE)
+           return ret;
+         ret = c_finish_omp_masked (loc, block,
+                                    cclauses[C_OMP_CLAUSE_SPLIT_MASKED]);
+         OMP_MASKED_COMBINED (ret) = 1;
+         return ret;
+       }
+    }
+  if (!flag_openmp)  /* flag_openmp_simd  */
+    {
+      c_parser_skip_to_pragma_eol (parser, false);
+      return NULL_TREE;
+    }
+
+  clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
+  if (cclauses)
+    {
+      omp_split_clauses (loc, OMP_MASKED, mask, clauses, cclauses);
+      clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED];
+    }
+
+  return c_finish_omp_masked (loc, c_parser_omp_structured_block (parser,
+                                                                 if_p),
+                             clauses);
+}
+
 /* OpenMP 2.5:
    # pragma omp ordered new-line
      structured-block
@@ -19260,7 +19362,36 @@ c_parser_omp_parallel (location_t loc, c_parser *parser,
   else if (c_parser_next_token_is (parser, CPP_NAME))
     {
       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
-      if (cclauses == NULL && strcmp (p, "master") == 0)
+      if (cclauses == NULL && strcmp (p, "masked") == 0)
+       {
+         tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
+         cclauses = cclauses_buf;
+
+         c_parser_consume_token (parser);
+         if (!flag_openmp)  /* flag_openmp_simd  */
+           return c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
+                                       if_p);
+         block = c_begin_omp_parallel ();
+         tree ret = c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
+                                         if_p);
+         stmt = c_finish_omp_parallel (loc,
+                                       cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
+                                       block);
+         if (ret == NULL)
+           return ret;
+         /* masked does have just filter clause, but during gimplification
+            isn't represented by a gimplification omp context, so for
+            #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
+            so that
+            #pragma omp parallel masked
+            #pragma omp taskloop simd lastprivate (x)
+            isn't confused with
+            #pragma omp parallel masked taskloop simd lastprivate (x)  */
+         if (OMP_MASKED_COMBINED (ret))
+           OMP_PARALLEL_COMBINED (stmt) = 1;
+         return stmt;
+       }
+      else if (cclauses == NULL && strcmp (p, "master") == 0)
        {
          tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
          cclauses = cclauses_buf;
@@ -21836,6 +21967,10 @@ c_parser_omp_construct (c_parser *parser, bool *if_p)
       strcpy (p_name, "#pragma omp");
       stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
       break;
+    case PRAGMA_OMP_MASKED:
+      strcpy (p_name, "#pragma omp");
+      stmt = c_parser_omp_masked (loc, parser, p_name, mask, NULL, if_p);
+      break;
     case PRAGMA_OMP_MASTER:
       strcpy (p_name, "#pragma omp");
       stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
index 8007787519104d50fb910fd339d210b7521dd9dd..9c4822bbf27a3461101329b064a8b1883e87d5f2 100644 (file)
@@ -15271,6 +15271,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
        case OMP_CLAUSE_THREADS:
        case OMP_CLAUSE_SIMD:
        case OMP_CLAUSE_HINT:
+       case OMP_CLAUSE_FILTER:
        case OMP_CLAUSE_DEFAULTMAP:
        case OMP_CLAUSE_BIND:
        case OMP_CLAUSE_NUM_GANGS:
index b6d196a245b1ec74d1dff87575328d7a9a288e7d..0df480e861bb04b41ddfef4db2cf12ee774df1fa 100644 (file)
@@ -1,3 +1,19 @@
+2021-08-16  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backported from master:
+       2021-08-12  Jakub Jelinek  <jakub@redhat.com>
+
+       * parser.c (cp_parser_omp_clause_name): Parse filter clause name.
+       (cp_parser_omp_clause_filter): New function.
+       (cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_FILTER.
+       (OMP_MASKED_CLAUSE_MASK): Define.
+       (cp_parser_omp_masked): New function.
+       (cp_parser_omp_parallel): Handle parallel masked.
+       (cp_parser_omp_construct, cp_parser_pragma): Handle PRAGMA_OMP_MASKED.
+       * semantics.c (finish_omp_clauses): Handle OMP_CLAUSE_FILTER.
+       * pt.c (tsubst_omp_clauses): Likewise.
+       (tsubst_expr): Handle OMP_MASKED.
+
 2021-08-16  Tobias Burnus  <tobias@codesourcery.com>
 
        Backported from master:
index 6ffe43a7870d50a9fca99460b846f4d84b872c88..83eabf1793cc58c2a375669a9c286b8bde22a2e1 100644 (file)
@@ -35791,7 +35791,9 @@ cp_parser_omp_clause_name (cp_parser *parser)
            result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
          break;
        case 'f':
-         if (!strcmp ("final", p))
+         if (!strcmp ("filter", p))
+           result = PRAGMA_OMP_CLAUSE_FILTER;
+         else if (!strcmp ("final", p))
            result = PRAGMA_OMP_CLAUSE_FINAL;
          else if (!strcmp ("finalize", p))
            result = PRAGMA_OACC_CLAUSE_FINALIZE;
@@ -37176,6 +37178,34 @@ cp_parser_omp_clause_hint (cp_parser *parser, tree list, location_t location)
   return c;
 }
 
+/* OpenMP 5.1:
+   filter ( integer-expression ) */
+
+static tree
+cp_parser_omp_clause_filter (cp_parser *parser, tree list, location_t location)
+{
+  tree t, c;
+
+  matching_parens parens;
+  if (!parens.require_open (parser))
+    return list;
+
+  t = cp_parser_assignment_expression (parser);
+
+  if (t == error_mark_node
+      || !parens.require_close (parser))
+    cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+                                          /*or_comma=*/false,
+                                          /*consume_paren=*/true);
+  check_no_duplicate_clause (list, OMP_CLAUSE_FILTER, "filter", location);
+
+  c = build_omp_clause (location, OMP_CLAUSE_FILTER);
+  OMP_CLAUSE_FILTER_EXPR (c) = t;
+  OMP_CLAUSE_CHAIN (c) = list;
+
+  return c;
+}
+
 /* OpenMP 4.5:
    defaultmap ( tofrom : scalar )
 
@@ -39284,6 +39314,11 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
                                                  token->location, false);
          c_name = "default";
          break;
+       case PRAGMA_OMP_CLAUSE_FILTER:
+         clauses = cp_parser_omp_clause_filter (parser, clauses,
+                                                token->location);
+         c_name = "filter";
+         break;
        case PRAGMA_OMP_CLAUSE_FINAL:
          clauses = cp_parser_omp_clause_final (parser, clauses, token->location);
          c_name = "final";
@@ -41820,6 +41855,73 @@ cp_parser_omp_master (cp_parser *parser, cp_token *pragma_tok,
                              cp_parser_omp_structured_block (parser, if_p));
 }
 
+/* OpenMP 5.1:
+   # pragma omp masked masked-clauses new-line
+     structured-block  */
+
+#define OMP_MASKED_CLAUSE_MASK                                 \
+       (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
+
+static tree
+cp_parser_omp_masked (cp_parser *parser, cp_token *pragma_tok,
+                     char *p_name, omp_clause_mask mask, tree *cclauses,
+                     bool *if_p)
+{
+  tree clauses, sb, ret;
+  unsigned int save;
+  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+
+  strcat (p_name, " masked");
+  mask |= OMP_MASKED_CLAUSE_MASK;
+
+  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+    {
+      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+      const char *p = IDENTIFIER_POINTER (id);
+
+      if (strcmp (p, "taskloop") == 0)
+       {
+         tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
+         if (cclauses == NULL)
+           cclauses = cclauses_buf;
+
+         cp_lexer_consume_token (parser->lexer);
+         if (!flag_openmp)  /* flag_openmp_simd  */
+           return cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask,
+                                          cclauses, if_p);
+         sb = begin_omp_structured_block ();
+         save = cp_parser_begin_omp_structured_block (parser);
+         ret = cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask,
+                                       cclauses, if_p);
+         cp_parser_end_omp_structured_block (parser, save);
+         tree body = finish_omp_structured_block (sb);
+         if (ret == NULL)
+           return ret;
+         ret = c_finish_omp_masked (loc, body,
+                                    cclauses[C_OMP_CLAUSE_SPLIT_MASKED]);
+         OMP_MASKED_COMBINED (ret) = 1;
+         return ret;
+       }
+    }
+  if (!flag_openmp)  /* flag_openmp_simd  */
+    {
+      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+      return NULL_TREE;
+    }
+
+  clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
+                                      cclauses == NULL);
+  if (cclauses)
+    {
+      cp_omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
+      clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED];
+    }
+
+  return c_finish_omp_masked (loc,
+                             cp_parser_omp_structured_block (parser, if_p),
+                             clauses);
+}
+
 /* OpenMP 2.5:
    # pragma omp ordered new-line
      structured-block
@@ -42073,7 +42175,37 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok,
     {
       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
       const char *p = IDENTIFIER_POINTER (id);
-      if (cclauses == NULL && strcmp (p, "master") == 0)
+      if (cclauses == NULL && strcmp (p, "masked") == 0)
+       {
+         tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
+         cclauses = cclauses_buf;
+
+         cp_lexer_consume_token (parser->lexer);
+         if (!flag_openmp)  /* flag_openmp_simd  */
+           return cp_parser_omp_masked (parser, pragma_tok, p_name, mask,
+                                        cclauses, if_p);
+         block = begin_omp_parallel ();
+         save = cp_parser_begin_omp_structured_block (parser);
+         tree ret = cp_parser_omp_masked (parser, pragma_tok, p_name, mask,
+                                          cclauses, if_p);
+         cp_parser_end_omp_structured_block (parser, save);
+         stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
+                                     block);
+         if (ret == NULL_TREE)
+           return ret;
+         /* masked does have just filter clause, but during gimplification
+            isn't represented by a gimplification omp context, so for
+            #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
+            so that
+            #pragma omp parallel masked
+            #pragma omp taskloop simd lastprivate (x)
+            isn't confused with
+            #pragma omp parallel masked taskloop simd lastprivate (x)  */
+         if (OMP_MASKED_COMBINED (ret))
+           OMP_PARALLEL_COMBINED (stmt) = 1;
+         return stmt;
+       }
+      else if (cclauses == NULL && strcmp (p, "master") == 0)
        {
          tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
          cclauses = cclauses_buf;
@@ -45618,6 +45750,11 @@ cp_parser_omp_construct (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
       stmt = cp_parser_omp_loop (parser, pragma_tok, p_name, mask, NULL,
                                 if_p);
       break;
+    case PRAGMA_OMP_MASKED:
+      strcpy (p_name, "#pragma omp");
+      stmt = cp_parser_omp_masked (parser, pragma_tok, p_name, mask, NULL,
+                                  if_p);
+      break;
     case PRAGMA_OMP_MASTER:
       strcpy (p_name, "#pragma omp");
       stmt = cp_parser_omp_master (parser, pragma_tok, p_name, mask, NULL,
@@ -46258,6 +46395,7 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p)
     case PRAGMA_OMP_DISTRIBUTE:
     case PRAGMA_OMP_FOR:
     case PRAGMA_OMP_LOOP:
+    case PRAGMA_OMP_MASKED:
     case PRAGMA_OMP_MASTER:
     case PRAGMA_OMP_PARALLEL:
     case PRAGMA_OMP_SECTIONS:
index bedb0ef7cadc85f65c08fbfdc32b15cbe159d666..c1daada0a1b456b6b31e993195674f4a4f98de97 100644 (file)
@@ -17473,6 +17473,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
        case OMP_CLAUSE_PRIORITY:
        case OMP_CLAUSE_ORDERED:
        case OMP_CLAUSE_HINT:
+       case OMP_CLAUSE_FILTER:
        case OMP_CLAUSE_NUM_GANGS:
        case OMP_CLAUSE_NUM_WORKERS:
        case OMP_CLAUSE_VECTOR_LENGTH:
@@ -18858,6 +18859,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
       break;
 
     case OMP_SECTIONS:
+    case OMP_MASKED:
       omp_parallel_combined_clauses = NULL;
       /* FALLTHRU */
     case OMP_SINGLE:
index e412338922e96c29b6673c6f72ca4e1f9bff4b8a..e56ad8aa1e1fb4240a476f23b24ac518da699b3d 100644 (file)
@@ -8324,6 +8324,29 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
            }
          break;
 
+       case OMP_CLAUSE_FILTER:
+         t = OMP_CLAUSE_FILTER_EXPR (c);
+         if (t == error_mark_node)
+           remove = true;
+         else if (!type_dependent_expression_p (t)
+                  && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
+           {
+             error_at (OMP_CLAUSE_LOCATION (c),
+                       "%<filter%> expression must be integral");
+             remove = true;
+           }
+         else
+           {
+             t = mark_rvalue_use (t);
+             if (!processing_template_decl)
+               {
+                 t = maybe_constant_value (t);
+                 t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+               }
+             OMP_CLAUSE_FILTER_EXPR (c) = t;
+           }
+         break;
+
        case OMP_CLAUSE_IS_DEVICE_PTR:
        case OMP_CLAUSE_USE_DEVICE_PTR:
          field_ok = (ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP;
index fa7d4de30c01ae5164676d6253ebc5013aced576..832d5c3721c8cf01cb3c4a101af8473a059c0faf 100644 (file)
@@ -334,6 +334,7 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data)
     case GIMPLE_OMP_SECTION:
     case GIMPLE_OMP_SINGLE:
     case GIMPLE_OMP_MASTER:
+    case GIMPLE_OMP_MASKED:
     case GIMPLE_OMP_TASKGROUP:
     case GIMPLE_OMP_ORDERED:
     case GIMPLE_OMP_SCAN:
index 0ef01e6420bcbacbee7e93ebb0810ac2a47de836..80aca691f6b846d3175ee9f23f6819318d8ca344 100644 (file)
@@ -1657,6 +1657,35 @@ dump_gimple_omp_taskgroup (pretty_printer *buffer, const gimple *gs,
     }
 }
 
+/* Dump a GIMPLE_OMP_MASKED tuple on the pretty_printer BUFFER.  */
+
+static void
+dump_gimple_omp_masked (pretty_printer *buffer, const gimple *gs,
+                       int spc, dump_flags_t flags)
+{
+  if (flags & TDF_RAW)
+    {
+      dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
+                      gimple_omp_body (gs));
+      dump_omp_clauses (buffer, gimple_omp_masked_clauses (gs), spc, flags);
+      dump_gimple_fmt (buffer, spc, flags, " >");
+    }
+  else
+    {
+      pp_string (buffer, "#pragma omp masked");
+      dump_omp_clauses (buffer, gimple_omp_masked_clauses (gs), spc, flags);
+      if (!gimple_seq_empty_p (gimple_omp_body (gs)))
+       {
+         newline_and_indent (buffer, spc + 2);
+         pp_left_brace (buffer);
+         pp_newline (buffer);
+         dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
+         newline_and_indent (buffer, spc + 2);
+         pp_right_brace (buffer);
+       }
+    }
+}
+
 /* Dump a GIMPLE_OMP_TARGET tuple on the pretty_printer BUFFER.  */
 
 static void
@@ -2709,6 +2738,10 @@ pp_gimple_stmt_1 (pretty_printer *buffer, const gimple *gs, int spc,
       dump_gimple_omp_taskgroup (buffer, gs, spc, flags);
       break;
 
+    case GIMPLE_OMP_MASKED:
+      dump_gimple_omp_masked (buffer, gs, spc, flags);
+      break;
+
     case GIMPLE_OMP_MASTER:
     case GIMPLE_OMP_SECTION:
       dump_gimple_omp_block (buffer, gs, spc, flags);
index b1d2f10f52f474dfe7faee4943b65248cdc86575..7ba458c54fcd0900ba577d1348aafab12a51b6e9 100644 (file)
@@ -682,6 +682,7 @@ walk_gimple_stmt (gimple_stmt_iterator *gsi, walk_stmt_fn callback_stmt,
       /* FALL THROUGH.  */
     case GIMPLE_OMP_CRITICAL:
     case GIMPLE_OMP_MASTER:
+    case GIMPLE_OMP_MASKED:
     case GIMPLE_OMP_TASKGROUP:
     case GIMPLE_OMP_ORDERED:
     case GIMPLE_OMP_SCAN:
index c6f7c2d49002a64b133f6c8d1f9d14e7ab84f60f..e9892d6ae1806d438f9298a9b61aeeeecbd5cfc9 100644 (file)
@@ -1038,6 +1038,21 @@ gimple_build_omp_master (gimple_seq body)
   return p;
 }
 
+/* Build a GIMPLE_OMP_MASKED statement.
+
+   BODY is the sequence of statements to be executed by the selected thread(s).  */
+
+gimple *
+gimple_build_omp_masked (gimple_seq body, tree clauses)
+{
+  gimple *p = gimple_alloc (GIMPLE_OMP_MASKED, 0);
+  gimple_omp_masked_set_clauses (p, clauses);
+  if (body)
+    gimple_omp_set_body (p, body);
+
+  return p;
+}
+
 /* Build a GIMPLE_OMP_TASKGROUP statement.
 
    BODY is the sequence of statements to be executed by the taskgroup
@@ -2031,6 +2046,11 @@ gimple_copy (gimple *stmt)
          gimple_omp_set_body (copy, new_seq);
          break;
 
+       case GIMPLE_OMP_MASKED:
+         t = unshare_expr (gimple_omp_masked_clauses (stmt));
+         gimple_omp_masked_set_clauses (copy, t);
+         goto copy_omp_body;
+
        case GIMPLE_TRANSACTION:
          new_seq = gimple_seq_copy (gimple_transaction_body (
                                       as_a <gtransaction *> (stmt)));
index 0ac0cf72bfa31ad7b3d5facd23068439ee244566..e66546c6be3d1e5f2d9c9467bb5ee59bfb35e12e 100644 (file)
@@ -279,6 +279,10 @@ DEFGSCODE(GIMPLE_OMP_FOR, "gimple_omp_for", GSS_OMP_FOR)
    BODY is the sequence of statements to execute in the master section.  */
 DEFGSCODE(GIMPLE_OMP_MASTER, "gimple_omp_master", GSS_OMP)
 
+/* GIMPLE_OMP_MASKED <BODY, CLAUSES> represents #pragma omp masked.
+   BODY is the sequence of statements to execute in the masked section.  */
+DEFGSCODE(GIMPLE_OMP_MASKED, "gimple_omp_masked", GSS_OMP_SINGLE_LAYOUT)
+
 /* GIMPLE_OMP_TASKGROUP <BODY, CLAUSES> represents #pragma omp taskgroup.
    BODY is the sequence of statements inside the taskgroup section.
    CLAUSES is an OMP_CLAUSE chain holding the associated clauses.  */
index 3ec86f5f08283e55d4eefdf0f4d709d1b6c16abf..5ba7f14221cb781c4f80eb46a2fd867a2f7eba2f 100644 (file)
@@ -1559,6 +1559,7 @@ gomp_task *gimple_build_omp_task (gimple_seq, tree, tree, tree, tree,
                                       tree, tree);
 gimple *gimple_build_omp_section (gimple_seq);
 gimple *gimple_build_omp_master (gimple_seq);
+gimple *gimple_build_omp_masked (gimple_seq, tree);
 gimple *gimple_build_omp_taskgroup (gimple_seq, tree);
 gomp_continue *gimple_build_omp_continue (tree, tree);
 gomp_ordered *gimple_build_omp_ordered (gimple_seq, tree);
@@ -1817,6 +1818,7 @@ gimple_has_substatements (gimple *g)
     case GIMPLE_TRY:
     case GIMPLE_OMP_FOR:
     case GIMPLE_OMP_MASTER:
+    case GIMPLE_OMP_MASKED:
     case GIMPLE_OMP_TASKGROUP:
     case GIMPLE_OMP_ORDERED:
     case GIMPLE_OMP_SECTION:
@@ -5183,6 +5185,40 @@ gimple_omp_taskgroup_set_clauses (gimple *gs, tree clauses)
 }
 
 
+/* Return the clauses associated with OMP_MASTER statement GS.  */
+
+static inline tree
+gimple_omp_masked_clauses (const gimple *gs)
+{
+  GIMPLE_CHECK (gs, GIMPLE_OMP_MASKED);
+  return
+    static_cast <const gimple_statement_omp_single_layout *> (gs)->clauses;
+}
+
+
+/* Return a pointer to the clauses associated with OMP masked statement
+   GS.  */
+
+static inline tree *
+gimple_omp_masked_clauses_ptr (gimple *gs)
+{
+  GIMPLE_CHECK (gs, GIMPLE_OMP_MASKED);
+  return &static_cast <gimple_statement_omp_single_layout *> (gs)->clauses;
+}
+
+
+/* Set CLAUSES to be the clauses associated with OMP masked statement
+   GS.  */
+
+static inline void
+gimple_omp_masked_set_clauses (gimple *gs, tree clauses)
+{
+  GIMPLE_CHECK (gs, GIMPLE_OMP_MASKED);
+  static_cast <gimple_statement_omp_single_layout *> (gs)->clauses
+    = clauses;
+}
+
+
 /* Return the kind of the OMP_FOR statemement G.  */
 
 static inline int
@@ -6471,6 +6507,7 @@ gimple_return_set_retval (greturn *gs, tree retval)
     case GIMPLE_OMP_TEAMS:                     \
     case GIMPLE_OMP_SECTION:                   \
     case GIMPLE_OMP_MASTER:                    \
+    case GIMPLE_OMP_MASKED:                    \
     case GIMPLE_OMP_TASKGROUP:                 \
     case GIMPLE_OMP_ORDERED:                   \
     case GIMPLE_OMP_CRITICAL:                  \
index c6fd1b89d328c460eda3b1d388fe3b5cae2f28af..be2fd03a46f9d9aeb0f717da970bf3e1867dd716 100644 (file)
@@ -5673,6 +5673,7 @@ is_gimple_stmt (tree t)
     case OMP_SECTION:
     case OMP_SINGLE:
     case OMP_MASTER:
+    case OMP_MASKED:
     case OMP_TASKGROUP:
     case OMP_ORDERED:
     case OMP_CRITICAL:
@@ -10713,6 +10714,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
        case OMP_CLAUSE_PRIORITY:
        case OMP_CLAUSE_GRAINSIZE:
        case OMP_CLAUSE_NUM_TASKS:
+       case OMP_CLAUSE_FILTER:
        case OMP_CLAUSE_HINT:
        case OMP_CLAUSE_ASYNC:
        case OMP_CLAUSE_WAIT:
@@ -10721,9 +10723,20 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
        case OMP_CLAUSE_VECTOR_LENGTH:
        case OMP_CLAUSE_WORKER:
        case OMP_CLAUSE_VECTOR:
-         if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
-                            is_gimple_val, fb_rvalue) == GS_ERROR)
-           remove = true;
+         if (OMP_CLAUSE_OPERAND (c, 0)
+             && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c, 0)))
+           {
+             if (error_operand_p (OMP_CLAUSE_OPERAND (c, 0)))
+               {
+                 remove = true;
+                 break;
+               }
+             /* All these clauses care about value, not a particular decl,
+                so try to force it into a SSA_NAME or fresh temporary.  */
+             OMP_CLAUSE_OPERAND (c, 0)
+               = get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c, 0),
+                                          pre_p, NULL, true);
+           }
          break;
 
        case OMP_CLAUSE_GANG:
@@ -11973,6 +11986,7 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
        case OMP_CLAUSE_NOGROUP:
        case OMP_CLAUSE_THREADS:
        case OMP_CLAUSE_SIMD:
+       case OMP_CLAUSE_FILTER:
        case OMP_CLAUSE_HINT:
        case OMP_CLAUSE_DEFAULTMAP:
        case OMP_CLAUSE_ORDER:
@@ -15633,6 +15647,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 
        case OMP_SECTION:
        case OMP_MASTER:
+       case OMP_MASKED:
        case OMP_ORDERED:
        case OMP_CRITICAL:
        case OMP_SCAN:
@@ -15655,6 +15670,15 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
              case OMP_ORDERED:
                g = gimplify_omp_ordered (*expr_p, body);
                break;
+             case OMP_MASKED:
+               gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p),
+                                          pre_p, ORT_WORKSHARE, OMP_MASKED);
+               gimplify_adjust_omp_clauses (pre_p, body,
+                                            &OMP_MASKED_CLAUSES (*expr_p),
+                                            OMP_MASKED);
+               g = gimple_build_omp_masked (body,
+                                            OMP_MASKED_CLAUSES (*expr_p));
+               break;
              case OMP_CRITICAL:
                gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
                                           pre_p, ORT_WORKSHARE, OMP_CRITICAL);
@@ -16027,6 +16051,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
                  && code != OMP_FOR
                  && code != OACC_LOOP
                  && code != OMP_MASTER
+                 && code != OMP_MASKED
                  && code != OMP_TASKGROUP
                  && code != OMP_ORDERED
                  && code != OMP_PARALLEL
index c69a05329cedfbf4990512b9b0fe24f6189189e1..98133d0fe68994d994058ae61550e4500ccdf73e 100644 (file)
@@ -8507,6 +8507,7 @@ expand_omp_synch (struct omp_region *region)
   si = gsi_last_nondebug_bb (entry_bb);
   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE
              || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_MASTER
+             || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_MASKED
              || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_TASKGROUP
              || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ORDERED
              || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CRITICAL
@@ -10010,6 +10011,7 @@ expand_omp (struct omp_region *region)
          }
          /* FALLTHRU */
        case GIMPLE_OMP_MASTER:
+       case GIMPLE_OMP_MASKED:
        case GIMPLE_OMP_TASKGROUP:
        case GIMPLE_OMP_CRITICAL:
        case GIMPLE_OMP_TEAMS:
@@ -10328,6 +10330,7 @@ omp_make_gimple_edges (basic_block bb, struct omp_region **region,
     case GIMPLE_OMP_SINGLE:
     case GIMPLE_OMP_TEAMS:
     case GIMPLE_OMP_MASTER:
+    case GIMPLE_OMP_MASKED:
     case GIMPLE_OMP_TASKGROUP:
     case GIMPLE_OMP_CRITICAL:
     case GIMPLE_OMP_SECTION:
index 197cc454dcdf80155305fe04f71c7b38641d9265..a9ef894547f1264c5cc839fda1630b34b294b814 100644 (file)
@@ -1568,6 +1568,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx,
        case OMP_CLAUSE_NUM_WORKERS:
        case OMP_CLAUSE_VECTOR_LENGTH:
        case OMP_CLAUSE_DETACH:
+       case OMP_CLAUSE_FILTER:
          if (ctx->outer)
            scan_omp_op (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
          break;
@@ -2005,6 +2006,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx,
        case OMP_CLAUSE__SIMT_:
        case OMP_CLAUSE_IF_PRESENT:
        case OMP_CLAUSE_FINALIZE:
+       case OMP_CLAUSE_FILTER:
        case OMP_CLAUSE__CONDTEMP_:
          break;
 
@@ -3678,6 +3680,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
          case GIMPLE_OMP_SINGLE:
          case GIMPLE_OMP_ORDERED:
          case GIMPLE_OMP_MASTER:
+         case GIMPLE_OMP_MASKED:
          case GIMPLE_OMP_TASK:
          case GIMPLE_OMP_CRITICAL:
            if (is_gimple_call (stmt))
@@ -3688,14 +3691,15 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
                error_at (gimple_location (stmt),
                          "barrier region may not be closely nested inside "
                          "of work-sharing, %<loop%>, %<critical%>, "
-                         "%<ordered%>, %<master%>, explicit %<task%> or "
-                         "%<taskloop%> region");
+                         "%<ordered%>, %<master%>, %<masked%>, explicit "
+                         "%<task%> or %<taskloop%> region");
                return false;
              }
            error_at (gimple_location (stmt),
                      "work-sharing region may not be closely nested inside "
                      "of work-sharing, %<loop%>, %<critical%>, %<ordered%>, "
-                     "%<master%>, explicit %<task%> or %<taskloop%> region");
+                     "%<master%>, %<masked%>, explicit %<task%> or "
+                     "%<taskloop%> region");
            return false;
          case GIMPLE_OMP_PARALLEL:
          case GIMPLE_OMP_TEAMS:
@@ -3710,6 +3714,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
          }
       break;
     case GIMPLE_OMP_MASTER:
+    case GIMPLE_OMP_MASKED:
       for (; ctx != NULL; ctx = ctx->outer)
        switch (gimple_code (ctx->stmt))
          {
@@ -3722,9 +3727,11 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
          case GIMPLE_OMP_SINGLE:
          case GIMPLE_OMP_TASK:
            error_at (gimple_location (stmt),
-                     "%<master%> region may not be closely nested inside "
+                     "%qs region may not be closely nested inside "
                      "of work-sharing, %<loop%>, explicit %<task%> or "
-                     "%<taskloop%> region");
+                     "%<taskloop%> region",
+                     gimple_code (stmt) == GIMPLE_OMP_MASTER
+                     ? "master" : "masked");
            return false;
          case GIMPLE_OMP_PARALLEL:
          case GIMPLE_OMP_TEAMS:
@@ -4329,6 +4336,12 @@ scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
       scan_omp (gimple_omp_body_ptr (stmt), ctx);
       break;
 
+    case GIMPLE_OMP_MASKED:
+      ctx = new_omp_context (stmt, ctx);
+      scan_sharing_clauses (gimple_omp_masked_clauses (stmt), ctx);
+      scan_omp (gimple_omp_body_ptr (stmt), ctx);
+      break;
+
     case GIMPLE_OMP_TASKGROUP:
       ctx = new_omp_context (stmt, ctx);
       scan_sharing_clauses (gimple_omp_taskgroup_clauses (stmt), ctx);
@@ -8924,7 +8937,7 @@ lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 }
 
 
-/* Expand code for an OpenMP master directive.  */
+/* Expand code for an OpenMP master or masked directive.  */
 
 static void
 lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
@@ -8934,9 +8947,20 @@ lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   gbind *bind;
   location_t loc = gimple_location (stmt);
   gimple_seq tseq;
+  tree filter = integer_zero_node;
 
   push_gimplify_context ();
 
+  if (gimple_code (stmt) == GIMPLE_OMP_MASKED)
+    {
+      filter = omp_find_clause (gimple_omp_masked_clauses (stmt),
+                               OMP_CLAUSE_FILTER);
+      if (filter)
+       filter = fold_convert (integer_type_node,
+                              OMP_CLAUSE_FILTER_EXPR (filter));
+      else
+       filter = integer_zero_node;
+    }
   block = make_node (BLOCK);
   bind = gimple_build_bind (NULL, NULL, block);
   gsi_replace (gsi_p, bind, true);
@@ -8944,7 +8968,7 @@ lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 
   bfn_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
   x = build_call_expr_loc (loc, bfn_decl, 0);
-  x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
+  x = build2 (EQ_EXPR, boolean_type_node, x, filter);
   x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
   tseq = NULL;
   gimplify_and_add (x, &tseq);
@@ -14140,6 +14164,7 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
       lower_omp_single (gsi_p, ctx);
       break;
     case GIMPLE_OMP_MASTER:
+    case GIMPLE_OMP_MASKED:
       ctx = maybe_lookup_ctx (stmt);
       gcc_assert (ctx);
       lower_omp_master (gsi_p, ctx);
@@ -14517,6 +14542,7 @@ diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
     case GIMPLE_OMP_SINGLE:
     case GIMPLE_OMP_SECTION:
     case GIMPLE_OMP_MASTER:
+    case GIMPLE_OMP_MASKED:
     case GIMPLE_OMP_ORDERED:
     case GIMPLE_OMP_SCAN:
     case GIMPLE_OMP_CRITICAL:
@@ -14578,6 +14604,7 @@ diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
     case GIMPLE_OMP_SINGLE:
     case GIMPLE_OMP_SECTION:
     case GIMPLE_OMP_MASTER:
+    case GIMPLE_OMP_MASKED:
     case GIMPLE_OMP_ORDERED:
     case GIMPLE_OMP_SCAN:
     case GIMPLE_OMP_CRITICAL:
index 3e55b54bb05b8f471d97965120512f21671f26e0..27613fca2f50e18076a6ba82dd3f216d078993f6 100644 (file)
@@ -1,3 +1,28 @@
+2021-08-16  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backported from master:
+       2021-08-12  Jakub Jelinek  <jakub@redhat.com>
+
+       * c-c++-common/gomp/clauses-1.c (bar): Add tests for combined masked
+       constructs with clauses.
+       * c-c++-common/gomp/clauses-5.c (foo): Add testcase for filter clause.
+       * c-c++-common/gomp/clause-dups-1.c (f1): Likewise.
+       * c-c++-common/gomp/masked-1.c: New test.
+       * c-c++-common/gomp/masked-2.c: New test.
+       * c-c++-common/gomp/masked-combined-1.c: New test.
+       * c-c++-common/gomp/masked-combined-2.c: New test.
+       * c-c++-common/goacc/uninit-if-clause.c: Remove xfails.
+       * g++.dg/gomp/block-11.C: New test.
+       * g++.dg/gomp/tpl-masked-1.C: New test.
+       * g++.dg/gomp/attrs-1.C (bar): Add tests for masked construct and
+       combined masked constructs with clauses in attribute syntax.
+       * g++.dg/gomp/attrs-2.C (bar): Likewise.
+       * gcc.dg/gomp/nesting-1.c (f1, f2): Add tests for masked construct
+       nesting.
+       * gfortran.dg/goacc/host_data-tree.f95: Allow also SSA_NAMEs in if
+       clause.
+       * gfortran.dg/goacc/kernels-tree.f95: Likewise.
+
 2021-08-16  Tobias Burnus  <tobias@codesourcery.com>
 
        Backported from master:
index 7f78d7296810af1d07ea925f59bbaa7bafed3ff5..683ac1b8c45dbce784d2006c8f7f10530ea2de63 100644 (file)
@@ -1,6 +1,5 @@
 /* { dg-do compile } */
 /* { dg-additional-options "-Wuninitialized" } */
-/* { dg-excess-errors "PR70392" { xfail c++ } } */
 
 #include <stdbool.h>
 
@@ -14,25 +13,25 @@ main (void)
   #pragma acc parallel if(l) /* { dg-warning "is used uninitialized" } */
   ;
 
-  #pragma acc parallel if(b) /* { dg-warning "is used uninitialized" "" { xfail c++ } } */
+  #pragma acc parallel if(b) /* { dg-warning "is used uninitialized" } */
   ;
 
   #pragma acc kernels if(l2) /* { dg-warning "is used uninitialized" } */
   ;
 
-  #pragma acc kernels if(b2) /* { dg-warning "is used uninitialized" "" { xfail c++ } } */
+  #pragma acc kernels if(b2) /* { dg-warning "is used uninitialized" } */
   ;
 
   #pragma acc data if(l3) /* { dg-warning "is used uninitialized" } */
   ;
 
-  #pragma acc data if(b3) /* { dg-warning "is used uninitialized" "" { xfail c++ } } */
+  #pragma acc data if(b3) /* { dg-warning "is used uninitialized" } */
   ;
 
   #pragma acc update if(l4) self(i) /* { dg-warning "is used uninitialized" } */
   ;
 
-  #pragma acc update if(b4) self(i2) /* { dg-warning "is used uninitialized" "" { xfail c++ } } */
+  #pragma acc update if(b4) self(i2) /* { dg-warning "is used uninitialized" } */
   ;
 
 }
index 3dde0589f7c5da7fc06f9b3e8684403ee774595a..7b71ad37f9c7742c5ec26d62edac80add524771f 100644 (file)
@@ -203,7 +203,8 @@ f1 (int *p)
   i = p[0]++;
   #pragma omp atomic capture hint(0) hint (0)                  /* { dg-error "too many 'hint' clauses" } */
   i = p[0]++;
-  
+  #pragma omp masked filter (0) filter (0)                     /* { dg-error "too many 'filter' clauses" } */
+  f0 ();
 }
 
 #pragma omp declare simd simdlen (4) simdlen (4)               /* { dg-error "too many 'simdlen' clauses" } */
index 105288ea6ec4321a85c5ff625f262be647df873b..3a70a4f6180f4d0bffe6b17ce8924ceb279bb861 100644 (file)
@@ -273,6 +273,10 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) reduction(+:r) \
     num_threads (nth) proc_bind(spread) copyin(t) allocate (f)
     ;
+  #pragma omp parallel masked \
+    private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) reduction(+:r) \
+    num_threads (nth) proc_bind(spread) copyin(t) allocate (f) filter (d)
+    ;
   #pragma omp taskgroup task_reduction (+:r2) allocate (r2)
   #pragma omp master taskloop \
     private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) final(fi) mergeable priority (pp) \
@@ -280,23 +284,47 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
   for (int i = 0; i < 64; i++)
     ll++;
   #pragma omp taskgroup task_reduction (+:r2) allocate (r2)
+  #pragma omp masked taskloop \
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) final(fi) mergeable priority (pp) \
+    reduction(default, +:r) in_reduction(+:r2) allocate (f) filter (d)
+  for (int i = 0; i < 64; i++)
+    ll++;
+  #pragma omp taskgroup task_reduction (+:r2) allocate (r2)
   #pragma omp master taskloop simd \
     private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) if(simd: i2) final(fi) mergeable priority (pp) \
     safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm) \
     order(concurrent) allocate (f)
   for (int i = 0; i < 64; i++)
     ll++;
+  #pragma omp taskgroup task_reduction (+:r2) allocate (r2)
+  #pragma omp masked taskloop simd \
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) if(simd: i2) final(fi) mergeable priority (pp) \
+    safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm) \
+    order(concurrent) allocate (f) filter (d)
+  for (int i = 0; i < 64; i++)
+    ll++;
   #pragma omp parallel master taskloop \
     private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) final(fi) mergeable priority (pp) \
     reduction(default, +:r) if (parallel: i2) num_threads (nth) proc_bind(spread) copyin(t) allocate (f)
   for (int i = 0; i < 64; i++)
     ll++;
+  #pragma omp parallel masked taskloop \
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) final(fi) mergeable priority (pp) \
+    reduction(default, +:r) if (parallel: i2) num_threads (nth) proc_bind(spread) copyin(t) allocate (f) filter (d)
+  for (int i = 0; i < 64; i++)
+    ll++;
   #pragma omp parallel master taskloop simd \
     private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) if(simd: i2) final(fi) mergeable priority (pp) \
     safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) nontemporal(ntm) if (parallel: i2) num_threads (nth) proc_bind(spread) copyin(t) \
     order(concurrent) allocate (f)
   for (int i = 0; i < 64; i++)
     ll++;
+  #pragma omp parallel masked taskloop simd \
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) if(simd: i2) final(fi) mergeable priority (pp) \
+    safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) nontemporal(ntm) if (parallel: i2) num_threads (nth) proc_bind(spread) copyin(t) \
+    order(concurrent) allocate (f) filter (d)
+  for (int i = 0; i < 64; i++)
+    ll++;
   #pragma omp taskgroup task_reduction (+:r2) allocate (r2)
   #pragma omp master taskloop \
     private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp) \
@@ -304,23 +332,47 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
   for (int i = 0; i < 64; i++)
     ll++;
   #pragma omp taskgroup task_reduction (+:r2) allocate (r2)
+  #pragma omp mastked taskloop \
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp) \
+    reduction(default, +:r) in_reduction(+:r2) filter (d)
+  for (int i = 0; i < 64; i++)
+    ll++;
+  #pragma omp taskgroup task_reduction (+:r2) allocate (r2)
   #pragma omp master taskloop simd \
     private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp) \
     safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm) \
     order(concurrent) allocate (f)
   for (int i = 0; i < 64; i++)
     ll++;
+  #pragma omp taskgroup task_reduction (+:r2) allocate (r2)
+  #pragma omp masked taskloop simd \
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp) \
+    safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm) \
+    order(concurrent) allocate (f) filter (d)
+  for (int i = 0; i < 64; i++)
+    ll++;
   #pragma omp parallel master taskloop \
     private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp) \
     reduction(default, +:r) num_threads (nth) proc_bind(spread) copyin(t) allocate (f)
   for (int i = 0; i < 64; i++)
     ll++;
+  #pragma omp parallel masked taskloop \
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp) \
+    reduction(default, +:r) num_threads (nth) proc_bind(spread) copyin(t) allocate (f) filter (d)
+  for (int i = 0; i < 64; i++)
+    ll++;
   #pragma omp parallel master taskloop simd \
     private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp) \
     safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) nontemporal(ntm) num_threads (nth) proc_bind(spread) copyin(t) \
     order(concurrent) allocate (f)
   for (int i = 0; i < 64; i++)
     ll++;
+  #pragma omp parallel masked taskloop simd \
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp) \
+    safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) nontemporal(ntm) num_threads (nth) proc_bind(spread) copyin(t) \
+    order(concurrent) allocate (f) filter (d)
+  for (int i = 0; i < 64; i++)
+    ll++;
   #pragma omp loop bind(thread) order(concurrent) \
     private (p) lastprivate (l) collapse(1) reduction(+:r)
   for (l = 0; l < 64; ++l)
index 35e16f095b3205a08e1b70332b309c5c0e6aee5c..87e53a94ac39017ce684c6272635ef9bbaf86dbb 100644 (file)
@@ -49,4 +49,6 @@ foo (int *p)
   ;
   #pragma omp critical (baz) hint (2, 3)       /* { dg-error "expected" } */
   ;
+  #pragma omp masked filter (3, 4)             /* { dg-error "expected" } */
+  ;
 }
diff --git a/gcc/testsuite/c-c++-common/gomp/masked-1.c b/gcc/testsuite/c-c++-common/gomp/masked-1.c
new file mode 100644 (file)
index 0000000..36c2e49
--- /dev/null
@@ -0,0 +1,23 @@
+void bar (void);
+
+void
+foo (int x, int *a)
+{
+  #pragma omp masked
+  bar ();
+  #pragma omp masked filter (0)
+  bar ();
+  #pragma omp masked filter (7)
+  bar ();
+  #pragma omp masked filter (x)
+  bar ();
+  #pragma omp masked taskloop simd filter (x) grainsize (12) simdlen (4)
+  for (int i = 0; i < 128; i++)
+    a[i] = i;
+  #pragma omp parallel masked filter (x) firstprivate (x)
+  bar ();
+  #pragma omp masked
+  #pragma omp masked filter (0)
+  #pragma omp masked filter (x)
+  ;
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/masked-2.c b/gcc/testsuite/c-c++-common/gomp/masked-2.c
new file mode 100644 (file)
index 0000000..7230c82
--- /dev/null
@@ -0,0 +1,11 @@
+void bar (void);
+struct S { int s; };
+
+void
+foo (float f, struct S s)
+{
+  #pragma omp masked filter (0.0)      /* { dg-error "integral|integer" } */
+  bar ();
+  #pragma omp masked filter (s)                /* { dg-error "integral|integer" } */
+  bar ();
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/masked-combined-1.c b/gcc/testsuite/c-c++-common/gomp/masked-combined-1.c
new file mode 100644 (file)
index 0000000..0b3ff58
--- /dev/null
@@ -0,0 +1,37 @@
+void bar (int *);
+
+void
+foo (int *a, int f)
+{
+  int i, j, k, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0;
+  #pragma omp parallel masked default(none) private (k) filter (f) firstprivate (f)
+  bar (&k);
+  #pragma omp parallel masked default(none) private (k)
+  bar (&k);
+  #pragma omp parallel default(none) firstprivate(a, f) shared(x, y, z)
+  {
+    #pragma omp masked taskloop reduction (+:x) default(none) firstprivate(a) filter (f)
+    for (i = 0; i < 64; i++)
+      x += a[i];
+    #pragma omp masked taskloop simd reduction (+:y) default(none) firstprivate(a) private (i) filter (f)
+    for (i = 0; i < 64; i++)
+      y += a[i];
+    #pragma omp masked taskloop simd reduction (+:y) default(none) firstprivate(a) private (i)
+    for (i = 0; i < 64; i++)
+      y += a[i];
+    #pragma omp masked taskloop simd collapse(2) reduction (+:z) default(none) firstprivate(a) private (i, j) filter (f)
+    for (j = 0; j < 1; j++)
+      for (i = 0; i < 64; ++i)
+       z += a[i];
+  }
+  #pragma omp parallel masked taskloop reduction (+:u) default(none) firstprivate(a, f) filter (f)
+  for (i = 0; i < 64; i++)
+    u += a[i];
+  #pragma omp parallel masked taskloop simd reduction (+:v) default(none) firstprivate(a, f) filter (f)
+  for (i = 0; i < 64; i++)
+    v += a[i];
+  #pragma omp parallel masked taskloop simd collapse(2) reduction (+:w) default(none) firstprivate(a, f) filter (f)
+  for (j = 0; j < 1; j++)
+    for (i = 0; i < 64; ++i)
+      w += a[i];
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/masked-combined-2.c b/gcc/testsuite/c-c++-common/gomp/masked-combined-2.c
new file mode 100644 (file)
index 0000000..1d63969
--- /dev/null
@@ -0,0 +1,13 @@
+void
+foo (int *a)
+{
+  int i, r = 0, s = 0;
+  #pragma omp taskgroup task_reduction(+:r)
+  #pragma omp parallel masked taskloop in_reduction(+:r)       /* { dg-error "'in_reduction' is not valid for '#pragma omp parallel masked taskloop'" } */
+  for (i = 0; i < 64; i++)
+    r += a[i];
+  #pragma omp taskgroup task_reduction(+:s)
+  #pragma omp parallel masked taskloop simd in_reduction(+:s)  /* { dg-error "'in_reduction' is not valid for '#pragma omp parallel masked taskloop simd'" } */
+  for (i = 0; i < 64; i++)
+    s += a[i];
+}
index 5c7007be8a63a0dd19c782b97834c1a10095ae4c..c3483756dd6edff68c2d805f7c276f933571f543 100644 (file)
@@ -348,6 +348,10 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) reduction(+:r)
     num_threads (nth) proc_bind(spread) copyin(t) allocate (f))]]
     ;
+  [[omp::directive (parallel masked
+    private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) reduction(+:r)
+    num_threads (nth) proc_bind(spread) copyin(t) allocate (f) filter (d))]]
+    ;
   [[omp::directive (parallel
     private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) reduction(+:r)
     num_threads (nth) proc_bind(spread) copyin(t) allocate (f))]]
@@ -358,7 +362,15 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     reduction(default, +:r) in_reduction(+:r2) allocate (f)))]]
   for (int i = 0; i < 64; i++)
     ll++;
+  [[omp::sequence (directive (taskgroup task_reduction (+:r2) allocate (r2)),
+    omp::directive (masked taskloop
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) final(fi) mergeable priority (pp)
+    reduction(default, +:r) in_reduction(+:r2) allocate (f) filter (d)))]]
+  for (int i = 0; i < 64; i++)
+    ll++;
   [[omp::directive (master)]];
+  [[omp::directive (masked)]];
+  [[omp::directive (masked filter (d))]];
   [[omp::sequence (omp::directive (taskgroup task_reduction (+:r2) allocate (r2)),
     directive (master taskloop simd
     private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) if(simd: i2) final(fi) mergeable priority (pp)
@@ -366,23 +378,47 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     order(concurrent) allocate (f)))]]
   for (int i = 0; i < 64; i++)
     ll++;
+  [[omp::sequence (omp::directive (taskgroup task_reduction (+:r2) allocate (r2)),
+    directive (masked taskloop simd
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) if(simd: i2) final(fi) mergeable priority (pp)
+    safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm)
+    order(concurrent) allocate (f) filter (d)))]]
+  for (int i = 0; i < 64; i++)
+    ll++;
   [[omp::directive (parallel master taskloop
     private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) final(fi) mergeable priority (pp)
     reduction(default, +:r) if (parallel: i2) num_threads (nth) proc_bind(spread) copyin(t) allocate (f))]]
   for (int i = 0; i < 64; i++)
     ll++;
+  [[omp::directive (parallel masked taskloop
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) final(fi) mergeable priority (pp)
+    reduction(default, +:r) if (parallel: i2) num_threads (nth) proc_bind(spread) copyin(t) allocate (f) filter (d))]]
+  for (int i = 0; i < 64; i++)
+    ll++;
   [[omp::directive (parallel master taskloop simd
     private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) if(simd: i2) final(fi) mergeable priority (pp)
     safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) nontemporal(ntm) if (parallel: i2) num_threads (nth) proc_bind(spread) copyin(t)
     order(concurrent) allocate (f))]]
   for (int i = 0; i < 64; i++)
     ll++;
+  [[omp::directive (parallel masked taskloop simd
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) if(simd: i2) final(fi) mergeable priority (pp)
+    safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) nontemporal(ntm) if (parallel: i2) num_threads (nth) proc_bind(spread) copyin(t)
+    order(concurrent) allocate (f) filter (d))]]
+  for (int i = 0; i < 64; i++)
+    ll++;
   [[omp::sequence (directive (taskgroup task_reduction (+:r2) allocate (r2)),
     directive (master taskloop
     private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp)
     reduction(default, +:r) in_reduction(+:r2)))]]
   for (int i = 0; i < 64; i++)
     ll++;
+  [[omp::sequence (directive (taskgroup task_reduction (+:r2) allocate (r2)),
+    directive (masked taskloop
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp)
+    reduction(default, +:r) in_reduction(+:r2) filter (d)))]]
+  for (int i = 0; i < 64; i++)
+    ll++;
   [[omp::sequence (omp::directive (taskgroup task_reduction (+:r2) allocate (r2)),
     omp::directive (master taskloop simd
     private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp)
@@ -390,17 +426,35 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     order(concurrent) allocate (f)))]]
   for (int i = 0; i < 64; i++)
     ll++;
+  [[omp::sequence (omp::directive (taskgroup task_reduction (+:r2) allocate (r2)),
+    omp::directive (masked taskloop simd
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp)
+    safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm)
+    order(concurrent) allocate (f) filter (d)))]]
+  for (int i = 0; i < 64; i++)
+    ll++;
   [[omp::directive (parallel master taskloop
     private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp)
     reduction(default, +:r) num_threads (nth) proc_bind(spread) copyin(t) allocate (f))]]
   for (int i = 0; i < 64; i++)
     ll++;
+  [[omp::directive (parallel masked taskloop
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp)
+    reduction(default, +:r) num_threads (nth) proc_bind(spread) copyin(t) allocate (f) filter (d))]]
+  for (int i = 0; i < 64; i++)
+    ll++;
   [[omp::directive (parallel master taskloop simd
     private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp)
     safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) nontemporal(ntm) num_threads (nth) proc_bind(spread) copyin(t)
     order(concurrent) allocate (f))]]
   for (int i = 0; i < 64; i++)
     ll++;
+  [[omp::directive (parallel masked taskloop simd
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp)
+    safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) nontemporal(ntm) num_threads (nth) proc_bind(spread) copyin(t)
+    order(concurrent) allocate (f) filter (d))]]
+  for (int i = 0; i < 64; i++)
+    ll++;
   [[omp::directive (loop bind(thread) order(concurrent)
     private (p) lastprivate (l) collapse(1) reduction(+:r))]]
   for (l = 0; l < 64; ++l)
index 1b59abdbd1e17a6b96e78619f040fd8f20adb1db..b2fba21d71ab6060582b4b7d4a57069e536fbec8 100644 (file)
@@ -348,6 +348,10 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     private (p),firstprivate (f),if (parallel: i2),default(shared),shared(s),reduction(+:r),
     num_threads (nth),proc_bind(spread),copyin(t),allocate (f))]]
     ;
+  [[omp::directive (parallel masked,
+    private (p),firstprivate (f),if (parallel: i2),default(shared),shared(s),reduction(+:r),
+    num_threads (nth),proc_bind(spread),copyin(t),allocate (f),filter(d))]]
+    ;
   [[omp::directive (parallel,
     private (p),firstprivate (f),if (parallel: i2),default(shared),shared(s),reduction(+:r),
     num_threads (nth),proc_bind(spread),copyin(t),allocate (f))]]
@@ -358,7 +362,15 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     reduction(default, +:r),in_reduction(+:r2),allocate (f)))]]
   for (int i = 0; i < 64; i++)
     ll++;
+  [[using omp:sequence (directive (taskgroup, task_reduction (+:r2),allocate (r2)),
+    omp::directive (masked taskloop,
+    private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),grainsize (g),collapse(1),untied, if(taskloop: i1),final(fi),mergeable, priority (pp),
+    reduction(default, +:r),in_reduction(+:r2),allocate (f),filter(d)))]]
+  for (int i = 0; i < 64; i++)
+    ll++;
   [[using omp:directive (master)]];
+  [[using omp:directive (masked)]];
+  [[using omp:directive (masked,filter(d))]];
   [[omp::sequence (omp::directive (taskgroup task_reduction (+:r2),allocate (r2)),
     directive (master taskloop simd,
     private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),grainsize (g),collapse(1),untied,if(taskloop: i1),if(simd: i2),final(fi),mergeable,priority (pp),
@@ -366,23 +378,47 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     order(concurrent),allocate (f)))]]
   for (int i = 0; i < 64; i++)
     ll++;
+  [[omp::sequence (omp::directive (taskgroup task_reduction (+:r2),allocate (r2)),
+    directive (masked taskloop simd,
+    private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),grainsize (g),collapse(1),untied,if(taskloop: i1),if(simd: i2),final(fi),mergeable,priority (pp),
+    safelen(8),simdlen(4),linear(ll: 1),aligned(q: 32),reduction(default, +:r),in_reduction(+:r2),nontemporal(ntm),
+    order(concurrent),allocate (f),filter(d)))]]
+  for (int i = 0; i < 64; i++)
+    ll++;
   [[omp::directive (parallel master taskloop,
     private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),grainsize (g),collapse(1),untied,if(taskloop: i1),final(fi),mergeable,priority (pp),
     reduction(default, +:r),if (parallel: i2),num_threads (nth),proc_bind(spread),copyin(t),allocate (f))]]
   for (int i = 0; i < 64; i++)
     ll++;
+  [[omp::directive (parallel masked taskloop,
+    private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),grainsize (g),collapse(1),untied,if(taskloop: i1),final(fi),mergeable,priority (pp),
+    reduction(default, +:r),if (parallel: i2),num_threads (nth),proc_bind(spread),copyin(t),allocate (f),filter(d))]]
+  for (int i = 0; i < 64; i++)
+    ll++;
   [[omp::directive (parallel master taskloop simd,
     private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),grainsize (g),collapse(1),untied,if(taskloop: i1),if(simd: i2),final(fi),mergeable,priority (pp),
     safelen(8),simdlen(4),linear(ll: 1),aligned(q: 32),reduction(default, +:r),nontemporal(ntm),if (parallel: i2),num_threads (nth),proc_bind(spread),copyin(t),
     order(concurrent),allocate (f))]]
   for (int i = 0; i < 64; i++)
     ll++;
+  [[omp::directive (parallel masked taskloop simd,
+    private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),grainsize (g),collapse(1),untied,if(taskloop: i1),if(simd: i2),final(fi),mergeable,priority (pp),
+    safelen(8),simdlen(4),linear(ll: 1),aligned(q: 32),reduction(default, +:r),nontemporal(ntm),if (parallel: i2),num_threads (nth),proc_bind(spread),copyin(t),
+    order(concurrent),allocate (f),filter(d))]]
+  for (int i = 0; i < 64; i++)
+    ll++;
   [[omp::sequence (directive (taskgroup,task_reduction (+:r2),allocate (r2)),
     directive (master taskloop,
     private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),num_tasks (nta),collapse(1),untied,if(i1),final(fi),mergeable,priority (pp),
     reduction(default, +:r),in_reduction(+:r2)))]]
   for (int i = 0; i < 64; i++)
     ll++;
+  [[omp::sequence (directive (taskgroup,task_reduction (+:r2),allocate (r2)),
+    directive (masked taskloop,
+    private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),num_tasks (nta),collapse(1),untied,if(i1),final(fi),mergeable,priority (pp),
+    reduction(default, +:r),in_reduction(+:r2),filter(d)))]]
+  for (int i = 0; i < 64; i++)
+    ll++;
   [[omp::sequence (omp::directive (taskgroup,task_reduction (+:r2),allocate (r2)),
     omp::directive (master taskloop simd,
     private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),num_tasks (nta),collapse(1),untied,if(i1),final(fi),mergeable,priority (pp),
@@ -390,17 +426,35 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     order(concurrent),allocate (f)))]]
   for (int i = 0; i < 64; i++)
     ll++;
+  [[omp::sequence (omp::directive (taskgroup,task_reduction (+:r2),allocate (r2)),
+    omp::directive (masked taskloop simd,
+    private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),num_tasks (nta),collapse(1),untied,if(i1),final(fi),mergeable,priority (pp),
+    safelen(8),simdlen(4),linear(ll: 1),aligned(q: 32),reduction(default, +:r),in_reduction(+:r2),nontemporal(ntm),
+    order(concurrent),allocate (f),filter(d)))]]
+  for (int i = 0; i < 64; i++)
+    ll++;
   [[omp::directive (parallel master taskloop,
     private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),num_tasks (nta),collapse(1),untied if(i1),final(fi),mergeable priority (pp),
     reduction(default, +:r),num_threads (nth),proc_bind(spread),copyin(t),allocate (f))]]
   for (int i = 0; i < 64; i++)
     ll++;
+  [[omp::directive (parallel masked taskloop,
+    private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),num_tasks (nta),collapse(1),untied if(i1),final(fi),mergeable priority (pp),
+    reduction(default, +:r),num_threads (nth),proc_bind(spread),copyin(t),allocate (f),filter(d))]]
+  for (int i = 0; i < 64; i++)
+    ll++;
   [[omp::directive (parallel master taskloop simd,
     private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),num_tasks (nta),collapse(1),untied if(i1),final(fi),mergeable priority (pp),
     safelen(8),simdlen(4),linear(ll: 1),aligned(q: 32),reduction(default, +:r),nontemporal(ntm),num_threads (nth),proc_bind(spread),copyin(t),
     order(concurrent),allocate (f))]]
   for (int i = 0; i < 64; i++)
     ll++;
+  [[omp::directive (parallel masked taskloop simd,
+    private (p),firstprivate (f),lastprivate (l),shared (s),default(shared),num_tasks (nta),collapse(1),untied if(i1),final(fi),mergeable priority (pp),
+    safelen(8),simdlen(4),linear(ll: 1),aligned(q: 32),reduction(default, +:r),nontemporal(ntm),num_threads (nth),proc_bind(spread),copyin(t),
+    order(concurrent),allocate (f),filter(d))]]
+  for (int i = 0; i < 64; i++)
+    ll++;
   [[omp::directive (loop, bind(thread),order(concurrent),
     private (p),lastprivate (l),collapse(1),reduction(+:r))]]
   for (l = 0; l < 64; ++l)
index c2800061b6e78b2ca523b536021e1a3bf41dafb9..cf4b0d37c3d41f216770f0a66844839a7d7b8075 100644 (file)
@@ -1,3 +1,21 @@
+// { dg-do compile }
+
+void foo()
+{
+  #pragma omp masked
+    {
+      goto bad1;       // { dg-message "from here" }
+    }
+
+  #pragma omp masked filter(1)
+    {
+    bad1:              // { dg-error "jump" }
+                       // { dg-message "exits OpenMP" "" { target *-*-* } .-1 }
+      return;          // { dg-error "invalid exit" }
+    }
+}
+
+// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 7 }
 /* PR c++/24516 */
 /* { dg-do compile } */
 
diff --git a/gcc/testsuite/g++.dg/gomp/tpl-masked-1.C b/gcc/testsuite/g++.dg/gomp/tpl-masked-1.C
new file mode 100644 (file)
index 0000000..8574861
--- /dev/null
@@ -0,0 +1,21 @@
+// { dg-do compile }
+// { dg-options "-fopenmp -fdump-tree-gimple" }
+
+int i;
+
+template <typename T> void f1 (bool p, T t)
+{
+  if (p)
+    {
+      #pragma omp masked filter (t)
+       i++;
+    }
+}
+
+void f2 ()
+{
+  f1<int> (true, 0);
+  f1<long> (true, 0L);
+}
+
+// { dg-final { scan-tree-dump-times "#pragma omp masked" 2 "gimple" } }
index 52fcda741ea0e30ab14bdffb9ad3b536aaffb204..4a471c8fbb69702120a7910f1286d4ecf7e67732 100644 (file)
@@ -19,8 +19,10 @@ f1 (void)
       }
       #pragma omp single       /* { dg-error "may not be closely nested" } */
        ;
-    #pragma omp master         /* { dg-error "may not be closely nested" } */
-      ;
+      #pragma omp master       /* { dg-error "may not be closely nested" } */
+       ;
+      #pragma omp masked       /* { dg-error "may not be closely nested" } */
+       ;
       #pragma omp barrier      /* { dg-error "may not be closely nested" } */
     }
   #pragma omp sections
@@ -49,6 +51,11 @@ f1 (void)
       ;
   }
   #pragma omp sections
+  {
+    #pragma omp masked         /* { dg-error "may not be closely nested" } */
+      ;
+  }
+  #pragma omp sections
   {
     #pragma omp section
       ;
@@ -81,6 +88,9 @@ f1 (void)
     #pragma omp section
     #pragma omp master         /* { dg-error "may not be closely nested" } */
       ;
+    #pragma omp section
+    #pragma omp masked         /* { dg-error "may not be closely nested" } */
+      ;
   }
   #pragma omp single
   {
@@ -97,6 +107,8 @@ f1 (void)
       ;
     #pragma omp master         /* { dg-error "may not be closely nested" } */
       ;
+    #pragma omp masked         /* { dg-error "may not be closely nested" } */
+      ;
     #pragma omp barrier                /* { dg-error "may not be closely nested" } */
   }
   #pragma omp master
@@ -116,6 +128,23 @@ f1 (void)
       ;
     #pragma omp barrier                /* { dg-error "may not be closely nested" } */
   }
+  #pragma omp masked filter (1)
+  {
+    #pragma omp for            /* { dg-error "may not be closely nested" } */
+    for (j = 0; j < 3; j++)
+      ;
+    #pragma omp sections       /* { dg-error "may not be closely nested" } */
+    {
+      ;
+    #pragma omp section
+      ;
+    }
+    #pragma omp single         /* { dg-error "may not be closely nested" } */
+      ;
+    #pragma omp master
+      ;
+    #pragma omp barrier                /* { dg-error "may not be closely nested" } */
+  }
   #pragma omp task
   {
     #pragma omp for            /* { dg-error "may not be closely nested" } */
@@ -131,6 +160,8 @@ f1 (void)
       ;
     #pragma omp master         /* { dg-error "may not be closely nested" } */
       ;
+    #pragma omp masked         /* { dg-error "may not be closely nested" } */
+      ;
     #pragma omp barrier                /* { dg-error "may not be closely nested" } */
   }
   #pragma omp parallel
@@ -148,6 +179,8 @@ f1 (void)
       ;
     #pragma omp master
       ;
+    #pragma omp masked
+      ;
     #pragma omp barrier
   }
 }
@@ -171,6 +204,8 @@ f2 (void)
       ;
     #pragma omp master
       ;
+    #pragma omp masked
+      ;
     #pragma omp barrier                /* { dg-error "may not be closely nested" } */
   }
 }
index 558e80014d758b3ffc9edb991a8af7a7260a5166..e575890c9fcc6ba393ff222a0a7cf9fc291909af 100644 (file)
@@ -12,12 +12,12 @@ program test
   !$acc host_data use_device(p) if (p == 42)
   ! { dg-final { scan-tree-dump-times "(?n)D\\.\[0-9\]+ = \\*p == 42;$" 1 "original" } }
   ! { dg-final { scan-tree-dump-times "(?n)#pragma acc host_data use_device_ptr\\(p\\) if\\(D\\.\[0-9\]+\\)$" 1 "original" } }
-  ! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_host_data use_device_ptr\\(p\\) if\\(D\\.\[0-9\]+\\)$" 1 "gimple" } }
+  ! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_host_data use_device_ptr\\(p\\) if\\((?:D\\.|_)\[0-9\]+\\)$" 1 "gimple" } }
   !$acc end host_data
 
   !$acc host_data use_device(p) if_present if (p == 43)
   ! { dg-final { scan-tree-dump-times "(?n)D\\.\[0-9\]+ = \\*p == 43;$" 1 "original" } }
   ! { dg-final { scan-tree-dump-times "(?n)#pragma acc host_data use_device_ptr\\(p\\) if\\(D\\.\[0-9\]+\\) if_present$" 1 "original" } }
-  ! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_host_data use_device_ptr\\(if_present:p\\) if\\(D\\.\[0-9\]+\\) if_present$" 1 "gimple" } }
+  ! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_host_data use_device_ptr\\(if_present:p\\) if\\((?:D\\.|_)\[0-9\]+\\) if_present$" 1 "gimple" } }
   !$acc end host_data
 end program test
index 63ef7e17a9e4e88c90ffe4033bb149194eaa6fba..688ed0a7dc37581f5c945ee63c602e3040bc320f 100644 (file)
@@ -37,5 +37,5 @@ end program test
 
 ! { dg-final { scan-tree-dump-times "map\\(force_deviceptr:u\\)" 1 "original" } } 
 
-! { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_data_kernels if\(D\.[0-9]+\)$} 1 "omp_oacc_kernels_decompose" } }
-! { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_parallel_kernels_gang_single num_gangs\(1\) if\(D\.[0-9]+\) async\(-1\)$} 1 "omp_oacc_kernels_decompose" } }
+! { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_data_kernels if\((?:D\.|_)[0-9]+\)$} 1 "omp_oacc_kernels_decompose" } }
+! { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_parallel_kernels_gang_single num_gangs\(1\) if\((?:D\.|_)[0-9]+\) async\(-1\)$} 1 "omp_oacc_kernels_decompose" } }
index c3e590b11ac31770e541c2e863b4fc9e291c6d8c..c98cca7be85f62a246691a5b1cba4572389e9950 100644 (file)
@@ -475,6 +475,9 @@ enum omp_clause_code {
   /* OpenMP clause: bind (binding).  */
   OMP_CLAUSE_BIND,
 
+  /* OpenMP clause: filter (integer-expression).  */
+  OMP_CLAUSE_FILTER,
+
   /* Internally used only clause, holding SIMD uid.  */
   OMP_CLAUSE__SIMDUID_,
 
index d45d2bbd18e2b811629f67286a815daa1aa5d4ae..938a4af3445bab532ae8a09e9b15482b9a3c3730 100644 (file)
@@ -1677,6 +1677,12 @@ remap_gimple_stmt (gimple *stmt, copy_body_data *id)
          copy = gimple_build_omp_master (s1);
          break;
 
+       case GIMPLE_OMP_MASKED:
+         s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
+         copy = gimple_build_omp_masked
+                  (s1, gimple_omp_masked_clauses (stmt));
+         break;
+
        case GIMPLE_OMP_TASKGROUP:
          s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
          copy = gimple_build_omp_taskgroup
@@ -4560,6 +4566,7 @@ estimate_num_insns (gimple *stmt, eni_weights *weights)
     case GIMPLE_OMP_TASK:
     case GIMPLE_OMP_CRITICAL:
     case GIMPLE_OMP_MASTER:
+    case GIMPLE_OMP_MASKED:
     case GIMPLE_OMP_TASKGROUP:
     case GIMPLE_OMP_ORDERED:
     case GIMPLE_OMP_SCAN:
index 0c30657b8448e30b5b95e15d1bf807b1363e635f..d6c8177bcc969d7e40df1658713e2748abc154de 100644 (file)
@@ -1375,6 +1375,7 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
        case OMP_CLAUSE_GRAINSIZE:
        case OMP_CLAUSE_NUM_TASKS:
        case OMP_CLAUSE_HINT:
+       case OMP_CLAUSE_FILTER:
        case OMP_CLAUSE_NUM_GANGS:
        case OMP_CLAUSE_NUM_WORKERS:
        case OMP_CLAUSE_VECTOR_LENGTH:
@@ -1783,6 +1784,7 @@ convert_nonlocal_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
 
     case GIMPLE_OMP_SECTION:
     case GIMPLE_OMP_MASTER:
+    case GIMPLE_OMP_MASKED:
     case GIMPLE_OMP_ORDERED:
     case GIMPLE_OMP_SCAN:
       walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
@@ -2152,6 +2154,7 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
        case OMP_CLAUSE_GRAINSIZE:
        case OMP_CLAUSE_NUM_TASKS:
        case OMP_CLAUSE_HINT:
+       case OMP_CLAUSE_FILTER:
        case OMP_CLAUSE_NUM_GANGS:
        case OMP_CLAUSE_NUM_WORKERS:
        case OMP_CLAUSE_VECTOR_LENGTH:
@@ -2515,6 +2518,7 @@ convert_local_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
 
     case GIMPLE_OMP_SECTION:
     case GIMPLE_OMP_MASTER:
+    case GIMPLE_OMP_MASKED:
     case GIMPLE_OMP_ORDERED:
     case GIMPLE_OMP_SCAN:
       walk_body (convert_local_reference_stmt, convert_local_reference_op,
@@ -3025,6 +3029,7 @@ convert_gimple_call (gimple_stmt_iterator *gsi, bool *handled_ops_p,
     case GIMPLE_OMP_SECTION:
     case GIMPLE_OMP_SINGLE:
     case GIMPLE_OMP_MASTER:
+    case GIMPLE_OMP_MASKED:
     case GIMPLE_OMP_TASKGROUP:
     case GIMPLE_OMP_ORDERED:
     case GIMPLE_OMP_SCAN:
index 81005e4712e9a3b3a922040ec762ee59b4977491..0c3621f20a43ebc9c7597a3351f9182ade5d8d11 100644 (file)
@@ -1136,6 +1136,13 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
       pp_right_paren (pp);
       break;
 
+    case OMP_CLAUSE_FILTER:
+      pp_string (pp, "filter(");
+      dump_generic_node (pp, OMP_CLAUSE_FILTER_EXPR (clause),
+                        spc, flags, false);
+      pp_right_paren (pp);
+      break;
+
     case OMP_CLAUSE_DEFAULTMAP:
       pp_string (pp, "defaultmap(");
       switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (clause))
@@ -3637,6 +3644,11 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags,
       pp_string (pp, "#pragma omp master");
       goto dump_omp_body;
 
+    case OMP_MASKED:
+      pp_string (pp, "#pragma omp masked");
+      dump_omp_clauses (pp, OMP_MASKED_CLAUSES (node), spc, flags);
+      goto dump_omp_body;
+
     case OMP_TASKGROUP:
       pp_string (pp, "#pragma omp taskgroup");
       dump_omp_clauses (pp, OMP_TASKGROUP_CLAUSES (node), spc, flags);
index c0462a9ea848f60ba2689353bc19f28231a3d9bc..c1d64ec732e311641667f17f7b7731e0f1b3758f 100644 (file)
@@ -351,6 +351,7 @@ unsigned const char omp_clause_num_ops[] =
   0, /* OMP_CLAUSE_DEFAULTMAP  */
   0, /* OMP_CLAUSE_ORDER  */
   0, /* OMP_CLAUSE_BIND  */
+  1, /* OMP_CLAUSE_FILTER  */
   1, /* OMP_CLAUSE__SIMDUID_  */
   0, /* OMP_CLAUSE__SIMT_  */
   0, /* OMP_CLAUSE_INDEPENDENT  */
@@ -439,6 +440,7 @@ const char * const omp_clause_code_name[] =
   "defaultmap",
   "order",
   "bind",
+  "filter",
   "_simduid_",
   "_simt_",
   "independent",
@@ -12267,6 +12269,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
        case OMP_CLAUSE_GRAINSIZE:
        case OMP_CLAUSE_NUM_TASKS:
        case OMP_CLAUSE_HINT:
+       case OMP_CLAUSE_FILTER:
        case OMP_CLAUSE_TO_DECLARE:
        case OMP_CLAUSE_LINK:
        case OMP_CLAUSE_DETACH:
index eda050bdc55c68fa11ac5526e3a3f618aad0df4b..ff8b5e6503cbf55bb7355603d0c6f3aed462125a 100644 (file)
@@ -1218,6 +1218,11 @@ DEFTREECODE (OMP_SINGLE, "omp_single", tcc_statement, 2)
    Operand 1: OMP_SINGLE_CLAUSES: List of clauses.  */
 DEFTREECODE (OMP_TASKGROUP, "omp_taskgroup", tcc_statement, 2)
 
+/* OpenMP - #pragma omp masked
+   Operand 0: OMP_MASKED_BODY: Masked section body.
+   Operand 1: OMP_MASKED_CLAUSES: List of clauses.  */
+DEFTREECODE (OMP_MASKED, "omp_masked", tcc_statement, 2)
+
 /* OpenMP - #pragma omp scan
    Operand 0: OMP_SCAN_BODY: Scan body.
    Operand 1: OMP_SCAN_CLAUSES: List of clauses.  */
index bc7405c087d713f7dce5591d9c424d633dd8f3a4..38f299ebe8c938d966ba709b9c1a88b19fb38da2 100644 (file)
@@ -1428,6 +1428,9 @@ class auto_suppress_location_wrappers
 
 #define OMP_MASTER_BODY(NODE)     TREE_OPERAND (OMP_MASTER_CHECK (NODE), 0)
 
+#define OMP_MASKED_BODY(NODE)     TREE_OPERAND (OMP_MASKED_CHECK (NODE), 0)
+#define OMP_MASKED_CLAUSES(NODE)   TREE_OPERAND (OMP_MASKED_CHECK (NODE), 1)
+
 #define OMP_TASKGROUP_BODY(NODE)   TREE_OPERAND (OMP_TASKGROUP_CHECK (NODE), 0)
 #define OMP_TASKGROUP_CLAUSES(NODE) \
   TREE_OPERAND (OMP_TASKGROUP_CHECK (NODE), 1)
@@ -1513,6 +1516,11 @@ class auto_suppress_location_wrappers
 #define OMP_MASTER_COMBINED(NODE) \
   (OMP_MASTER_CHECK (NODE)->base.private_flag)
 
+/* True on an OMP_MASKED statement if it represents an explicit
+   combined masked constructs.  */
+#define OMP_MASKED_COMBINED(NODE) \
+  (OMP_MASKED_CHECK (NODE)->base.private_flag)
+
 /* Memory order for OMP_ATOMIC*.  */
 #define OMP_ATOMIC_MEMORY_ORDER(NODE) \
   (TREE_RANGE_CHECK (NODE, OMP_ATOMIC, \
@@ -1597,6 +1605,8 @@ class auto_suppress_location_wrappers
   OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_NUM_TASKS), 0)
 #define OMP_CLAUSE_HINT_EXPR(NODE) \
   OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_HINT), 0)
+#define OMP_CLAUSE_FILTER_EXPR(NODE) \
+  OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_FILTER), 0)
 
 #define OMP_CLAUSE_GRAINSIZE_EXPR(NODE) \
   OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_GRAINSIZE),0)
index d0f711777554a4bab1db5ec6c020dc51216c6b88..29794c7442d36c5589a246175d90d54c1a307a61 100644 (file)
@@ -1,3 +1,10 @@
+2021-08-16  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backported from master:
+       2021-08-12  Jakub Jelinek  <jakub@redhat.com>
+
+       * testsuite/libgomp.c-c++-common/masked-1.c: New test.
+
 2021-08-16  Tobias Burnus  <tobias@codesourcery.com>
 
        Backported from master:
diff --git a/libgomp/testsuite/libgomp.c-c++-common/masked-1.c b/libgomp/testsuite/libgomp.c-c++-common/masked-1.c
new file mode 100644 (file)
index 0000000..4ba259c
--- /dev/null
@@ -0,0 +1,83 @@
+#include <omp.h>
+#include <stdlib.h>
+
+void
+foo (int x, int *a)
+{
+  #pragma omp masked
+  {
+    if (omp_get_thread_num () != 0)
+      abort ();
+    a[128]++;
+  }
+  #pragma omp masked filter (0)
+  {
+    if (omp_get_thread_num () != 0)
+      abort ();
+    a[129]++;
+  }
+  #pragma omp masked filter (7)
+  {
+    if (omp_get_thread_num () != 7)
+      abort ();
+    a[130]++;
+  }
+  #pragma omp masked filter (x)
+  {
+    if (omp_get_thread_num () != x)
+      abort ();
+    a[131]++;
+  }
+  #pragma omp masked taskloop simd filter (x) grainsize (12) simdlen (4)
+  for (int i = 0; i < 128; i++)
+    a[i] += i;
+}
+
+int
+main ()
+{
+  int a[136] = {};
+  #pragma omp parallel num_threads (4)
+  foo (4, a);
+  for (int i = 0; i < 128; i++)
+    if (a[i])
+      abort ();
+  if (a[128] != 1 || a[129] != 1 || a[130] || a[131])
+    abort ();
+  #pragma omp parallel num_threads (4)
+  foo (3, a);
+  for (int i = 0; i < 128; i++)
+    if (a[i] != i)
+      abort ();
+  if (a[128] != 2 || a[129] != 2 || a[130] || a[131] != 1)
+    abort ();
+  #pragma omp parallel num_threads (8)
+  foo (8, a);
+  for (int i = 0; i < 128; i++)
+    if (a[i] != i)
+      abort ();
+  if (a[128] != 3 || a[129] != 3 || a[130] != 1 || a[131] != 1)
+    abort ();
+  #pragma omp parallel num_threads (8)
+  foo (6, a);
+  for (int i = 0; i < 128; i++)
+    if (a[i] != 2 * i)
+      abort ();
+  if (a[128] != 4 || a[129] != 4 || a[130] != 2 || a[131] != 2)
+    abort ();
+  for (int i = 0; i < 8; i++)
+    a[i] = 0;
+  /* The filter expression can evaluate to different values in different threads.  */
+  #pragma omp parallel masked num_threads (8) filter (omp_get_thread_num () + 1)
+  a[omp_get_thread_num ()]++;
+  for (int i = 0; i < 8; i++)
+    if (a[i])
+      abort ();
+  /* And multiple threads can be filtered.  */
+  #pragma omp parallel masked num_threads (8) filter (omp_get_thread_num () & ~1)
+  a[omp_get_thread_num ()]++;
+  for (int i = 0; i < 8; i++)
+    if (a[i] != !(i & 1))
+      abort ();
+  return 0;
+}