Hi! The problem on this testcase is that ldist pass changes some GIMPLE_CONDs into 0 != 0 or similar, but the pass doesn't perform any cleanups, then ifcvt is run and does completely useless work of duplicating dead loops and guarding them with LOOP_VECTORIZED ifns, and then during the ifcvt cfg cleanup the dead loops are optimized away, but nothing removes the corresponding LOOP_VECTORIZED ifns. While perhaps we'll need to hook into the loop removal and remove the dead ifns or remove the dead ifns during vectorizer pass using a more expensive way at some point (e.g. by scanning all bb's last insn for GIMPLE_COND checking LOOP_VECTORIZED) at some point, in this case it seems to me clearly preferrable to let the ldist pass clean up after itself, so that we don't do useless work in ifcvt from the beginning.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2017-12-30 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/83581 * tree-loop-distribution.c (pass_loop_distribution::execute): Return TODO_cleanup_cfg if any changes have been made. * gcc.dg/pr83581.c: New test. --- gcc/tree-loop-distribution.c.jj 2017-12-21 09:43:17.486071696 +0100 +++ gcc/tree-loop-distribution.c 2017-12-30 16:54:08.106143319 +0100 @@ -3103,7 +3103,7 @@ pass_loop_distribution::execute (functio checking_verify_loop_structure (); - return 0; + return changed ? TODO_cleanup_cfg : 0; } } // anon namespace --- gcc/testsuite/gcc.dg/pr83581.c.jj 2017-12-30 16:55:35.950164947 +0100 +++ gcc/testsuite/gcc.dg/pr83581.c 2017-12-30 16:55:17.520160406 +0100 @@ -0,0 +1,21 @@ +/* PR tree-optimization/83581 */ +/* { dg-do compile } */ +/* { dg-options "-O3 -fno-tree-copy-prop -fno-tree-loop-im" } */ + +int a, b, c; + +int +foo (int x) +{ + int *d = &x; + while (a < 1) + { + for (b = 0; b < 2; ++b) + { + *d += !!x + 1; + d = &c; + } + ++a; + } + return *d; +} Jakub