Commit c2e8bd51 by Martin Sebor Committed by Martin Sebor

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
parent a0aeb7fb
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> 2019-07-09 Joern Rennecke <joern.rennecke@riscy-ip.com>
* tree-vect-stmts.c (vectorizable_comparison) <!slp_node>: * 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> 2019-07-09 Dragan Mladjenovic <dmladjenovic@wavecomp.com>
* gcc.target/mips/cfgcleanup-jalr1.c: New test. * gcc.target/mips/cfgcleanup-jalr1.c: New test.
......
...@@ -17,8 +17,7 @@ main (void) ...@@ -17,8 +17,7 @@ main (void)
{ {
char p[] = "foobar"; char p[] = "foobar";
const char *volatile q = "xyzzy"; const char *volatile q = "xyzzy";
fn1 (p, q); return fn1 (p, q);
return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
......
/* 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) ...@@ -3462,34 +3462,38 @@ handle_char_store (gimple_stmt_iterator *gsi)
return false; 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 if (cmp > 0
string and any other zero terminated string in memory remains && storing_nonzero_p
the same. In that case we move to the next gimple statement and && TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE)
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)
{ {
/* 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); gsi_next (gsi);
return false; return false;
} }
else if (storing_all_zeros_p
|| storing_nonzero_p if (storing_all_zeros_p
|| (offset != 0 && cmp > 0)) || storing_nonzero_p
|| (offset != 0 && cmp > 0))
{ {
/* When STORING_NONZERO_P, we know that the string will start /* When STORING_NONZERO_P, we know that the string will start
with at least OFFSET + 1 nonzero characters. If storing with at least OFFSET + 1 nonzero characters. If storing
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment