public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/omp/gcc-12] openmp: Add support for inoutset depend-kind
@ 2022-07-04 20:11 Tobias Burnus
  0 siblings, 0 replies; only message in thread
From: Tobias Burnus @ 2022-07-04 20:11 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:3062a5dd41c05331cf37f4fc49f677c98cd1227e

commit 3062a5dd41c05331cf37f4fc49f677c98cd1227e
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Mon Jul 4 21:32:48 2022 +0200

    openmp: Add support for inoutset depend-kind
    
    This patch adds support for inoutset depend-kind in depend
    clauses.  It is very similar to the in depend-kind in that
    a task with a dependency with that depend-kind is dependent
    on all previously created sibling tasks with matching address
    unless they have the same depend-kind.
    In the in depend-kind case everything is dependent except
    for in -> in dependency, for inoutset everything is
    dependent except for inoutset -> inoutset dependency.
    mutexinoutset is also similar (everything is dependent except
    for mutexinoutset -> mutexinoutset dependency), but there is
    also the additional restriction that only one task with
    mutexinoutset for each address can be scheduled at once (i.e.
    mutual exclusitivty).  For now we support mutexinoutset
    the same as inout/out, but the inoutset support is full.
    
    In order not to bump the ABI for dependencies each time
    (we've bumped it already once, the old ABI supports only
    inout/out and in depend-kind, the new ABI supports
    inout/out, mutexinoutset, in and depobj), this patch arranges
    for inoutset to be at least for the time being always handled
    as if it was specified through depobj even when it is not.
    So it uses the new ABI for that and inoutset are represented
    like depobj - pointer to a pair of pointers where the first one
    will be the actual address of the object mentioned in depend
    clause and second pointer will be (void *) GOMP_DEPEND_INOUTSET.
    
    2022-05-17  Jakub Jelinek  <jakub@redhat.com>
    
    gcc/
            * tree-core.h (enum omp_clause_depend_kind): Add
            OMP_CLAUSE_DEPEND_INOUTSET.
            * tree-pretty-print.cc (dump_omp_clause): Handle
            OMP_CLAUSE_DEPEND_INOUTSET.
            * gimplify.cc (gimplify_omp_depend): Likewise.
            * omp-low.cc (lower_depend_clauses): Likewise.
    gcc/c-family/
            * c-omp.cc (c_finish_omp_depobj): Handle
            OMP_CLAUSE_DEPEND_INOUTSET.
    gcc/c/
            * c-parser.cc (c_parser_omp_clause_depend): Parse
            inoutset depend-kind.
            (c_parser_omp_depobj): Likewise.
    gcc/cp/
            * parser.cc (cp_parser_omp_clause_depend): Parse
            inoutset depend-kind.
            (cp_parser_omp_depobj): Likewise.
            * cxx-pretty-print.cc (cxx_pretty_printer::statement): Handle
            OMP_CLAUSE_DEPEND_INOUTSET.
    gcc/testsuite/
            * c-c++-common/gomp/all-memory-1.c (boo): Add test with
            inoutset depend-kind.
            * c-c++-common/gomp/all-memory-2.c (boo): Likewise.
            * c-c++-common/gomp/depobj-1.c (f1): Likewise.
            (f2): Adjusted expected diagnostics.
            * g++.dg/gomp/depobj-1.C (f4): Adjust expected diagnostics.
    include/
            * gomp-constants.h (GOMP_DEPEND_INOUTSET): Define.
    libgomp/
            * libgomp.h (struct gomp_task_depend_entry): Change is_in type
            from bool to unsigned char.
            * task.c (gomp_task_handle_depend): Handle GOMP_DEPEND_INOUTSET.
            Ignore dependencies where
            task->depend[i].is_in && task->depend[i].is_in == ent->is_in
            rather than just task->depend[i].is_in && ent->is_in.  Remember
            whether GOMP_DEPEND_IN loop is needed and guard the loop with that
            conditional.
            (gomp_task_maybe_wait_for_dependencies): Handle GOMP_DEPEND_INOUTSET.
            Ignore dependencies where elem.is_in && elem.is_in == ent->is_in
            rather than just elem.is_in && ent->is_in.
            * testsuite/libgomp.c-c++-common/depend-1.c (test): Add task with
            inoutset depend-kind.
            * testsuite/libgomp.c-c++-common/depend-2.c (test): Likewise.
            * testsuite/libgomp.c-c++-common/depend-3.c (test): Likewise.
            * testsuite/libgomp.c-c++-common/depend-inoutset-1.c: New test.
    
    (cherry picked from commit 2c16eb3157f86ae561468c540caf8eb326106b5f)

Diff:
---
 gcc/ChangeLog.omp                                  |  12 ++
 gcc/c-family/ChangeLog.omp                         |  10 +-
 gcc/c-family/c-omp.cc                              |   4 +
 gcc/c/ChangeLog.omp                                |   9 ++
 gcc/c/c-parser.cc                                  |  10 +-
 gcc/cp/ChangeLog.omp                               |  11 ++
 gcc/cp/cxx-pretty-print.cc                         |   3 +
 gcc/cp/parser.cc                                   |   8 +-
 gcc/gimplify.cc                                    | 100 +++++++++++--
 gcc/omp-low.cc                                     |  44 +++++-
 gcc/testsuite/ChangeLog.omp                        |  12 ++
 gcc/testsuite/c-c++-common/gomp/all-memory-1.c     |   2 +
 gcc/testsuite/c-c++-common/gomp/all-memory-2.c     |   2 +
 gcc/testsuite/c-c++-common/gomp/depobj-1.c         |   5 +-
 gcc/testsuite/g++.dg/gomp/depobj-1.C               |   2 +-
 gcc/tree-core.h                                    |   1 +
 gcc/tree-pretty-print.cc                           |   3 +
 include/ChangeLog.omp                              |   9 +-
 include/gomp-constants.h                           |   1 +
 libgomp/ChangeLog.omp                              |  22 +++
 libgomp/libgomp.h                                  |   4 +-
 libgomp/task.c                                     |  33 +++--
 libgomp/testsuite/libgomp.c-c++-common/depend-1.c  |   7 +-
 libgomp/testsuite/libgomp.c-c++-common/depend-2.c  |   7 +-
 libgomp/testsuite/libgomp.c-c++-common/depend-3.c  |   7 +-
 .../libgomp.c-c++-common/depend-inoutset-1.c       | 164 +++++++++++++++++++++
 26 files changed, 448 insertions(+), 44 deletions(-)

