re PR tree-optimization/61757 (genmodes failure with enable-checking)

2014-07-14  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/61757
	PR tree-optimization/61783
	PR tree-optimization/61787
	* tree-ssa-dom.c (record_equality): Revert canonicalization
	change and add comment.
	(propagate_rhs_into_lhs): Revert previous fix, removing
	loop depth restriction again.

	* gcc.dg/torture/pr61757.c: New testcase.
	* gcc.dg/torture/pr61787.c: Likewise.

From-SVN: r212513
This commit is contained in:
Richard Biener 2014-07-14 10:50:46 +00:00 committed by Richard Biener
parent 04ae06daaa
commit 406bfdd39f
5 changed files with 110 additions and 30 deletions

View File

@ -1,3 +1,13 @@
2014-07-14 Richard Biener <rguenther@suse.de>
PR tree-optimization/61757
PR tree-optimization/61783
PR tree-optimization/61787
* tree-ssa-dom.c (record_equality): Revert canonicalization
change and add comment.
(propagate_rhs_into_lhs): Revert previous fix, removing
loop depth restriction again.
2014-07-14 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/arm/cortex-a15.md (cortex_a15_alu): Handle clz, rbit.

View File

@ -1,3 +1,11 @@
2014-07-14 Richard Biener <rguenther@suse.de>
PR tree-optimization/61757
PR tree-optimization/61783
PR tree-optimization/61787
* gcc.dg/torture/pr61757.c: New testcase.
* gcc.dg/torture/pr61787.c: Likewise.
2014-07-14 Jakub Jelinek <jakub@redhat.com>
PR middle-end/61294

View File

@ -0,0 +1,33 @@
/* { dg-do run } */
extern void abort (void);
struct X { void *p; int res; } a[32];
int foo (unsigned i, unsigned n, void *q)
{
if (i + 1 < n && q == a[i + 1].p)
{
do {
++i;
} while (i < n && q == a[i].p);
--i;
return a[i].res;
}
else
return a[i].res;
}
int main ()
{
int x;
a[0].p = &x;
a[0].res = -1;
a[1].p = &x;
a[1].res = 1;
a[2].p = (void *)0;
a[2].res = 0;
if (foo (0, 3, &x) != 1)
abort ();
return 0;
}

View File

@ -0,0 +1,27 @@
/* { dg-do run } */
unsigned int a = 1;
int
fn1 ()
{
char b;
for (;;)
{
for (b = 0; b < 5; b++)
if (!a - (unsigned int) b)
return 0;
a = 0;
}
}
int
main ()
{
fn1 ();
if (a != 1)
__builtin_abort ();
return 0;
}

View File

@ -1589,6 +1589,33 @@ record_const_or_copy (tree x, tree y)
record_const_or_copy_1 (x, y, prev_x);
}
/* Return the loop depth of the basic block of the defining statement of X.
This number should not be treated as absolutely correct because the loop
information may not be completely up-to-date when dom runs. However, it
will be relatively correct, and as more passes are taught to keep loop info
up to date, the result will become more and more accurate. */
static int
loop_depth_of_name (tree x)
{
gimple defstmt;
basic_block defbb;
/* If it's not an SSA_NAME, we have no clue where the definition is. */
if (TREE_CODE (x) != SSA_NAME)
return 0;
/* Otherwise return the loop depth of the defining statement's bb.
Note that there may not actually be a bb for this statement, if the
ssa_name is live on entry. */
defstmt = SSA_NAME_DEF_STMT (x);
defbb = gimple_bb (defstmt);
if (!defbb)
return 0;
return bb_loop_depth (defbb);
}
/* Similarly, but assume that X and Y are the two operands of an EQ_EXPR.
This constrains the cases in which we may treat this as assignment. */
@ -1608,7 +1635,10 @@ record_equality (tree x, tree y)
long as we canonicalize on one value. */
if (is_gimple_min_invariant (y))
;
else if (is_gimple_min_invariant (x))
else if (is_gimple_min_invariant (x)
/* ??? When threading over backedges the following is important
for correctness. See PR61757. */
|| (loop_depth_of_name (x) <= loop_depth_of_name (y)))
prev_x = x, x = y, y = prev_x, prev_x = prev_y;
else if (prev_x && is_gimple_min_invariant (prev_x))
x = y, y = prev_x, prev_x = prev_y;
@ -2638,33 +2668,6 @@ get_lhs_or_phi_result (gimple stmt)
gcc_unreachable ();
}
/* Return the loop depth of the basic block of the defining statement of X.
This number should not be treated as absolutely correct because the loop
information may not be completely up-to-date when dom runs. However, it
will be relatively correct, and as more passes are taught to keep loop info
up to date, the result will become more and more accurate. */
static int
loop_depth_of_name (tree x)
{
gimple defstmt;
basic_block defbb;
/* If it's not an SSA_NAME, we have no clue where the definition is. */
if (TREE_CODE (x) != SSA_NAME)
return 0;
/* Otherwise return the loop depth of the defining statement's bb.
Note that there may not actually be a bb for this statement, if the
ssa_name is live on entry. */
defstmt = SSA_NAME_DEF_STMT (x);
defbb = gimple_bb (defstmt);
if (!defbb)
return 0;
return bb_loop_depth (defbb);
}
/* Propagate RHS into all uses of LHS (when possible).
RHS and LHS are derived from STMT, which is passed in solely so
@ -2680,8 +2683,7 @@ static void
propagate_rhs_into_lhs (gimple stmt, tree lhs, tree rhs, bitmap interesting_names)
{
/* First verify that propagation is valid. */
if (may_propagate_copy (lhs, rhs)
&& loop_depth_of_name (lhs) >= loop_depth_of_name (rhs))
if (may_propagate_copy (lhs, rhs))
{
use_operand_p use_p;
imm_use_iterator iter;