diff options
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr61757.c | 33 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr61787.c | 27 | ||||
-rw-r--r-- | gcc/tree-ssa-dom.c | 62 |
5 files changed, 110 insertions, 30 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b01b571..43f871f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a8fe5e4..a2529fc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/gcc.dg/torture/pr61757.c b/gcc/testsuite/gcc.dg/torture/pr61757.c new file mode 100644 index 0000000..9a921a0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr61757.c @@ -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; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr61787.c b/gcc/testsuite/gcc.dg/torture/pr61787.c new file mode 100644 index 0000000..a7eefe8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr61787.c @@ -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; +} diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index 4c0c276..c4ec4e5 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -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; |