diff mbox series

[committed] Fix omp lowering when global vars turn to be addressable while lowering (PR middle-end/91216)

Message ID 20190730073407.GL15878@tucnak
State New
Headers show
Series [committed] Fix omp lowering when global vars turn to be addressable while lowering (PR middle-end/91216) | expand

Commit Message

Jakub Jelinek July 30, 2019, 7:34 a.m. UTC
Hi!

We ICE on the following testcase, because the reduction is expanded as
__atomic_* operation on the address of the global variable which makes the
global var, previously not TREE_ADDRESSABLE, suddenly TREE_ADDRESSABLE
during the lowering, but after scanning when we decided how to pass certain
vars.  If the variable is then privatized again, the scanning and lowering
disagrees on how to pass it.  I believe this can happen only for global vars
and the following patch fixes it by remembering the global vars for which
we saw once they aren't addressable and repeating that even in cases where
they are later addressable.

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

2019-07-30  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/91216
	* omp-low.c (global_nonaddressable_vars): New variable.
	(use_pointer_for_field): For global decls, if they are non-addressable,
	remember it in the global_nonaddressable_vars bitmap, if they are
	addressable and in the global_nonaddressable_vars bitmap, ignore their
	TREE_ADDRESSABLE bit.
	(omp_copy_decl_2): Clear TREE_ADDRESSABLE also on private copies of
	vars in global_nonaddressable_vars bitmap.
	(execute_lower_omp): Free global_nonaddressable_vars bitmap.

	* gcc.dg/gomp/pr91216.c: New test.


	Jakub
diff mbox series

Patch

--- gcc/omp-low.c.jj	2019-07-20 13:18:54.477980721 +0200
+++ gcc/omp-low.c	2019-07-29 18:49:04.838065123 +0200
@@ -162,6 +162,7 @@  static splay_tree all_contexts;
 static int taskreg_nesting_level;
 static int target_nesting_level;
 static bitmap task_shared_vars;
+static bitmap global_nonaddressable_vars;
 static vec<omp_context *> taskreg_contexts;
 
 static void scan_omp (gimple_seq *, omp_context *);
@@ -426,7 +427,26 @@  use_pointer_for_field (tree decl, omp_co
 
       /* Do not use copy-in/copy-out for variables that have their
 	 address taken.  */
-      if (TREE_ADDRESSABLE (decl))
+      if (is_global_var (decl))
+	{
+	  /* For file scope vars, track whether we've seen them as
+	     non-addressable initially and in that case, keep the same
+	     answer for the duration of the pass, even when they are made
+	     addressable later on e.g. through reduction expansion.  Global
+	     variables which weren't addressable before the pass will not
+	     have their privatized copies address taken.  See PR91216.  */
+	  if (!TREE_ADDRESSABLE (decl))
+	    {
+	      if (!global_nonaddressable_vars)
+		global_nonaddressable_vars = BITMAP_ALLOC (NULL);
+	      bitmap_set_bit (global_nonaddressable_vars, DECL_UID (decl));
+	    }
+	  else if (!global_nonaddressable_vars
+		   || !bitmap_bit_p (global_nonaddressable_vars,
+				     DECL_UID (decl)))
+	    return true;
+	}
+      else if (TREE_ADDRESSABLE (decl))
 	return true;
 
       /* lower_send_shared_vars only uses copy-in, but not copy-out
@@ -504,8 +524,10 @@  omp_copy_decl_2 (tree var, tree name, tr
      it's address.  But we don't need to take address of privatizations
      from that var.  */
   if (TREE_ADDRESSABLE (var)
-      && task_shared_vars
-      && bitmap_bit_p (task_shared_vars, DECL_UID (var)))
+      && ((task_shared_vars
+	   && bitmap_bit_p (task_shared_vars, DECL_UID (var)))
+	  || (global_nonaddressable_vars
+	      && bitmap_bit_p (global_nonaddressable_vars, DECL_UID (var)))))
     TREE_ADDRESSABLE (copy) = 0;
   ctx->block_vars = copy;
 
@@ -12730,6 +12752,7 @@  execute_lower_omp (void)
       all_contexts = NULL;
     }
   BITMAP_FREE (task_shared_vars);
+  BITMAP_FREE (global_nonaddressable_vars);
 
   /* If current function is a method, remove artificial dummy VAR_DECL created
      for non-static data member privatization, they aren't needed for
--- gcc/testsuite/gcc.dg/gomp/pr91216.c.jj	2019-07-29 18:57:02.915209678 +0200
+++ gcc/testsuite/gcc.dg/gomp/pr91216.c	2019-07-29 18:56:53.930338628 +0200
@@ -0,0 +1,20 @@ 
+/* PR middle-end/91216 */
+
+int r;
+
+void
+foo (int *a)
+{
+  int i;
+  #pragma omp for reduction(+:r)
+  for (i = 0; i < 64; i++)
+    a[i] = i;
+  #pragma omp for private (r)
+  for (i = 0; i < 64; i++)
+    {
+      r = 0;
+      #pragma omp parallel shared(r)
+      #pragma omp master
+      r = r + 1;
+    }
+}