PR tree-optimization
authorMartin Sebor <msebor@redhat.com>
Tue, 9 Jul 2019 23:29:33 +0000 (23:29 +0000)
committerMartin Sebor <msebor@gcc.gnu.org>
Tue, 9 Jul 2019 23:29:33 +0000 (17:29 -0600)
gcc/ChangeLog:

PR tree-optimization
* tree-ssa-strlen.c (handle_char_store): Constrain a single character
optimization to just single character stores.

gcc/testsuite/ChangeLog:

PR tree-optimization
* gcc.dg/strlenopt-26.c: Exit with test result status.
* gcc.dg/strlenopt-67.c: New test.

From-SVN: r273317

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/strlenopt-26.c
gcc/testsuite/gcc.dg/strlenopt-67.c [new file with mode: 0644]
gcc/tree-ssa-strlen.c

index 4ae2fd81261a29487b4db936c451d488515863a3..f37b1f061e83c66042325500cd48e5c119ba5f4e 100644 (file)
@@ -1,3 +1,9 @@
+2019-07-09  Martin Sebor  <msebor@redhat.com>
+
+       PR tree-optimization/90989
+       * tree-ssa-strlen.c (handle_char_store): Constrain a single character
+       optimization to just single character stores.
+
 2019-07-09  Joern Rennecke  <joern.rennecke@riscy-ip.com>
 
        * tree-vect-stmts.c (vectorizable_comparison) <!slp_node>:
index bf7c992afb985058700df04f5d65eaa579522a54..b0255219450deecbd05e51b07f664102b696d149 100644 (file)
@@ -1,3 +1,9 @@
+2019-07-09  Martin Sebor  <msebor@redhat.com>
+
+       PR tree-optimization/90989
+       * gcc.dg/strlenopt-26.c: Exit with test result status.
+       * gcc.dg/strlenopt-67.c: New test.
+
 2019-07-09  Dragan Mladjenovic  <dmladjenovic@wavecomp.com>
 
        * gcc.target/mips/cfgcleanup-jalr1.c: New test.
index da2f465a5b5003fa5dca05f3a6ee00e97b98b5dd..6bb0263d315b4443a93f9d859aebcd1d04f9c289 100644 (file)
@@ -17,8 +17,7 @@ main (void)
 {
   char p[] = "foobar";
   const char *volatile q = "xyzzy";
-  fn1 (p, q);
-  return 0;
+  return fn1 (p, q);
 }
 
 /* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
diff --git a/gcc/testsuite/gcc.dg/strlenopt-67.c b/gcc/testsuite/gcc.dg/strlenopt-67.c
new file mode 100644 (file)
index 0000000..a2bcfba
--- /dev/null
@@ -0,0 +1,104 @@
+/* PR tree-optimization/90989 - incorrrect strlen result after second strcpy
+   into the same destination.
+   { dg-do compile }
+   { dg-options "-O2 -Wall -fdump-tree-optimized" } */
+
+// #include "strlenopt.h"
+
+char a[4];
+
+int f4 (void)
+{
+  char b[4];
+  __builtin_strcpy (b, "12");
+
+  int i = __builtin_strcmp (a, b);
+
+  __builtin_strcpy (b, "123");
+  if (__builtin_strlen (b) != 3)
+    __builtin_abort ();
+
+  return i;
+}
+
+int f6 (void)
+{
+  char b[6];
+  __builtin_strcpy (b, "1234");
+
+  int i = __builtin_strcmp (a, b);
+
+  __builtin_strcpy (b, "12345");
+  if (__builtin_strlen (b) != 5)
+    __builtin_abort ();
+
+  return i;
+}
+
+int f8 (void)
+{
+  char b[8];
+  __builtin_strcpy (b, "1234");
+
+  int i = __builtin_strcmp (a, b);
+
+  __builtin_strcpy (b, "1234567");
+  if (__builtin_strlen (b) != 7)
+    __builtin_abort ();
+
+  return i;
+}
+
+/* { dg-final { scan-tree-dump-times "abort|strlen" 0 "optimized" } } */
+/* PR tree-optimization/ - incorrrect strlen result after second strcpy
+   into the same destination.
+   { dg-do compile }
+   { dg-options "-O2 -Wall -fdump-tree-optimized" } */
+
+// #include "strlenopt.h"
+
+char a[4];
+
+int f4 (void)
+{
+  char b[4];
+  __builtin_strcpy (b, "12");
+
+  int i = __builtin_strcmp (a, b);
+
+  __builtin_strcpy (b, "123");
+  if (__builtin_strlen (b) != 3)
+    __builtin_abort ();
+
+  return i;
+}
+
+int f6 (void)
+{
+  char b[6];
+  __builtin_strcpy (b, "1234");
+
+  int i = __builtin_strcmp (a, b);
+
+  __builtin_strcpy (b, "12345");
+  if (__builtin_strlen (b) != 5)
+    __builtin_abort ();
+
+  return i;
+}
+
+int f8 (void)
+{
+  char b[8];
+  __builtin_strcpy (b, "1234");
+
+  int i = __builtin_strcmp (a, b);
+
+  __builtin_strcpy (b, "1234567");
+  if (__builtin_strlen (b) != 7)
+    __builtin_abort ();
+
+  return i;
+}
+
+/* { dg-final { scan-tree-dump-times "abort|strlen" 0 "optimized" } } */
index 74cd6c44874c48c741110ed8bad7f16764d74ece..88b6bd7869ef8b60ff7f426ae5b7323afc2a1118 100644 (file)
@@ -3462,34 +3462,38 @@ handle_char_store (gimple_stmt_iterator *gsi)
              return false;
            }
        }
