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:
parent
a0aeb7fb93
commit
c2e8bd5141
@ -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>:
|
||||
|
@ -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.
|
||||
|
@ -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" } } */
|
||||
|
104
gcc/testsuite/gcc.dg/strlenopt-67.c
Normal file
104
gcc/testsuite/gcc.dg/strlenopt-67.c
Normal 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" } } */
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user