aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr61757.c33
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr61787.c27
-rw-r--r--gcc/tree-ssa-dom.c62
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;