re PR tree-optimization/65136 (VRP inserts unnecessary constant copy in the loop)
authorRichard Biener <rguenther@suse.de>
Fri, 20 Feb 2015 16:58:11 +0000 (16:58 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 20 Feb 2015 16:58:11 +0000 (16:58 +0000)
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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr65136.c [new file with mode: 0644]
gcc/tree-ssa-propagate.c

index cae66174bee090a22d5f9d3d609745fb49375bbe..b1bd62283914d15b841d8e27969f5a99acbf3708 100644 (file)
@@ -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>
 
index f942a68e98eca67ded8fa02fd8f7e4f59f11736e..1efc08dcbc5eb283e28aa1c81a3ce8ed1435bb20 100644 (file)
@@ -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 (file)
index 0000000..4238bcb
--- /dev/null
@@ -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 6d665ea0100df10f4ad492bf46a4a9cae160a2db..8b82f9e20866b9c338336c7ae99c18cdff8c1b3b 100644 (file)
@@ -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;
+               }
            }
        }
     }