Hi!

While OpenMP parsing ensures the parallel, task, taskloop, target, teams
etc. body are wrapped in ERT_MUST_NOT_THROW EH regions, for parloops we can
actually end up with multiple different EH regions.  If they still have some
common outer region, perhaps covering much bigger part of code than the
region itself, we still handle it by duplicating perhaps more of EH tree
than strictly necessary (but it isn't that easy to determine what are all
the roots we want to copy), if there isn't a common outer region, we ICE.

The following patch just extends what we are actually doing to copying the
whole EH tree of the function in that case, eh cleanups can remove
unreachable regions later on.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2019-01-31  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/88107
        * tree-cfg.c (find_outermost_region_in_block): Add ALL argument,
        instead of assertion that eh_region_outermost is non-NULL, if it
        is NULL, set *ALL to true and return NULL.
        (move_sese_region_to_fn): Adjust caller, if all is set, call
        duplicate_eh_regions with NULL region.

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

--- gcc/tree-cfg.c.jj   2019-01-28 11:33:14.704888408 +0100
+++ gcc/tree-cfg.c      2019-01-31 17:17:58.357007322 +0100
@@ -7143,11 +7143,14 @@ move_block_to_fn (struct function *dest_
 }
 
 /* Examine the statements in BB (which is in SRC_CFUN); find and return
-   the outermost EH region.  Use REGION as the incoming base EH region.  */
+   the outermost EH region.  Use REGION as the incoming base EH region.
+   If there is no single outermost region, return NULL and set *ALL to
+   true.  */
 
 static eh_region
 find_outermost_region_in_block (struct function *src_cfun,
-                               basic_block bb, eh_region region)
+                               basic_block bb, eh_region region,
+                               bool *all)
 {
   gimple_stmt_iterator si;
 
@@ -7166,7 +7169,11 @@ find_outermost_region_in_block (struct f
          else if (stmt_region != region)
            {
              region = eh_region_outermost (src_cfun, stmt_region, region);
-             gcc_assert (region != NULL);
+             if (region == NULL)
+               {
+                 *all = true;
+                 return NULL;
+               }
            }
        }
     }
@@ -7501,12 +7508,17 @@ move_sese_region_to_fn (struct function
   if (saved_cfun->eh)
     {
       eh_region region = NULL;
+      bool all = false;
 
       FOR_EACH_VEC_ELT (bbs, i, bb)
-       region = find_outermost_region_in_block (saved_cfun, bb, region);
+       {
+         region = find_outermost_region_in_block (saved_cfun, bb, region, 
&all);
+         if (all)
+           break;
+       }
 
       init_eh_for_function ();
-      if (region != NULL)
+      if (region != NULL || all)
        {
          new_label_map = htab_create (17, tree_map_hash, tree_map_eq, free);
          eh_map = duplicate_eh_regions (saved_cfun, region, 0,
--- gcc/testsuite/gcc.dg/gomp/pr88107.c.jj      2019-01-31 18:11:53.605582170 
+0100
+++ gcc/testsuite/gcc.dg/gomp/pr88107.c 2019-01-31 18:10:43.100745223 +0100
@@ -0,0 +1,35 @@
+/* PR tree-optimization/88107 */
+/* { dg-do compile { target fgraphite } } */
+/* { dg-require-effective-target vect_simd_clones } */
+/* { dg-options "-O2 -fexceptions -floop-nest-optimize -fnon-call-exceptions 
-fopenmp-simd -ftree-parallelize-loops=2" } */
+
+#define N 1024
+int a[N], b[N];
+long int c[N];
+unsigned char d[N];
+
+#pragma omp declare simd notinbranch
+__attribute__((noinline)) static int
+foo (long int a, int b, int c)
+{
+  return a + b + c;
+}
+
+#pragma omp declare simd notinbranch
+__attribute__((noinline)) static long int
+bar (int a, int b, long int c)
+{
+  return a + b + c;
+}
+
+void
+baz (void)
+{
+  int i;
+  #pragma omp simd
+  for (i = 0; i < N; i++)
+    a[i] = foo (c[i], a[i], b[i]) + 6;
+  #pragma omp simd
+  for (i = 0; i < N; i++)
+    c[i] = bar (a[i], b[i], c[i]) * 2;
+}

        Jakub

Reply via email to