aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2014-04-23 12:04:46 -0600
committerJeff Law <law@gcc.gnu.org>2014-04-23 12:04:46 -0600
commit9219922e543dec72f15bc095f8a99d25d2a60d24 (patch)
treef8adaeb72edcd87f9048cb8d2adcbfeeeeeba83f /gcc
parent0e4d63c5eef5c0565ac1d42ae1ac43a12c9fd071 (diff)
downloadgcc-9219922e543dec72f15bc095f8a99d25d2a60d24.zip
gcc-9219922e543dec72f15bc095f8a99d25d2a60d24.tar.gz
gcc-9219922e543dec72f15bc095f8a99d25d2a60d24.tar.bz2
re PR tree-optimization/60902 (ffmpeg built with gcc 4.9 RC produces incorrect flac playback code)
PR tree-optimization/60902 * tree-ssa-threadedge.c (record_temporary_equivalences_from_stmts_at_dest): Make sure to invalidate outputs from statements that do not produce useful outputs for threading. PR tree-optimization/60902 * gcc.target/i386/pr60902.c: New test. From-SVN: r209716
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr60902.c32
-rw-r--r--gcc/tree-ssa-threadedge.c29
4 files changed, 73 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 638c0da..ddebba7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2014-04-23 Jeff Law <law@redhat.com>
+
+ PR tree-optimization/60902
+ * tree-ssa-threadedge.c
+ (record_temporary_equivalences_from_stmts_at_dest): Make sure to
+ invalidate outputs from statements that do not produce useful
+ outputs for threading.
+
2014-04-23 Venkataramanan Kumar <venkataramanan.kumar@linaro.org>
* config/aarch64/aarch64.md (stack_protect_set, stack_protect_test)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 126ad08..62b07f4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2014-04-23 Jeff Law <law@redhat.com>
+
+ PR tree-optimization/60902
+ * gcc.target/i386/pr60902.c: New test.
+
2014-04-23 Alex Velenko <Alex.Velenko@arm.com>
* gcc.target/aarch64/vdup_lane_1.c: New testcase.
diff --git a/gcc/testsuite/gcc.target/i386/pr60902.c b/gcc/testsuite/gcc.target/i386/pr60902.c
new file mode 100644
index 0000000..b81dcd7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr60902.c
@@ -0,0 +1,32 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+extern void abort ();
+extern void exit (int);
+
+int x;
+
+foo()
+{
+ static int count;
+ count++;
+ if (count > 1)
+ abort ();
+}
+
+static inline int
+frob ()
+{
+ int a;
+ __asm__ ("mov %1, %0\n\t" : "=r" (a) : "m" (x));
+ x++;
+ return a;
+}
+
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 10 && frob () == 0; i++)
+ foo();
+ exit (0);
+}
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index c447b72..8a0103b 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -387,7 +387,34 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
&& (gimple_code (stmt) != GIMPLE_CALL
|| gimple_call_lhs (stmt) == NULL_TREE
|| TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME))
- continue;
+ {
+ /* STMT might still have DEFS and we need to invalidate any known
+ equivalences for them.
+
+ Consider if STMT is a GIMPLE_ASM with one or more outputs that
+ feeds a conditional inside a loop. We might derive an equivalence
+ due to the conditional. */
+ tree op;
+ ssa_op_iter iter;
+
+ if (backedge_seen)
+ FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_ALL_DEFS)
+ {
+ /* This call only invalidates equivalences created by
+ PHI nodes. This is by design to keep the cost of
+ of invalidation reasonable. */
+ invalidate_equivalences (op, stack, src_map, dst_map);
+
+ /* However, conditionals can imply values for real
+ operands as well. And those won't be recorded in the
+ maps. In fact, those equivalences may be recorded totally
+ outside the threading code. We can just create a new
+ temporary NULL equivalence here. */
+ record_temporary_equivalence (op, NULL_TREE, stack);
+ }
+
+ continue;
+ }
/* The result of __builtin_object_size depends on all the arguments
of a phi node. Temporarily using only one edge produces invalid