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
This commit is contained in:
Martin Sebor 2019-07-09 23:29:33 +00:00 committed by Martin Sebor
parent a0aeb7fb93
commit c2e8bd5141
5 changed files with 144 additions and 25 deletions

View 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>:

View 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.

View 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" } } */

View File

@ -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" } } */

View 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