aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2015-02-20 16:58:11 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2015-02-20 16:58:11 +0000
commit31935398315662c9155d2f87e82f10463a023b6f (patch)
tree626e47bda91bb20ad107020c730cebfaa3560ba7 /gcc
parent8b0487010cf07edbb687ff160f396c7ff6b4634a (diff)
downloadgcc-31935398315662c9155d2f87e82f10463a023b6f.zip
gcc-31935398315662c9155d2f87e82f10463a023b6f.tar.gz
gcc-31935398315662c9155d2f87e82f10463a023b6f.tar.bz2
re PR tree-optimization/65136 (VRP inserts unnecessary constant copy in the loop)
2015-02-20 Richard Biener <rguenther@suse.de> PR tree-optimization/65136 * tree-ssa-propagate.c: Include cfgloop.h. (replace_phi_args_in): Avoid replacing loop latch edge PHI arguments with constants. * gcc.dg/tree-ssa/pr65136.c: New testcase. From-SVN: r220876
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr65136.c16
-rw-r--r--gcc/tree-ssa-propagate.c28
4 files changed, 54 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cae6617..b1bd622 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2015-02-20 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/65136
+ * tree-ssa-propagate.c: Include cfgloop.h.
+ (replace_phi_args_in): Avoid replacing loop latch edge PHI
+ arguments with constants.
+
2015-02-20 Jakub Jelinek <jakub@redhat.com>
Martin Liska <mliska@suse.cz>
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f942a68..1efc08d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2015-02-20 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/65136
+ * gcc.dg/tree-ssa/pr65136.c: New testcase.
+
2015-02-20 Jakub Jelinek <jakub@redhat.com>
PR testsuite/64158
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr65136.c b/gcc/testsuite/gcc.dg/tree-ssa/pr65136.c
new file mode 100644
index 0000000..4238bcb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr65136.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-rtl-expand-details" } */
+
+int foo(unsigned int cc )
+{
+
+ while ( cc >> 16 )
+ {
+ cc = (cc & 0xffff) + (cc >> 16);
+ }
+
+ return ( (unsigned short)(cc) ) == ((unsigned short)(-1));
+}
+
+/* { dg-final { scan-rtl-dump-not "_\[0-9\]* = 1;" "expand" } } */
+/* { dg-final { cleanup-rtl-dump "expand" } } */
diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c
index 6d665ea..8b82f9e 100644
--- a/gcc/tree-ssa-propagate.c
+++ b/gcc/tree-ssa-propagate.c
@@ -66,6 +66,7 @@
#include "langhooks.h"
#include "value-prof.h"
#include "domwalk.h"
+#include "cfgloop.h"
/* This file implements a generic value propagation engine based on
the same propagation used by the SSA-CCP algorithm [1].
@@ -992,6 +993,7 @@ replace_phi_args_in (gphi *phi, ssa_prop_get_value_fn get_value)
print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
}
+ basic_block bb = gimple_bb (phi);
for (i = 0; i < gimple_phi_num_args (phi); i++)
{
tree arg = gimple_phi_arg_def (phi, i);
@@ -1002,6 +1004,21 @@ replace_phi_args_in (gphi *phi, ssa_prop_get_value_fn get_value)
if (val && val != arg && may_propagate_copy (arg, val))
{
+ edge e = gimple_phi_arg_edge (phi, i);
+
+ /* Avoid propagating constants into loop latch edge
+ PHI arguments as this makes coalescing the copy
+ across this edge impossible. If the argument is
+ defined by an assert - otherwise the stmt will
+ get removed without replacing its uses. */
+ if (TREE_CODE (val) != SSA_NAME
+ && bb->loop_father->header == bb
+ && dominated_by_p (CDI_DOMINATORS, e->src, bb)
+ && is_gimple_assign (SSA_NAME_DEF_STMT (arg))
+ && (gimple_assign_rhs_code (SSA_NAME_DEF_STMT (arg))
+ == ASSERT_EXPR))
+ continue;
+
if (TREE_CODE (val) != SSA_NAME)
prop_stats.num_const_prop++;
else
@@ -1014,8 +1031,15 @@ replace_phi_args_in (gphi *phi, ssa_prop_get_value_fn get_value)
through an abnormal edge, update the replacement
accordingly. */
if (TREE_CODE (val) == SSA_NAME
- && gimple_phi_arg_edge (phi, i)->flags & EDGE_ABNORMAL)
- SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val) = 1;
+ && e->flags & EDGE_ABNORMAL
+ && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val))
+ {
+ /* This can only occur for virtual operands, since
+ for the real ones SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val))
+ would prevent replacement. */
+ gcc_checking_assert (virtual_operand_p (val));
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val) = 1;
+ }
}
}
}