diff --git a/gcc/ChangeLog.omp b/gcc/ChangeLog.omp
index 6e059579a81..1c4634d09ab 100644
--- a/gcc/ChangeLog.omp
+++ b/gcc/ChangeLog.omp
@@ -1,3 +1,15 @@
+2022-07-04  Tobias Burnus  <tobias@codesourcery.com>
+
+	Backport from mainline:
+	2022-05-17  Jakub Jelinek  <jakub@redhat.com>
+
+	* tree-core.h (enum omp_clause_depend_kind): Add
+	OMP_CLAUSE_DEPEND_INOUTSET.
+	* tree-pretty-print.cc (dump_omp_clause): Handle
+	OMP_CLAUSE_DEPEND_INOUTSET.
+	* gimplify.cc (gimplify_omp_depend): Likewise.
+	* omp-low.cc (lower_depend_clauses): Likewise.
+
 2022-06-17  Andrew Stubbs  <ams@codesourcery.com>
 
 	* config/gcn/gcn.c (unified_shared_memory_enabled): New variable.
diff --git a/gcc/c-family/ChangeLog.omp b/gcc/c-family/ChangeLog.omp
index e46a556ada5..f4d2dce3f45 100644
--- a/gcc/c-family/ChangeLog.omp
+++ b/gcc/c-family/ChangeLog.omp
@@ -1,3 +1,11 @@
+2022-07-04  Tobias Burnus  <tobias@codesourcery.com>
+
+	Backport from mainline:
+	2022-05-17  Jakub Jelinek  <jakub@redhat.com>
+
+	* c-omp.cc (c_finish_omp_depobj): Handle
+	OMP_CLAUSE_DEPEND_INOUTSET.
+
 2022-04-15  Kwok Cheung Yeung  <kcy@codesourcery.com>
 
 	gcc/c-family/
@@ -44,7 +52,7 @@
 	(check_and_annotate_for_loop): Use the new helper function.
 
 2020-08-30  Sandra Loosemore  <sandra@codesourcery.com>
-    
+
 	* c-omp.cc (annotate_for_loop): Move initializer processing...
 	(check_and_annotate_for_loop): ... to here.  Allow the loop
 	variable as either operand to the condition.
diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc
index a6fea51d46e..d71d5e446be 100644
--- a/gcc/c-family/c-omp.cc
+++ b/gcc/c-family/c-omp.cc
@@ -739,6 +739,7 @@ c_finish_omp_depobj (location_t loc, tree depobj,
 	case OMP_CLAUSE_DEPEND_OUT:
 	case OMP_CLAUSE_DEPEND_INOUT:
 	case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
+	case OMP_CLAUSE_DEPEND_INOUTSET:
 	  kind = OMP_CLAUSE_DEPEND_KIND (clause);
 	  t = OMP_CLAUSE_DECL (clause);
 	  gcc_assert (t);
@@ -797,6 +798,9 @@ c_finish_omp_depobj (location_t loc, tree depobj,
     case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
       k = GOMP_DEPEND_MUTEXINOUTSET;
       break;
+    case OMP_CLAUSE_DEPEND_INOUTSET:
+      k = GOMP_DEPEND_INOUTSET;
+      break;
     case OMP_CLAUSE_DEPEND_LAST:
       k = -1;
       break;
diff --git a/gcc/c/ChangeLog.omp b/gcc/c/ChangeLog.omp
index 77b7602ad69..51d735341f2 100644
--- a/gcc/c/ChangeLog.omp
+++ b/gcc/c/ChangeLog.omp
@@ -1,3 +1,12 @@
+2022-07-04  Tobias Burnus  <tobias@codesourcery.com>
+
+	Backport from mainline:
+	2022-05-17  Jakub Jelinek  <jakub@redhat.com>
+
+	* c-parser.cc (c_parser_omp_clause_depend): Parse
+	inoutset depend-kind.
+	(c_parser_omp_depobj): Likewise.
+
 2022-06-30  Tobias Burnus  <tobias@codesourcery.com>
 
 	* c-parser.cc (c_parser_omp_requires): Add missing %<...%> in error.
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 5cabcb684e9..903063d4c1e 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -16309,7 +16309,7 @@ c_parser_omp_clause_affinity (c_parser *parser, tree list)
    depend ( depend-modifier , depend-kind: variable-list )
 
    depend-kind:
-     in | out | inout | mutexinoutset | depobj
+     in | out | inout | mutexinoutset | depobj | inoutset
 
    depend-modifier:
      iterator ( iterators-definition )  */
@@ -16341,6 +16341,8 @@ c_parser_omp_clause_depend (c_parser *parser, tree list)
 	kind = OMP_CLAUSE_DEPEND_IN;
       else if (strcmp ("inout", p) == 0)
 	kind = OMP_CLAUSE_DEPEND_INOUT;
+      else if (strcmp ("inoutset", p) == 0)
+	kind = OMP_CLAUSE_DEPEND_INOUTSET;
       else if (strcmp ("mutexinoutset", p) == 0)
 	kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
       else if (strcmp ("out", p) == 0)
@@ -19315,12 +19317,14 @@ c_parser_omp_depobj (c_parser *parser)
 		    kind = OMP_CLAUSE_DEPEND_INOUT;
 		  else if (!strcmp ("mutexinoutset", p2))
 		    kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
+		  else if (!strcmp ("inoutset", p2))
+		    kind = OMP_CLAUSE_DEPEND_INOUTSET;
 		}
 	      if (kind == OMP_CLAUSE_DEPEND_SOURCE)
 		{
 		  clause = error_mark_node;
-		  error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%> or "
-				    "%<mutexinoutset%>");
+		  error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%>, "
+				    "%<mutexinoutset%> or %<inoutset%>");
 		}
 	      c_parens.skip_until_found_close (parser);
 	    }
diff --git a/gcc/cp/ChangeLog.omp b/gcc/cp/ChangeLog.omp
index 5704076ab70..924e0a3ec2e 100644
--- a/gcc/cp/ChangeLog.omp
+++ b/gcc/cp/ChangeLog.omp
@@ -1,3 +1,14 @@
+2022-07-04  Tobias Burnus  <tobias@codesourcery.com>
+
+	Backport from mainline:
+	2022-05-17  Jakub Jelinek  <jakub@redhat.com>
+
+	* parser.cc (cp_parser_omp_clause_depend): Parse
+	inoutset depend-kind.
+	(cp_parser_omp_depobj): Likewise.
+	* cxx-pretty-print.cc (cxx_pretty_printer::statement): Handle
+	OMP_CLAUSE_DEPEND_INOUTSET.
+
 2022-07-04  Tobias Burnus  <tobias@codesourcery.com>
 
 	Backport from mainline:
