On January 31, 2019 11:56:39 PM GMT+01:00, Jakub Jelinek <ja...@redhat.com> wrote: >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?
OK. Richard. >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