ifcvt is confused about fake edges not being loop exits which the following fixes.
Bootstrap / regtest pending on x86_64-unknown-linux-gnu. Richard. 2016-05-10 Richard Biener <rguent...@suse.de> PR tree-optimization/70986 * cfganal.c: Include cfgloop.h. (connect_infinite_loops_to_exit): Properly register fake edges as loop exits. * gcc.dg/torture/pr70986-1.c: New testcase. * gcc.dg/torture/pr70986-2.c: Likewise. * gcc.dg/torture/pr70986-3.c: Likewise. Index: gcc/cfganal.c =================================================================== --- gcc/cfganal.c (revision 236069) +++ gcc/cfganal.c (working copy) @@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. #include "cfghooks.h" #include "timevar.h" #include "cfganal.h" +#include "cfgloop.h" /* Store the data structures necessary for depth-first search. */ struct depth_first_search_ds { @@ -602,7 +603,10 @@ connect_infinite_loops_to_exit (void) break; deadend_block = dfs_find_deadend (unvisited_block); - make_edge (deadend_block, EXIT_BLOCK_PTR_FOR_FN (cfun), EDGE_FAKE); + edge e = make_edge (deadend_block, EXIT_BLOCK_PTR_FOR_FN (cfun), + EDGE_FAKE); + if (current_loops != NULL) + rescan_loop_exit (e, true, false); flow_dfs_compute_reverse_add_bb (&dfs_ds, deadend_block); } Index: gcc/testsuite/gcc.dg/torture/pr70986-1.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr70986-1.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/pr70986-1.c (working copy) @@ -0,0 +1,22 @@ +/* { dg-do compile } */ + +int a, g; +char b, c; +short d, e, f; + +char +fn1 () +{ + return a ? a : 1; +} + +void +fn2 () +{ + char h; + for (; d;) + for (; e; e++) + c = (fn1 () && h) & !(f |= 9 ^ (b > (g = c))); + for (;;) + ; +} Index: gcc/testsuite/gcc.dg/torture/pr70986-2.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr70986-2.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/pr70986-2.c (working copy) @@ -0,0 +1,20 @@ +/* { dg-do compile } */ + +int gi, dg; + +void +fe (void) +{ + int ka = gi; + + for (;;) + { + if (ka != 0) + { + if (dg != 0) + gi = 0; + ++ka; + } + ++dg; + } +} Index: gcc/testsuite/gcc.dg/torture/pr70986-3.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr70986-3.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/pr70986-3.c (working copy) @@ -0,0 +1,18 @@ +/* { dg-do compile } */ + +int a, b; +int +fn1 (int p1) +{ + return p1 < 0 ? p1 : a; +} + +void +fn2 () +{ +lbl_100: + b = 1; + for (; b != 21; b = fn1 (b)) + ; + goto lbl_100; +}