-      /* If si->nonzero_chars > OFFSET, we aren't overwriting '\0',
-        and if we aren't storing '\0', we know that the length of the
-        string and any other zero terminated string in memory remains
-        the same.  In that case we move to the next gimple statement and
-        return to signal the caller that it shouldn't invalidate anything.
-
-        This is benefical for cases like:
-
-        char p[20];
-        void foo (char *q)
-        {
-          strcpy (p, "foobar");
-          size_t len = strlen (p);        // This can be optimized into 6
-          size_t len2 = strlen (q);        // This has to be computed
-          p[0] = 'X';
-          size_t len3 = strlen (p);        // This can be optimized into 6
-          size_t len4 = strlen (q);        // This can be optimized into len2
-          bar (len, len2, len3, len4);
-        }
-       */
-      else if (storing_nonzero_p && cmp > 0)
+
+      if (cmp > 0
+         && storing_nonzero_p
+         && TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE)
        {
+         /* Handle a single non-nul character store.
+            If si->nonzero_chars > OFFSET, we aren't overwriting '\0',
+            and if we aren't storing '\0', we know that the length of the
+            string and any other zero terminated string in memory remains
+            the same.  In that case we move to the next gimple statement and
+            return to signal the caller that it shouldn't invalidate anything.
+
+            This is benefical for cases like:
+
+            char p[20];
+            void foo (char *q)
+            {
+              strcpy (p, "foobar");
+              size_t len = strlen (p);     // can be folded to 6
+              size_t len2 = strlen (q);    // has to be computed
+              p[0] = 'X';
+              size_t len3 = strlen (p);    // can be folded to 6
+              size_t len4 = strlen (q);    // can be folded to len2
+              bar (len, len2, len3, len4);
+              } */
          gsi_next (gsi);
          return false;
        }
-      else if (storing_all_zeros_p
-              || storing_nonzero_p
-              || (offset != 0 && cmp > 0))
+
+      if (storing_all_zeros_p
+         || storing_nonzero_p
+         || (offset != 0 && cmp > 0))
        {
          /* When STORING_NONZERO_P, we know that the string will start
             with at least OFFSET + 1 nonzero characters.  If storing