Hi!

This PR shows another bug, the computation of the size argument
for GOMP_task call could include uninitialized variable uses.

The problem is that the task arg_size needs to be finalized only
after mwe return from omp_low_1 of the task construct, thus it
is hard to gimplify it somewhere, but it can include references
to temporaries that need to be remapped if in nested constructs.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
committed to trunk, queued for release branches.

2017-05-22  Jakub Jelinek  <ja...@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.

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

--- gcc/omp-low.c.jj    2017-05-22 11:34:51.000000000 +0200
+++ gcc/omp-low.c       2017-05-22 18:31:30.045010460 +0200
@@ -1913,6 +1913,29 @@ scan_omp_task (gimple_stmt_iterator *gsi
     }
 }
 
+/* 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));
--- libgomp/testsuite/libgomp.c/pr80809-2.c.jj  2017-05-22 18:36:28.950298209 
+0200
+++ libgomp/testsuite/libgomp.c/pr80809-2.c     2017-05-22 14:28:40.000000000 
+0200
@@ -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;
+}
--- libgomp/testsuite/libgomp.c/pr80809-3.c.jj  2017-05-22 18:36:32.252257201 
+0200
+++ libgomp/testsuite/libgomp.c/pr80809-3.c     2017-05-22 18:34:46.000000000 
+0200
@@ -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;
+}

        Jakub

Reply via email to