diff mbox

Fix PR78154

Message ID CAAgBjMnv6ZS=uW44wU=ufFEAZqsKjw-GMY6nsuf9nvORC+X7ZQ@mail.gmail.com
State New
Headers show

Commit Message

Prathamesh Kulkarni Nov. 23, 2016, 9:35 a.m. UTC
On 22 November 2016 at 20:23, Richard Biener <rguenther@suse.de> wrote:
> On Tue, 22 Nov 2016, Prathamesh Kulkarni wrote:

>

>> On 21 November 2016 at 15:34, Richard Biener <rguenther@suse.de> wrote:

>> > On Fri, 18 Nov 2016, Prathamesh Kulkarni wrote:

>> >

>> >> On 17 November 2016 at 15:24, Richard Biener <rguenther@suse.de> wrote:

>> >> > On Thu, 17 Nov 2016, Prathamesh Kulkarni wrote:

>> >> >

>> >> >> On 17 November 2016 at 14:21, Richard Biener <rguenther@suse.de> wrote:

>> >> >> > On Thu, 17 Nov 2016, Prathamesh Kulkarni wrote:

>> >> >> >

>> >> >> >> 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 ?

>> >> >> >

>> >> >> > As people noted we have returns_nonnull for this and that is already

>> >> >> > checked.  So please make sure the builtins get this attribute instead.

>> >> >> OK thanks, I will add the returns_nonnull attribute to the required

>> >> >> string builtins.

>> >> >> I noticed some of the string builtins don't have RET1 in builtins.def:

>> >> >> strcat, strncpy, strncat have ATTR_NOTHROW_NONNULL_LEAF.

>> >> >> Should they instead be having ATTR_RET1_NOTHROW_NONNULL_LEAF similar

>> >> >> to entries for memmove, strcpy ?

>> >> >

>> >> > Yes, I think so.

>> >> Hi,

>> >> In the attached patch I added returns_nonnull attribute to

>> >> ATTR_RET1_NOTHROW_NONNULL_LEAF,

>> >> and changed few builtins like strcat, strncpy, strncat and

>> >> corresponding _chk builtins to use ATTR_RET1_NOTHROW_NONNULL_LEAF.

>> >> Does the patch look correct ?

>> >

>> > Hmm, given you only change ATTR_RET1_NOTHROW_NONNULL_LEAF means that

>> > the gimple_stmt_nonzero_warnv_p code is incomplete -- it should

>> > infer returns_nonnull itself from RET1 (which is fnspec("1") basically)

>> > and the nonnull attribute on the argument.  So

>> >

>> >   unsigned rf = gimple_call_return_flags (stmt);

>> >   if (rf & ERF_RETURNS_ARG)

>> >    {

>> >      tree arg = gimple_call_arg (stmt, rf & ERF_RETURN_ARG_MASK);

>> >      if (range of arg is ! VARYING)

>> >        use range of arg;

>> >      else if (infer_nonnull_range_by_attribute (stmt, arg))

>> >         ... nonnull ...

>> >

>> Hi,

>> Thanks for the suggestions, modified gimple_stmt_nonzero_warnv_p

>> accordingly in this version.

>> For functions like stpcpy that return nonnull but not one of it's

>> arguments, I added new enum ATTR_RETNONNULL_NOTHROW_LEAF.

>> Is that OK ?

>> Bootstrapped+tested on x86_64-unknown-linux-gnu.

>> Cross-testing on arm*-*-*, aarch64*-*-* in progress.

>

> +               value_range *vr = get_value_range (arg);

> +               if ((vr && vr->type != VR_VARYING)

> +                   || infer_nonnull_range_by_attribute (stmt, arg))

> +                 return true;

> +             }

>

> actually that's not quite correct (failed to notice the function

> doesn't return a range but whether the range is nonnull).  For

> nonnull it's just

>

>   if (infer_nonnull_range_by_attribute (stmt, arg))

>     return true;

>

> in the extract_range_basic call handling we could handle

> ERF_RETURNS_ARG by returning the range of the argument (if not varying).

>

> Thus the patch is ok with the above condition changed.  Please refer

