This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR65136
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 20 Feb 2015 17:53:50 +0100 (CET)
- Subject: [PATCH] Fix PR65136
- Authentication-results: sourceware.org; auth=none
VRP was constant-propagating to a loop latch edge PHI arg from
sth derived from an assert-expr. That's usually not a good idea
because it prevents coalescing (or the fixup code has to insert
a copy from a constant). If we derive the constant from an
assert then we don't even save computation of the constant.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
Richard.
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.
Index: gcc/tree-ssa-propagate.c
===================================================================
--- gcc/tree-ssa-propagate.c (revision 220809)
+++ gcc/tree-ssa-propagate.c (working copy)
@@ -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
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
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
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;
+ }
}
}
}
Index: gcc/testsuite/gcc.dg/tree-ssa/pr65136.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/pr65136.c (revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/pr65136.c (working copy)
@@ -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" } } */