This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[committed] Fix OpenMP ICE with private allocatable on orphaned worksharing construct (PR middle-end/69183)


Hi!

allocatable privatized vars need access to the outer var for sizing,
but unlike e.g. firstprivate the standard allows them on orphaned
worksharing constructs or when the var is already private outside of
the worksharing construct.  Therefore, we should treat it similarly
to outer refs on simd construct.

Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk.

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.

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

--- gcc/omp-low.c.jj	2016-11-22 21:31:49.000000000 +0100
+++ gcc/omp-low.c	2016-11-23 16:20:31.830429649 +0100
@@ -1283,7 +1283,8 @@ build_receiver_ref (tree var, bool by_re
    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_conte
   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_conte
       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_conte
       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_conte
 	  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, g
 		  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;
@@ -5687,7 +5694,7 @@ lower_lastprivate_clauses (tree clauses,
 		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);
--- gcc/testsuite/gfortran.dg/gomp/pr69183.f90.jj	2016-11-23 16:18:55.801635373 +0100
+++ gcc/testsuite/gfortran.dg/gomp/pr69183.f90	2016-11-23 16:18:41.000000000 +0100
@@ -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

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]