[committed] Fix omp simd clone creation for multiple return stmts (PR tree-optimization/87895)

Jakub Jelinek jakub@redhat.com
Tue Nov 20 20:48:00 GMT 2018


Hi!

In certain cases like the testcases below there are multiple return stmts
in the function for which we create simd clones and the simd clone adjusting
code wasn't handling that case properly, some bbs could end up with
non-fallthru edges to the increment bb even without a gimple_goto at the
end, others could be missed from redirection to incr_bb.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
committed to trunk.

2018-11-20  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/87895
	* omp-simd-clone.c (ipa_simd_modify_function_body): When removing
	or replacing GIMPLE_RETURN, set EDGE_FALLTHRU on the edge to EXIT.
	(simd_clone_adjust): Don't set EDGE_FALLTHRU here. In a loop that
	redirects edges to EXIT to edges to incr_bb, iterate while EXIT
	has any preds and always use EDGE_PRED (, 0).

	* gcc.dg/gomp/pr87895-1.c: New test.
	* gcc.dg/gomp/pr87895-2.c: New test.
	* gcc.dg/gomp/pr87895-3.c: New test.

--- gcc/omp-simd-clone.c.jj	2018-11-14 01:01:56.758459348 +0100
+++ gcc/omp-simd-clone.c	2018-11-20 13:57:53.902488981 +0100
@@ -994,6 +994,8 @@ ipa_simd_modify_function_body (struct cg
 	  if (greturn *return_stmt = dyn_cast <greturn *> (stmt))
 	    {
 	      tree retval = gimple_return_retval (return_stmt);
+	      edge e = find_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun));
+	      e->flags |= EDGE_FALLTHRU;
 	      if (!retval)
 		{
 		  gsi_remove (&gsi, true);
@@ -1150,14 +1152,9 @@ simd_clone_adjust (struct cgraph_node *n
       incr_bb = create_empty_bb (orig_exit);
       incr_bb->count = profile_count::zero ();
       add_bb_to_loop (incr_bb, body_bb->loop_father);
-      /* The succ of orig_exit was EXIT_BLOCK_PTR_FOR_FN (cfun), with an empty
-	 flag.  Set it now to be a FALLTHRU_EDGE.  */
-      gcc_assert (EDGE_COUNT (orig_exit->succs) == 1);
-      EDGE_SUCC (orig_exit, 0)->flags |= EDGE_FALLTHRU;
-      for (unsigned i = 0;
-	   i < EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds); ++i)
+      while (EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds))
 	{
-	  edge e = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), i);
+	  edge e = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
 	  redirect_edge_succ (e, incr_bb);
 	  incr_bb->count += e->count ();
 	}
--- gcc/testsuite/gcc.dg/gomp/pr87895-1.c.jj	2018-11-20 13:18:00.483355400 +0100
+++ gcc/testsuite/gcc.dg/gomp/pr87895-1.c	2018-11-20 13:18:28.792884133 +0100
@@ -0,0 +1,19 @@
+/* PR tree-optimization/87895 */
+/* { dg-do compile } */
+/* { dg-additional-options "-O0" } */
+
+#pragma omp declare simd
+int
+foo (int x)
+{
+  if (x == 0)
+    return 0;
+}
+
+#pragma omp declare simd
+int
+bar (int *x, int y)
+{
+  if ((y == 0) ? (*x = 0) : *x)
+    return 0;
+}
--- gcc/testsuite/gcc.dg/gomp/pr87895-2.c.jj	2018-11-20 13:18:07.780233931 +0100
+++ gcc/testsuite/gcc.dg/gomp/pr87895-2.c	2018-11-20 13:18:57.265410143 +0100
@@ -0,0 +1,5 @@
+/* PR tree-optimization/87895 */
+/* { dg-do compile } */
+/* { dg-additional-options "-O1" } */
+
+#include "pr87895-1.c"
--- gcc/testsuite/gcc.dg/gomp/pr87895-3.c.jj	2018-11-20 14:06:23.131004074 +0100
+++ gcc/testsuite/gcc.dg/gomp/pr87895-3.c	2018-11-20 14:06:03.697327933 +0100
@@ -0,0 +1,18 @@
+/* PR tree-optimization/87895 */
+/* { dg-do compile } */
+/* { dg-additional-options "-O2" } */
+
+#pragma omp declare simd
+int foo (int x) __attribute__((noreturn));
+
+#pragma omp declare simd
+int
+bar (int x, int y)
+{
+  if (y == 1)
+    foo (x + 2);
+  if (y == 10)
+    foo (x + 6);
+  if (y != 25)
+    return 4;
+}

	Jakub



More information about the Gcc-patches mailing list