diff --git a/gcc/cp/cxx-pretty-print.cc b/gcc/cp/cxx-pretty-print.cc
index 4f9a090e520..7e4db2e413b 100644
--- a/gcc/cp/cxx-pretty-print.cc
+++ b/gcc/cp/cxx-pretty-print.cc
@@ -2139,6 +2139,9 @@ cxx_pretty_printer::statement (tree t)
 	      case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
 		pp_cxx_ws_string (this, " update(mutexinoutset)");
 		break;
+	      case OMP_CLAUSE_DEPEND_INOUTSET:
+		pp_cxx_ws_string (this, " update(inoutset)");
+		break;
 	      case OMP_CLAUSE_DEPEND_LAST:
 		pp_cxx_ws_string (this, " destroy");
 		break;
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 11193b9d6cd..957206cdc0c 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -39553,6 +39553,8 @@ cp_parser_omp_clause_depend (cp_parser *parser, tree list, location_t loc)
 	kind = OMP_CLAUSE_DEPEND_IN;
       else if (strcmp ("inout", p) == 0)
 	kind = OMP_CLAUSE_DEPEND_INOUT;
+      else if (strcmp ("inoutset", p) == 0)
+	kind = OMP_CLAUSE_DEPEND_INOUTSET;
       else if (strcmp ("mutexinoutset", p) == 0)
 	kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
       else if (strcmp ("out", p) == 0)
@@ -41856,12 +41858,14 @@ cp_parser_omp_depobj (cp_parser *parser, cp_token *pragma_tok)
 		    kind = OMP_CLAUSE_DEPEND_INOUT;
 		  else if (!strcmp ("mutexinoutset", p2))
 		    kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
+		  else if (!strcmp ("inoutset", p2))
+		    kind = OMP_CLAUSE_DEPEND_INOUTSET;
 		}
 	      if (kind == OMP_CLAUSE_DEPEND_SOURCE)
 		{
 		  clause = error_mark_node;
-		  error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%> or "
-				    "%<mutexinoutset%>");
+		  error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%>, "
+				    "%<mutexinoutset%> or %<inoutset%>");
 		}
 	      if (!c_parens.require_close (parser))
 		cp_parser_skip_to_closing_parenthesis (parser,
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index e0af57058d8..f7614ae6caa 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -8302,9 +8302,9 @@ gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
 {
   tree c;
   gimple *g;
-  size_t n[4] = { 0, 0, 0, 0 };
-  bool unused[4];
-  tree counts[4] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
+  size_t n[5] = { 0, 0, 0, 0, 0 };
+  bool unused[5];
+  tree counts[5] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
   tree last_iter = NULL_TREE, last_count = NULL_TREE;
   size_t i, j;
   location_t first_loc = UNKNOWN_LOCATION;
@@ -8327,6 +8327,9 @@ gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
 	  case OMP_CLAUSE_DEPEND_DEPOBJ:
 	    i = 3;
 	    break;
+	  case OMP_CLAUSE_DEPEND_INOUTSET:
+	    i = 4;
+	    break;
 	  case OMP_CLAUSE_DEPEND_SOURCE:
 	  case OMP_CLAUSE_DEPEND_SINK:
 	    continue;
@@ -8432,14 +8435,14 @@ gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
 	else
 	  n[i]++;
       }
-  for (i = 0; i < 4; i++)
+  for (i = 0; i < 5; i++)
     if (counts[i])
       break;
-  if (i == 4)
+  if (i == 5)
     return 0;
 
   tree total = size_zero_node;
-  for (i = 0; i < 4; i++)
+  for (i = 0; i < 5; i++)
     {
       unused[i] = counts[i] == NULL_TREE && n[i] == 0;
       if (counts[i] == NULL_TREE)
@@ -8455,9 +8458,12 @@ gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
   if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
       == GS_ERROR)
     return 2;
-  bool is_old = unused[1] && unused[3];
+  bool is_old = unused[1] && unused[3] && unused[4];
   tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
 			     size_int (is_old ? 1 : 4));
+  if (!unused[4])
+    totalpx = size_binop (PLUS_EXPR, totalpx,
+			  size_binop (MULT_EXPR, counts[4], size_int (2)));
   tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
   tree array = create_tmp_var_raw (type);
   TREE_ADDRESSABLE (array) = 1;
@@ -8503,11 +8509,11 @@ gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
       gimplify_and_add (tem, pre_p);
     }
 
-  tree cnts[4];
-  for (j = 4; j; j--)
+  tree cnts[6];
+  for (j = 5; j; j--)
     if (!unused[j - 1])
       break;
-  for (i = 0; i < 4; i++)
+  for (i = 0; i < 5; i++)
     {
       if (i && (i >= j || unused[i - 1]))
 	{
@@ -8531,6 +8537,15 @@ gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
 	}
       gimple_seq_add_stmt (pre_p, g);
     }
+  if (unused[4])
+    cnts[5] = NULL_TREE;
+  else
+    {
+      tree t = size_binop (PLUS_EXPR, total, size_int (5));
+      cnts[5] = create_tmp_var (sizetype);
+      g = gimple_build_assign (cnts[i], t);
+      gimple_seq_add_stmt (pre_p, g);
+    }
 
   last_iter = NULL_TREE;
   tree last_bind = NULL_TREE;
@@ -8553,6 +8568,9 @@ gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
 	  case OMP_CLAUSE_DEPEND_DEPOBJ:
 	    i = 3;
 	    break;
+	  case OMP_CLAUSE_DEPEND_INOUTSET:
+	    i = 4;
+	    break;
 	  case OMP_CLAUSE_DEPEND_SOURCE:
 	  case OMP_CLAUSE_DEPEND_SINK:
 	    continue;
@@ -8657,14 +8675,42 @@ gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
 	      return 2;
 	    if (TREE_VALUE (t) != null_pointer_node)
 	      TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
+	    if (i == 4)
+	      {
+		r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
+			    NULL_TREE, NULL_TREE);
+		tree r2 = build4 (ARRAY_REF, ptr_type_node, array, cnts[5],
+				  NULL_TREE, NULL_TREE);
+		r2 = build_fold_addr_expr_with_type (r2, ptr_type_node);
+		tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
+				  void_type_node, r, r2);
+		append_to_statement_list_force (tem, last_body);
+		tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
+				  void_type_node, cnts[i],
+				  size_binop (PLUS_EXPR, cnts[i],
+					      size_int (1)));
+		append_to_statement_list_force (tem, last_body);
+		i = 5;
+	      }
 	    r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
 			NULL_TREE, NULL_TREE);
 	    tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
 			      void_type_node, r, TREE_VALUE (t));
 	    append_to_statement_list_force (tem, last_body);
