aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2013-02-11 15:07:40 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2013-02-11 15:07:40 +0000
commit8e89b5b5fbe131046e8f8905c455a52fd9378e28 (patch)
tree51f6d16e5f451e7162e917a8e60c40e7bd15004f /gcc
parentb4a4b56dc7ff0bb336abd777cb8f2437cd05909b (diff)
downloadgcc-8e89b5b5fbe131046e8f8905c455a52fd9378e28.zip
gcc-8e89b5b5fbe131046e8f8905c455a52fd9378e28.tar.gz
gcc-8e89b5b5fbe131046e8f8905c455a52fd9378e28.tar.bz2
re PR tree-optimization/56264 (ICE in check_loop_closed_ssa_use, at tree-ssa-loop-manip.c:557)
2013-02-11 Richard Biener <rguenther@suse.de> PR tree-optimization/56264 * cfgloop.h (fix_loop_structure): Adjust prototype. * loop-init.c (fix_loop_structure): Return the number of newly discovered loops. * tree-cfgcleanup.c (repair_loop_structures): When new loops are discovered, do a full loop-closed SSA rewrite. * gcc.dg/torture/pr56264.c: New testcase. From-SVN: r195941
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/cfgloop.h2
-rw-r--r--gcc/loop-init.c15
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr56264.c20
-rw-r--r--gcc/tree-cfgcleanup.c10
6 files changed, 54 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4c69a8d..0cdcc3c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,14 @@
2013-02-11 Richard Biener <rguenther@suse.de>
+ PR tree-optimization/56264
+ * cfgloop.h (fix_loop_structure): Adjust prototype.
+ * loop-init.c (fix_loop_structure): Return the number of
+ newly discovered loops.
+ * tree-cfgcleanup.c (repair_loop_structures): When new loops
+ are discovered, do a full loop-closed SSA rewrite.
+
+2013-02-11 Richard Biener <rguenther@suse.de>
+
PR tree-optimization/56273
* tree-vrp.c (simplify_cond_using_ranges): Disable for the
first VRP run.
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 7506ac5..0b2af72 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -216,7 +216,7 @@ extern void flow_loop_dump (const struct loop *, FILE *,
struct loop *alloc_loop (void);
extern void flow_loop_free (struct loop *);
int flow_loop_nodes_find (basic_block, struct loop *);
-void fix_loop_structure (bitmap changed_bbs);
+unsigned fix_loop_structure (bitmap changed_bbs);
bool mark_irreducible_loops (void);
void release_recorded_exits (void);
void record_loop_exits (void);
diff --git a/gcc/loop-init.c b/gcc/loop-init.c
index d64c110..5b3fd63 100644
--- a/gcc/loop-init.c
+++ b/gcc/loop-init.c
@@ -171,16 +171,19 @@ loop_fini_done:
the latch, and loops did not get new subloops (new loops might possibly
get created, but we are not interested in them). Fix up the mess.
- If CHANGED_BBS is not NULL, basic blocks whose loop has changed are
- marked in it. */
+ If CHANGED_BBS is not NULL, basic blocks whose loop depth has changed are
+ marked in it.
-void
+ Returns the number of new discovered loops. */
+
+unsigned
fix_loop_structure (bitmap changed_bbs)
{
basic_block bb;
int record_exits = 0;
loop_iterator li;
struct loop *loop;
+ unsigned old_nloops;
timevar_push (TV_LOOP_INIT);
@@ -228,6 +231,10 @@ fix_loop_structure (bitmap changed_bbs)
delete_loop (loop);
}
+ /* Remember the number of loops so we can return how many new loops
+ flow_loops_find discovered. */
+ old_nloops = number_of_loops ();
+
/* Re-compute loop structure in-place. */
flow_loops_find (current_loops);
@@ -253,6 +260,8 @@ fix_loop_structure (bitmap changed_bbs)
#endif
timevar_pop (TV_LOOP_INIT);
+
+ return number_of_loops () - old_nloops;
}
/* Gate for the RTL loop superpass. The actual passes are subpasses.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e21dbf7..f5ada1c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2013-02-11 Richard Biener <rguenther@suse.de>
+ PR tree-optimization/56264
+ * gcc.dg/torture/pr56264.c: New testcase.
+
+2013-02-11 Richard Biener <rguenther@suse.de>
+
PR tree-optimization/56273
* g++.dg/warn/Warray-bounds-6.C: New testcase.
* gcc.dg/tree-ssa/pr21559.c: Adjust.
diff --git a/gcc/testsuite/gcc.dg/torture/pr56264.c b/gcc/testsuite/gcc.dg/torture/pr56264.c
new file mode 100644
index 0000000..ca5eb47
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr56264.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-funswitch-loops" } */
+
+int a, b, c;
+
+void f(void)
+{
+ if(b)
+ {
+ for(a = 0; a < 1; a++)
+ lbl:
+ c = c && b ? : 0;
+
+ c = 0;
+ goto lbl;
+ }
+
+ if(a)
+ goto lbl;
+}
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index b26281d..94e616b 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -707,18 +707,22 @@ static void
repair_loop_structures (void)
{
bitmap changed_bbs;
+ unsigned n_new_loops;
calculate_dominance_info (CDI_DOMINATORS);
timevar_push (TV_REPAIR_LOOPS);
changed_bbs = BITMAP_ALLOC (NULL);
- fix_loop_structure (changed_bbs);
+ n_new_loops = fix_loop_structure (changed_bbs);
/* This usually does nothing. But sometimes parts of cfg that originally
were inside a loop get out of it due to edge removal (since they
- become unreachable by back edges from latch). */
+ become unreachable by back edges from latch). Also a former
+ irreducible loop can become reducible - in this case force a full
+ rewrite into loop-closed SSA form. */
if (loops_state_satisfies_p (LOOP_CLOSED_SSA))
- rewrite_into_loop_closed_ssa (changed_bbs, TODO_update_ssa);
+ rewrite_into_loop_closed_ssa (n_new_loops ? NULL : changed_bbs,
+ TODO_update_ssa);
BITMAP_FREE (changed_bbs);