re PR tree-optimization/83444 (missing strlen optimization on a member array of a...
authorJakub Jelinek <jakub@redhat.com>
Tue, 19 Dec 2017 18:10:04 +0000 (19:10 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 19 Dec 2017 18:10:04 +0000 (19:10 +0100)
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.

From-SVN: r255835

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/strlenopt-38.c
gcc/tree-ssa-strlen.c

index 328ce281e812b47de51db330c87ba693ed198b50..5e8e9bf6accdfcd1b84609ac084de324108af8f7 100644 (file)
@@ -1,3 +1,10 @@
+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.
+
 2017-12-19  Alexandre Oliva <aoliva@redhat.com>
 
        PR debug/83422
index 81f96c6ce079e4af89f9d44abf6293b22251cad7..1146e94c0e912aa2e5cbf9bcd27db1ddc4da9442 100644 (file)
@@ -5,6 +5,9 @@
 
 2017-12-19  Jakub Jelinek  <jakub@redhat.com>
 
+       PR tree-optimization/83444
+       * gcc.dg/strlenopt-38.c: New test.
+
        PR testsuite/83454
        * gcc.dg/tree-ssa/cswtch-4.c: Require nonpic effective target.
        * gcc.dg/tree-ssa/cswtch-5.c: Likewise.
index 3b698f9c1e80bc5cb24941705a9caea78b665304..7c39f3a175b121ea4181e6f49d3b545ac1259027 100644 (file)
@@ -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 ();
+}
index a2d514cb35a954e86a33ac7a915297b92bac97a9..8971c7df4f3294fb6e57d466f83e1c3ab042b94c 100644 (file)
@@ -3155,14 +3155,27 @@ strlen_check_and_optimize_stmt (gimple_stmt_iterator *gsi)
          {
            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)
              {