Hi, this patch by Andrey fixes iteration in get_all_loop_headers where we want to visit only inner loops, not the outer loop.
Alexander 2019-04-02 Andrey Belevantsev <a...@ispras.ru> PR rtl-optimization/84206 * sel-sched-ir.h (get_all_loop_exits): Avoid the outer loop when iterating over loop headers. * gcc.dg/pr84206.c: New test. diff --git a/gcc/sel-sched-ir.h b/gcc/sel-sched-ir.h index 1d9c04a322a..5dd273f40a4 100644 --- a/gcc/sel-sched-ir.h +++ b/gcc/sel-sched-ir.h @@ -1144,6 +1144,7 @@ get_all_loop_exits (basic_block bb) struct loop *this_loop; struct loop *pred_loop = NULL; int i; + unsigned this_depth; edge e; for (this_loop = bb->loop_father; @@ -1155,11 +1156,14 @@ get_all_loop_exits (basic_block bb) gcc_assert (this_loop != NULL); exits = get_loop_exit_edges_unique_dests (this_loop); + this_depth = loop_depth (this_loop); - /* Traverse all loop headers. */ + /* Traverse all loop headers. Be careful not to go back + to the outer loop's header (see PR 84206). */ for (i = 0; exits.iterate (i, &e); i++) - if (in_current_region_p (e->dest) - || inner_loop_header_p (e->dest)) + if ((in_current_region_p (e->dest) + || (inner_loop_header_p (e->dest))) + && loop_depth (e->dest->loop_father) >= this_depth) { vec<edge> next_exits = get_all_loop_exits (e->dest); diff --git a/gcc/testsuite/gcc.dg/pr84206.c b/gcc/testsuite/gcc.dg/pr84206.c new file mode 100644 index 00000000000..b4ac9c24c78 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr84206.c @@ -0,0 +1,24 @@ +/* { dg-do compile { target powerpc*-*-* ia64-*-* i?86-*-* x86_64-*-* } } */ +/* { dg-options "-O2 -fselective-scheduling -fsel-sched-pipelining -fsel-sched-pipelining-outer-loops -fno-forward-propagate -fno-tree-fre -w" } */ + +long long unsigned int ao; +int hk; + +void +b8 (void) +{ + int *w9; + + c8: + ao = 0; + w9 = &ao; + for (;;) + for (hk = 0; hk < 1; ++hk) + for (ao = 0; ao < 4; ++ao) + { + int f4 = (ao != 0) ? *w9 : hk; + + if (f4 != 0) + goto c8; + } +}