On Thu, 10 Sep 2026 at 6:55 AM, Andrea Pinski <
[email protected]> wrote:

> On Wed, Sep 9, 2026 at 6:07 PM Shivam Gupta <[email protected]>
> wrote:
> >
> >
> >
> > On Thu, 10 Sep 2026 at 6:32 AM, Andrea Pinski <
> [email protected]> wrote:
> >>
> >> On Sun, Sep 6, 2026 at 6:07 PM Shivam Gupta <[email protected]>
> wrote:
> >> >
> >> > is_rshift_by_1 previously checked TYPE_UNSIGNED on the shift
> statement,
> >> > preventing signed arithmetic right shifts from being optimized into
> CLZ
> >> > calls. However, an arithmetic right shift behaves identically to a
> logical
> >> > right shift when the initial operand entering the loop is
> non-negative.
> >> >
> >> > This patch removes the strict TYPE_UNSIGNED requirement from
> is_rshift_by_1
> >> > and adds ranger range_on_edge non-negativity checks in
> number_of_iterations_cltz
> >> > and number_of_iterations_cltz_complement on the loop preheader edge.
> >>
> >>
> >> Ok.  I forgot if you have write after approval access or not.
> >>
> >
> >
> > Thank you, I do not have write after approval access but it would be
> nice to have someday. I plan to contribute to GCC in long term.
>
> Pushed as r17-4047-ge90e0f66051d338c1950d2cc9e36967552d75c3a.  Will
> come back to you on write after approval access though.
>

Awesome, thanks!


> >
> >
> >>
> >> >
> >> >         PR tree-optimization/125734
> >> >
> >> > gcc/ChangeLog:
> >> >
> >> >         * tree-ssa-loop-niter.cc (is_rshift_by_1): Remove
> TYPE_UNSIGNED restriction.
> >> >         (number_of_iterations_cltz): Use range_on_edge to check
> non-negativity of
> >> >         signed preheader input.
> >> >         (number_of_iterations_cltz_complement): Likewise.
> >> >
> >> > gcc/testsuite/ChangeLog:
> >> >
> >> >         * gcc.dg/tree-ssa/pr125734.c: New test.
> >> >
> >> > Regression tested on arch64-unknown-linux-gnu.
> >> >
> >> > Signed-off-by: Shivam Gupta <[email protected]>
> >> > ---
> >> >  gcc/testsuite/gcc.dg/tree-ssa/pr125734.c | 32
> ++++++++++++++++++++++++
> >> >  gcc/tree-ssa-loop-niter.cc               | 26 +++++++++++++++++--
> >> >  2 files changed, 56 insertions(+), 2 deletions(-)
> >> >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr125734.c
> >> >
> >> > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr125734.c
> b/gcc/testsuite/gcc.dg/tree-ssa/pr125734.c
> >> > new file mode 100644
> >> > index 000000000..f8d76c459
> >> > --- /dev/null
> >> > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr125734.c
> >> > @@ -0,0 +1,32 @@
> >> > +/* { dg-do compile } */
> >> > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> >> > +
> >> > +int
> >> > +nlz32 (int b)
> >> > +{
> >> > +  int c = sizeof(b) * 8;
> >> > +  if (b < 0)
> >> > +    return -1;
> >> > +  while (b != 0)
> >> > +    {
> >> > +      b >>= 1;
> >> > +      c--;
> >> > +    }
> >> > +  return c;
> >> > +}
> >> > +
> >> > +int
> >> > +nlz32_negative (int b)
> >> > +{
> >> > +  int c = sizeof(b) * 8;
> >> > +
> >> > +  while (b != 0)
> >> > +    {
> >> > +      b >>= 1;
> >> > +      c--;
> >> > +    }
> >> > +
> >> > +  return c;
> >> > +}
> >> > +
> >> > +/* { dg-final { scan-tree-dump-times "\\.CLZ" 1 "optimized" } } */
> >> > diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc
> >> > index 0c1ebd1c7..3ce3dccfa 100644
> >> > --- a/gcc/tree-ssa-loop-niter.cc
> >> > +++ b/gcc/tree-ssa-loop-niter.cc
> >> > @@ -2313,8 +2313,6 @@ is_lshift_by_1 (gassign *stmt)
> >> >  static bool
> >> >  is_rshift_by_1 (gassign *stmt)
> >> >  {
> >> > -  if (!TYPE_UNSIGNED (TREE_TYPE (gimple_assign_lhs (stmt))))
> >> > -    return false;
> >> >    if (gimple_assign_rhs_code (stmt) == RSHIFT_EXPR
> >> >        && integer_onep (gimple_assign_rhs2 (stmt)))
> >> >      return true;
> >> > @@ -2482,6 +2480,18 @@ number_of_iterations_cltz (loop_p loop, edge
> exit,
> >> >
> >> >    /* We found a match.  */
> >> >    tree src = gimple_phi_arg_def (phi, loop_preheader_edge
> (loop)->dest_idx);
> >> > +
> >> > +  /* If the type is signed, verify via Ranger on the preheader edge
> >> > +     that the initial value entering the loop is non-negative.  */
> >> > +  if (!TYPE_UNSIGNED (TREE_TYPE (src)))
> >> > +    {
> >> > +      int_range_max r (TREE_TYPE (src));
> >> > +      edge e = loop_preheader_edge (loop);
> >> > +      if (!get_range_query (cfun)->range_on_edge (r, e, src)
> >> > +         || !r.nonnegative_p ())
> >> > +       return false;
> >> > +    }
> >> > +
> >> >    int src_precision = TYPE_PRECISION (TREE_TYPE (src));
> >> >
> >> >    /* Save the original SSA name before preprocessing for ranger
> queries.  */
> >> > @@ -2641,6 +2651,18 @@ number_of_iterations_cltz_complement (loop_p
> loop, edge exit,
> >> >
> >> >    /* We found a match.  */
> >> >    tree src = gimple_phi_arg_def (phi, loop_preheader_edge
> (loop)->dest_idx);
> >> > +
> >> > +  /* If the type is signed, verify via Ranger on the preheader edge
> >> > +     that the initial value entering the loop is non-negative.  */
> >> > +  if (!TYPE_UNSIGNED (TREE_TYPE (src)))
> >> > +    {
> >> > +      int_range_max r (TREE_TYPE (src));
> >> > +      edge e = loop_preheader_edge (loop);
> >> > +      if (!get_range_query (cfun)->range_on_edge (r, e, src)
> >> > +         || !r.nonnegative_p ())
> >> > +       return false;
> >> > +    }
> >> > +
> >> >    int src_precision = TYPE_PRECISION (TREE_TYPE (src));
> >> >
> >> >    /* Get the corresponding c[lt]z builtin.  */
> >> > --
> >> > 2.43.0
> >> >
>

Reply via email to