[committed] openmp: Don't optimize shared to firstprivate on task with depend clause

Jakub Jelinek jakub@redhat.com
Fri Dec 18 20:49:05 GMT 2020


Hi!

The attached testcase is miscompiled, because we optimize shared clauses
to firstprivate when task body can't modify the variable even when the
task has depend clause.  That is wrong, because firstprivate means the
variable will be copied immediately when the task is created, while with
depend clause some other task might change it later before the dependencies
are satisfied and the task should observe the value only after the change.

Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk
so far.

2020-12-18  Jakub Jelinek  <jakub@redhat.com>

	* gimplify.c (struct gimplify_omp_ctx): Add has_depend member.
	(gimplify_scan_omp_clauses): Set it to true if OMP_CLAUSE_DEPEND
	appears on OMP_TASK.
	(gimplify_adjust_omp_clauses_1, gimplify_adjust_omp_clauses): Force
	GOVD_WRITTEN on shared variables if task construct has depend clause.

	* testsuite/libgomp.c/task-6.c: New test.

--- gcc/gimplify.c.jj	2020-11-26 01:14:47.537081889 +0100
+++ gcc/gimplify.c	2020-12-18 17:31:53.746888168 +0100
@@ -231,6 +231,7 @@ struct gimplify_omp_ctx
   bool target_firstprivatize_array_bases;
   bool add_safelen1;
   bool order_concurrent;
+  bool has_depend;
   int defaultmap[4];
 };
 
@@ -9497,6 +9498,8 @@ gimplify_scan_omp_clauses (tree *list_p,
 	      remove = true;
 	      break;
 	    }
+	  if (code == OMP_TASK)
+	    ctx->has_depend = true;
 	  break;
 
 	case OMP_CLAUSE_TO:
@@ -10207,6 +10210,11 @@ gimplify_adjust_omp_clauses_1 (splay_tre
 	    return 0;
 	}
       code = OMP_CLAUSE_SHARED;
+      /* Don't optimize shared into firstprivate for read-only vars
+	 on tasks with depend clause, we shouldn't try to copy them
+	 until the dependencies are satisfied.  */
+      if (gimplify_omp_ctxp->has_depend)
+	flags |= GOVD_WRITTEN;
     }
   else if (flags & GOVD_PRIVATE)
     code = OMP_CLAUSE_PRIVATE;
@@ -10494,6 +10502,10 @@ gimplify_adjust_omp_clauses (gimple_seq
 		  OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
 		  OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
 		}
+              if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
+		  && ctx->has_depend
+		  && DECL_P (decl))
+		n->value |= GOVD_WRITTEN;
 	      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
 		  && (n->value & GOVD_WRITTEN) == 0
 		  && DECL_P (decl)
--- libgomp/testsuite/libgomp.c/task-6.c.jj	2020-12-18 16:55:34.422690908 +0100
+++ libgomp/testsuite/libgomp.c/task-6.c	2020-12-18 17:22:02.568615365 +0100
@@ -0,0 +1,47 @@
+#include <stdlib.h>
+#include <unistd.h>
+
+int
+main ()
+{
+  int x = 0, y = 0;
+  #pragma omp parallel shared(x, y)
+  #pragma omp master
+  {
+    #pragma omp task depend(out:y) shared(x, y)
+    {
+      sleep (1);
+      x = 1;
+      y = 1;
+    }
+    #pragma omp task depend(inout:y) shared(x, y)
+    {
+      if (x != 1 || y != 1)
+	abort ();
+      y++;
+    }
+  }
+  if (x != 1 || y != 2)
+    abort ();
+  x = 0;
+  y = 0;
+  #pragma omp parallel
+  #pragma omp master
+  {
+    #pragma omp task depend(out:y)
+    {
+      sleep (1);
+      x = 1;
+      y = 1;
+    }
+    #pragma omp task depend(inout:y)
+    {
+      if (x != 1 || y != 1)
+	abort ();
+      y++;
+    }
+  }
+  if (x != 1 || y != 2)
+    abort ();
+  return 0;
+}


	Jakub



More information about the Gcc-patches mailing list