> to the recently opened PR from the ChangeLog.

Err sorry I think had looked at wrong results for bootstrap+test for
previous patch :/
It caused ICE for pr55890-3.c and regressed nonnull-3.c, which is fixed in this
version, and changed the above condition to only check
infer_nonnull_range_by_attribute().
Bootstrapped+tested on x86_64-unknown-linux-gnu.
Cross-tested on arm*-*-*, aarch64*-*-*.
OK to commit ?

Thanks,
Prathamesh
>

> Thanks,

> Richard.
2016-11-23  Richard Biener  <rguenther@suse.de>
	    Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.rog>

	PR tree-optimization/78154
	* tree-vrp.c (gimple_stmt_nonzero_warnv_p): Return true if function
	returns it's argument and the argument is nonnull.
	* builtin-attrs.def: Define ATTR_RETURNS_NONNULL,
	ATT_RETNONNULL_NOTHROW_LEAF.
	* builtins.def (BUILT_IN_MEMPCPY): Change attribute to
	ATTR_RETNONNULL_NOTHROW_LEAF.
	(BUILT_IN_STPCPY): Likewise.
	(BUILT_IN_STPNCPY): Likewise.
	(BUILT_IN_MEMPCPY_CHK): Likewise.
	(BUILT_IN_STPCPY_CHK): Likewise.
	(BUILT_IN_STPNCPY_CHK): Likewise.
	(BUILT_IN_STRCAT): Change attribute to ATTR_RET1_NOTHROW_NONNULL_LEAF.
	(BUILT_IN_STRNCAT): Likewise.
	(BUILT_IN_STRNCPY): Likewise.
	(BUILT_IN_MEMSET_CHK): Likewise.
	(BUILT_IN_STRCAT_CHK): Likewise.
	(BUILT_IN_STRCPY_CHK): Likewise.
	(BUILT_IN_STRNCAT_CHK): Likewise.
	(BUILT_IN_STRNCPY_CHK): Likewise.

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

Comments

Richard Biener Nov. 23, 2016, 9:42 a.m. UTC | #1
On Wed, 23 Nov 2016, Prathamesh Kulkarni wrote:

> On 22 November 2016 at 20:23, Richard Biener <rguenther@suse.de> wrote:

> > On Tue, 22 Nov 2016, Prathamesh Kulkarni wrote:

> >

> >> On 21 November 2016 at 15:34, Richard Biener <rguenther@suse.de> wrote:

> >> > On Fri, 18 Nov 2016, Prathamesh Kulkarni wrote:

> >> >

> >> >> On 17 November 2016 at 15:24, Richard Biener <rguenther@suse.de> wrote:

> >> >> > On Thu, 17 Nov 2016, Prathamesh Kulkarni wrote:

> >> >> >

> >> >> >> On 17 November 2016 at 14:21, Richard Biener <rguenther@suse.de> wrote:

> >> >> >> > On Thu, 17 Nov 2016, Prathamesh Kulkarni wrote:

> >> >> >> >

> >> >> >> >> 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 ?

> >> >> >> >

> >> >> >> > As people noted we have returns_nonnull for this and that is already

> >> >> >> > checked.  So please make sure the builtins get this attribute instead.

> >> >> >> OK thanks, I will add the returns_nonnull attribute to the required

> >> >> >> string builtins.

> >> >> >> I noticed some of the string builtins don't have RET1 in builtins.def:

> >> >> >> strcat, strncpy, strncat have ATTR_NOTHROW_NONNULL_LEAF.

> >> >> >> Should they instead be having ATTR_RET1_NOTHROW_NONNULL_LEAF similar

> >> >> >> to entries for memmove, strcpy ?

> >> >> >

> >> >> > Yes, I think so.

> >> >> Hi,

> >> >> In the attached patch I added returns_nonnull attribute to

> >> >> ATTR_RET1_NOTHROW_NONNULL_LEAF,

> >> >> and changed few builtins like strcat, strncpy, strncat and

> >> >> corresponding _chk builtins to use ATTR_RET1_NOTHROW_NONNULL_LEAF.

