Currently, we give up in fold_strstr_to_strncmp() if the length of the
the second argument to strstr() isn't known to us by the time we hit
that function. However, we can instead insert a strlen() in ourselves
and continue trying to fold strstr() into strlen()+strncmp().

        PR tree-optimization/96601

gcc/ChangeLog:

        * tree-ssa-strlen.cc (fold_strstr_to_strncmp): If arg1_len == NULL,
        insert a strlen() for strstr()'s arg1 and use it as arg1_len.

gcc/testsuite/ChangeLog:

        * gcc.dg/strlenopt-30.c: Modify test.

Signed-off-by: Hamza Mahfooz <some...@effective-light.com>
---
Please push this for me if you think it looks good. Since, I don't have
write access to the repository.
---
 gcc/testsuite/gcc.dg/strlenopt-30.c |  5 +-
 gcc/tree-ssa-strlen.cc              | 81 ++++++++++++++++-------------
 2 files changed, 45 insertions(+), 41 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/strlenopt-30.c 
b/gcc/testsuite/gcc.dg/strlenopt-30.c
index 2a3098ba96f..1ee814048c1 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-30.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-30.c
@@ -38,9 +38,6 @@ void f5(char *s)
     foo_f5();
 }
 
-/* Do not perform transform, since strlen (t)
-   is unknown.  */
-
 __attribute__((no_icf))
 _Bool f6(char *s, char *t)
 {
@@ -60,4 +57,4 @@ _Bool f7(char *s)
   return (t1 == s);
 }
 
-/* { dg-final { scan-tree-dump-times "__builtin_strncmp" 5 "strlen1" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_strncmp" 6 "strlen1" } } */
diff --git a/gcc/tree-ssa-strlen.cc b/gcc/tree-ssa-strlen.cc
index 8b7ef919826..b0ebbb0db62 100644
--- a/gcc/tree-ssa-strlen.cc
+++ b/gcc/tree-ssa-strlen.cc
@@ -5273,6 +5273,7 @@ fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple 
*stmt)
          tree arg1 = gimple_call_arg (call_stmt, 1);
          tree arg1_len = NULL_TREE;
          int idx = get_stridx (arg1, call_stmt);
+         gimple_stmt_iterator gsi = gsi_for_stmt (call_stmt);
 
          if (idx)
            {
@@ -5286,51 +5287,57 @@ fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple 
*stmt)
                }
            }
 
-         if (arg1_len != NULL_TREE)
+         if (arg1_len == NULL_TREE)
            {
-             gimple_stmt_iterator gsi = gsi_for_stmt (call_stmt);
-             tree strncmp_decl = builtin_decl_explicit (BUILT_IN_STRNCMP);
+             tree strlen_decl = builtin_decl_explicit (BUILT_IN_STRLEN);
+             gcall *strlen_call = gimple_build_call (strlen_decl, 1, arg1);
+             tree strlen_lhs = make_ssa_name (size_type_node, strlen_call);
+
+             gimple_call_set_lhs (strlen_call, strlen_lhs);
+             gimple_set_vuse (strlen_call, gimple_vuse (call_stmt));
+             gsi_insert_before (&gsi, strlen_call, GSI_SAME_STMT);
+             arg1_len = strlen_lhs;
+           }
+         else if (!is_gimple_val (arg1_len))
+           {
+             tree arg1_len_tmp = make_ssa_name (TREE_TYPE (arg1_len));
+             gassign *arg1_stmt = gimple_build_assign (arg1_len_tmp,
+                                                       arg1_len);
+             gsi_insert_before (&gsi, arg1_stmt, GSI_SAME_STMT);
+             arg1_len = arg1_len_tmp;
+           }
 
-             if (!is_gimple_val (arg1_len))
+         tree strncmp_decl = builtin_decl_explicit (BUILT_IN_STRNCMP);
+         gcall *strncmp_call = gimple_build_call (strncmp_decl, 3,
+                                                  arg0, arg1, arg1_len);
+         tree strncmp_lhs = make_ssa_name (integer_type_node);
+         gimple_set_vuse (strncmp_call, gimple_vuse (call_stmt));
+         gimple_call_set_lhs (strncmp_call, strncmp_lhs);
+         gsi_remove (&gsi, true);
+         gsi_insert_before (&gsi, strncmp_call, GSI_SAME_STMT);
+         tree zero = build_zero_cst (TREE_TYPE (strncmp_lhs));
+
+         if (is_gimple_assign (stmt))
+           {
+             if (gimple_assign_rhs_code (stmt) == COND_EXPR)
                {
-                 tree arg1_len_tmp = make_ssa_name (TREE_TYPE (arg1_len));
-                 gassign *arg1_stmt = gimple_build_assign (arg1_len_tmp,
-                                                           arg1_len);
-                 gsi_insert_before (&gsi, arg1_stmt, GSI_SAME_STMT);
-                 arg1_len = arg1_len_tmp;
-               }
-
-             gcall *strncmp_call = gimple_build_call (strncmp_decl, 3,
-                                                     arg0, arg1, arg1_len);
-             tree strncmp_lhs = make_ssa_name (integer_type_node);
-             gimple_set_vuse (strncmp_call, gimple_vuse (call_stmt));
-             gimple_call_set_lhs (strncmp_call, strncmp_lhs);
-             gsi_remove (&gsi, true);
-             gsi_insert_before (&gsi, strncmp_call, GSI_SAME_STMT);
-             tree zero = build_zero_cst (TREE_TYPE (strncmp_lhs));
-
-             if (is_gimple_assign (stmt))
-               {
-                 if (gimple_assign_rhs_code (stmt) == COND_EXPR)
-                   {
-                     tree cond = gimple_assign_rhs1 (stmt);
-                     TREE_OPERAND (cond, 0) = strncmp_lhs;
-                     TREE_OPERAND (cond, 1) = zero;
-                   }
-                 else
-                   {
-                     gimple_assign_set_rhs1 (stmt, strncmp_lhs);
-                     gimple_assign_set_rhs2 (stmt, zero);
-                   }
+                 tree cond = gimple_assign_rhs1 (stmt);
+                 TREE_OPERAND (cond, 0) = strncmp_lhs;
+                 TREE_OPERAND (cond, 1) = zero;
                }
              else
                {
-                 gcond *cond = as_a<gcond *> (stmt);
-                 gimple_cond_set_lhs (cond, strncmp_lhs);
-                 gimple_cond_set_rhs (cond, zero);
+                 gimple_assign_set_rhs1 (stmt, strncmp_lhs);
+                 gimple_assign_set_rhs2 (stmt, zero);
                }
-             update_stmt (stmt);
            }
+         else
+           {
+             gcond *cond = as_a<gcond *> (stmt);
+             gimple_cond_set_lhs (cond, strncmp_lhs);
+             gimple_cond_set_rhs (cond, zero);
+           }
+         update_stmt (stmt);
        }
     }
 }
-- 
2.42.0

Reply via email to