aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2019-07-09 23:29:33 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2019-07-09 17:29:33 -0600
commitc2e8bd51418b927c2b31f48aa9cd630d94a59b3a (patch)
treea7ddb5fb711afabfe5545986fb93805959e02ae4
parenta0aeb7fb93da156b64fd08391c79ff35a69af7ba (diff)
downloadgcc-c2e8bd51418b927c2b31f48aa9cd630d94a59b3a.zip
gcc-c2e8bd51418b927c2b31f48aa9cd630d94a59b3a.tar.gz
gcc-c2e8bd51418b927c2b31f48aa9cd630d94a59b3a.tar.bz2
PR tree-optimization
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-26.c3
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-67.c104
-rw-r--r--gcc/tree-ssa-strlen.c52
5 files changed, 145 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4ae2fd8..f37b1f06 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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>:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index bf7c992..b025521 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gcc.dg/strlenopt-26.c b/gcc/testsuite/gcc.dg/strlenopt-26.c
index da2f465..6bb0263 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-26.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-26.c
@@ -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
index 0000000..a2bcfba
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/strlenopt-67.c
@@ -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" } } */
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index 74cd6c4..88b6bd7 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -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