diff mbox

[gomp4.1] Fixup handling of doacross loops with noreturn body

Message ID 20150929172837.GL1847@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Sept. 29, 2015, 5:28 p.m. UTC
On Thu, Sep 24, 2015 at 08:32:10PM +0200, Jakub Jelinek wrote:
> then there is a bug with ordered loops that have noreturn body (need to add
> some edge for that case and condition checking),

This patch fixes the above issue, if we have any of the ordered > collapse
loops that might have zero iterations, we need to deal with the !cont_bb
(aka broken_loop) case, for lastprivate reasons not just as simple checking
of the conditions and falling through into the cont_bb case, but have to
emit all the loops, and just for the innermost handle the case that there is
no fallthru from the body to the cont_bb block; the innermost could have
zero iterations and some of the outer ones could have all non-zero
iterations, at which point we want lastprivate to contain the initial value
of the innermost iterator and last iteration's values of the outer ones.

2015-09-29  Jakub Jelinek  <jakub@redhat.com>

	* omp-low.c (expand_omp_for_ordered_loops): Handle the case
	when cont_bb has no predecessors.
	(expand_omp_for_generic): If any of the ordered loops above
	collapsed loops could have zero iterations for broken_loop,
	create a cont_bb and continue as if the loop is not broken.

	* testsuite/libgomp.c/doacross-1.c (main): Adjust, so that one
	of the doacross loops has noreturn loop body.



	Jakub
diff mbox

Patch

--- gcc/omp-low.c.jj	2015-09-25 18:17:13.000000000 +0200
+++ gcc/omp-low.c	2015-09-29 19:07:25.366494422 +0200
@@ -7345,36 +7345,44 @@  expand_omp_for_ordered_loops (struct omp
       basic_block new_body = e1->dest;
       if (body_bb == cont_bb)
 	cont_bb = new_body;
-      gsi = gsi_last_bb (cont_bb);
-      if (POINTER_TYPE_P (type))
-	t = fold_build_pointer_plus (fd->loops[i].v,
-				     fold_convert (sizetype,
-						   fd->loops[i].step));
-      else
-	t = fold_build2 (PLUS_EXPR, type, fd->loops[i].v,
-			 fold_convert (type, fd->loops[i].step));
-      expand_omp_build_assign (&gsi, fd->loops[i].v, t);
-      if (counts[i])
-	{
-	  t = fold_build2 (PLUS_EXPR, fd->iter_type, counts[i],
-			   build_int_cst (fd->iter_type, 1));
-	  expand_omp_build_assign (&gsi, counts[i], t);
-	  t = counts[i];
-	}
-      else
+      edge e2 = NULL;
+      basic_block new_header;
+      if (EDGE_COUNT (cont_bb->preds) > 0)
 	{
-	  t = fold_build2 (MINUS_EXPR, TREE_TYPE (fd->loops[i].v),
-			   fd->loops[i].v, fd->loops[i].n1);
-	  t = fold_convert (fd->iter_type, t);
-	  t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
-					true, GSI_SAME_STMT);
+	  gsi = gsi_last_bb (cont_bb);
+	  if (POINTER_TYPE_P (type))
+	    t = fold_build_pointer_plus (fd->loops[i].v,
+					 fold_convert (sizetype,
+						       fd->loops[i].step));
+	  else
+	    t = fold_build2 (PLUS_EXPR, type, fd->loops[i].v,
+			     fold_convert (type, fd->loops[i].step));
+	  expand_omp_build_assign (&gsi, fd->loops[i].v, t);
+	  if (counts[i])
+	    {
+	      t = fold_build2 (PLUS_EXPR, fd->iter_type, counts[i],
+			       build_int_cst (fd->iter_type, 1));
+	      expand_omp_build_assign (&gsi, counts[i], t);
+	      t = counts[i];
+	    }
+	  else
+	    {
+	      t = fold_build2 (MINUS_EXPR, TREE_TYPE (fd->loops[i].v),
+			       fd->loops[i].v, fd->loops[i].n1);
+	      t = fold_convert (fd->iter_type, t);
+	      t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
+					    true, GSI_SAME_STMT);
+	    }
+	  aref = build4 (ARRAY_REF, fd->iter_type, counts[fd->ordered],
+			 size_int (i - fd->collapse + 1),
+			 NULL_TREE, NULL_TREE);
+	  expand_omp_build_assign (&gsi, aref, t);
+	  gsi_prev (&gsi);
+	  e2 = split_block (cont_bb, gsi_stmt (gsi));
+	  new_header = e2->dest;
 	}
