tree-optimization/107618 - enhance copy propagation of constants
authorRichard Biener <rguenther@suse.de>
Fri, 11 Nov 2022 09:12:28 +0000 (10:12 +0100)
committerRichard Biener <rguenther@suse.de>
Fri, 11 Nov 2022 13:31:51 +0000 (14:31 +0100)
The following enhances copy propagation of constants to also see
through simple operations like conversions but also operations with
otherwise constant operands.  That's required to fulfill the promise

      /* Copy propagation also copy-propagates constants, this is necessary
         to forward object-size and builtin folding results properly.  */
      NEXT_PASS (pass_copy_prop);

and avoid false diagnostics as shown in the testcase.  We're
using gimple_fold_stmt_to_constant_1 with not following SSA edges
and accordingly adjust what stmts we simulate during SSA propagation.

PR tree-optimization/107618
* tree-ssa-copy.cc (stmt_may_generate_copy): Simulate all
assignments with a single SSA use.
(copy_prop_visit_assignment): Use gimple_fold_stmt_to_constant_1
to perform simple constant folding.
(copy_prop::visit_stmt): Visit all assignments.

* gcc.dg/pr107618.c: New testcase.

gcc/testsuite/gcc.dg/pr107618.c [new file with mode: 0644]
gcc/tree-ssa-copy.cc

diff --git a/gcc/testsuite/gcc.dg/pr107618.c b/gcc/testsuite/gcc.dg/pr107618.c
new file mode 100644 (file)
index 0000000..9e73cc1
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-Og" } */
+
+void a(void) __attribute__((__warning__("")));
+int main(void)
+{
+  unsigned long b = __builtin_object_size(0, 0);
+  if (__builtin_expect(b < 1, 0))
+    a(); /* { dg-bogus "warning" } */
+}
index 782ceb5..811161c 100644 (file)
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cfgloop.h"
 #include "tree-scalar-evolution.h"
 #include "tree-ssa-loop-niter.h"
+#include "gimple-fold.h"
 
 
 /* This file implements the copy propagation pass and provides a
@@ -99,12 +100,16 @@ stmt_may_generate_copy (gimple *stmt)
   if (gimple_vuse (stmt))
     return false;
 
+  /* If the assignment is from a constant it generates a useful copy.  */
+  if (gimple_assign_single_p (stmt)
+      && is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
+    return true;
+
   /* Otherwise, the only statements that generate useful copies are
-     assignments whose RHS is just an SSA name that doesn't flow
-     through abnormal edges.  */
-  return ((gimple_assign_rhs_code (stmt) == SSA_NAME
-          && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (stmt)))
-         || is_gimple_min_invariant (gimple_assign_rhs1 (stmt)));
+     assignments whose single SSA use doesn't flow through abnormal
+     edges.  */
+  tree rhs = single_ssa_tree_operand (stmt, SSA_OP_USE);
+  return (rhs && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs));
 }
 
 
@@ -197,26 +202,24 @@ dump_copy_of (FILE *file, tree var)
 static enum ssa_prop_result
 copy_prop_visit_assignment (gimple *stmt, tree *result_p)
 {
-  tree lhs, rhs;
-
-  lhs = gimple_assign_lhs (stmt);
-  rhs = valueize_val (gimple_assign_rhs1 (stmt));
-
-  if (TREE_CODE (lhs) == SSA_NAME)
+  tree lhs = gimple_assign_lhs (stmt);
+  tree rhs = gimple_fold_stmt_to_constant_1 (stmt, valueize_val);
+  if (rhs
+      && (TREE_CODE (rhs) == SSA_NAME
+         || is_gimple_min_invariant (rhs)))
     {
-      /* Straight copy between two SSA names.  First, make sure that
+      /* Straight copy between two SSA names or a constant.  Make sure that
         we can propagate the RHS into uses of LHS.  */
       if (!may_propagate_copy (lhs, rhs))
-       return SSA_PROP_VARYING;
-
-      *result_p = lhs;
-      if (set_copy_of_val (*result_p, rhs))
-       return SSA_PROP_INTERESTING;
-      else
-       return SSA_PROP_NOT_INTERESTING;
+       rhs = lhs;
     }
+  else
+    rhs = lhs;
 
-  return SSA_PROP_VARYING;
+  *result_p = lhs;
+  if (set_copy_of_val (*result_p, rhs))
+    return SSA_PROP_INTERESTING;
+  return rhs != lhs ? SSA_PROP_NOT_INTERESTING : SSA_PROP_VARYING;
 }
 
 
@@ -282,10 +285,8 @@ copy_prop::visit_stmt (gimple *stmt, edge *taken_edge_p, tree *result_p)
       fprintf (dump_file, "\n");
     }
 
-  if (gimple_assign_single_p (stmt)
-      && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
-      && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
-         || is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
+  if (is_gimple_assign (stmt)
+      && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME)
     {
       /* If the statement is a copy assignment, evaluate its RHS to
         see if the lattice value of its output has changed.  */