This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR60903
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 23 Apr 2014 13:19:57 +0200 (CEST)
- Subject: [PATCH] Fix PR60903
- Authentication-results: sourceware.org; auth=none
LIM fails to properly mark new blocks/edges it creates as
belonging to irreducible regions.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk
and 4.9 branch.
Richard.
2014-04-23 Richard Biener <rguenther@suse.de>
PR tree-optimization/60903
* tree-ssa-loop-im.c (analyze_memory_references): Remove
commented code block.
(execute_sm_if_changed): Properly apply IRREDUCIBLE_LOOP
loop flags to newly created BBs and edges.
* gcc.dg/torture/pr60903.c: New testcase.
Index: gcc/tree-ssa-loop-im.c
===================================================================
*** gcc/tree-ssa-loop-im.c (revision 209677)
--- gcc/tree-ssa-loop-im.c (working copy)
*************** analyze_memory_references (void)
*** 1544,1558 ****
struct loop *loop, *outer;
unsigned i, n;
- #if 0
- /* Initialize bb_loop_postorder with a mapping from loop->num to
- its postorder index. */
- i = 0;
- bb_loop_postorder = XNEWVEC (unsigned, number_of_loops (cfun));
- FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
- bb_loop_postorder[loop->num] = i++;
- #endif
-
/* Collect all basic-blocks in loops and sort them after their
loops postorder. */
i = 0;
--- 1547,1552 ----
*************** execute_sm_if_changed (edge ex, tree mem
*** 1807,1812 ****
--- 1803,1809 ----
gimple_stmt_iterator gsi;
gimple stmt;
struct prev_flag_edges *prev_edges = (struct prev_flag_edges *) ex->aux;
+ bool irr = ex->flags & EDGE_IRREDUCIBLE_LOOP;
/* ?? Insert store after previous store if applicable. See note
below. */
*************** execute_sm_if_changed (edge ex, tree mem
*** 1821,1828 ****
old_dest = ex->dest;
new_bb = split_edge (ex);
then_bb = create_empty_bb (new_bb);
! if (current_loops && new_bb->loop_father)
! add_bb_to_loop (then_bb, new_bb->loop_father);
gsi = gsi_start_bb (new_bb);
stmt = gimple_build_cond (NE_EXPR, flag, boolean_false_node,
--- 1818,1826 ----
old_dest = ex->dest;
new_bb = split_edge (ex);
then_bb = create_empty_bb (new_bb);
! if (irr)
! then_bb->flags = BB_IRREDUCIBLE_LOOP;
! add_bb_to_loop (then_bb, new_bb->loop_father);
gsi = gsi_start_bb (new_bb);
stmt = gimple_build_cond (NE_EXPR, flag, boolean_false_node,
*************** execute_sm_if_changed (edge ex, tree mem
*** 1834,1842 ****
stmt = gimple_build_assign (unshare_expr (mem), tmp_var);
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
! make_edge (new_bb, then_bb, EDGE_TRUE_VALUE);
! make_edge (new_bb, old_dest, EDGE_FALSE_VALUE);
! then_old_edge = make_edge (then_bb, old_dest, EDGE_FALLTHRU);
set_immediate_dominator (CDI_DOMINATORS, then_bb, new_bb);
--- 1832,1843 ----
stmt = gimple_build_assign (unshare_expr (mem), tmp_var);
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
! make_edge (new_bb, then_bb,
! EDGE_TRUE_VALUE | (irr ? EDGE_IRREDUCIBLE_LOOP : 0));
! make_edge (new_bb, old_dest,
! EDGE_FALSE_VALUE | (irr ? EDGE_IRREDUCIBLE_LOOP : 0));
! then_old_edge = make_edge (then_bb, old_dest,
! EDGE_FALLTHRU | (irr ? EDGE_IRREDUCIBLE_LOOP : 0));
set_immediate_dominator (CDI_DOMINATORS, then_bb, new_bb);
Index: gcc/testsuite/gcc.dg/torture/pr60903.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr60903.c (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr60903.c (working copy)
***************
*** 0 ****
--- 1,22 ----
+ /* { dg-do compile } */
+
+ extern int a, b, k, q;
+
+ void
+ foo ()
+ {
+ if (a)
+ {
+ while (q)
+ {
+ lbl:
+ if (a)
+ {
+ a = 0;
+ goto lbl;
+ }
+ }
+ b = k;
+ }
+ goto lbl;
+ }