re PR tree-optimization/79201 (missed optimization: sinking doesn't handle calls...
authorRichard Biener <rguenther@suse.de>
Tue, 25 Apr 2017 09:26:37 +0000 (09:26 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 25 Apr 2017 09:26:37 +0000 (09:26 +0000)
2017-04-25  Richard Biener  <rguenther@suse.de>

PR tree-optimization/79201
* tree-ssa-sink.c (statement_sink_location): Handle calls.

* gcc.dg/tree-ssa/ssa-sink-16.c: New testcase.
* gcc.target/i386/pr22152.c: Disable sinking.

From-SVN: r247159

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-16.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr22152.c
gcc/tree-ssa-sink.c

index 05d38bdd077eb4d7d6a10c0fede27685ac1a42cb..e1c79a8116af8c8f0e224909f806012d863da121 100644 (file)
@@ -1,3 +1,8 @@
+2017-04-25  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/79201
+       * tree-ssa-sink.c (statement_sink_location): Handle calls.
+
 2017-04-25  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>
 
        PR target/80464
index 1f347f44101e6a81b7e8c8955279e2a18dcd22c9..409725c46bf36e7a7b711f48a6493395a99d60fd 100644 (file)
@@ -1,3 +1,9 @@
+2017-04-25  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/79201
+       * gcc.dg/tree-ssa/ssa-sink-16.c: New testcase.
+       * gcc.target/i386/pr22152.c: Disable sinking.
+
 2017-04-25  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>
 
        PR target/80464
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-16.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-16.c
new file mode 100644 (file)
index 0000000..1b94c33
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* Note PRE rotates the loop and blocks the sinking opportunity.  */
+/* { dg-options "-O2 -fno-tree-pre -fdump-tree-sink -fdump-tree-optimized" } */
+
+int f(int n)
+{
+  int i,j=0;
+  for (i = 0; i < 31; i++)
+    j = __builtin_ffs(i);
+  return j;
+}
+
+/* { dg-final { scan-tree-dump "Sinking j_. = __builtin_ffs" "sink" } } */
+/* { dg-final { scan-tree-dump "return 2;" "optimized" } } */
index 5e2d4ac731baeacd1d5bb7ca6d3374baaf54710f..8603b09fe4a2f155ad6e12732b3a816ee504bb35 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -msse2 -mtune=core2" } */
+/* { dg-options "-O2 -fno-tree-sink -msse2 -mtune=core2" } */
 /* { dg-additional-options "-mno-vect8-ret-in-mem" { target *-*-vxworks* } } */
 /* { dg-additional-options "-mabi=sysv" { target x86_64-*-mingw* } } */
 
index bb8d2ca97327dae726badfcb84fba000751b85a1..eb8b36095d885fa561bec3c535e8a27d128c9d55 100644 (file)
@@ -256,8 +256,12 @@ statement_sink_location (gimple *stmt, basic_block frombb,
 
   *zero_uses_p = false;
 
-  /* We only can sink assignments.  */
-  if (!is_gimple_assign (stmt))
+  /* We only can sink assignments and non-looping const/pure calls.  */
+  int cf;
+  if (!is_gimple_assign (stmt)
+      && (!is_gimple_call (stmt)
+         || !((cf = gimple_call_flags (stmt)) & (ECF_CONST|ECF_PURE))
+         || (cf & ECF_LOOPING_CONST_OR_PURE)))
     return false;
 
   /* We only can sink stmts with a single definition.  */
@@ -291,7 +295,7 @@ statement_sink_location (gimple *stmt, basic_block frombb,
   if (stmt_ends_bb_p (stmt)
       || gimple_has_side_effects (stmt)
       || (cfun->has_local_explicit_reg_vars
-         && TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt))) == BLKmode))
+         && TYPE_MODE (TREE_TYPE (gimple_get_lhs (stmt))) == BLKmode))
     return false;
 
   /* Return if there are no immediate uses of this stmt.  */
@@ -323,15 +327,15 @@ statement_sink_location (gimple *stmt, basic_block frombb,
 
          /* A killing definition is not a use.  */
          if ((gimple_has_lhs (use_stmt)
-              && operand_equal_p (gimple_assign_lhs (stmt),
+              && operand_equal_p (gimple_get_lhs (stmt),
                                   gimple_get_lhs (use_stmt), 0))
-             || stmt_kills_ref_p (use_stmt, gimple_assign_lhs (stmt)))
+             || stmt_kills_ref_p (use_stmt, gimple_get_lhs (stmt)))
            {
              /* If use_stmt is or might be a nop assignment then USE_STMT
                 acts as a use as well as definition.  */
              if (stmt != use_stmt
                  && ref_maybe_used_by_stmt_p (use_stmt,
-                                              gimple_assign_lhs (stmt)))
+                                              gimple_get_lhs (stmt)))
                return false;
              continue;
            }