[committed] Fix OpenMP shared var handling in nested parallels (PR middle-end/49897)
Jakub Jelinek
jakub@redhat.com
Fri Jul 29 19:36:00 GMT 2011
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.
--- 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;
+}
Jakub
More information about the Gcc-patches
mailing list