On Wed, 1 Feb 2017, Richard Biener wrote: > Applied as follows, bootstrapped & tested on x86_64-unknown-linux-gnu.
And as shown by the new testcase (ICEing on the gcc-6-branch only) the fix is not enough as breadth merging of loop and loop->next may pull in other loops into the region. Eventually this also shows that only trying to merge loop with loop->next may not find all valid scops as loop and loop->next->next may eventually be successfully merged (inner loops of a loop are not sorted in any particular way, SCoP dection seems to assume dominance order). Bootstrap / regtest running on x86_64-unknown-linux-gnu. Thanks, Richard. 2017-02-07 Richard Biener <rguent...@suse.de> PR tree-optimization/71824 * graphite-scop-detection.c (scop_detection::build_scop_breadth): Check all loops contained in the merged region. * gcc.dg/graphite/pr71824-2.c: New testcase. Index: gcc/graphite-scop-detection.c =================================================================== --- gcc/graphite-scop-detection.c (revision 245243) +++ gcc/graphite-scop-detection.c (working copy) @@ -905,9 +905,19 @@ scop_detection::build_scop_breadth (sese sese_l combined = merge_sese (s1, s2); - if (combined - && loop_is_valid_in_scop (loop, combined) - && loop_is_valid_in_scop (loop->next, combined)) + /* Combining adjacent loops may add unrelated loops into the + region so we have to check all sub-loops of the outer loop + that are in the combined region. */ + if (combined) + for (l = loop_outer (loop)->inner; l; l = l->next) + if (bb_in_sese_p (l->header, combined) + && ! loop_is_valid_in_scop (l, combined)) + { + combined = invalid_sese; + break; + } + + if (combined) s1 = combined; else add_scop (s2); Index: gcc/testsuite/gcc.dg/graphite/pr71824-2.c =================================================================== --- gcc/testsuite/gcc.dg/graphite/pr71824-2.c (nonexistent) +++ gcc/testsuite/gcc.dg/graphite/pr71824-2.c (working copy) @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -floop-nest-optimize" } */ + +typedef struct { float x1; } bx; +typedef struct { + int w; + short o; +} T2P; +T2P a; +int b; +void fn2(); +void fn3(bx*,short); +void fn1() { + unsigned i = 0; + int c; + bx *d; + bx **h; + if (b == 0) { + fn2(); + return; + } + for (; c; c++) + for (; i < 100; i++) { + d = h[i]; + d->x1 = a.w; + } + for (; i < 100; i++) { + d = h[i]; + d->x1 = a.w; + } + if (a.o) + for (; b;) + fn3(d, a.o); +}