Hi!

The omp for loop iterator can be addressable e.g. because of shared use of
it in a 2x nested parallel (in which case we can't use copy-in/out).

The following patch tweaks expand_omp_for* to allow the iterators to be
addressable.

Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk.
Will backport to 4.8 soon (and to 4.7 after 4.7.3 is released).

2013-04-09  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/56883
        * omp-low.c (expand_omp_for_generic, expand_omp_for_static_nochunk,
        expand_omp_for_static_chunk): Use simple_p = true in
        force_gimple_operand_gsi calls when assigning to addressable decls.

        * c-c++-common/gomp/pr56883.c: New test.

--- gcc/omp-low.c.jj    2013-02-07 08:59:48.000000000 +0100
+++ gcc/omp-low.c       2013-04-09 11:09:42.197181925 +0200
@@ -3920,8 +3920,10 @@ expand_omp_for_generic (struct omp_regio
   if (POINTER_TYPE_P (type))
     t = fold_convert (signed_type_for (type), t);
   t = fold_convert (type, t);
-  t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
-                               false, GSI_CONTINUE_LINKING);
+  t = force_gimple_operand_gsi (&gsi, t,
+                               DECL_P (fd->loop.v)
+                               && TREE_ADDRESSABLE (fd->loop.v),
+                               NULL_TREE, false, GSI_CONTINUE_LINKING);
   stmt = gimple_build_assign (fd->loop.v, t);
   gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
 
@@ -3952,8 +3954,11 @@ expand_omp_for_generic (struct omp_regio
            t = fold_build_pointer_plus (fd->loops[i].n1, t);
          else
            t = fold_build2 (PLUS_EXPR, itype, fd->loops[i].n1, t);
-         t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
-                                       false, GSI_CONTINUE_LINKING);
+         t = force_gimple_operand_gsi (&gsi, t,
+                                       DECL_P (fd->loops[i].v)
+                                       && TREE_ADDRESSABLE (fd->loops[i].v),
+                                       NULL_TREE, false,
+                                       GSI_CONTINUE_LINKING);
          stmt = gimple_build_assign (fd->loops[i].v, t);
          gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
          if (i != 0)
@@ -3981,12 +3986,15 @@ expand_omp_for_generic (struct omp_regio
        t = fold_build_pointer_plus (vmain, fd->loop.step);
       else
        t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
-      t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
-                                   true, GSI_SAME_STMT);
+      t = force_gimple_operand_gsi (&gsi, t,
+                                   DECL_P (vback) && TREE_ADDRESSABLE (vback),
+                                   NULL_TREE, true, GSI_SAME_STMT);
       stmt = gimple_build_assign (vback, t);
       gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
 
-      t = build2 (fd->loop.cond_code, boolean_type_node, vback, iend);
+      t = build2 (fd->loop.cond_code, boolean_type_node,
+                 DECL_P (vback) && TREE_ADDRESSABLE (vback) ? t : vback,
+                 iend);
       stmt = gimple_build_cond_empty (t);
       gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
 
@@ -4011,8 +4019,12 @@ expand_omp_for_generic (struct omp_regio
                  e->probability = REG_BR_PROB_BASE / 8;
 
                  t = fd->loops[i + 1].n1;
-                 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
-                                               false, GSI_CONTINUE_LINKING);
+                 t = force_gimple_operand_gsi (&gsi, t,
+                                               DECL_P (fd->loops[i + 1].v)
+                                               && TREE_ADDRESSABLE
+                                                       (fd->loops[i + 1].v),
+                                               NULL_TREE, false,
+                                               GSI_CONTINUE_LINKING);
                  stmt = gimple_build_assign (fd->loops[i + 1].v, t);
                  gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
                }
@@ -4026,8 +4038,11 @@ expand_omp_for_generic (struct omp_regio
              else
                t = fold_build2 (PLUS_EXPR, vtype, fd->loops[i].v,
                                 fd->loops[i].step);
-             t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
-                                           false, GSI_CONTINUE_LINKING);
+             t = force_gimple_operand_gsi (&gsi, t,
+                                           DECL_P (fd->loops[i].v)
+                                           && TREE_ADDRESSABLE 
(fd->loops[i].v),
+                                           NULL_TREE, false,
+                                           GSI_CONTINUE_LINKING);
              stmt = gimple_build_assign (fd->loops[i].v, t);
              gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
 
@@ -4036,8 +4051,12 @@ expand_omp_for_generic (struct omp_regio
                  t = fd->loops[i].n2;
                  t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
                                                false, GSI_CONTINUE_LINKING);
+                 tree v = fd->loops[i].v;
+                 if (DECL_P (v) && TREE_ADDRESSABLE (v))
+                   v = force_gimple_operand_gsi (&gsi, v, true, NULL_TREE,
+                                                 false, GSI_CONTINUE_LINKING);
                  t = fold_build2 (fd->loops[i].cond_code, boolean_type_node,
-                                  fd->loops[i].v, t);
+                                  v, t);
                  stmt = gimple_build_cond_empty (t);
                  gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
                  e = make_edge (bb, l1_bb, EDGE_TRUE_VALUE);