> >> >> Does the patch look correct ?

> >> >

> >> > Hmm, given you only change ATTR_RET1_NOTHROW_NONNULL_LEAF means that

> >> > the gimple_stmt_nonzero_warnv_p code is incomplete -- it should

> >> > infer returns_nonnull itself from RET1 (which is fnspec("1") basically)

> >> > and the nonnull attribute on the argument.  So

> >> >

> >> >   unsigned rf = gimple_call_return_flags (stmt);

> >> >   if (rf & ERF_RETURNS_ARG)

> >> >    {

> >> >      tree arg = gimple_call_arg (stmt, rf & ERF_RETURN_ARG_MASK);

> >> >      if (range of arg is ! VARYING)

> >> >        use range of arg;

> >> >      else if (infer_nonnull_range_by_attribute (stmt, arg))

> >> >         ... nonnull ...

> >> >

> >> Hi,

> >> Thanks for the suggestions, modified gimple_stmt_nonzero_warnv_p

> >> accordingly in this version.

> >> For functions like stpcpy that return nonnull but not one of it's

> >> arguments, I added new enum ATTR_RETNONNULL_NOTHROW_LEAF.

> >> Is that OK ?

> >> Bootstrapped+tested on x86_64-unknown-linux-gnu.

> >> Cross-testing on arm*-*-*, aarch64*-*-* in progress.

> >

> > +               value_range *vr = get_value_range (arg);

> > +               if ((vr && vr->type != VR_VARYING)

> > +                   || infer_nonnull_range_by_attribute (stmt, arg))

> > +                 return true;

> > +             }

> >

> > actually that's not quite correct (failed to notice the function

> > doesn't return a range but whether the range is nonnull).  For

> > nonnull it's just

> >

> >   if (infer_nonnull_range_by_attribute (stmt, arg))

> >     return true;

> >

> > in the extract_range_basic call handling we could handle

> > ERF_RETURNS_ARG by returning the range of the argument (if not varying).

> >

> > Thus the patch is ok with the above condition changed.  Please refer

> > to the recently opened PR from the ChangeLog.

> Err sorry I think had looked at wrong results for bootstrap+test for

> previous patch :/

> It caused ICE for pr55890-3.c and regressed nonnull-3.c, which is fixed in this

> version, and changed the above condition to only check

> infer_nonnull_range_by_attribute().

> Bootstrapped+tested on x86_64-unknown-linux-gnu.

> Cross-tested on arm*-*-*, aarch64*-*-*.

> OK to commit ?


Ok.

Richard.

> Thanks,

> Prathamesh

> >

> > Thanks,

> > Richard.

> 


-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)
diff mbox

Patch

diff --git a/gcc/builtin-attrs.def b/gcc/builtin-attrs.def
index 8dc59c9..88c9bd1 100644
--- a/gcc/builtin-attrs.def
+++ b/gcc/builtin-attrs.def
@@ -108,6 +108,7 @@  DEF_ATTR_IDENT (ATTR_TYPEGENERIC, "type generic")
 DEF_ATTR_IDENT (ATTR_TM_REGPARM, "*tm regparm")
 DEF_ATTR_IDENT (ATTR_TM_TMPURE, "transaction_pure")
 DEF_ATTR_IDENT (ATTR_RETURNS_TWICE, "returns_twice")
+DEF_ATTR_IDENT (ATTR_RETURNS_NONNULL, "returns_nonnull")
 
 DEF_ATTR_TREE_LIST (ATTR_NOVOPS_LIST, ATTR_NOVOPS, ATTR_NULL, ATTR_NULL)
 
