aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Sebor <msebor@gmail.com>2018-01-11 04:37:48 +0000
committerPrathamesh Kulkarni <prathamesh3492@gcc.gnu.org>2018-01-11 04:37:48 +0000
commit05ef31736c431ca4721ba8d05156e99af79a5aac (patch)
tree8e4795ba658e8de4ed56247873a0632d4efd2ddd
parent840573729e5fa22ebea44e0c580efd14b46f111e (diff)
downloadgcc-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
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/gcc.dg/pr81703.c12
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-39.c66
-rw-r--r--gcc/tree-ssa-strlen.c42
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;
}