@@ -4273,8 +4292,10 @@ expand_omp_for_static_nochunk (struct om
     t = fold_build_pointer_plus (fd->loop.n1, t);
   else
     t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
-  t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
-                               false, GSI_CONTINUE_LINKING);
+  t = force_gimple_operand_gsi (&gsi, t,
+                               DECL_P (fd->loop.v)
+                               && TREE_ADDRESSABLE (fd->loop.v),
+                               NULL_TREE, false, GSI_CONTINUE_LINKING);
   stmt = gimple_build_assign (fd->loop.v, t);
   gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
 
@@ -4299,12 +4320,14 @@ expand_omp_for_static_nochunk (struct om
     t = fold_build_pointer_plus (vmain, fd->loop.step);
   else
     t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
-  t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
-                               true, GSI_SAME_STMT);
+  t = force_gimple_operand_gsi (&gsi, t,
+                               DECL_P (vback) && TREE_ADDRESSABLE (vback),
+                               NULL_TREE, true, GSI_SAME_STMT);
   stmt = gimple_build_assign (vback, t);
   gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
 
-  t = build2 (fd->loop.cond_code, boolean_type_node, vback, e);
+  t = build2 (fd->loop.cond_code, boolean_type_node,
+             DECL_P (vback) && TREE_ADDRESSABLE (vback) ? t : vback, e);
   gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
 
   /* Remove the GIMPLE_OMP_CONTINUE statement.  */
@@ -4504,8 +4527,10 @@ expand_omp_for_static_chunk (struct omp_
     t = fold_build_pointer_plus (fd->loop.n1, t);
   else
     t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
-  t = force_gimple_operand_gsi (&si, t, false, NULL_TREE,
-                               false, GSI_CONTINUE_LINKING);
+  t = force_gimple_operand_gsi (&si, t,
+                               DECL_P (fd->loop.v)
+                               && TREE_ADDRESSABLE (fd->loop.v),
+                               NULL_TREE, false, GSI_CONTINUE_LINKING);
   stmt = gimple_build_assign (fd->loop.v, t);
   gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
 
@@ -4530,10 +4555,15 @@ expand_omp_for_static_chunk (struct omp_
     t = fold_build_pointer_plus (v_main, fd->loop.step);
   else
     t = fold_build2 (PLUS_EXPR, type, v_main, fd->loop.step);
+  if (DECL_P (v_back) && TREE_ADDRESSABLE (v_back))
+    t = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
+                                 true, GSI_SAME_STMT);
   stmt = gimple_build_assign (v_back, t);
   gsi_insert_before (&si, stmt, GSI_SAME_STMT);
 
-  t = build2 (fd->loop.cond_code, boolean_type_node, v_back, e);
+  t = build2 (fd->loop.cond_code, boolean_type_node,
+             DECL_P (v_back) && TREE_ADDRESSABLE (v_back)
+             ? t : v_back, e);
   gsi_insert_before (&si, gimple_build_cond_empty (t), GSI_SAME_STMT);
 
   /* Remove GIMPLE_OMP_CONTINUE.  */
--- gcc/testsuite/c-c++-common/gomp/pr56883.c.jj        2013-04-09 
11:16:04.618006796 +0200
+++ gcc/testsuite/c-c++-common/gomp/pr56883.c   2013-04-09 11:15:59.458036182 
+0200
@@ -0,0 +1,57 @@
+/* PR middle-end/56883 */
+/* { dg-do compile }
+/* { dg-options "-O2 -fopenmp" } */
+
+void
+f1 (int ***x)
+{
+  int i, j, k;
+#pragma omp parallel for
+  for (i = 0; i < 10; ++i)
+    {
+    #pragma omp parallel shared(j)
+      #pragma omp for
+       for (j = 0; j < 10; ++j)
+         {
+         #pragma omp parallel for
+             for (k = 0; k < 10; ++k)
+               x[i][j][k] = k;
+         }
+    }
+}
+
+void
+f2 (int ***x)
+{
+  int i, j, k;
+#pragma omp parallel for schedule(static,1)
+  for (i = 0; i < 10; ++i)
+    {
+    #pragma omp parallel shared(j)
+      #pragma omp for schedule(static,1)
+       for (j = 0; j < 10; ++j)
+         {
+         #pragma omp parallel for schedule(static,1)
+             for (k = 0; k < 10; ++k)
+               x[i][j][k] = k;
+         }
+    }
+}
+
+void
+f3 (int ***x)
+{
+  int i, j, k;
+#pragma omp parallel for schedule(runtime)
+  for (i = 0; i < 10; ++i)
+    {
+    #pragma omp parallel shared(j)
+      #pragma omp for schedule(runtime)
+       for (j = 0; j < 10; ++j)
+         {
+         #pragma omp parallel for schedule(runtime)
+             for (k = 0; k < 10; ++k)
+               x[i][j][k] = k;
+         }
+    }
+}

        Jakub

Reply via email to