+	    if (i == 5)
+	      {
+		r = build4 (ARRAY_REF, ptr_type_node, array,
+			    size_binop (PLUS_EXPR, cnts[i], size_int (1)),
+			    NULL_TREE, NULL_TREE);
+		tem = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET);
+		tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
+				  void_type_node, r, tem);
+		append_to_statement_list_force (tem, last_body);
+	      }
 	    tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
 			      void_type_node, cnts[i],
-			      size_binop (PLUS_EXPR, cnts[i], size_int (1)));
+			      size_binop (PLUS_EXPR, cnts[i],
+					  size_int (1 + (i == 5))));
 	    append_to_statement_list_force (tem, last_body);
 	    TREE_VALUE (t) = null_pointer_node;
 	  }
@@ -8688,12 +8734,38 @@ gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
 	    if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
 			       is_gimple_val, fb_rvalue) == GS_ERROR)
 	      return 2;
+	    if (i == 4)
+	      {
+		r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
+			    NULL_TREE, NULL_TREE);
+		tree r2 = build4 (ARRAY_REF, ptr_type_node, array, cnts[5],
+				  NULL_TREE, NULL_TREE);
+		r2 = build_fold_addr_expr_with_type (r2, ptr_type_node);
+		tem = build2 (MODIFY_EXPR, void_type_node, r, r2);
+		gimplify_and_add (tem, pre_p);
+		g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR,
+							      cnts[i],
+							      size_int (1)));
+		gimple_seq_add_stmt (pre_p, g);
+		i = 5;
+	      }
 	    r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
 			NULL_TREE, NULL_TREE);
 	    tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
 	    gimplify_and_add (tem, pre_p);
-	    g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR, cnts[i],
-							  size_int (1)));
+	    if (i == 5)
+	      {
+		r = build4 (ARRAY_REF, ptr_type_node, array,
+			    size_binop (PLUS_EXPR, cnts[i], size_int (1)),
+			    NULL_TREE, NULL_TREE);
+		tem = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET);
+		tem = build2 (MODIFY_EXPR, void_type_node, r, tem);
+		append_to_statement_list_force (tem, last_body);
+		gimplify_and_add (tem, pre_p);
+	      }
+	    g = gimple_build_assign (cnts[i],
+				     size_binop (PLUS_EXPR, cnts[i],
+						 size_int (1 + (i == 5))));
 	    gimple_seq_add_stmt (pre_p, g);
 	  }
       }
@@ -8717,7 +8789,7 @@ gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
   else
     {
       tree prev = size_int (5);
-      for (i = 0; i < 4; i++)
+      for (i = 0; i < 5; i++)
 	{
 	  if (unused[i])
 	    continue;
diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc
index 04b315d47b6..c366fb55c80 100644
--- a/gcc/omp-low.cc
+++ b/gcc/omp-low.cc
@@ -13095,7 +13095,7 @@ lower_depend_clauses (tree *pclauses, gimple_seq *iseq, gimple_seq *oseq)
 {
   tree c, clauses;
   gimple *g;
-  size_t cnt[4] = { 0, 0, 0, 0 }, idx = 2, i;
+  size_t cnt[5] = { 0, 0, 0, 0, 0 }, idx = 2, i;
 
   clauses = omp_find_clause (*pclauses, OMP_CLAUSE_DEPEND);
   gcc_assert (clauses);
@@ -13119,16 +13119,20 @@ lower_depend_clauses (tree *pclauses, gimple_seq *iseq, gimple_seq *oseq)
 	case OMP_CLAUSE_DEPEND_DEPOBJ:
 	  cnt[3]++;
 	  break;
+	case OMP_CLAUSE_DEPEND_INOUTSET:
+	  cnt[4]++;
+	  break;
 	case OMP_CLAUSE_DEPEND_SOURCE:
 	case OMP_CLAUSE_DEPEND_SINK:
 	  /* FALLTHRU */
 	default:
 	  gcc_unreachable ();
 	}
-  if (cnt[1] || cnt[3])
+  if (cnt[1] || cnt[3] || cnt[4])
     idx = 5;
-  size_t total = cnt[0] + cnt[1] + cnt[2] + cnt[3];
-  tree type = build_array_type_nelts (ptr_type_node, total + idx);
+  size_t total = cnt[0] + cnt[1] + cnt[2] + cnt[3] + cnt[4];
+  size_t inoutidx = total + idx;
+  tree type = build_array_type_nelts (ptr_type_node, total + idx + 2 * cnt[4]);
   tree array = create_tmp_var (type);
   TREE_ADDRESSABLE (array) = 1;
   tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
@@ -13149,7 +13153,7 @@ lower_depend_clauses (tree *pclauses, gimple_seq *iseq, gimple_seq *oseq)
       g = gimple_build_assign (r, build_int_cst (ptr_type_node, cnt[i]));
       gimple_seq_add_stmt (iseq, g);
     }
-  for (i = 0; i < 4; i++)
+  for (i = 0; i < 5; i++)
     {
       if (cnt[i] == 0)
 	continue;
@@ -13177,10 +13181,21 @@ lower_depend_clauses (tree *pclauses, gimple_seq *iseq, gimple_seq *oseq)
 		if (i != 3)
 		  continue;
 		break;
+	      case OMP_CLAUSE_DEPEND_INOUTSET:
+		if (i != 4)
+		   continue;
+		break;
 	      default:
 		gcc_unreachable ();
 	      }
 	    tree t = OMP_CLAUSE_DECL (c);
+	    if (i == 4)
+	      {
+		t = build4 (ARRAY_REF, ptr_type_node, array,
+			    size_int (inoutidx), NULL_TREE, NULL_TREE);
+		t = build_fold_addr_expr (t);
+		inoutidx += 2;
+	      }
 	    t = fold_convert (ptr_type_node, t);
 	    gimplify_expr (&t, iseq, NULL, is_gimple_val, fb_rvalue);
 	    r = build4 (ARRAY_REF, ptr_type_node, array, size_int (idx++),
@@ -13189,6 +13204,25 @@ lower_depend_clauses (tree *pclauses, gimple_seq *iseq, gimple_seq *oseq)
 	    gimple_seq_add_stmt (iseq, g);
 	  }
     }
