This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Small load strlen opt follow-up improvement (PR tree-optimization/83444)


On December 19, 2017 6:23:55 PM GMT+01:00, Jakub Jelinek <jakub@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  <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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]