public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Handle strncpy in tree-ssa-dse.c
@ 2019-07-19 18:24 Jeff Law
  2019-07-22  8:07 ` Richard Biener
  0 siblings, 1 reply; 5+ messages in thread
From: Jeff Law @ 2019-07-19 18:24 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1753 bytes --]


While looking at BZ 80576 I realized a few things.

First for STRNCPY we know the exact count of bytes written and we can
treat it just like MEMCPY and others, both in terms of removing/trimming
them and in terms of using them to allow removal of other stores.

This patch adds support for those routines in DSE.  We test that
subsequent statements can make those calls dead and vice versa and that
we can trim from the head or tail appropriately.

While writing that code I also stumbled over a blob of code that I think
I copied from tree-ssa-alias.c that isn't necessary.  In the relevant
code the byte count is always found in the same place.  There's no need
to check the number of operands to the call to figure out where the
count would be.  So that little blob of code is simplified ever so slightly.

Finally, while writing the tests for strncpy I stumbled over a case that
we're still not handling well.

In particular something like this:



void h (char *s)
{
  extern char a[8];
  __builtin_memset (a, 0, sizeof a);
  __builtin_strncpy (a, s, sizeof a);
  frob (a);
}

In this case ref_maybe_used_by_stmt_p returns true for the "a" array at
the strncpy call.  AFAICT that appears to happen because  "a" and "s"
could alias each other.

strncpy is documented as not allowing overlap between the source and
destination objects.  So in theory we could consider them not aliasing
for this call.  I haven't implemented this, but I've got some ideas
here.  Anyway, I've included an xfailed test for this case in this patch.

Bootstrapped and regression tested on x86_64, ppc64, ppc64le, aarch64 &
sparc64.  Installing on the trunk momentarily.

We could in theory handle stpncpy too, we just have to be more careful
with its return value.

Jeff

[-- Attachment #2: P --]
[-- Type: text/plain, Size: 4585 bytes --]

commit 844df9c9ed48c2c0e80b633eb4f513d1228ef62d
Author: Jeff Law <law@redhat.com>
Date:   Fri Jul 19 11:03:10 2019 -0600

            * tree-ssa-dse.c (initialize_ao_ref_for_dse): Handle
            strncpy.  Drop some trivial dead code.
            (maybe_trim_memstar_call): Handle strncpy.
    
            * gcc.dg/tree-ssa/ssa-dse-37.c: New test.
            * gcc.dg/tree-ssa/ssa-dse-38.c: New test.

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 08f91ed32db..d8f60042ac1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2019-07-19  Jeff Law  <law@redhat.com>
+
+	* tree-ssa-dse.c (initialize_ao_ref_for_dse): Handle
+	strncpy.  Drop some trivial dead code.
+	(maybe_trim_memstar_call): Handle strncpy.
+
 2019-07-19  Richard Biener  <rguenther@suse.de>
 
 	PR tree-optimization/91211
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 98fb40ddd96..ce8e3c781b9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-07-19  Jeff Law  <law@redhat.com>
+
+	* gcc.dg/tree-ssa/ssa-dse-37.c: New test.
+	* gcc.dg/tree-ssa/ssa-dse-38.c: New test.
+
 2019-07-19  Richard Biener  <rguenther@suse.de>
 
 	PR tree-optimization/91211
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-37.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-37.c
new file mode 100644
index 00000000000..56251fc340f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-37.c
@@ -0,0 +1,60 @@
+/* { dg-options "-O2 -fdump-tree-dse-details -fno-tree-fre" } */
+
+
+#ifndef SCOPE
+#define SCOPE
+#endif
+
+extern void frob (char *);
+
+void g (char *s)
+{
+  SCOPE char a[8];
+  __builtin_strncpy (a, s, sizeof a);
+  __builtin_memset (a, 0, sizeof a); 
+  frob (a);
+}
+
+void h (char *s)
+{
+  SCOPE char a[8];
+  __builtin_memset (a, 0, sizeof a); 
+  __builtin_strncpy (a, s, sizeof a);
+  frob (a);
+}
+
+void i (char *s)
+{
+  SCOPE char a[8];
+  __builtin_strncpy (a, s, sizeof a);
+  __builtin_memset (a, 0, sizeof a - 5); 
+  frob (a);
+}
+
+void j (char *s)
+{
+  SCOPE char a[8];
+  __builtin_memset (a, 0, sizeof a); 
+  __builtin_strncpy (a, s, sizeof a - 5);
+  frob (a);
+}
+
+void l (char *s)
+{
+  SCOPE char a[8];
+  __builtin_strncpy (a, s, sizeof a);
+  __builtin_memset (a + 2, 0, sizeof a - 2); 
+  frob (a);
+}
+
+void m (char *s)
+{
+  SCOPE char a[8];
+  __builtin_memset (a, 0, sizeof a); 
+  __builtin_strncpy (a + 2, s, sizeof a - 2);
+  frob (a);
+}
+
+/* { dg-final { scan-tree-dump-times "Deleted dead call" 2 "dse1" } } */
+/* { dg-final { scan-tree-dump-times "Trimming statement " 4 "dse1" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-38.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-38.c
new file mode 100644
index 00000000000..7ae33bfd169
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-38.c
@@ -0,0 +1,12 @@
+/* { dg-options "-O2 -fdump-tree-dse-details -fno-tree-fre" } */
+
+
+/* This changes the scope of the destination object and exposes
+   missed optimizations in DSE.  */
+#define SCOPE extern
+#include "ssa-dse-37.c"
+
+/* { dg-final { scan-tree-dump-times "Deleted dead call" 2 "dse1" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "Trimming statement " 4 "dse1" { xfail *-*-* } } } */
+
+
diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
index 9bdcf9ae6af..5b7c4fc6d1a 100644
--- a/gcc/tree-ssa-dse.c
+++ b/gcc/tree-ssa-dse.c
@@ -113,10 +113,10 @@ initialize_ao_ref_for_dse (gimple *stmt, ao_ref *write)
 	case BUILT_IN_MEMCPY_CHK:
 	case BUILT_IN_MEMMOVE_CHK:
 	case BUILT_IN_MEMSET_CHK:
+	case BUILT_IN_STRNCPY:
+	case BUILT_IN_STRNCPY_CHK:
 	  {
-	    tree size = NULL_TREE;
-	    if (gimple_call_num_args (stmt) == 3)
-	      size = gimple_call_arg (stmt, 2);
+	    tree size = gimple_call_arg (stmt, 2);
 	    tree ptr = gimple_call_arg (stmt, 0);
 	    ao_ref_init_from_ptr_and_size (write, ptr, size);
 	    return true;
@@ -469,8 +469,10 @@ maybe_trim_memstar_call (ao_ref *ref, sbitmap live, gimple *stmt)
     {
     case BUILT_IN_MEMCPY:
     case BUILT_IN_MEMMOVE:
+    case BUILT_IN_STRNCPY:
     case BUILT_IN_MEMCPY_CHK:
     case BUILT_IN_MEMMOVE_CHK:
+    case BUILT_IN_STRNCPY_CHK:
       {
 	int head_trim, tail_trim;
 	compute_trims (ref, live, &head_trim, &tail_trim, stmt);
@@ -966,9 +968,11 @@ dse_dom_walker::dse_optimize_stmt (gimple_stmt_iterator *gsi)
 	{
 	case BUILT_IN_MEMCPY:
 	case BUILT_IN_MEMMOVE:
+	case BUILT_IN_STRNCPY:
 	case BUILT_IN_MEMSET:
 	case BUILT_IN_MEMCPY_CHK:
 	case BUILT_IN_MEMMOVE_CHK:
+	case BUILT_IN_STRNCPY_CHK:
 	case BUILT_IN_MEMSET_CHK:
 	  {
 	    /* Occasionally calls with an explicit length of zero

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2019-07-22 23:22 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-19 18:24 Handle strncpy in tree-ssa-dse.c Jeff Law
2019-07-22  8:07 ` Richard Biener
2019-07-22 15:11   ` Jeff Law
2019-07-22 15:46     ` Martin Sebor
2019-07-22 23:26       ` Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).