+  if (cnt[4])
+    for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
+      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
+	  && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_INOUTSET)
+	{
+	  tree t = OMP_CLAUSE_DECL (c);
+	  t = fold_convert (ptr_type_node, t);
+	  gimplify_expr (&t, iseq, NULL, is_gimple_val, fb_rvalue);
+	  r = build4 (ARRAY_REF, ptr_type_node, array, size_int (idx++),
+		      NULL_TREE, NULL_TREE);
+	  g = gimple_build_assign (r, t);
+	  gimple_seq_add_stmt (iseq, g);
+	  t = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET);
+	  r = build4 (ARRAY_REF, ptr_type_node, array, size_int (idx++),
+		      NULL_TREE, NULL_TREE);
+	  g = gimple_build_assign (r, t);
+	  gimple_seq_add_stmt (iseq, g);
+	}
+
   c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
   OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
   OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
diff --git a/gcc/testsuite/ChangeLog.omp b/gcc/testsuite/ChangeLog.omp
index 7260dd0c76b..0bfd4f2a3b7 100644
--- a/gcc/testsuite/ChangeLog.omp
+++ b/gcc/testsuite/ChangeLog.omp
@@ -1,3 +1,15 @@
+2022-07-04  Tobias Burnus  <tobias@codesourcery.com>
+
+	Backport from mainline:
+	2022-05-17  Jakub Jelinek  <jakub@redhat.com>
+
+	* c-c++-common/gomp/all-memory-1.c (boo): Add test with
+	inoutset depend-kind.
+	* c-c++-common/gomp/all-memory-2.c (boo): Likewise.
+	* c-c++-common/gomp/depobj-1.c (f1): Likewise.
+	(f2): Adjusted expected diagnostics.
+	* g++.dg/gomp/depobj-1.C (f4): Adjust expected diagnostics.
+
 2022-07-04  Tobias Burnus  <tobias@codesourcery.com>
 
 	Backport from mainline:
diff --git a/gcc/testsuite/c-c++-common/gomp/all-memory-1.c b/gcc/testsuite/c-c++-common/gomp/all-memory-1.c
index 5d63e0d0939..0fb457057c4 100644
--- a/gcc/testsuite/c-c++-common/gomp/all-memory-1.c
+++ b/gcc/testsuite/c-c++-common/gomp/all-memory-1.c
@@ -49,4 +49,6 @@ boo (void)
   ;
   #pragma omp task depend(mutexinoutset: omp_all_memory)	/* { dg-error "'omp_all_memory' used with 'depend' kind other than 'out' or 'inout'" } */
   ;
+  #pragma omp task depend(inoutset: omp_all_memory)		/* { dg-error "'omp_all_memory' used with 'depend' kind other than 'out' or 'inout'" } */
+  ;
 }
diff --git a/gcc/testsuite/c-c++-common/gomp/all-memory-2.c b/gcc/testsuite/c-c++-common/gomp/all-memory-2.c
index 6f5d31be29c..99b5945eac5 100644
--- a/gcc/testsuite/c-c++-common/gomp/all-memory-2.c
+++ b/gcc/testsuite/c-c++-common/gomp/all-memory-2.c
@@ -52,4 +52,6 @@ boo (void)
   ;
   #pragma omp task depend(mutexinoutset: omp_all_memory)
   ;
+  #pragma omp task depend(inoutset: omp_all_memory)
+  ;
 }
diff --git a/gcc/testsuite/c-c++-common/gomp/depobj-1.c b/gcc/testsuite/c-c++-common/gomp/depobj-1.c
index 688371b6232..77fd97159aa 100644
--- a/gcc/testsuite/c-c++-common/gomp/depobj-1.c
+++ b/gcc/testsuite/c-c++-common/gomp/depobj-1.c
@@ -21,6 +21,9 @@ f1 (void)
   ;
   #pragma omp depobj(pdepobj[0]) depend(mutexinoutset:a)
   #pragma omp depobj(*pdepobj) destroy
+  #pragma omp depobj(depobja[0]) depend(inoutset: a)
+  #pragma omp depobj(depobja[0]) update(mutexinoutset)
+  #pragma omp depobj(depobja[0]) update(inoutset)
 }
 
 void
@@ -38,7 +41,7 @@ f2 (void)
   #pragma omp depobj (a) destroy			/* { dg-error "type of 'depobj' expression is not 'omp_depend_t'" } */
   #pragma omp depobj (depobj) depend(depobj:a)		/* { dg-error "does not have 'omp_depend_t' type in 'depend' clause with 'depobj' dependence type" } */
   #pragma omp depobj (depobj) depend(depobj:*depobjb)	/* { dg-error "'depobj' dependence type specified in 'depend' clause on 'depobj' construct" } */
-  #pragma omp depobj (depobj) update(foobar)		/* { dg-error "expected 'in', 'out', 'inout' or 'mutexinoutset'" } */
+  #pragma omp depobj (depobj) update(foobar)		/* { dg-error "expected 'in', 'out', 'inout', 'mutexinoutset' or 'inoutset'" } */
   #pragma omp depobj (depobj) depend(in: *depobja)	/* { dg-error "should not have 'omp_depend_t' type in 'depend' clause with dependence type" } */
   #pragma omp depobj (depobj) depend(in: a) depend(in: b)	/* { dg-error "expected" } */
   #pragma omp depobj (depobj) depend(in: a) update(out)	/* { dg-error "expected" } */
diff --git a/gcc/testsuite/g++.dg/gomp/depobj-1.C b/gcc/testsuite/g++.dg/gomp/depobj-1.C
index 6004f1e6e6d..cb091a1da2c 100644
--- a/gcc/testsuite/g++.dg/gomp/depobj-1.C
+++ b/gcc/testsuite/g++.dg/gomp/depobj-1.C
@@ -83,7 +83,7 @@ f4 (void)
   #pragma omp depobj (a) destroy			// { dg-error "type of 'depobj' expression is not 'omp_depend_t'" }
   #pragma omp depobj (depobj) depend(depobj:a)		// { dg-error "does not have 'omp_depend_t' type in 'depend' clause with 'depobj' dependence type" }
   #pragma omp depobj (depobj) depend(depobj:*depobjb)	// { dg-error "'depobj' dependence type specified in 'depend' clause on 'depobj' construct" }
-  #pragma omp depobj (depobj) update(foobar)		// { dg-error "expected 'in', 'out', 'inout' or 'mutexinoutset'" }
+  #pragma omp depobj (depobj) update(foobar)		// { dg-error "expected 'in', 'out', 'inout', 'mutexinoutset' or 'inoutset'" }
   #pragma omp depobj (depobj) depend(in: *depobja)	// { dg-error "should not have 'omp_depend_t' type in 'depend' clause with dependence type" }
   #pragma omp depobj (depobj) depend(in: a) depend(in: b)	// { dg-error "expected" }
   #pragma omp depobj (depobj) depend(in: a) update(out)	// { dg-error "expected" }
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index d0020405cc6..3013db3df75 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -1541,6 +1541,7 @@ enum omp_clause_depend_kind
   OMP_CLAUSE_DEPEND_OUT,
   OMP_CLAUSE_DEPEND_INOUT,
   OMP_CLAUSE_DEPEND_MUTEXINOUTSET,
