diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/loop-invariant.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr78185.c | 28 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-im.c | 13 |
5 files changed, 63 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9222baa..8a455c1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2016-11-04 Richard Biener <rguenther@suse.de> + + PR middle-end/78185 + * loop-invariant.c (find_exits): Record entering inner + loops as possibly exiting to handle infinite sub-loops. + * tree-ssa-loop-im.c: Include tree-ssa-loop-niter.h. + (fill_always_executed_in_1): Honor infinite child loops. + 2016-11-03 Michael Meissner <meissner@linux.vnet.ibm.com> PR target/78192 diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c index 551103f..f617241 100644 --- a/gcc/loop-invariant.c +++ b/gcc/loop-invariant.c @@ -598,13 +598,17 @@ find_exits (struct loop *loop, basic_block *body, FOR_EACH_EDGE (e, ei, body[i]->succs) { - if (flow_bb_inside_loop_p (loop, e->dest)) - continue; - - bitmap_set_bit (may_exit, i); - bitmap_set_bit (has_exit, i); - outermost_exit = find_common_loop (outermost_exit, - e->dest->loop_father); + if (! flow_bb_inside_loop_p (loop, e->dest)) + { + bitmap_set_bit (may_exit, i); + bitmap_set_bit (has_exit, i); + outermost_exit = find_common_loop (outermost_exit, + e->dest->loop_father); + } + /* If we enter a subloop that might never terminate treat + it like a possible exit. */ + if (flow_loop_nested_p (loop, e->dest->loop_father)) + bitmap_set_bit (may_exit, i); } continue; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c62bb93..9451ca9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-11-04 Richard Biener <rguenther@suse.de> + + PR middle-end/78185 + * gcc.dg/pr78185.c: New testcase. + 2016-10-04 David Edelsohn <dje.gcc@gmail.com> * g++.dg/debug/dwarf2/ref-3.C: XFAIL AIX. diff --git a/gcc/testsuite/gcc.dg/pr78185.c b/gcc/testsuite/gcc.dg/pr78185.c new file mode 100644 index 0000000..405f748 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr78185.c @@ -0,0 +1,28 @@ +/* { dg-do run { target *-*-linux* *-*-gnu* } } */ +/* { dg-options "-O" } */ + +#include <unistd.h> +#include <signal.h> +#include <stdlib.h> + +static char var1 = 0L; +static char *var2 = &var1; + +void do_exit (int i) +{ + exit (0); +} + +int main(void) +{ + struct sigaction s; + sigemptyset (&s.sa_mask); + s.sa_handler = do_exit; + s.sa_flags = 0; + sigaction (SIGALRM, &s, NULL); + alarm (1); + /* The following loop is infinite, the division by zero should not + be hoisted out of it. */ + for (; (var1 == 0 ? 0 : (100 / var1)) == *var2; ); + return 0; +} diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c index 463db04..0524e57 100644 --- a/gcc/tree-ssa-loop-im.c +++ b/gcc/tree-ssa-loop-im.c @@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. If not see #include "trans-mem.h" #include "gimple-fold.h" #include "tree-scalar-evolution.h" +#include "tree-ssa-loop-niter.h" /* TODO: Support for predicated code motion. I.e. @@ -2369,8 +2370,16 @@ fill_always_executed_in_1 (struct loop *loop, sbitmap contains_call) break; FOR_EACH_EDGE (e, ei, bb->succs) - if (!flow_bb_inside_loop_p (loop, e->dest)) - break; + { + /* If there is an exit from this BB. */ + if (!flow_bb_inside_loop_p (loop, e->dest)) + break; + /* Or we enter a possibly non-finite loop. */ + if (flow_loop_nested_p (bb->loop_father, + e->dest->loop_father) + && ! finite_loop_p (e->dest->loop_father)) + break; + } if (e) break; |