Patchwork Fix omp loop ICEs if iterators are addressable

login
register
mail settings
Submitter Jakub Jelinek
Date April 9, 2013, 1:29 p.m.
Message ID <20130409132901.GW20334@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/235083/
State New
Headers show

Comments

Jakub Jelinek - April 9, 2013, 1:29 p.m.
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  <jakub@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.


	Jakub

Patch

--- 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;
+	  }
+    }
+}