diff options
author | Jeff Law <law@redhat.com> | 2014-04-23 12:04:46 -0600 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2014-04-23 12:04:46 -0600 |
commit | 9219922e543dec72f15bc095f8a99d25d2a60d24 (patch) | |
tree | f8adaeb72edcd87f9048cb8d2adcbfeeeeeba83f /gcc | |
parent | 0e4d63c5eef5c0565ac1d42ae1ac43a12c9fd071 (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr60902.c | 32 | ||||
-rw-r--r-- | gcc/tree-ssa-threadedge.c | 29 |
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 |