Currently, we are not saving the strlen() call we inserted for possible future common subexpression elimination. Also, it's possible that we can further fold that strlen() call. So, refactor handle_builtin_strlen() so that it can be called from fold_strstr_to_strncmp().
gcc/ChangeLog: * tree-ssa-strlen.cc (strlen_pass::handle_builtin_strlen): Remove from class and mark as static. (handle_builtin_strlen): Add parameter "gimple_stmt_iterator gsi" and replace references of m_gsi with gsi. (fold_strstr_to_strncmp): Call handle_builtin_strlen(). (strlen_pass::check_and_optimize_call): Add m_gsi to the handle_builtin_strlen() call. gcc/testsuite/ChangeLog: * gcc.dg/strlenopt-30.c: Add a 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 | 7 +++++++ gcc/tree-ssa-strlen.cc | 23 ++++++++++++----------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/gcc/testsuite/gcc.dg/strlenopt-30.c b/gcc/testsuite/gcc.dg/strlenopt-30.c index 1ee814048c1..de51a66383b 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-30.c +++ b/gcc/testsuite/gcc.dg/strlenopt-30.c @@ -44,6 +44,12 @@ _Bool f6(char *s, char *t) return __builtin_strstr (s, t) == s; } +__attribute__((no_icf)) +_Bool f6plus(char *s, char *t) +{ + return __builtin_strstr (s, t) == s && __builtin_strlen(t) > 10; +} + /* Do not perform transform in this case, since t1 doesn't have single use. */ @@ -57,4 +63,5 @@ _Bool f7(char *s) return (t1 == s); } +/* { dg-final { scan-tree-dump-times "__builtin_strlen" 2 "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 b0ebbb0db62..8ec6ddbc7c0 100644 --- a/gcc/tree-ssa-strlen.cc +++ b/gcc/tree-ssa-strlen.cc @@ -252,7 +252,6 @@ public: bool handle_assign (tree lhs, bool *zero_write); bool handle_store (bool *zero_write); void handle_pointer_plus (); - void handle_builtin_strlen (); void handle_builtin_strchr (); void handle_builtin_strcpy (built_in_function); void handle_integral_assign (bool *cleanup_eh); @@ -2211,10 +2210,10 @@ strlen_pass::maybe_warn_overflow (gimple *stmt, bool call_lhs, the strlen call with the known value, otherwise remember that strlen of the argument is stored in the lhs SSA_NAME. */ -void -strlen_pass::handle_builtin_strlen () +static void +handle_builtin_strlen (gimple_stmt_iterator gsi) { - gimple *stmt = gsi_stmt (m_gsi); + gimple *stmt = gsi_stmt (gsi); tree lhs = gimple_call_lhs (stmt); if (lhs == NULL_TREE) @@ -2268,8 +2267,8 @@ strlen_pass::handle_builtin_strlen () if (bound) rhs = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (rhs), rhs, bound); - gimplify_and_update_call_from_tree (&m_gsi, rhs); - stmt = gsi_stmt (m_gsi); + gimplify_and_update_call_from_tree (&gsi, rhs); + stmt = gsi_stmt (gsi); update_stmt (stmt); if (dump_file && (dump_flags & TDF_DETAILS) != 0) { @@ -2367,8 +2366,8 @@ strlen_pass::handle_builtin_strlen () } if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (ret))) ret = fold_convert_loc (loc, TREE_TYPE (lhs), ret); - gimplify_and_update_call_from_tree (&m_gsi, ret); - stmt = gsi_stmt (m_gsi); + gimplify_and_update_call_from_tree (&gsi, ret); + stmt = gsi_stmt (gsi); update_stmt (stmt); if (dump_file && (dump_flags & TDF_DETAILS) != 0) { @@ -5272,8 +5271,9 @@ 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); +again: + int idx = get_stridx (arg1, call_stmt); if (idx) { @@ -5296,7 +5296,8 @@ fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple *stmt) 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; + handle_builtin_strlen (gsi_for_stmt (strlen_call)); + goto again; } else if (!is_gimple_val (arg1_len)) { @@ -5393,7 +5394,7 @@ strlen_pass::check_and_optimize_call (bool *zero_write) { case BUILT_IN_STRLEN: case BUILT_IN_STRNLEN: - handle_builtin_strlen (); + handle_builtin_strlen (m_gsi); break; case BUILT_IN_STRCHR: handle_builtin_strchr (); -- 2.42.0