diff options
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cfghooks.c | 7 | ||||
-rw-r--r-- | gcc/cfgloop.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr56350.c | 41 |
5 files changed, 76 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 044ca29cfaa..15a8fd18128 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,14 @@ 2013-02-18 Richard Biener <rguenther@suse.de> + PR middle-end/56350 + * cfghooks.c (merge_blocks): If we merge a latch into another + block adjust references to it. + * cfgloop.c (flow_loops_find): Reset latch before recomputing it. + (verify_loop_structure): Verify that a recorded latch is in fact + a latch. + +2013-02-18 Richard Biener <rguenther@suse.de> + PR tree-optimization/56321 * tree-ssa-reassoc.c (propagate_op_to_single_use): Properly order SSA name release and virtual operand unlinking. diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c index 54f805f5ff9..5e3eeb587b5 100644 --- a/gcc/cfghooks.c +++ b/gcc/cfghooks.c @@ -761,7 +761,12 @@ merge_blocks (basic_block a, basic_block b) { e->src = a; if (current_loops != NULL) - rescan_loop_exit (e, true, false); + { + /* If b was a latch, a now is. */ + if (e->dest->loop_father->latch == b) + e->dest->loop_father->latch = a; + rescan_loop_exit (e, true, false); + } } a->succs = b->succs; a->flags |= b->flags; diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c index 3619907f727..751da5a2c17 100644 --- a/gcc/cfgloop.c +++ b/gcc/cfgloop.c @@ -466,6 +466,8 @@ flow_loops_find (struct loops *loops) "loop %d with header %d\n", loop->num, header->index); } + /* Reset latch, we recompute it below. */ + loop->latch = NULL; larray.safe_push (loop); } @@ -1413,6 +1415,19 @@ verify_loop_structure (void) error ("loop %d%'s header does not have exactly 2 entries", i); err = 1; } + if (loop->latch) + { + if (!find_edge (loop->latch, loop->header)) + { + error ("loop %d%'s latch does not have an edge to its header", i); + err = 1; + } + if (!dominated_by_p (CDI_DOMINATORS, loop->latch, loop->header)) + { + error ("loop %d%'s latch is not dominated by its header", i); + err = 1; + } + } if (loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES)) { if (!single_succ_p (loop->latch)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ac25824326e..f4287ea6878 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2013-02-18 Richard Biener <rguenther@suse.de> + PR middle-end/56350 + * gcc.dg/torture/pr56350.c: New testcase. + +2013-02-18 Richard Biener <rguenther@suse.de> + PR tree-optimization/56321 * gcc.dg/torture/pr56321.c: New testcase. diff --git a/gcc/testsuite/gcc.dg/torture/pr56350.c b/gcc/testsuite/gcc.dg/torture/pr56350.c new file mode 100644 index 00000000000..dc9ed082b8f --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr56350.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ + +int a, b; +short c; + +void f(void) +{ + int a = 0; + int *k = 0; + + for(; a < 2; a++); + + if(!!(b |= a < 3) - 1) + { + if(0) + for (;; a++) + { + for (; c; *k = 0); +lbl1: + ; + } + + for(; *k; k++) + { + c = b ? : a; + + if (c) + lbl2: + b = 0; + } + goto lbl1; + } + + for(;; b++) + { + if(b) + goto lbl2; + + k = &b; + } +} |