Patchwork [committed] Fix OpenMP shared var handling in nested parallels (PR middle-end/49897)

login
register
mail settings
Submitter Jakub Jelinek
Date July 29, 2011, 5:56 p.m.
Message ID <20110729175640.GO2687@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/107445/
State New
Headers show

Comments

Jakub Jelinek - July 29, 2011, 5:56 p.m.
Hi!

This is something that happened to work in 4.4 and earlier, before
DECL_GIMPLE_FORMAL_TEMP_P removal.  If use_pointer_for_field needs to return
true because something is shared in a nested parallel and thus in-out
wouldn't work, as each thread would have its own location, and that var
isn't addressable, before DECL_GIMPLE_FORMAL_TEMP_P removal
.omp_data_2.o.y = &y;
would be gimplified as is and nothing complained about the missing
TREE_ADDRESSABLE on y, supposedly because ompexp cleaned it up.
But after that change, i.e. in 4.5+, the above is gimplified into
y.3 = y;
.omp_data_2.o.y = &y.3;
and thus the inner parallel modifies a wrong variable.
Fixed by treating it like the other case where we need to make
the var addressable for tasks.

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

2011-07-29  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/49897
	PR middle-end/49898
	* omp-low.c (use_pointer_for_field): If disallowing copy-in/out
	in nested parallel and outer is a gimple_reg, mark it as addressable
	and set its bit in task_shared_vars bitmap too.

	* testsuite/libgomp.c/pr49897-1.c: New test.
	* testsuite/libgomp.c/pr49897-2.c: New test.
	* testsuite/libgomp.c/pr49898-1.c: New test.
	* testsuite/libgomp.c/pr49898-2.c: New test.


	Jakub

Patch

--- gcc/omp-low.c.jj	2011-07-21 09:54:49.000000000 +0200
+++ gcc/omp-low.c	2011-07-29 16:31:08.000000000 +0200
@@ -781,7 +781,7 @@  use_pointer_for_field (tree decl, omp_co
 		  break;
 
 	      if (c)
-		return true;
+		goto maybe_mark_addressable_and_ret;
 	    }
 	}
 
@@ -791,7 +791,9 @@  use_pointer_for_field (tree decl, omp_co
 	 returns, the task hasn't necessarily terminated.  */
       if (!TREE_READONLY (decl) && is_task_ctx (shared_ctx))
 	{
-	  tree outer = maybe_lookup_decl_in_outer_ctx (decl, shared_ctx);
+	  tree outer;
+	maybe_mark_addressable_and_ret:
+	  outer = maybe_lookup_decl_in_outer_ctx (decl, shared_ctx);
 	  if (is_gimple_reg (outer))
 	    {
 	      /* Taking address of OUTER in lower_send_shared_vars
--- libgomp/testsuite/libgomp.c/pr49897-1.c.jj	2011-07-29 17:03:07.000000000 +0200
+++ libgomp/testsuite/libgomp.c/pr49897-1.c	2011-07-29 17:00:23.000000000 +0200
@@ -0,0 +1,31 @@ 
+/* PR middle-end/49897 */
+/* { dg-do run } */
+
+extern void abort (void);
+
+int
+main ()
+{
+  int i, j, x = 0, y, sum = 0;
+#pragma omp parallel reduction(+:sum)
+  {
+  #pragma omp for firstprivate(x) lastprivate(x, y)
+    for (i = 0; i < 10; i++)
+      {
+	x = i;
+	y = 0;
+      #pragma omp parallel reduction(+:sum)
+	{
+	#pragma omp for firstprivate(y) lastprivate(y)
+	  for (j = 0; j < 10; j++)
+	    {
+	      y = j;
+	      sum += y;
+	    }
+	}
+      }
+  }
+  if (x != 9 || y != 9 || sum != 450)
+    abort ();
+  return 0;
+}
--- libgomp/testsuite/libgomp.c/pr49897-2.c.jj	2011-07-29 17:03:07.000000000 +0200
+++ libgomp/testsuite/libgomp.c/pr49897-2.c	2011-07-29 17:00:07.000000000 +0200
@@ -0,0 +1,25 @@ 
+/* PR middle-end/49897 */
+/* { dg-do run } */
+
+extern void abort (void);
+
+int
+main ()
+{
+  int i, j, x = 0, y, sum = 0;
+#pragma omp parallel for reduction(+:sum) firstprivate(x) lastprivate(x, y)
+  for (i = 0; i < 10; i++)
+    {
+      x = i;
+      y = 0;
+    #pragma omp parallel for reduction(+:sum) firstprivate(y) lastprivate(y)
+      for (j = 0; j < 10; j++)
+	{
+	  y = j;
+	  sum += y;
+	}
+    }
+  if (x != 9 || y != 9 || sum != 450)
+    abort ();
+  return 0;
+}
--- libgomp/testsuite/libgomp.c/pr49898-1.c.jj	2011-07-29 17:03:07.000000000 +0200
+++ libgomp/testsuite/libgomp.c/pr49898-1.c	2011-07-29 17:01:44.000000000 +0200
@@ -0,0 +1,26 @@ 
+/* PR middle-end/49898 */
+/* { dg-do run } */
+
+extern void abort (void);
+
+int
+main ()
+{
+  int i, j, sum = 0;
+#pragma omp parallel
+  {
+  #pragma omp for reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      {
+      #pragma omp parallel
+	{
+	#pragma omp for reduction(+:sum)
+	  for (j = 0; j < 10; j++)
+	    sum += j;
+	}
+      }
+  }
+  if (sum != 450)
+    abort ();
+  return 0;
+}
--- libgomp/testsuite/libgomp.c/pr49898-2.c.jj	2011-07-29 17:03:07.000000000 +0200
+++ libgomp/testsuite/libgomp.c/pr49898-2.c	2011-07-29 17:02:28.000000000 +0200
@@ -0,0 +1,18 @@ 
+/* PR middle-end/49898 */
+/* { dg-do run } */
+
+extern void abort (void);
+
+int
+main ()
+{
+  int i, j, sum = 0;
+#pragma omp parallel for reduction(+:sum)
+  for (i = 0; i < 10; i++)
+    #pragma omp parallel for reduction(+:sum)
+    for (j = 0; j < 10; j++)
+      sum += j;
+  if (sum != 450)
+    abort ();
+  return 0;
+}