re PR middle-end/80809 (Multi-free error for variable size array used within OpenMP...
authorJakub Jelinek <jakub@redhat.com>
Mon, 22 May 2017 18:54:54 +0000 (20:54 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 22 May 2017 18:54:54 +0000 (20:54 +0200)
PR middle-end/80809
* omp-low.c (finish_taskreg_remap): New function.
(finish_taskreg_scan): If unit size of ctx->record_type
is non-constant, unshare the size expression and replace
decls in it with possible outer var refs.

* testsuite/libgomp.c/pr80809-2.c: New test.
* testsuite/libgomp.c/pr80809-3.c: New test.

From-SVN: r248346

gcc/ChangeLog
gcc/omp-low.c
libgomp/ChangeLog
libgomp/testsuite/libgomp.c/pr80809-2.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/pr80809-3.c [new file with mode: 0644]

index cfa15c2a7e19bda87fef573157d920a494d3dd9c..7bdd6f2c7a769a696ddabebbe6dbfc70783f2fe5 100644 (file)
@@ -1,5 +1,11 @@
 2017-05-22  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/80809
+       * omp-low.c (finish_taskreg_remap): New function.
+       (finish_taskreg_scan): If unit size of ctx->record_type
+       is non-constant, unshare the size expression and replace
+       decls in it with possible outer var refs.
+
        PR middle-end/80809
        * gimplify.c (omp_add_variable): For GOVD_DEBUG_PRIVATE use
        GOVD_SHARED rather than GOVD_PRIVATE with it.
index 26e6586a0706d362bca19825534e9cf598bae14b..968075c3df547c2cf13a873437b420899f649ebc 100644 (file)
@@ -1913,6 +1913,29 @@ scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
     }
 }
 
+/* Helper function for finish_taskreg_scan, called through walk_tree.
+   If maybe_lookup_decl_in_outer_context returns non-NULL for some
+   tree, replace it in the expression.  */
+
+static tree
+finish_taskreg_remap (tree *tp, int *walk_subtrees, void *data)
+{
+  if (VAR_P (*tp))
+    {
+      omp_context *ctx = (omp_context *) data;
+      tree t = maybe_lookup_decl_in_outer_ctx (*tp, ctx);
+      if (t != *tp)
+       {
+         if (DECL_HAS_VALUE_EXPR_P (t))
+           t = unshare_expr (DECL_VALUE_EXPR (t));
+         *tp = t;
+       }
+      *walk_subtrees = 0;
+    }
+  else if (IS_TYPE_OR_DECL_P (*tp))
+    *walk_subtrees = 0;
+  return NULL_TREE;
+}
 
 /* If any decls have been made addressable during scan_omp,
    adjust their fields if needed, and layout record types
@@ -2033,6 +2056,11 @@ finish_taskreg_scan (omp_context *ctx)
        layout_type (ctx->srecord_type);
       tree t = fold_convert_loc (loc, long_integer_type_node,
                                 TYPE_SIZE_UNIT (ctx->record_type));
+      if (TREE_CODE (t) != INTEGER_CST)
+       {
+         t = unshare_expr (t);
+         walk_tree (&t, finish_taskreg_remap, ctx, NULL);
+       }
       gimple_omp_task_set_arg_size (ctx->stmt, t);
       t = build_int_cst (long_integer_type_node,
                         TYPE_ALIGN_UNIT (ctx->record_type));
index c73683efff411c86928c0e409bf24bb52a06be2c..8209f9fa75c3a6d56845951c4fe161e1d9de0a04 100644 (file)
@@ -1,5 +1,9 @@
 2017-05-22  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/80809
+       * testsuite/libgomp.c/pr80809-2.c: New test.
+       * testsuite/libgomp.c/pr80809-3.c: New test.
+
        PR middle-end/80809
        * testsuite/libgomp.c/pr80809-1.c: New test.
 
diff --git a/libgomp/testsuite/libgomp.c/pr80809-2.c b/libgomp/testsuite/libgomp.c/pr80809-2.c
new file mode 100644 (file)
index 0000000..48af370
--- /dev/null
@@ -0,0 +1,35 @@
+/* PR middle-end/80809 */
+/* { dg-do run } */
+
+__attribute__((noinline, noclone)) void
+foo (int x)
+{
+  int i, v[x], w[16];
+  for (i = 0; i < x; i++)
+    v[i] = i;
+  for (i = 0; i < 16; i++)
+    w[i] = 0;
+#pragma omp parallel
+#pragma omp single
+  for (i = 0; i < 16; i++)
+#pragma omp task firstprivate (v)
+    {
+      int j;
+      for (j = 0; j < x; j++)
+       v[j] += i;
+      for (j = 0; j < x; j++)
+       w[i] += v[j];
+    }
+  for (i = 0; i < 16; i++)
+    if (w[i] != (x - 1) * x / 2 + x * i)
+      __builtin_abort ();
+}
+
+int
+main ()
+{
+  foo (4);
+  foo (27);
+  foo (196);
+  return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/pr80809-3.c b/libgomp/testsuite/libgomp.c/pr80809-3.c
new file mode 100644 (file)
index 0000000..7e0d179
--- /dev/null
@@ -0,0 +1,42 @@
+/* PR middle-end/80809 */
+/* { dg-do run } */
+
+__attribute__((noinline, noclone)) void
+foo (int x)
+{
+  int i, v[x], w[16];
+  for (i = 0; i < x; i++)
+    v[i] = i;
+  for (i = 0; i < 16; i++)
+    w[i] = 0;
+#pragma omp parallel
+#pragma omp single
+  {
+    int z[x];
+    for (i = 0; i < x; i++)
+      z[0] = 0;
+    for (i = 0; i < 16; i++)
+#pragma omp task firstprivate (z) firstprivate (v)
+      {
+       int j;
+       for (j = 0; j < x; j++)
+         z[j] = i;
+       for (j = 0; j < x; j++)
+         v[j] += z[j];
+       for (j = 0; j < x; j++)
+         w[i] += v[j];
+      }
+  }
+  for (i = 0; i < 16; i++)
+    if (w[i] != (x - 1) * x / 2 + x * i)
+      __builtin_abort ();
+}
+
+int
+main ()
+{
+  foo (4);
+  foo (27);
+  foo (196);
+  return 0;
+}