From 1bd3f7500b7223cded3ae19ff27eb27e05a9b147 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Thu, 17 Jan 2013 19:19:37 +0000 Subject: [PATCH] Fix PR55833. From-SVN: r195280 --- gcc/ChangeLog | 12 ++++++++++++ gcc/cfgloopmanip.c | 18 +++++++++++++----- gcc/loop-unswitch.c | 11 +++++------ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/pr55833.c | 28 ++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr55833.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d7816844a51..773f4d7221b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2013-01-17 Richard Biener + Marek Polacek + + PR rtl-optimization/55833 + * loop-unswitch.c (unswitch_loops): Move loop verification... + (unswitch_single_loop): ...here. Call mark_irreducible_loops. + * cfgloopmanip.c (fix_loop_placement): Add IRRED_INVALIDATED parameter. + Set it to true when we're removing a loop from hierarchy tree in + an irreducible region. + (fix_bb_placements): Adjust caller. + (fix_loop_placements): Likewise. + 2013-01-17 Georg-Johann Lay * config/avr/builtins.def (DEF_BUILTIN): Factor out diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c index 487560734fa..8c6c39de86b 100644 --- a/gcc/cfgloopmanip.c +++ b/gcc/cfgloopmanip.c @@ -111,10 +111,13 @@ fix_bb_placement (basic_block bb) /* Fix placement of LOOP inside loop tree, i.e. find the innermost superloop of LOOP to that leads at least one exit edge of LOOP, and set it as the immediate superloop of LOOP. Return true if the immediate superloop - of LOOP changed. */ + of LOOP changed. + + IRRED_INVALIDATED is set to true if a change in the loop structures might + invalidate the information about irreducible regions. */ static bool -fix_loop_placement (struct loop *loop) +fix_loop_placement (struct loop *loop, bool *irred_invalidated) { unsigned i; edge e; @@ -139,7 +142,12 @@ fix_loop_placement (struct loop *loop) /* The exit edges of LOOP no longer exits its original immediate superloops; remove them from the appropriate exit lists. */ FOR_EACH_VEC_ELT (exits, i, e) - rescan_loop_exit (e, false, false); + { + /* We may need to recompute irreducible loops. */ + if (e->flags & EDGE_IRREDUCIBLE_LOOP) + *irred_invalidated = true; + rescan_loop_exit (e, false, false); + } ret = true; } @@ -212,7 +220,7 @@ fix_bb_placements (basic_block from, if (from->loop_father->header == from) { /* Subloop header, maybe move the loop upward. */ - if (!fix_loop_placement (from->loop_father)) + if (!fix_loop_placement (from->loop_father, irred_invalidated)) continue; target_loop = loop_outer (from->loop_father); } @@ -965,7 +973,7 @@ fix_loop_placements (struct loop *loop, bool *irred_invalidated) while (loop_outer (loop)) { outer = loop_outer (loop); - if (!fix_loop_placement (loop)) + if (!fix_loop_placement (loop, irred_invalidated)) break; /* Changing the placement of a loop in the loop tree may alter the diff --git a/gcc/loop-unswitch.c b/gcc/loop-unswitch.c index 25cbf181283..ded0aed3e0e 100644 --- a/gcc/loop-unswitch.c +++ b/gcc/loop-unswitch.c @@ -144,12 +144,7 @@ unswitch_loops (void) /* Go through inner loops (only original ones). */ FOR_EACH_LOOP (li, loop, LI_ONLY_INNERMOST) - { - unswitch_single_loop (loop, NULL_RTX, 0); -#ifdef ENABLE_CHECKING - verify_loop_structure (); -#endif - } + unswitch_single_loop (loop, NULL_RTX, 0); iv_analysis_done (); } @@ -369,6 +364,10 @@ unswitch_single_loop (struct loop *loop, rtx cond_checked, int num) nloop = unswitch_loop (loop, bbs[i], copy_rtx_if_shared (cond), cinsn); gcc_assert (nloop); +#ifdef ENABLE_CHECKING + verify_loop_structure (); +#endif + /* Invoke itself on modified loops. */ unswitch_single_loop (nloop, rconds, num + 1); unswitch_single_loop (loop, conds, num + 1); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bfdb73ae5b4..1bd5ca36ded 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-01-17 Marek Polacek + + PR rtl-optimization/55833 + * gcc.dg/pr55833.c: New test. + 2013-01-17 Jan Hubicka PR tree-optimization/55273 diff --git a/gcc/testsuite/gcc.dg/pr55833.c b/gcc/testsuite/gcc.dg/pr55833.c new file mode 100644 index 00000000000..7a5c549d786 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr55833.c @@ -0,0 +1,28 @@ +/* PR rtl-optimization/55833 */ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +int a, b, c; + +void foo() +{ + unsigned d, l, *p, k = 1; + + if(bar()) + { +label: + if((a = a <= 0)) + { + if(c) + d = b; + + if (b || d ? l : k ? : 0) + a = d = 0; + + goto label; + } + } + + while(*p++) + goto label; +} -- 2.30.2