aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2019-05-13 11:37:21 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2019-05-13 11:37:21 +0000
commit40289199ee725183a286f50cf448f6347267047e (patch)
treee5c9e26646781ec79c4aa4ae92b04c9ebef06279 /gcc
parentaae6da83564549a6f8700407df50cdd52d411727 (diff)
downloadgcc-40289199ee725183a286f50cf448f6347267047e.zip
gcc-40289199ee725183a286f50cf448f6347267047e.tar.gz
gcc-40289199ee725183a286f50cf448f6347267047e.tar.bz2
re PR tree-optimization/90402 (ICE in slpeel_duplicate_current_defs_from_edges)
2019-05-13 Richard Biener <rguenther@suse.de> 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr90402-1.c26
-rw-r--r--gcc/tree-if-conv.c4
-rw-r--r--gcc/tree-ssa-sccvn.c164
5 files changed, 142 insertions, 69 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 42448f5..925d23c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,17 @@
2019-05-13 Richard Biener <rguenther@suse.de>
+ 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 <rguenther@suse.de>
+
PR tree-optimization/90316
* tree-ssa-pre.c (insert_aux): Fold into ...
(insert): ... this function. Use a RPO walk to reduce the
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 286bfe2..ebefd00 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-05-13 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/90402
+ * gcc.dg/torture/pr90402-1.c: New testcase.
+
2019-05-12 Iain Sandoe <iain@sandoe.co.uk>
Dominique d'Humieres <dominiq@gcc.gnu.org>
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 0000000..c4bd894
--- /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 ec2db00..98566e3 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -3066,10 +3066,12 @@ tree_if_conversion (struct loop *loop, vec<gimple *> *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 c3ca49b..b4f6260 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)