diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 32a94eb7c32..aab0e3abb3d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-12-18 Yuri Rumyantsev + + PR tree-optimization/68906 + * tree-ssa-loop-unswitch.c (tree_unswitch_outer_loop): Add check + that an exit block belongs to LOOP. + 2015-12-18 Ilya Enkovich PR tree-optimization/68956 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6120ed1b2f3..eee04341709 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-12-18 Yuri Rumyantsev + + PR tree-optimization/68906 + * gcc.dg/torture/pr68906.c: New test. + 2015-12-18 Ilya Enkovich PR tree-optimization/68956 diff --git a/gcc/testsuite/gcc.dg/torture/pr68906.c b/gcc/testsuite/gcc.dg/torture/pr68906.c new file mode 100644 index 00000000000..8c89bbd2ea4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr68906.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +int a; +volatile int b; +short c, d; +int +fn1 () +{ + int e; + for (;;) + { + a = 3; + if (c) + continue; + e = 0; + for (; e > -30; e--) + if (b) + { + int f = e; + return d; + } + } +} diff --git a/gcc/tree-ssa-loop-unswitch.c b/gcc/tree-ssa-loop-unswitch.c index c340bcb2c04..a17c60e927c 100644 --- a/gcc/tree-ssa-loop-unswitch.c +++ b/gcc/tree-ssa-loop-unswitch.c @@ -429,9 +429,9 @@ tree_unswitch_outer_loop (struct loop *loop) gcc_assert (loop->inner); if (loop->inner->next) return false; - /* Accept loops with single exit only. */ + /* Accept loops with single exit only which is not from inner loop. */ exit = single_exit (loop); - if (!exit) + if (!exit || exit->src->loop_father != loop) return false; /* Check that phi argument of exit edge is not defined inside loop. */ if (!check_exit_phi (loop))