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