+  OMP_CLAUSE_DEPEND_INOUTSET,
   OMP_CLAUSE_DEPEND_SOURCE,
   OMP_CLAUSE_DEPEND_SINK,
   OMP_CLAUSE_DEPEND_DEPOBJ,
diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc
index b200be3b34d..23672082ad6 100644
--- a/gcc/tree-pretty-print.cc
+++ b/gcc/tree-pretty-print.cc
@@ -832,6 +832,9 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
 	case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
 	  name = "mutexinoutset";
 	  break;
+	case OMP_CLAUSE_DEPEND_INOUTSET:
+	  name = "inoutset";
+	  break;
 	case OMP_CLAUSE_DEPEND_SOURCE:
 	  pp_string (pp, "source)");
 	  return;
diff --git a/include/ChangeLog.omp b/include/ChangeLog.omp
index 4c63f1107ee..6c3b73b44a9 100644
--- a/include/ChangeLog.omp
+++ b/include/ChangeLog.omp
@@ -1,3 +1,10 @@
+2022-07-04  Tobias Burnus  <tobias@codesourcery.com>
+
+	Backport from mainline:
+	2022-05-17  Jakub Jelinek  <jakub@redhat.com>
+
+	* gomp-constants.h (GOMP_DEPEND_INOUTSET): Define.
+
 2022-06-21  Kwok Cheung Yeung  <kcy@codesourcery.com>
 
 	* cuda/cuda.h (CUdevice_attribute): Add definitions for
@@ -19,7 +26,7 @@
 	* dwarf2.def (DW_OP_LLVM_piece_end): New extension operator.
 
 2018-10-04  Cesar Philippidis  <cesar@codesourcery.com>
-            Julian Brown  <julian@codesourcery.com>
+	    Julian Brown  <julian@codesourcery.com>
 
 	* gomp-constants.h (enum gomp_map_kind): Define
 	GOMP_MAP_DECLARE_{ALLOCATE,DEALLOCATE} and GOMP_MAP_FLAG_SPECIAL_4.
diff --git a/include/gomp-constants.h b/include/gomp-constants.h
index 04e7c08db47..011d2de091d 100644
--- a/include/gomp-constants.h
+++ b/include/gomp-constants.h
@@ -355,6 +355,7 @@ enum gomp_map_kind
 #define GOMP_DEPEND_OUT			2
 #define GOMP_DEPEND_INOUT		3
 #define GOMP_DEPEND_MUTEXINOUTSET	4
+#define GOMP_DEPEND_INOUTSET		5
 
 /* Flag values for requires-directive features, must match corresponding
    OMP_REQUIRES_* values in gcc/omp-general.h.  */
diff --git a/libgomp/ChangeLog.omp b/libgomp/ChangeLog.omp
index ff5d52f87e7..5e1997de255 100644
--- a/libgomp/ChangeLog.omp
+++ b/libgomp/ChangeLog.omp
@@ -1,3 +1,25 @@
+2022-07-04  Tobias Burnus  <tobias@codesourcery.com>
+
+	Backport from mainline:
+	2022-05-17  Jakub Jelinek  <jakub@redhat.com>
+
+	* libgomp.h (struct gomp_task_depend_entry): Change is_in type
+	from bool to unsigned char.
+	* task.c (gomp_task_handle_depend): Handle GOMP_DEPEND_INOUTSET.
+	Ignore dependencies where
+	task->depend[i].is_in && task->depend[i].is_in == ent->is_in
+	rather than just task->depend[i].is_in && ent->is_in.  Remember
+	whether GOMP_DEPEND_IN loop is needed and guard the loop with that
+	conditional.
+	(gomp_task_maybe_wait_for_dependencies): Handle GOMP_DEPEND_INOUTSET.
+	Ignore dependencies where elem.is_in && elem.is_in == ent->is_in
+	rather than just elem.is_in && ent->is_in.
+	* testsuite/libgomp.c-c++-common/depend-1.c (test): Add task with
+	inoutset depend-kind.
+	* testsuite/libgomp.c-c++-common/depend-2.c (test): Likewise.
+	* testsuite/libgomp.c-c++-common/depend-3.c (test): Likewise.
+	* testsuite/libgomp.c-c++-common/depend-inoutset-1.c: New test.
+
 2022-07-04  Tobias Burnus  <tobias@codesourcery.com>
 
 	Backport from mainline:
diff --git a/libgomp/libgomp.h b/libgomp/libgomp.h
index 53a0244d58c..77669ed95b0 100644
--- a/libgomp/libgomp.h
+++ b/libgomp/libgomp.h
@@ -535,8 +535,8 @@ struct gomp_task_depend_entry
   struct gomp_task_depend_entry *prev;
   /* Task that provides the dependency in ADDR.  */
   struct gomp_task *task;
-  /* Depend entry is of type "IN".  */
-  bool is_in;
+  /* Depend entry is of type "IN" (1) or "INOUTSET" (2).  */
+  unsigned char is_in;
   bool redundant;
   bool redundant_out;
 };
