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.

>
>
>>
>> >
>> >         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