re PR c/79940 (OpenMP pragma - internal compiler error with taskloop)
authorJakub Jelinek <jakub@redhat.com>
Wed, 8 Mar 2017 17:21:06 +0000 (18:21 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 8 Mar 2017 17:21:06 +0000 (18:21 +0100)
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.

From-SVN: r245980

gcc/ChangeLog
gcc/gimplify.c
libgomp/ChangeLog
libgomp/testsuite/libgomp.c/pr79940.c [new file with mode: 0644]

index c59224eab3903c96d355c0021ff290720c4624fa..c20fa94b3a7b3350a9b0a28a777cadcc17261f05 100644 (file)
@@ -1,3 +1,10 @@
+2017-03-08  Jakub Jelinek  <jakub@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.
+
 2017-03-08  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/79955
index 820459c4dd76fb30c9563c780dd7d4961bad832f..fbf136fbce4a0242839a1171d046656728afdc6c 100644 (file)
@@ -10232,8 +10232,9 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
       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_seq *pre_p)
          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);
     }
index 28cf0826e643d030eeea90434f5c6c2ac09e937a..f63f028d3e5e1fda438fb7be6140dc2d5a4c4114 100644 (file)
@@ -1,3 +1,8 @@
+2017-03-08  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/79940
+       * testsuite/libgomp.c/pr79940.c: New test.
+
 2017-02-15  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        * testsuite/libgomp.c/pr48591.c: Enable on all __float128
diff --git a/libgomp/testsuite/libgomp.c/pr79940.c b/libgomp/testsuite/libgomp.c/pr79940.c
new file mode 100644 (file)
index 0000000..6f66465
--- /dev/null
@@ -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;
+}