re PR middle-end/69183 (ICE when using OpenMP PRIVATE keyword in OMP DO loop not...
authorJakub Jelinek <jakub@gcc.gnu.org>
Wed, 23 Nov 2016 19:28:41 +0000 (20:28 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 23 Nov 2016 19:28:41 +0000 (20:28 +0100)
PR middle-end/69183
* omp-low.c (build_outer_var_ref): Change lastprivate argument
to code, pass it recursively, adjust uses.  For OMP_CLAUSE_PRIVATE
on worksharing constructs, treat it like clauses on simd construct.
Formatting fix.
(lower_rec_input_clauses): For OMP_CLAUSE_PRIVATE_OUTER_REF pass
OMP_CLAUSE_PRIVATE as last argument to build_outer_var_ref.
(lower_lastprivate_clauses): Pass OMP_CLAUSE_LASTPRIVATE instead
of true as last argument to build_outer_var_ref.

* gfortran.dg/gomp/pr69183.f90: New test.

From-SVN: r242793

gcc/ChangeLog
gcc/omp-low.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/gomp/pr69183.f90 [new file with mode: 0644]

index a62f378..c610804 100644 (file)
@@ -1,6 +1,18 @@
+2016-11-23  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/69183
+       * omp-low.c (build_outer_var_ref): Change lastprivate argument
+       to code, pass it recursively, adjust uses.  For OMP_CLAUSE_PRIVATE
+       on worksharing constructs, treat it like clauses on simd construct.
+       Formatting fix.
+       (lower_rec_input_clauses): For OMP_CLAUSE_PRIVATE_OUTER_REF pass
+       OMP_CLAUSE_PRIVATE as last argument to build_outer_var_ref.
+       (lower_lastprivate_clauses): Pass OMP_CLAUSE_LASTPRIVATE instead
+       of true as last argument to build_outer_var_ref.
+
 2016-11-23  Uros Bizjak  <ubizjak@gmail.com>
 
-       * gcc.target/config/i386.md (*movqi_internal): Calculate mode
+       * config/i386/i386.md (*movqi_internal): Calculate mode
        attribute of alternatives 7,8,9 depending on TARGET_AVX512DQ.
        <TYPE_MSKMOV>: Emit kmovw for MODE_HI insn mode attribute.
        (*k<logic><mode>): Calculate mode attribute depending on
index 3eff4e7..7bcaeee 100644 (file)
@@ -1283,7 +1283,8 @@ build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
    this is some variable.  */
 
 static tree
-build_outer_var_ref (tree var, omp_context *ctx, bool lastprivate = false)
+build_outer_var_ref (tree var, omp_context *ctx,
+                    enum omp_clause_code code = OMP_CLAUSE_ERROR)
 {
   tree x;
 
@@ -1292,7 +1293,7 @@ build_outer_var_ref (tree var, omp_context *ctx, bool lastprivate = false)
   else if (is_variable_sized (var))
     {
       x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
-      x = build_outer_var_ref (x, ctx, lastprivate);
+      x = build_outer_var_ref (x, ctx, code);
       x = build_simple_mem_ref (x);
     }
   else if (is_taskreg_ctx (ctx))
@@ -1300,11 +1301,17 @@ build_outer_var_ref (tree var, omp_context *ctx, bool lastprivate = false)
       bool by_ref = use_pointer_for_field (var, NULL);
       x = build_receiver_ref (var, by_ref, ctx);
     }
-  else if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
-          && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
-    {
-      /* #pragma omp simd isn't a worksharing construct, and can reference even
-        private vars in its linear etc. clauses.  */
+  else if ((gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
+           && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
+          || (code == OMP_CLAUSE_PRIVATE
+              && (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
+                  || gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS
+                  || gimple_code (ctx->stmt) == GIMPLE_OMP_SINGLE)))
+    {
+      /* #pragma omp simd isn't a worksharing construct, and can reference
+        even private vars in its linear etc. clauses.
+        Similarly for OMP_CLAUSE_PRIVATE with outer ref, that can refer
+        to private vars in all worksharing constructs.  */
       x = NULL_TREE;
       if (ctx->outer && is_taskreg_ctx (ctx))
        x = lookup_decl (var, ctx->outer);
@@ -1313,7 +1320,7 @@ build_outer_var_ref (tree var, omp_context *ctx, bool lastprivate = false)
       if (x == NULL_TREE)
        x = var;
     }
-  else if (lastprivate && is_taskloop_ctx (ctx))
+  else if (code == OMP_CLAUSE_LASTPRIVATE && is_taskloop_ctx (ctx))
     {
       gcc_assert (ctx->outer);
       splay_tree_node n
@@ -1350,7 +1357,7 @@ build_outer_var_ref (tree var, omp_context *ctx, bool lastprivate = false)
          gcc_assert (outer
                      && gimple_code (outer->stmt) != GIMPLE_OMP_GRID_BODY);
        }
-       x = lookup_decl (var, outer);
+      x = lookup_decl (var, outer);
     }
   else if (is_reference (var))
     /* This can happen with orphaned constructs.  If var is reference, it is
@@ -5031,7 +5038,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
                  if (is_task_ctx (ctx))
                    x = build_receiver_ref (var, false, ctx);
                  else
-                   x = build_outer_var_ref (var, ctx);
+                   x = build_outer_var_ref (var, ctx, OMP_CLAUSE_PRIVATE);
                }
              else
                x = NULL;
@@ -5697,7 +5704,7 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
                x = ovar;
            }
          if (!x)
-           x = build_outer_var_ref (var, ctx, true);
+           x = build_outer_var_ref (var, ctx, OMP_CLAUSE_LASTPRIVATE);
          if (is_reference (var))
            new_var = build_simple_mem_ref_loc (clause_loc, new_var);
          x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
index b116ed6..6c95928 100644 (file)
@@ -1,4 +1,9 @@
-2016-11-23  Kito Cheng <kito.cheng@gmail.com>
+2016-11-23  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/69183
+       * gfortran.dg/gomp/pr69183.f90: New test.
+
+2016-11-23  Kito Cheng  <kito.cheng@gmail.com>
 
        PR target/78230
        * gcc.dg/torture/pr66178.c (test): Use uintptr_t instead of int.
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr69183.f90 b/gcc/testsuite/gfortran.dg/gomp/pr69183.f90
new file mode 100644 (file)
index 0000000..5dc985a
--- /dev/null
@@ -0,0 +1,11 @@
+! PR middle-end/69183
+! { dg-do compile }
+
+program pr69183
+  integer, allocatable :: z
+  integer :: i
+  !$omp do private(z)
+  do i = 1, 2
+    z = i
+  end do
+end