On Thu, Oct 2, 2025 at 1:36 AM Richard Biener
<[email protected]> wrote:
>
> On Wed, Sep 24, 2025 at 11:07 AM Andrew Pinski
> <[email protected]> wrote:
> >
> > This moves from the memcmp->memcmp_eq to forwprop by
> > checking PROP_last_full_fold.
> >
> > Note this means at -Og, we no longer optimize some
> > memcmp. That will be fixed when I exchange fab/copyprop
> > for a (late) forwprop.
> >
> > Bootstrapped and tested on x86_64-linux-gnu.
> >
> > gcc/ChangeLog:
> >
> >         * tree-ssa-ccp.cc (optimize_memcmp_eq): Remove.
> >         (pass_fold_builtins::execute): Remove handling of memcmp.
> >         * tree-ssa-forwprop.cc (simplify_builtin_memcmp): Add folding
> >         of memcmp to memcmp_eq for PROP_last_full_fold.
> >
> > Signed-off-by: Andrew Pinski <[email protected]>
> > ---
> >  gcc/tree-ssa-ccp.cc      | 34 ----------------------------------
> >  gcc/tree-ssa-forwprop.cc | 10 +++++++++-
> >  2 files changed, 9 insertions(+), 35 deletions(-)
> >
> > diff --git a/gcc/tree-ssa-ccp.cc b/gcc/tree-ssa-ccp.cc
> > index c74f7cc9d0c..389525b4be7 100644
> > --- a/gcc/tree-ssa-ccp.cc
> > +++ b/gcc/tree-ssa-ccp.cc
> > @@ -4205,36 +4205,6 @@ public:
> >
> >  }; // class pass_fold_builtins
> >
> > -/* Optimize memcmp STMT into memcmp_eq if it is only used with
> > -   `== 0` or `!= 0`. */
> > -
> > -static void
> > -optimize_memcmp_eq (gcall *stmt)
> > -{
> > -  /* Make sure memcmp arguments are the correct type.  */
> > -  if (gimple_call_num_args (stmt) != 3)
> > -    return;
> > -  tree arg1 = gimple_call_arg (stmt, 0);
> > -  tree arg2 = gimple_call_arg (stmt, 1);
> > -  tree len = gimple_call_arg (stmt, 2);
> > -
> > -  if (!POINTER_TYPE_P (TREE_TYPE (arg1)))
> > -    return;
> > -  if (!POINTER_TYPE_P (TREE_TYPE (arg2)))
> > -    return;
> > -  if (!INTEGRAL_TYPE_P (TREE_TYPE (len)))
> > -    return;
> > -  /* The return value of the memcmp has to be used
> > -     equality comparison to zero. */
> > -  tree res = gimple_call_lhs (stmt);
> > -
> > -  if (!res || !use_in_zero_equality (res))
> > -    return;
> > -
> > -  gimple_call_set_fndecl (stmt, builtin_decl_explicit 
> > (BUILT_IN_MEMCMP_EQ));
> > -  update_stmt (stmt);
> > -}
> > -
> >  unsigned int
> >  pass_fold_builtins::execute (function *fun)
> >  {
> > @@ -4296,10 +4266,6 @@ pass_fold_builtins::execute (function *fun)
> >                   gsi_next (&i);
> >                   continue;
> >
> > -               case BUILT_IN_MEMCMP:
> > -                 optimize_memcmp_eq (as_a<gcall*>(stmt));
> > -                 break;
> > -
> >                 case BUILT_IN_UNREACHABLE:
> >                   if (optimize_unreachable (i))
> >                     cfg_changed = true;
> > diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
> > index 4c438a0f86c..917f3d90f6c 100644
> > --- a/gcc/tree-ssa-forwprop.cc
> > +++ b/gcc/tree-ssa-forwprop.cc
> > @@ -1842,7 +1842,15 @@ simplify_builtin_memcmp (gimple_stmt_iterator 
> > *gsi_p, gcall *stmt)
> >           return true;
> >         }
> >      }
> > -  return false;
> > +
> > +  /* Replace memcmp with memcmp_eq if the above fails. */
> > +  if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt)) == BUILT_IN_MEMCMP_EQ)
> > +    return false;
> > +  if (!(cfun->curr_properties & (PROP_last_full_fold)))
> > +    return false;
>
> The patch is OK.  Seeing the above more and more I wonder if we want to 
> abstract
> that into an inline function (in gimple-fold.h?), like
> fold_before_rtl_expansion_p ()
> or so?  Similar to the canonicalize_math_p (),
> optimize_vectors_before_lowering_p (), etc.
> predicates we have in {gimple,generic}-match-head.cc

Yes that is a good idea, I filed PR 122142 to remind myself to implement this.

Thanks,
Andrew

>
> Richard.
>
> > +  gimple_call_set_fndecl (stmt, builtin_decl_explicit 
> > (BUILT_IN_MEMCMP_EQ));
> > +  update_stmt (stmt);
> > +  return true;
> >  }
> >
> >  /* Optimizes builtin memchrs for small constant sizes with a const string.
> > --
> > 2.43.0
> >

Reply via email to