diff options
author | Martin Sebor <msebor@gmail.com> | 2018-01-11 04:37:48 +0000 |
---|---|---|
committer | Prathamesh Kulkarni <prathamesh3492@gcc.gnu.org> | 2018-01-11 04:37:48 +0000 |
commit | 05ef31736c431ca4721ba8d05156e99af79a5aac (patch) | |
tree | 8e4795ba658e8de4ed56247873a0632d4efd2ddd /gcc | |
parent | 840573729e5fa22ebea44e0c580efd14b46f111e (diff) | |
download | gcc-05ef31736c431ca4721ba8d05156e99af79a5aac.zip gcc-05ef31736c431ca4721ba8d05156e99af79a5aac.tar.gz gcc-05ef31736c431ca4721ba8d05156e99af79a5aac.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr81703.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/strlenopt-39.c | 66 | ||||
-rw-r--r-- | gcc/tree-ssa-strlen.c | 42 |
5 files changed, 130 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3662659..bb6bf49 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +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> diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 016f677..dd4bfce 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +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. diff --git a/gcc/testsuite/gcc.dg/pr81703.c b/gcc/testsuite/gcc.dg/pr81703.c new file mode 100644 index 0000000..190f4a8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr81703.c @@ -0,0 +1,12 @@ +/* { 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" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-39.c b/gcc/testsuite/gcc.dg/strlenopt-39.c new file mode 100644 index 0000000..a4177c9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/strlenopt-39.c @@ -0,0 +1,66 @@ +/* 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" } } */ diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index aae242d..4e36327 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -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; } |