From: Richard Biener Date: Mon, 13 May 2019 11:37:21 +0000 (+0000) Subject: re PR tree-optimization/90402 (ICE in slpeel_duplicate_current_defs_from_edges) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=40289199ee725183a286f50cf448f6347267047e;p=gcc.git re PR tree-optimization/90402 (ICE in slpeel_duplicate_current_defs_from_edges) 2019-05-13 Richard Biener PR tree-optimization/90402 * tree-if-conv.c (tree_if_conversion): Value number only the loop body by making the latch an exit of the region as well. * tree-ssa-sccvn.c (process_bb): Add flag whether to skip processing PHIs. (do_rpo_vn): Deal with multiple edges into the entry block that are not backedges inside the region by skipping PHIs of the entry block. * gcc.dg/torture/pr90402-1.c: New testcase. From-SVN: r271125 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 42448f5ef85..925d23ca69d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2019-05-13 Richard Biener + + PR tree-optimization/90402 + * tree-if-conv.c (tree_if_conversion): Value number only + the loop body by making the latch an exit of the region + as well. + * tree-ssa-sccvn.c (process_bb): Add flag whether to skip + processing PHIs. + (do_rpo_vn): Deal with multiple edges into the entry block + that are not backedges inside the region by skipping PHIs + of the entry block. + 2019-05-13 Richard Biener PR tree-optimization/90316 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 286bfe285ee..ebefd00c02d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-05-13 Richard Biener + + PR tree-optimization/90402 + * gcc.dg/torture/pr90402-1.c: New testcase. + 2019-05-12 Iain Sandoe Dominique d'Humieres diff --git a/gcc/testsuite/gcc.dg/torture/pr90402-1.c b/gcc/testsuite/gcc.dg/torture/pr90402-1.c new file mode 100644 index 00000000000..c4bd8945ed5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr90402-1.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-mavx" { target x86_64-*-* i?86-*-* } } */ + +int kn, ha; + +int +c7 (void) +{ +} + +void +ul (int w3) +{ + kn = c7 (); + + while (w3 < 1) + { + ha += !!kn ? 1 : w3; + + for (kn = 0; kn < 2; ++kn) + { + } + + ++w3; + } +} diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index ec2db007a61..98566e3fd19 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -3066,10 +3066,12 @@ tree_if_conversion (struct loop *loop, vec *preds) ifcvt_local_dce (loop->header); /* Perform local CSE, this esp. helps the vectorizer analysis if loads - and stores are involved. + and stores are involved. CSE only the loop body, not the entry + PHIs, those are to be kept in sync with the non-if-converted copy. ??? We'll still keep dead stores though. */ exit_bbs = BITMAP_ALLOC (NULL); bitmap_set_bit (exit_bbs, single_exit (loop)->dest->index); + bitmap_set_bit (exit_bbs, loop->latch->index); todo |= do_rpo_vn (cfun, loop_preheader_edge (loop), exit_bbs); BITMAP_FREE (exit_bbs); diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index c3ca49bd867..b4f626000dd 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -5979,7 +5979,7 @@ insert_related_predicates_on_edge (enum tree_code code, tree *ops, edge pred_e) static unsigned process_bb (rpo_elim &avail, basic_block bb, bool bb_visited, bool iterate_phis, bool iterate, bool eliminate, - bool do_region, bitmap exit_bbs) + bool do_region, bitmap exit_bbs, bool skip_phis) { unsigned todo = 0; edge_iterator ei; @@ -5990,7 +5990,8 @@ process_bb (rpo_elim &avail, basic_block bb, /* If we are in loop-closed SSA preserve this state. This is relevant when called on regions from outside of FRE/PRE. */ bool lc_phi_nodes = false; - if (loops_state_satisfies_p (LOOP_CLOSED_SSA)) + if (!skip_phis + && loops_state_satisfies_p (LOOP_CLOSED_SSA)) FOR_EACH_EDGE (e, ei, bb->preds) if (e->src->loop_father != e->dest->loop_father && flow_loop_nested_p (e->dest->loop_father, @@ -6011,67 +6012,68 @@ process_bb (rpo_elim &avail, basic_block bb, } /* Value-number all defs in the basic-block. */ - for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi); - gsi_next (&gsi)) - { - gphi *phi = gsi.phi (); - tree res = PHI_RESULT (phi); - vn_ssa_aux_t res_info = VN_INFO (res); - if (!bb_visited) - { - gcc_assert (!res_info->visited); - res_info->valnum = VN_TOP; - res_info->visited = true; - } + if (!skip_phis) + for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi); + gsi_next (&gsi)) + { + gphi *phi = gsi.phi (); + tree res = PHI_RESULT (phi); + vn_ssa_aux_t res_info = VN_INFO (res); + if (!bb_visited) + { + gcc_assert (!res_info->visited); + res_info->valnum = VN_TOP; + res_info->visited = true; + } - /* When not iterating force backedge values to varying. */ - visit_stmt (phi, !iterate_phis); - if (virtual_operand_p (res)) - continue; + /* When not iterating force backedge values to varying. */ + visit_stmt (phi, !iterate_phis); + if (virtual_operand_p (res)) + continue; - /* Eliminate */ - /* The interesting case is gcc.dg/tree-ssa/pr22230.c for correctness - how we handle backedges and availability. - And gcc.dg/tree-ssa/ssa-sccvn-2.c for optimization. */ - tree val = res_info->valnum; - if (res != val && !iterate && eliminate) - { - if (tree leader = avail.eliminate_avail (bb, res)) - { - if (leader != res - /* Preserve loop-closed SSA form. */ - && (! lc_phi_nodes - || is_gimple_min_invariant (leader))) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "Replaced redundant PHI node " - "defining "); - print_generic_expr (dump_file, res); - fprintf (dump_file, " with "); - print_generic_expr (dump_file, leader); - fprintf (dump_file, "\n"); - } - avail.eliminations++; + /* Eliminate */ + /* The interesting case is gcc.dg/tree-ssa/pr22230.c for correctness + how we handle backedges and availability. + And gcc.dg/tree-ssa/ssa-sccvn-2.c for optimization. */ + tree val = res_info->valnum; + if (res != val && !iterate && eliminate) + { + if (tree leader = avail.eliminate_avail (bb, res)) + { + if (leader != res + /* Preserve loop-closed SSA form. */ + && (! lc_phi_nodes + || is_gimple_min_invariant (leader))) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Replaced redundant PHI node " + "defining "); + print_generic_expr (dump_file, res); + fprintf (dump_file, " with "); + print_generic_expr (dump_file, leader); + fprintf (dump_file, "\n"); + } + avail.eliminations++; - if (may_propagate_copy (res, leader)) - { - /* Schedule for removal. */ - avail.to_remove.safe_push (phi); - continue; - } - /* ??? Else generate a copy stmt. */ - } - } - } - /* Only make defs available that not already are. But make - sure loop-closed SSA PHI node defs are picked up for - downstream uses. */ - if (lc_phi_nodes - || res == val - || ! avail.eliminate_avail (bb, res)) - avail.eliminate_push_avail (bb, res); - } + if (may_propagate_copy (res, leader)) + { + /* Schedule for removal. */ + avail.to_remove.safe_push (phi); + continue; + } + /* ??? Else generate a copy stmt. */ + } + } + } + /* Only make defs available that not already are. But make + sure loop-closed SSA PHI node defs are picked up for + downstream uses. */ + if (lc_phi_nodes + || res == val + || ! avail.eliminate_avail (bb, res)) + avail.eliminate_push_avail (bb, res); + } /* For empty BBs mark outgoing edges executable. For non-empty BBs we do this when processing the last stmt as we have to do this @@ -6415,6 +6417,13 @@ do_rpo_vn (function *fn, edge entry, bitmap exit_bbs, bitmap_set_bit (exit_bbs, EXIT_BLOCK); } + /* Clear EDGE_DFS_BACK on "all" entry edges, RPO order compute will + re-mark those that are contained in the region. */ + edge_iterator ei; + edge e; + FOR_EACH_EDGE (e, ei, entry->dest->preds) + e->flags &= ~EDGE_DFS_BACK; + int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fn) - NUM_FIXED_BLOCKS); int n = rev_post_order_and_mark_dfs_back_seme (fn, entry, exit_bbs, !loops_state_satisfies_p (LOOPS_NEED_FIXUP), rpo); @@ -6425,6 +6434,18 @@ do_rpo_vn (function *fn, edge entry, bitmap exit_bbs, if (!do_region) BITMAP_FREE (exit_bbs); + /* If there are any non-DFS_BACK edges into entry->dest skip + processing PHI nodes for that block. This supports + value-numbering loop bodies w/o the actual loop. */ + FOR_EACH_EDGE (e, ei, entry->dest->preds) + if (e != entry + && !(e->flags & EDGE_DFS_BACK)) + break; + bool skip_entry_phis = e != NULL; + if (skip_entry_phis && dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Region does not contain all edges into " + "the entry block, skipping its PHIs.\n"); + int *bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (fn)); for (int i = 0; i < n; ++i) bb_to_rpo[rpo[i]] = i; @@ -6454,7 +6475,9 @@ do_rpo_vn (function *fn, edge entry, bitmap exit_bbs, edge e; edge_iterator ei; FOR_EACH_EDGE (e, ei, bb->preds) - gcc_assert (e == entry || (e->src->flags & bb_in_region)); + gcc_assert (e == entry + || (skip_entry_phis && bb == entry->dest) + || (e->src->flags & bb_in_region)); } for (int i = 0; i < n; ++i) { @@ -6499,7 +6522,7 @@ do_rpo_vn (function *fn, edge entry, bitmap exit_bbs, if (e->flags & EDGE_DFS_BACK) has_backedges = true; e->flags &= ~EDGE_EXECUTABLE; - if (iterate || e == entry) + if (iterate || e == entry || (skip_entry_phis && bb == entry->dest)) continue; if (bb_to_rpo[e->src->index] > i) { @@ -6532,7 +6555,7 @@ do_rpo_vn (function *fn, edge entry, bitmap exit_bbs, edge_iterator ei; FOR_EACH_EDGE (e, ei, bb->preds) { - if (e == entry) + if (e == entry || (skip_entry_phis && bb == entry->dest)) continue; int max_rpo = MAX (rpo_state[i].max_rpo, rpo_state[bb_to_rpo[e->src->index]].max_rpo); @@ -6621,7 +6644,7 @@ do_rpo_vn (function *fn, edge entry, bitmap exit_bbs, todo |= process_bb (avail, bb, rpo_state[idx].visited != 0, rpo_state[idx].iterate, - iterate, eliminate, do_region, exit_bbs); + iterate, eliminate, do_region, exit_bbs, false); rpo_state[idx].visited++; /* Verify if changed values flow over executable outgoing backedges @@ -6719,8 +6742,10 @@ do_rpo_vn (function *fn, edge entry, bitmap exit_bbs, edge e; FOR_EACH_EDGE (e, ei, bb->preds) if (!(e->flags & EDGE_EXECUTABLE) - && !rpo_state[bb_to_rpo[e->src->index]].visited - && rpo_state[bb_to_rpo[e->src->index]].max_rpo >= (int)idx) + && (bb == entry->dest + || (!rpo_state[bb_to_rpo[e->src->index]].visited + && (rpo_state[bb_to_rpo[e->src->index]].max_rpo + >= (int)idx)))) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Cannot trust state of predecessor " @@ -6731,7 +6756,8 @@ do_rpo_vn (function *fn, edge entry, bitmap exit_bbs, nblk++; todo |= process_bb (avail, bb, false, false, false, eliminate, - do_region, exit_bbs); + do_region, exit_bbs, + skip_entry_phis && bb == entry->dest); rpo_state[idx].visited++; FOR_EACH_EDGE (e, ei, bb->succs) @@ -6813,7 +6839,9 @@ do_rpo_vn (function *fn, edge entry, bitmap exit_bbs, } /* Region-based entry for RPO VN. Performs value-numbering and elimination - on the SEME region specified by ENTRY and EXIT_BBS. */ + on the SEME region specified by ENTRY and EXIT_BBS. If ENTRY is not + the only edge into the region at ENTRY->dest PHI nodes in ENTRY->dest + are not considered. */ unsigned do_rpo_vn (function *fn, edge entry, bitmap exit_bbs)