+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>:
+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.
{
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" } } */
--- /dev/null
+/* 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" } } */
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