re PR tree-optimization/68465 (pass_lim doesn't detect identical loop entry conditions)

2015-11-23  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/68465
	* tree-ssa-sccvn.c (sccvn_dom_walker::before_dom_children):
	Also record equalities from multiple predecessor blocks if
	only one non-backedge exists.

	* gcc.dg/tree-ssa/ssa-fre-52.c: New testcase.

From-SVN: r230764
This commit is contained in:
Richard Biener 2015-11-23 15:21:32 +00:00 committed by Richard Biener
parent 78cc43a2ab
commit 3789bf8412
4 changed files with 59 additions and 7 deletions

View File

@ -1,3 +1,10 @@
2015-11-23 Richard Biener <rguenther@suse.de>
PR tree-optimization/68465
* tree-ssa-sccvn.c (sccvn_dom_walker::before_dom_children):
Also record equalities from multiple predecessor blocks if
only one non-backedge exists.
2015-11-23 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR target/68363

View File

@ -1,3 +1,8 @@
2015-11-23 Richard Biener <rguenther@suse.de>
PR tree-optimization/68465
* gcc.dg/tree-ssa/ssa-fre-52.c: New testcase.
2015-11-23 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR target/68363

View File

@ -0,0 +1,26 @@
/* { dg-do compile } */
/* { dg-options "-O -fdump-tree-fre1" } */
void bar ();
void foo (int n)
{
if (n > 0)
{
int j = 0;
do
{
if (n > 0)
{
int i = 0;
do
{
bar ();
}
while (i < n);
}
}
while (j < n);
}
}
/* { dg-final { scan-tree-dump-times "if" 1 "fre1" } } */

View File

@ -4357,20 +4357,34 @@ sccvn_dom_walker::before_dom_children (basic_block bb)
/* If we have a single predecessor record the equivalence from a
possible condition on the predecessor edge. */
if (single_pred_p (bb))
edge pred_e = NULL;
FOR_EACH_EDGE (e, ei, bb->preds)
{
/* Ignore simple backedges from this to allow recording conditions
in loop headers. */
if (dominated_by_p (CDI_DOMINATORS, e->src, e->dest))
continue;
if (! pred_e)
pred_e = e;
else
{
pred_e = NULL;
break;
}
}
if (pred_e)
{
edge e = single_pred_edge (bb);
/* Check if there are multiple executable successor edges in
the source block. Otherwise there is no additional info
to be recorded. */
edge e2;
FOR_EACH_EDGE (e2, ei, e->src->succs)
if (e2 != e
FOR_EACH_EDGE (e2, ei, pred_e->src->succs)
if (e2 != pred_e
&& e2->flags & EDGE_EXECUTABLE)
break;
if (e2 && (e2->flags & EDGE_EXECUTABLE))
{
gimple *stmt = last_stmt (e->src);
gimple *stmt = last_stmt (pred_e->src);
if (stmt
&& gimple_code (stmt) == GIMPLE_COND)
{
@ -4378,11 +4392,11 @@ sccvn_dom_walker::before_dom_children (basic_block bb)
tree lhs = gimple_cond_lhs (stmt);
tree rhs = gimple_cond_rhs (stmt);
record_conds (bb, code, lhs, rhs,
(e->flags & EDGE_TRUE_VALUE) != 0);
(pred_e->flags & EDGE_TRUE_VALUE) != 0);
code = invert_tree_comparison (code, HONOR_NANS (lhs));
if (code != ERROR_MARK)
record_conds (bb, code, lhs, rhs,
(e->flags & EDGE_TRUE_VALUE) == 0);
(pred_e->flags & EDGE_TRUE_VALUE) == 0);
}
}
}