@@ -197,6 +198,10 @@  DEF_ATTR_TREE_LIST (ATTR_CONST_NOTHROW_NONNULL, ATTR_CONST, ATTR_NULL, \
    and which return their first argument.  */
 DEF_ATTR_TREE_LIST (ATTR_RET1_NOTHROW_NONNULL_LEAF, ATTR_FNSPEC, ATTR_LIST_STR1, \
 			ATTR_NOTHROW_NONNULL_LEAF)
+/* Nothrow leaf functions whose pointer parameter(s) are all nonnull,
+   and return value is also nonnull.  */
+DEF_ATTR_TREE_LIST (ATTR_RETNONNULL_NOTHROW_LEAF, ATTR_RETURNS_NONNULL, ATTR_NULL, \
+			ATTR_NOTHROW_NONNULL_LEAF)
 /* Nothrow const leaf functions whose pointer parameter(s) are all nonnull.  */
 DEF_ATTR_TREE_LIST (ATTR_CONST_NOTHROW_NONNULL_LEAF, ATTR_CONST, ATTR_NULL, \
 			ATTR_NOTHROW_NONNULL_LEAF)
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 219feeb..82c987d 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -646,13 +646,13 @@  DEF_LIB_BUILTIN        (BUILT_IN_MEMCHR, "memchr", BT_FN_PTR_CONST_PTR_INT_SIZE,
 DEF_LIB_BUILTIN        (BUILT_IN_MEMCMP, "memcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF)
 DEF_LIB_BUILTIN_CHKP   (BUILT_IN_MEMCPY, "memcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
 DEF_LIB_BUILTIN_CHKP   (BUILT_IN_MEMMOVE, "memmove", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
-DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_MEMPCPY, "mempcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
+DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_MEMPCPY, "mempcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RETNONNULL_NOTHROW_LEAF)
 DEF_LIB_BUILTIN_CHKP   (BUILT_IN_MEMSET, "memset", BT_FN_PTR_PTR_INT_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_RINDEX, "rindex", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF)
-DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_STPCPY, "stpcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_LEAF)
-DEF_EXT_LIB_BUILTIN    (BUILT_IN_STPNCPY, "stpncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
+DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_STPCPY, "stpcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_RETNONNULL_NOTHROW_LEAF)
+DEF_EXT_LIB_BUILTIN    (BUILT_IN_STPNCPY, "stpncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_RETNONNULL_NOTHROW_LEAF)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRCASECMP, "strcasecmp", BT_FN_INT_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
-DEF_LIB_BUILTIN_CHKP   (BUILT_IN_STRCAT, "strcat", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_LEAF)
+DEF_LIB_BUILTIN_CHKP   (BUILT_IN_STRCAT, "strcat", BT_FN_STRING_STRING_CONST_STRING, ATTR_RET1_NOTHROW_NONNULL_LEAF)
 DEF_LIB_BUILTIN_CHKP   (BUILT_IN_STRCHR, "strchr", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF)
 DEF_LIB_BUILTIN        (BUILT_IN_STRCMP, "strcmp", BT_FN_INT_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
 DEF_LIB_BUILTIN_CHKP   (BUILT_IN_STRCPY, "strcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_RET1_NOTHROW_NONNULL_LEAF)
@@ -661,9 +661,9 @@  DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRDUP, "strdup", BT_FN_STRING_CONST_STRING, AT
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRNDUP, "strndup", BT_FN_STRING_CONST_STRING_SIZE, ATTR_MALLOC_NOTHROW_NONNULL_LEAF)
 DEF_LIB_BUILTIN_CHKP   (BUILT_IN_STRLEN, "strlen", BT_FN_SIZE_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRNCASECMP, "strncasecmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF)
-DEF_LIB_BUILTIN        (BUILT_IN_STRNCAT, "strncat", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
+DEF_LIB_BUILTIN        (BUILT_IN_STRNCAT, "strncat", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
 DEF_LIB_BUILTIN        (BUILT_IN_STRNCMP, "strncmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF)
-DEF_LIB_BUILTIN        (BUILT_IN_STRNCPY, "strncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
+DEF_LIB_BUILTIN        (BUILT_IN_STRNCPY, "strncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
 DEF_LIB_BUILTIN        (BUILT_IN_STRPBRK, "strpbrk", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
 DEF_LIB_BUILTIN        (BUILT_IN_STRRCHR, "strrchr", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF)
 DEF_LIB_BUILTIN        (BUILT_IN_STRSPN, "strspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
@@ -904,14 +904,14 @@  DEF_BUILTIN_STUB (BUILT_IN_MEMCMP_EQ, "__builtin_memcmp_eq")
 DEF_GCC_BUILTIN	       (BUILT_IN_OBJECT_SIZE, "object_size", BT_FN_SIZE_CONST_PTR_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
 DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_MEMCPY_CHK, "__memcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
 DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_MEMMOVE_CHK, "__memmove_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
-DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_MEMPCPY_CHK, "__mempcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
-DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_MEMSET_CHK, "__memset_chk", BT_FN_PTR_PTR_INT_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
-DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_STPCPY_CHK, "__stpcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
-DEF_EXT_LIB_BUILTIN    (BUILT_IN_STPNCPY_CHK, "__stpncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
-DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_STRCAT_CHK, "__strcat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
-DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_STRCPY_CHK, "__strcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
-DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRNCAT_CHK, "__strncat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
-DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRNCPY_CHK, "__strncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
+DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_MEMPCPY_CHK, "__mempcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_RETNONNULL_NOTHROW_LEAF)
+DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_MEMSET_CHK, "__memset_chk", BT_FN_PTR_PTR_INT_SIZE_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
+DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_STPCPY_CHK, "__stpcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_RETNONNULL_NOTHROW_LEAF)
+DEF_EXT_LIB_BUILTIN    (BUILT_IN_STPNCPY_CHK, "__stpncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_RETNONNULL_NOTHROW_LEAF)
+DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_STRCAT_CHK, "__strcat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
+DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_STRCPY_CHK, "__strcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
+DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRNCAT_CHK, "__strncat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
+DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRNCPY_CHK, "__strncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_SNPRINTF_CHK, "__snprintf_chk", BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_5_6)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_SPRINTF_CHK, "__sprintf_chk", BT_FN_INT_STRING_INT_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_4_5)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_VSNPRINTF_CHK, "__vsnprintf_chk", BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_5_0)
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..d908a39
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr78154.c
@@ -0,0 +1,43 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp-slim" } */
+
+void f(void *d, const void *s, __SIZE_TYPE__ n)
+{
+  void *t1 = __builtin_memcpy (d, s, n);
+  if (t1 == 0)
+    __builtin_abort ();
+
+  void *t2 = __builtin_memmove (d, s, n);
+  if (t2 == 0)
+    __builtin_abort ();
+
+  void *t3 = __builtin_memset (d, 0, n);
+  if (t3 == 0)
+    __builtin_abort ();
+
+  void *t4 = __builtin_strcpy (d, s);
+  if (t4 == 0)
+    __builtin_abort ();
+
+  void *t5 = __builtin_strncpy (d, s, n);
+  if (t5 == 0)
+    __builtin_abort ();
+
+  void *t6 = __builtin_strcat (d, s);
+  if (t6 == 0)
+    __builtin_abort ();
+
+  void *t7 = __builtin_strncat (d, s, n);
+  if (t7 == 0)
+    __builtin_abort ();
+
+  void *t8 = __builtin_stpcpy (d, s);
+  if (t8 == 0)
+    __builtin_abort ();
+
+  void *t9 = __builtin_stpncpy (d, s, n);
+  if (t9 == 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..5bd4418 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -1097,6 +1097,20 @@  gimple_stmt_nonzero_warnv_p (gimple *stmt, bool *strict_overflow_p)
 	    lookup_attribute ("returns_nonnull",
 			      TYPE_ATTRIBUTES (gimple_call_fntype (stmt))))
 	  return true;
+
+	gcall *call_stmt = as_a<gcall *> (stmt);
+	unsigned rf = gimple_call_return_flags (call_stmt);
+	if (rf & ERF_RETURNS_ARG)
+	  {
+	    unsigned argnum = rf & ERF_RETURN_ARG_MASK;
+	    if (argnum < gimple_call_num_args (call_stmt))
+	      {
+		tree arg = gimple_call_arg (call_stmt, argnum);
+		if (SSA_VAR_P (arg)
+		    && infer_nonnull_range_by_attribute (stmt, arg))
+		  return true;
+	      }
+	  }
 	return gimple_alloca_call_p (stmt);
       }
     default: