On December 19, 2017 6:23:55 PM GMT+01:00, Jakub Jelinek <ja...@redhat.com> 
wrote:
>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?

OK. 
Richard. 

>2017-12-19  Jakub Jelinek  <ja...@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

Reply via email to