Hi Richard,
Following your suggestion in PR78154, the patch checks if stmt
contains call to memmove (and friends) in gimple_stmt_nonzero_warnv_p
and returns true in that case.

Bootstrapped+tested on x86_64-unknown-linux-gnu.
Cross-testing on arm*-*-*, aarch64*-*-* in progress.
Would it be OK to commit this patch in stage-3 ?

Thanks,
Prathamesh
2016-11-17  Prathamesh Kulkarni  <prathamesh.kulka...@linaro.org>

        * tree-vrp.c (gimple_str_nonzero_warnv_p): New function.
        (gimple_stmt_nonzero_warnv_p): Call gimple_str_nonzero_warnv_p.

testsuite/
        * gcc.dg/tree-ssa/pr78154.c: New test-case.

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr78154.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr78154.c
new file mode 100644
index 0000000..d3463f4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr78154.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp-slim" } */
+
+void f (void *d, const void *s, __SIZE_TYPE__ n)
+{
+  if (__builtin_memcpy (d, s, n) == 0)
+    __builtin_abort ();
+
+  if (__builtin_memmove (d, s, n) == 0)
+    __builtin_abort ();
+
+  if (__builtin_memset (d, 0, n) == 0)
+    __builtin_abort ();
+
+  if (__builtin_strcpy (d, s) == 0)
+    __builtin_abort ();
+
+  if (__builtin_strcat (d, s) == 0)
+    __builtin_abort ();
+
+  if (__builtin_strncpy (d, s, n) == 0)
+    __builtin_abort ();
+
+  if (__builtin_strncat (d, s, n) == 0)
+    __builtin_abort ();
+}
+
+/* { dg-final { scan-tree-dump-not "__builtin_abort" "evrp" } } */
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index c2a4133..b563a7f 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -1069,6 +1069,34 @@ gimple_assign_nonzero_warnv_p (gimple *stmt, bool 
*strict_overflow_p)
     }
 }
 
+/* Return true if STMT is known to contain call to a string-builtin function
+   that is known to return nonnull.  */
+
+static bool
+gimple_str_nonzero_warnv_p (gimple *stmt)
+{
+  if (!is_gimple_call (stmt))
+    return false;
+
+  tree fndecl = gimple_call_fndecl (stmt);
+  if (!fndecl || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
+    return false;
+
+  switch (DECL_FUNCTION_CODE (fndecl))
+    {
+      case BUILT_IN_MEMMOVE:
+      case BUILT_IN_MEMCPY:
+      case BUILT_IN_MEMSET:
+      case BUILT_IN_STRCPY:
+      case BUILT_IN_STRNCPY:
+      case BUILT_IN_STRCAT:
+      case BUILT_IN_STRNCAT:
+       return true;
+      default:
+       return false;
+    }
+}
+
 /* Return true if STMT is known to compute a non-zero value.
    If the return value is based on the assumption that signed overflow is
    undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
@@ -1097,7 +1125,7 @@ gimple_stmt_nonzero_warnv_p (gimple *stmt, bool 
*strict_overflow_p)
            lookup_attribute ("returns_nonnull",
                              TYPE_ATTRIBUTES (gimple_call_fntype (stmt))))
          return true;
-       return gimple_alloca_call_p (stmt);
+       return gimple_alloca_call_p (stmt) || gimple_str_nonzero_warnv_p (stmt);
       }
     default:
       gcc_unreachable ();

Reply via email to