This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Small load strlen opt follow-up improvement (PR tree-optimization/83444)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Biener <rguenther at suse dot de>, Jeff Law <law at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Tue, 19 Dec 2017 18:23:55 +0100
- Subject: [PATCH] Small load strlen opt follow-up improvement (PR tree-optimization/83444)
- Authentication-results: sourceware.org; auth=none
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
As the testcase shows, we weren't handling the case where we have
_34 = MEM_REF[&b, 4B];
- we would (if it exists) find the string length for b.a, but not
for the second field. Using get_addr_stridx handles that well.
The reason to use get_stridx on the MEM_REF first operand is to handle
the case when the MEM_REF is based on SSA_NAME, that is something
get_addr_stridx doesn't handle.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2017-12-19 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/83444
* tree-ssa-strlen.c (strlen_check_and_optimize_stmt): For the
character load case, if get_stridx on MEM_REF's operand doesn't
look usable, retry with get_addr_stridx.
* gcc.dg/strlenopt-38.c: New test.
--- gcc/tree-ssa-strlen.c.jj 2017-12-19 08:43:35.000000000 +0100
+++ gcc/tree-ssa-strlen.c 2017-12-19 12:52:37.007267178 +0100
@@ -3155,14 +3155,27 @@ strlen_check_and_optimize_stmt (gimple_s
{
tree off = integer_zero_node;
unsigned HOST_WIDE_INT coff = 0;
- int idx = -1;
+ int idx = 0;
tree rhs1 = gimple_assign_rhs1 (stmt);
if (code == MEM_REF)
{
idx = get_stridx (TREE_OPERAND (rhs1, 0));
- off = TREE_OPERAND (rhs1, 1);
+ if (idx > 0)
+ {
+ strinfo *si = get_strinfo (idx);
+ if (si
+ && si->nonzero_chars
+ && TREE_CODE (si->nonzero_chars) == INTEGER_CST
+ && (wi::to_widest (si->nonzero_chars)
+ >= wi::to_widest (off)))
+ off = TREE_OPERAND (rhs1, 1);
+ else
+ /* This case is not useful. See if get_addr_stridx
+ returns something usable. */
+ idx = 0;
+ }
}
- else
+ if (idx <= 0)
idx = get_addr_stridx (rhs1, NULL_TREE, &coff);
if (idx > 0)
{
--- gcc/testsuite/gcc.dg/strlenopt-38.c.jj 2017-12-19 08:43:35.000000000 +0100
+++ gcc/testsuite/gcc.dg/strlenopt-38.c 2017-12-19 12:53:19.006730543 +0100
@@ -36,3 +36,14 @@ baz (void)
if (s.b[0] != 0)
abort ();
}
+
+void
+boo (void)
+{
+ struct S s;
+ strcpy (s.b, "012");
+ strcpy (s.c, "");
+ strcpy (s.b, s.c);
+ if (strlen (s.b) != 0)
+ abort ();
+}
Jakub