summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/cfghooks.c7
-rw-r--r--gcc/cfgloop.c15
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr56350.c41
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;
+ }
+}