This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR65136


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" } } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]