diff --git a/libgomp/task.c b/libgomp/task.c
index db4a6f71fb7..e9a28bf71cb 100644
--- a/libgomp/task.c
+++ b/libgomp/task.c
@@ -197,6 +197,7 @@ gomp_task_handle_depend (struct gomp_task *task, struct gomp_task *parent,
       /* ndepend - nout - nmutexinoutset - nin is # of depobjs */
       size_t normal = nout + nmutexinoutset + nin;
       size_t n = 0;
+      bool has_in = false;
       for (i = normal; i < ndepend; i++)
 	{
 	  void **d = (void **) (uintptr_t) depend[5 + i];
@@ -209,6 +210,8 @@ gomp_task_handle_depend (struct gomp_task *task, struct gomp_task *parent,
 	    case GOMP_DEPEND_MUTEXINOUTSET:
 	      break;
 	    case GOMP_DEPEND_IN:
+	    case GOMP_DEPEND_INOUTSET:
+	      has_in = true;
 	      continue;
 	    default:
 	      gomp_fatal ("unknown omp_depend_t dependence type %d",
@@ -222,14 +225,17 @@ gomp_task_handle_depend (struct gomp_task *task, struct gomp_task *parent,
 	  task->depend[n].addr = depend[5 + i];
 	  task->depend[n++].is_in = i >= nout + nmutexinoutset;
 	}
-      for (i = normal; i < ndepend; i++)
-	{
-	  void **d = (void **) (uintptr_t) depend[5 + i];
-	  if ((uintptr_t) d[1] != GOMP_DEPEND_IN)
-	    continue;
-	  task->depend[n].addr = d[0];
-	  task->depend[n++].is_in = 1;
-	}
+      if (has_in)
+	for (i = normal; i < ndepend; i++)
+	  {
+	    void **d = (void **) (uintptr_t) depend[5 + i];
+	    if ((uintptr_t) d[1] != GOMP_DEPEND_IN
+		&& (uintptr_t) d[1] != GOMP_DEPEND_INOUTSET)
+	      continue;
+	    task->depend[n].addr = d[0];
+	    task->depend[n++].is_in
+	      = 1 + ((uintptr_t) d[1] == GOMP_DEPEND_INOUTSET);
+	  }
     }
   task->num_dependees = 0;
   if (__builtin_expect (parent->depend_all_memory && ndepend, false))
@@ -381,8 +387,10 @@ gomp_task_handle_depend (struct gomp_task *task, struct gomp_task *parent,
 
 	      last = ent;
 
-	      /* depend(in:...) doesn't depend on earlier depend(in:...).  */
-	      if (task->depend[i].is_in && ent->is_in)
+	      /* depend(in:...) doesn't depend on earlier depend(in:...).
+		 Similarly depend(inoutset:...) doesn't depend on earlier
+		 depend(inoutset:...).  */
+	      if (task->depend[i].is_in && task->depend[i].is_in == ent->is_in)
 		continue;
 
 	      if (!ent->is_in)
@@ -1890,6 +1898,9 @@ gomp_task_maybe_wait_for_dependencies (void **depend)
 	    case GOMP_DEPEND_MUTEXINOUTSET:
 	      elem.is_in = 0;
 	      break;
+	    case GOMP_DEPEND_INOUTSET:
+	      elem.is_in = 2;
+	      break;
 	    default:
 	      gomp_fatal ("unknown omp_depend_t dependence type %d",
 			  (int) (uintptr_t) d[1]);
@@ -1928,7 +1939,7 @@ gomp_task_maybe_wait_for_dependencies (void **depend)
 	}
       ent = htab_find (task->depend_hash, &elem);
       for (; ent; ent = ent->next)
-	if (elem.is_in && ent->is_in)
+	if (elem.is_in && elem.is_in == ent->is_in)
 	  continue;
 	else
 	  {
diff --git a/libgomp/testsuite/libgomp.c-c++-common/depend-1.c b/libgomp/testsuite/libgomp.c-c++-common/depend-1.c
index 3376b99b18c..47d7570a196 100644
--- a/libgomp/testsuite/libgomp.c-c++-common/depend-1.c
+++ b/libgomp/testsuite/libgomp.c-c++-common/depend-1.c
@@ -48,6 +48,11 @@ test (int ifval)
       usleep (5000);
       b[4] = 48;
     }
+    #pragma omp task shared(b) depend(inoutset: b[5])
+    {
+      usleep (5000);
+      b[5] = 49;
+    }
     /* None of the above tasks depend on each other.
        The following task depends on all but the a[4] = 46; one.  */
     #pragma omp task shared(a, b) depend(out: omp_all_memory) private(i) if(ifval)
@@ -55,7 +60,7 @@ test (int ifval)
       if (a[0] != 42 || a[1] != 43 || a[2] != 44 || a[3] != 45
 	  || a[5] != 5 || a[6] != 6 || a[7] != 7
 	  || b[0] != 47 || b[1] != 2 || b[2] != 4 || b[3] != 6
-	  || b[4] != 48 || b[5] != 10 || b[6] != 12 || b[7] != 14)
+	  || b[4] != 48 || b[5] != 49 || b[6] != 12 || b[7] != 14)
 	abort ();
       for (i = 0; i < 8; ++i)
 	if (i != 4)
diff --git a/libgomp/testsuite/libgomp.c-c++-common/depend-2.c b/libgomp/testsuite/libgomp.c-c++-common/depend-2.c
index d7b533555c4..2fe867e2c83 100644
--- a/libgomp/testsuite/libgomp.c-c++-common/depend-2.c
+++ b/libgomp/testsuite/libgomp.c-c++-common/depend-2.c
@@ -52,6 +52,11 @@ test (int ifval)
       usleep (5000);
       b[4] = 48;
     }
+    #pragma omp task shared(b) depend(inoutset: b[5])
+    {
+      usleep (5000);
+      b[5] = 49;
+    }
     /* None of the above tasks depend on each other.
        The following task depends on all but the a[4] = 46; one.  */
     #pragma omp task shared(a, b) depend(depobj: d1) private(i) if(ifval)
@@ -59,7 +64,7 @@ test (int ifval)
       if (a[0] != 42 || a[1] != 43 || a[2] != 44 || a[3] != 45
 	  || a[5] != 5 || a[6] != 6 || a[7] != 7
 	  || b[0] != 47 || b[1] != 2 || b[2] != 4 || b[3] != 6
-	  || b[4] != 48 || b[5] != 10 || b[6] != 12 || b[7] != 14)
+	  || b[4] != 48 || b[5] != 49 || b[6] != 12 || b[7] != 14)
 	abort ();
       for (i = 0; i < 8; ++i)
 	if (i != 4)
diff --git a/libgomp/testsuite/libgomp.c-c++-common/depend-3.c b/libgomp/testsuite/libgomp.c-c++-common/depend-3.c
index 052e77c81e1..7cfda67318c 100644
--- a/libgomp/testsuite/libgomp.c-c++-common/depend-3.c
+++ b/libgomp/testsuite/libgomp.c-c++-common/depend-3.c
@@ -48,6 +48,11 @@ main ()
       usleep (5000);
       b[4] = 48;
     }
+    #pragma omp task shared(b) depend(inoutset: b[5])
+    {
+      usleep (5000);
+      b[5] = 49;
+    }
     /* None of the above tasks depend on each other.
        The following task depends on all but the a[4] = 46; one.  */
     #pragma omp task shared(a, b) depend(iterator (j=0:7), inout: omp_all_memory) private(i)
@@ -55,7 +60,7 @@ main ()
       if (a[0] != 42 || a[1] != 43 || a[2] != 44 || a[3] != 45
 	  || a[5] != 5 || a[6] != 6 || a[7] != 7
 	  || b[0] != 47 || b[1] != 2 || b[2] != 4 || b[3] != 6
-	  || b[4] != 48 || b[5] != 10 || b[6] != 12 || b[7] != 14)
+	  || b[4] != 48 || b[5] != 49 || b[6] != 12 || b[7] != 14)
 	abort ();
       for (i = 0; i < 8; ++i)
 	if (i != 4)
