Hi!

We split OMP_TASKLOOP into 3 constructs, two GIMPLE_OMP_FOR
with GIMPLE_OMP_PARALLEL sandwiched in between them, so that
it is possible to compute number of iterations etc. before calling
GOMP_taskloop*.  Using the original iterator in the outer gfor
doesn't play very well if the taskloop region is nested in other
OpenMP regions like parallel.  This patch just creates a temporary
for that.

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

2017-03-08  Jakub Jelinek  <ja...@redhat.com>

        PR c/79940
        * gimplify.c (gimplify_omp_for): Replace index var in outer
        taskloop statement with an artificial variable and add
        OMP_CLAUSE_PRIVATE clause for it.

        * testsuite/libgomp.c/pr79940.c: New test.

--- gcc/gimplify.c.jj   2017-02-21 09:03:57.000000000 +0100
+++ gcc/gimplify.c      2017-03-08 10:06:11.926501447 +0100
@@ -10232,8 +10232,9 @@ gimplify_omp_for (tree *expr_p, gimple_s
       gimple_omp_for_set_combined_into_p (gfor, true);
       for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
        {
-         t = unshare_expr (gimple_omp_for_index (gfor, i));
-         gimple_omp_for_set_index (gforo, i, t);
+         tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
+         tree v = create_tmp_var (type);
+         gimple_omp_for_set_index (gforo, i, v);
          t = unshare_expr (gimple_omp_for_initial (gfor, i));
          gimple_omp_for_set_initial (gforo, i, t);
          gimple_omp_for_set_cond (gforo, i,
@@ -10241,7 +10242,13 @@ gimplify_omp_for (tree *expr_p, gimple_s
          t = unshare_expr (gimple_omp_for_final (gfor, i));
          gimple_omp_for_set_final (gforo, i, t);
          t = unshare_expr (gimple_omp_for_incr (gfor, i));
+         gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
+         TREE_OPERAND (t, 0) = v;
          gimple_omp_for_set_incr (gforo, i, t);
+         t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
+         OMP_CLAUSE_DECL (t) = v;
+         OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
+         gimple_omp_for_set_clauses (gforo, t);
        }
       gimplify_seq_add_stmt (pre_p, gforo);
     }
--- libgomp/testsuite/libgomp.c/pr79940.c.jj    2017-03-08 10:47:26.179154442 
+0100
+++ libgomp/testsuite/libgomp.c/pr79940.c       2017-03-08 10:46:46.000000000 
+0100
@@ -0,0 +1,47 @@
+/* PR c/79940 */
+
+int
+main ()
+{
+  int i, j, l, m;
+  int a[10000], b[10000], c[10000];
+  for (i = 0; i < 10000; i++)
+    {
+      a[i] = i;
+      b[i] = i & 31;
+    }
+#pragma omp parallel shared(a, b, c)
+#pragma omp single
+#pragma omp taskloop shared(a, b, c)
+  for (i = 0; i < 10000; i++)
+    c[i] = a[i] + b[i];
+#pragma omp parallel
+#pragma omp single
+  {
+    #pragma omp taskloop shared(a, b, c) lastprivate (i)
+    for (i = 0; i < 10000; i++)
+      c[i] += a[i] + b[i];
+    l = i;
+  }
+#pragma omp parallel
+#pragma omp single
+#pragma omp taskloop shared(a, b, c) collapse(2)
+  for (i = 0; i < 100; i++)
+    for (j = 0; j < 100; j++)
+      c[i * 100 + j] += a[i * 100 + j] + b[i * 100 + j];
+#pragma omp parallel
+#pragma omp single
+  {
+    #pragma omp taskloop shared(a, b, c) lastprivate (i, j)
+    for (i = 0; i < 100; i++)
+      for (j = 0; j < 100; j++)
+       c[i * 100 + j] += a[i * 100 + j] + b[i * 100 + j];
+    m = i * 100 + j;
+  }
+  for (i = 0; i < 10000; i++)
+    if (a[i] != i || b[i] != (i & 31) || c[i] != 4 * i + 4 * (i & 31))
+      __builtin_abort ();
+  if (l != 10000 || m != 10100)
+    __builtin_abort ();
+  return 0;
+}

        Jakub

Reply via email to