-      aref = build4 (ARRAY_REF, fd->iter_type, counts[fd->ordered],
-		     size_int (i - fd->collapse + 1), NULL_TREE, NULL_TREE);
-      expand_omp_build_assign (&gsi, aref, t);
-      gsi_prev (&gsi);
-      edge e2 = split_block (cont_bb, gsi_stmt (gsi));
-      basic_block new_header = e2->dest;
+      else
+	new_header = cont_bb;
       gsi = gsi_after_labels (new_header);
       tree v = force_gimple_operand_gsi (&gsi, fd->loops[i].v, true, NULL_TREE,
 					 true, GSI_SAME_STMT);
@@ -7395,10 +7403,13 @@  expand_omp_for_ordered_loops (struct omp
       set_immediate_dominator (CDI_DOMINATORS, new_header, body_bb);
       set_immediate_dominator (CDI_DOMINATORS, new_body, new_header);
 
-      struct loop *loop = alloc_loop ();
-      loop->header = new_header;
-      loop->latch = e2->src;
-      add_loop (loop, body_bb->loop_father);
+      if (e2)
+	{
+	  struct loop *loop = alloc_loop ();
+	  loop->header = new_header;
+	  loop->latch = e2->src;
+	  add_loop (loop, body_bb->loop_father);
+	}
     }
   return cont_bb;
 }
@@ -7943,6 +7954,33 @@  expand_omp_for_generic (struct omp_regio
 	 depend(source).  */
       if (fd->collapse > 1)
 	memmove (counts, counts + 1, (fd->collapse - 1) * sizeof (counts[0]));
+      if (broken_loop)
+	{
+	  int i;
+	  for (i = fd->collapse; i < fd->ordered; i++)
+	    {
+	      tree type = TREE_TYPE (fd->loops[i].v);
+	      tree this_cond
+		= fold_build2 (fd->loops[i].cond_code, boolean_type_node,
+			       fold_convert (type, fd->loops[i].n1),
+			       fold_convert (type, fd->loops[i].n2));
+	      if (!integer_onep (this_cond))
+		break;
+	    }
+	  if (i < fd->ordered)
+	    {
+	      cont_bb
+		= create_empty_bb (EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb);
+	      add_bb_to_loop (cont_bb, l1_bb->loop_father);
+	      gimple_stmt_iterator gsi = gsi_after_labels (cont_bb);
+	      gimple g = gimple_build_omp_continue (fd->loop.v, fd->loop.v);
+	      gsi_insert_before (&gsi, g, GSI_SAME_STMT);
+	      make_edge (cont_bb, l3_bb, EDGE_FALLTHRU);
+	      make_edge (cont_bb, l1_bb, 0);
+	      l2_bb = create_empty_bb (cont_bb);
+	      broken_loop = false;
+	    }
+	}
       expand_omp_ordered_source_sink (region, fd, counts, cont_bb);
       cont_bb = expand_omp_for_ordered_loops (fd, counts, cont_bb, l1_bb);
       if (counts[fd->collapse - 1])
--- libgomp/testsuite/libgomp.c/doacross-1.c.jj	2015-09-25 16:54:47.000000000 +0200
+++ libgomp/testsuite/libgomp.c/doacross-1.c	2015-09-29 16:36:26.131321339 +0200
@@ -144,8 +144,7 @@  main ()
 	    {
 	      #pragma omp ordered depend (source)
 	      #pragma omp ordered depend (sink:i - 2, j + 2, k - 2, m)
-	      if (!e)
-		abort ();
+	      abort ();
 	    }
     #pragma omp single
     if (i != 1 || j != -1 || k != 2 || m != 0)