Bootstrapped and tested on x86_64-unknown-linux-gnu, applied. Richard.
2017-07-25 Richard Biener <rguent...@suse.de> PR tree-optimization/81455 * tree-ssa-loop-unswitch.c (find_loop_guard): Make sure to not walk in cycles when looking for guards. * gcc.dg/pr81455.c: New testcase. Index: gcc/tree-ssa-loop-unswitch.c =================================================================== --- gcc/tree-ssa-loop-unswitch.c (revision 250494) +++ gcc/tree-ssa-loop-unswitch.c (working copy) @@ -582,8 +582,9 @@ find_loop_guard (struct loop *loop) gcond *cond; do { + basic_block next = NULL; if (single_succ_p (header)) - header = single_succ (header); + next = single_succ (header); else { cond = dyn_cast <gcond *> (last_stmt (header)); @@ -593,12 +594,16 @@ find_loop_guard (struct loop *loop) /* Make sure to skip earlier hoisted guards that are left in place as if (true). */ if (gimple_cond_true_p (cond)) - header = te->dest; + next = te->dest; else if (gimple_cond_false_p (cond)) - header = fe->dest; + next = fe->dest; else break; } + /* Never traverse a backedge. */ + if (header->loop_father->header == next) + return NULL; + header = next; } while (1); if (!flow_bb_inside_loop_p (loop, te->dest) Index: gcc/testsuite/gcc.dg/pr81455.c =================================================================== --- gcc/testsuite/gcc.dg/pr81455.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr81455.c (working copy) @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O -funswitch-loops" } */ + +void +jh (unsigned int aw, int sn) +{ + int xs; + + for (xs = 0; xs < 1; ++xs) + aw &= 1; + + while (aw < 1 || ++sn < 1) + { + } +}