Value-numbering failed to handle __builtin_{memcpy,memset,...}_chk
variants when removing abstraction and also failed to use the
value-numbering lattice when requiring the length argument of the
call to be constant.

Bootstrapped and tested on x86_64-unknown-linux-gnu, queued for GCC 11
unless somebody things we want this right now.

Richard.

2020-01-30  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/93508
        * tree-ssa-sccvn.c (vn_reference_lookup_3): Handle _CHK like
        non-_CHK variants.  Valueize their length arguments.

        * gcc.dg/tree-ssa/ssa-fre-85.c: New testcase.
---
 gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-85.c | 13 +++++++++++++
 gcc/tree-ssa-sccvn.c                       | 19 +++++++++++++++----
 2 files changed, 28 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-85.c

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-85.c 
b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-85.c
new file mode 100644
index 00000000000..6dace16ecbd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-85.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
+
+unsigned int foo(unsigned int x, int *p)
+{
+  unsigned int src = x;
+  unsigned int dst;
+  *p = sizeof (unsigned int);
+  __builtin___memcpy_chk (&dst, &src, *p, 16);
+  return dst;
+}
+
+/* { dg-final { scan-tree-dump "return x" "fre1" } } */
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 6e0b2202157..632211f9887 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -2377,14 +2377,17 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void 
*data_,
      from that definition.
      1) Memset.  */
   if (is_gimple_reg_type (vr->type)
-      && gimple_call_builtin_p (def_stmt, BUILT_IN_MEMSET)
+      && (gimple_call_builtin_p (def_stmt, BUILT_IN_MEMSET)
+         || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMSET_CHK))
       && (integer_zerop (gimple_call_arg (def_stmt, 1))
          || ((TREE_CODE (gimple_call_arg (def_stmt, 1)) == INTEGER_CST
               || (INTEGRAL_TYPE_P (vr->type) && known_eq (ref->size, 8)))
              && CHAR_BIT == 8 && BITS_PER_UNIT == 8
              && offset.is_constant (&offseti)
              && offseti % BITS_PER_UNIT == 0))
-      && poly_int_tree_p (gimple_call_arg (def_stmt, 2))
+      && (poly_int_tree_p (gimple_call_arg (def_stmt, 2))
+         || (TREE_CODE (gimple_call_arg (def_stmt, 2)) == SSA_NAME
+             && poly_int_tree_p (SSA_VAL (gimple_call_arg (def_stmt, 2)))))
       && (TREE_CODE (gimple_call_arg (def_stmt, 0)) == ADDR_EXPR
          || TREE_CODE (gimple_call_arg (def_stmt, 0)) == SSA_NAME))
     {
@@ -2444,6 +2447,8 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void 
*data_,
       else
        return (void *)-1;
       tree len = gimple_call_arg (def_stmt, 2);
+      if (TREE_CODE (len) == SSA_NAME)
+       len = SSA_VAL (len);
       HOST_WIDE_INT leni, offset2i, offseti;
       /* Sometimes the above trickery is smarter than alias analysis.  Take
          advantage of that.  */
@@ -2925,13 +2930,19 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void 
*data_,
           && is_gimple_reg_type (vr->type)
           /* ???  Handle BCOPY as well.  */
           && (gimple_call_builtin_p (def_stmt, BUILT_IN_MEMCPY)
+              || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMCPY_CHK)
               || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMPCPY)
-              || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMMOVE))
+              || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMPCPY_CHK)
+              || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMMOVE)
+              || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMMOVE_CHK))
           && (TREE_CODE (gimple_call_arg (def_stmt, 0)) == ADDR_EXPR
               || TREE_CODE (gimple_call_arg (def_stmt, 0)) == SSA_NAME)
           && (TREE_CODE (gimple_call_arg (def_stmt, 1)) == ADDR_EXPR
               || TREE_CODE (gimple_call_arg (def_stmt, 1)) == SSA_NAME)
-          && poly_int_tree_p (gimple_call_arg (def_stmt, 2), &copy_size)
+          && (poly_int_tree_p (gimple_call_arg (def_stmt, 2), &copy_size)
+              || (TREE_CODE (gimple_call_arg (def_stmt, 2)) == SSA_NAME
+                  && poly_int_tree_p (SSA_VAL (gimple_call_arg (def_stmt, 2)),
+                                      &copy_size)))
           /* Handling this is more complicated, give up for now.  */
           && data->partial_defs.is_empty ())
     {
-- 
2.16.4

Reply via email to