+2013-01-17 Richard Biener <rguenther@suse.de>
+ Marek Polacek <polacek@redhat.com>
+
+ 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 <avr@gjlay.de>
* config/avr/builtins.def (DEF_BUILTIN): Factor out
/* 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;
/* 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;
}
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);
}
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
/* 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 ();
}
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);
+2013-01-17 Marek Polacek <polacek@redhat.com>
+
+ PR rtl-optimization/55833
+ * gcc.dg/pr55833.c: New test.
+
2013-01-17 Jan Hubicka <jh@suse.cz>
PR tree-optimization/55273
--- /dev/null
+/* 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;
+}