diff --git a/libgomp/testsuite/libgomp.c-c++-common/depend-inoutset-1.c b/libgomp/testsuite/libgomp.c-c++-common/depend-inoutset-1.c
new file mode 100644
index 00000000000..77956f26232
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/depend-inoutset-1.c
@@ -0,0 +1,164 @@
+#include <omp.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int
+main ()
+{
+  int a[8] = {};
+  omp_depend_t d1, d2;
+  #pragma omp depobj (d1) depend(inoutset: a)
+  #pragma omp depobj (d2) depend(inout: a)
+  #pragma omp depobj (d2) update(inoutset)
+  #pragma omp parallel
+  {
+    #pragma omp barrier
+    #pragma omp master
+    {
+    #pragma omp task shared(a) depend(out: a)
+    {
+      usleep (5000);
+      a[0] = 1; a[1] = 2; a[2] = 3; a[3] = 4;
+    }
+    /* The above task needs to finish first.  */
+    #pragma omp task shared(a) depend(in: a)
+    {
+      if (a[0] != 1 || a[1] != 2 || a[2] != 3 || a[3] != 4)
+	abort ();
+      usleep (5000);
+      a[4] = 42;
+    }
+    #pragma omp task shared(a) depend(in: a)
+    {
+      if (a[0] != 1 || a[1] != 2 || a[2] != 3 || a[3] != 4)
+	abort ();
+      usleep (5000);
+      a[5] = 43;
+    }
+    #pragma omp task shared(a) depend(in: a)
+    {
+      if (a[0] != 1 || a[1] != 2 || a[2] != 3 || a[3] != 4)
+	abort ();
+      usleep (5000);
+      a[6] = 44;
+    }
+    #pragma omp task shared(a) depend(in: a)
+    {
+      if (a[0] != 1 || a[1] != 2 || a[2] != 3 || a[3] != 4)
+	abort ();
+      usleep (5000);
+      a[7] = 45;
+    }
+    /* The above 4 tasks can be scheduled in any order but need to wait
+       for the depend(out: a) task.  */
+    #pragma omp task shared(a) depend(inoutset: a)
+    {
+      if (a[4] != 42 || a[5] != 43 || a[6] != 44 || a[7] != 45)
+	abort ();
+      usleep (5000);
+      a[0] = 42;
+    }
+    #pragma omp task shared(a) depend(iterator(i=1:3:2), inoutset: a)
+    {
+      if (a[4] != 42 || a[5] != 43 || a[6] != 44 || a[7] != 45)
+	abort ();
+      usleep (5000);
+      a[1] = 43;
+    }
+    #pragma omp task shared(a) depend(depobj: d1)
+    {
+      if (a[4] != 42 || a[5] != 43 || a[6] != 44 || a[7] != 45)
+	abort ();
+      usleep (5000);
+      a[2] = 44;
+    }
+    #pragma omp task shared(a) depend(depobj: d2)
+    {
+      if (a[4] != 42 || a[5] != 43 || a[6] != 44 || a[7] != 45)
+	abort ();
+      usleep (5000);
+      a[3] = 45;
+    }
+    /* The above 4 tasks can be scheduled in any order but need to wait
+       for all the above depend(in: a) tasks.  */
+    #pragma omp task shared(a) depend(in: a)
+    {
+      if (a[0] != 42 || a[1] != 43 || a[2] != 44 || a[3] != 45)
+	abort ();
+      usleep (5000);
+      a[4] = 46;
+    }
+    #pragma omp task shared(a) depend(in: a)
+    {
+      if (a[0] != 42 || a[1] != 43 || a[2] != 44 || a[3] != 45)
+	abort ();
+      usleep (5000);
+      a[5] = 47;
+    }
+    #pragma omp task shared(a) depend(in: a)
+    {
+      if (a[0] != 42 || a[1] != 43 || a[2] != 44 || a[3] != 45)
+	abort ();
+      usleep (5000);
+      a[6] = 48;
+    }
+    #pragma omp task shared(a) depend(in: a)
+    {
+      if (a[0] != 42 || a[1] != 43 || a[2] != 44 || a[3] != 45)
+	abort ();
+      usleep (5000);
+      a[7] = 49;
+    }
+    /* The above 4 tasks can be scheduled in any order but need to wait
+       for all the above depend(inoutset: a),
+       depend(iterator(i=1:3:2), inoutset: a), depend(depobj: d1) and
+       depend(depobj: d2) tasks.  */
+    #pragma omp task shared(a) depend(inoutset: a)
+    {
+      if (a[4] != 46|| a[5] != 47 || a[6] != 48 || a[7] != 49)
+	abort ();
+      usleep (5000);
+      a[0] = 50;
+    }
+    /* The above task needs to wait for all the above 4 depend(in: a)
+       tasks.  */
+    #pragma omp task shared(a) depend(out: a)
+    {
+      if (a[0] != 50 || a[4] != 46|| a[5] != 47 || a[6] != 48 || a[7] != 49)
+	abort ();
+      usleep (5000);
+      a[0] = 51;
+    }
+    /* The above task needs to wait for the above depend(inoutset: a) task.  */
+    #pragma omp task shared(a) depend(inoutset: a)
+    {
+      if (a[0] != 51 || a[4] != 46|| a[5] != 47 || a[6] != 48 || a[7] != 49)
+	abort ();
+      usleep (5000);
+      a[0] = 52;
+    }
+    /* The above task needs to wait for the above depend(out: a) task.  */
+    #pragma omp task shared(a) depend(mutexinoutset: a)
+    {
+      if (a[0] != 52 || a[4] != 46|| a[5] != 47 || a[6] != 48 || a[7] != 49)
+	abort ();
+      usleep (5000);
+      a[0] = 53;
+    }
+    /* The above task needs to wait for the above depend(inoutset: a) task.  */
+    #pragma omp task shared(a) depend(inoutset: a)
+    {
+      if (a[0] != 53 || a[4] != 46|| a[5] != 47 || a[6] != 48 || a[7] != 49)
+	abort ();
+      usleep (5000);
+      a[0] = 54;
+    }
+    /* The above task needs to wait for the above
+       depend(mutexinoutset: a) task.  */
+    }
+  }
+  if (a[0] != 54 || a[1] != 43 || a[2] != 44 || a[3] != 45
+      || a[4] != 46|| a[5] != 47 || a[6] != 48 || a[7] != 49)
+    abort ();
+  return 0;
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-07-04 20:11 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-04 20:11 [gcc/devel/omp/gcc-12] openmp: Add support for inoutset depend-kind Tobias Burnus

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