Commit 05ef3173 by Martin Sebor Committed by Prathamesh Kulkarni

re PR tree-optimization/83501 (strlen(a) not folded after strcpy(a, "..."))

2018-01-11  Martin Sebor  <msebor@gmail.com>
	    Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>

	PR tree-optimization/83501
	PR tree-optimization/81703

	* tree-ssa-strlen.c (get_string_cst): Rename...
	(get_string_len): ...to this.  Handle global constants.
	(handle_char_store): Adjust.

testsuite/
	* gcc.dg/strlenopt-39.c: New test-case.
	* gcc.dg/pr81703.c: Likewise.

Co-Authored-By: Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>

From-SVN: r256475
parent 84057372
2018-01-11 Martin Sebor <msebor@gmail.com>
Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
PR tree-optimization/83501
PR tree-optimization/81703
* tree-ssa-strlen.c (get_string_cst): Rename...
(get_string_len): ...to this. Handle global constants.
(handle_char_store): Adjust.
2018-01-10 Kito Cheng <kito.cheng@gmail.com>
Jim Wilson <jimw@sifive.com>
......
2018-01-11 Martin Sebor <msebor@gmail.com>
Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
PR tree-optimization/83501
PR tree-optimization/81703
* gcc.dg/strlenopt-39.c: New test-case.
* gcc.dg/pr81703.c: Likewise.
2018-01-10 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/atomic10.adb: New test.
......
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-strlen" } */
unsigned g (void)
{
char d[8];
const char s[] = "0123";
__builtin_memcpy (d, s, sizeof s);
return __builtin_strlen (d);
}
/* { dg-final { scan-tree-dump-not "__builtin_strlen" "strlen" } } */
/* PR tree-optimization/83444
{ dg-do compile }
{ dg-options "-O2 -fdump-tree-optimized" } */
#include "strlenopt.h"
#define STR "1234567"
const char str[] = STR;
char dst[10];
void copy_from_global_str (void)
{
strcpy (dst, str);
if (strlen (dst) != sizeof str - 1)
abort ();
}
void copy_from_local_str (void)
{
const char s[] = STR;
strcpy (dst, s);
if (strlen (dst) != sizeof s - 1)
abort ();
}
void copy_from_local_memstr (void)
{
struct {
char s[sizeof STR];
} x = { STR };
strcpy (dst, x.s);
if (strlen (dst) != sizeof x.s - 1)
abort ();
}
void copy_to_local_str (void)
{
char d[sizeof STR];
strcpy (d, str);
if (strlen (d) != sizeof str - 1)
abort ();
}
void copy_to_local_memstr (void)
{
struct {
char d[sizeof STR];
} x;
strcpy (x.d, str);
if (strlen (x.d) != sizeof str- 1)
abort ();
}
/* Verify that all calls to strlen have been eliminated.
{ dg-final { scan-tree-dump-not "(abort|strlen) \\(\\)" "optimized" } } */
......@@ -2773,18 +2773,40 @@ handle_pointer_plus (gimple_stmt_iterator *gsi)
}
/* Check if RHS is string_cst possibly wrapped by mem_ref. */
static tree
get_string_cst (tree rhs)
static int
get_string_len (tree rhs)
{
if (TREE_CODE (rhs) == MEM_REF
&& integer_zerop (TREE_OPERAND (rhs, 1)))
{
rhs = TREE_OPERAND (rhs, 0);
tree rhs_addr = rhs = TREE_OPERAND (rhs, 0);
if (TREE_CODE (rhs) == ADDR_EXPR)
rhs = TREE_OPERAND (rhs, 0);
{
rhs = TREE_OPERAND (rhs, 0);
if (TREE_CODE (rhs) != STRING_CST)
{
int idx = get_stridx (rhs_addr);
if (idx > 0)
{
strinfo *si = get_strinfo (idx);
if (si && si->full_string_p)
return tree_to_shwi (si->nonzero_chars);
}
}
}
}
return (TREE_CODE (rhs) == STRING_CST) ? rhs : NULL_TREE;
if (TREE_CODE (rhs) == VAR_DECL
&& TREE_READONLY (rhs))
rhs = DECL_INITIAL (rhs);
if (rhs && TREE_CODE (rhs) == STRING_CST)
{
unsigned HOST_WIDE_INT ilen = strlen (TREE_STRING_POINTER (rhs));
return ilen <= INT_MAX ? ilen : -1;
}
return -1;
}
/* Handle a single character store. */
......@@ -2799,6 +2821,9 @@ handle_char_store (gimple_stmt_iterator *gsi)
tree rhs = gimple_assign_rhs1 (stmt);
unsigned HOST_WIDE_INT offset = 0;
/* Set to the length of the string being assigned if known. */
int rhslen;
if (TREE_CODE (lhs) == MEM_REF
&& TREE_CODE (TREE_OPERAND (lhs, 0)) == SSA_NAME)
{
......@@ -2942,19 +2967,18 @@ handle_char_store (gimple_stmt_iterator *gsi)
}
}
else if (idx == 0
&& (rhs = get_string_cst (gimple_assign_rhs1 (stmt)))
&& (rhslen = get_string_len (gimple_assign_rhs1 (stmt))) >= 0
&& ssaname == NULL_TREE
&& TREE_CODE (TREE_TYPE (lhs)) == ARRAY_TYPE)
{
size_t l = strlen (TREE_STRING_POINTER (rhs));
HOST_WIDE_INT a = int_size_in_bytes (TREE_TYPE (lhs));
if (a > 0 && (unsigned HOST_WIDE_INT) a > l)
if (a > 0 && (unsigned HOST_WIDE_INT) a > (unsigned HOST_WIDE_INT) rhslen)
{
int idx = new_addr_stridx (lhs);
if (idx != 0)
{
si = new_strinfo (build_fold_addr_expr (lhs), idx,
build_int_cst (size_type_node, l), true);
build_int_cst (size_type_node, rhslen), true);
set_strinfo (idx, si);
si->dont_invalidate = true;
}
......
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