On Thu, Jul 2, 2026 at 12:54 AM Andrea Pinski
<[email protected]> wrote:
>
> On Wed, Jul 1, 2026 at 10:22 AM Kael Andrew Franco
> <[email protected]> wrote:
> >
> > From 05879b4239bcb970acfb5c5afe22ef7ebd5cf084 Mon Sep 17 00:00:00 2001
> > From: Kael Andrew Alonzo Franco <[email protected]>
> > Date: Wed, 1 Jul 2026 07:10:38 -0400
> > Subject: [PATCH] match: If a in (0,1), `1 << a` to `a + 1` and `2 >> a` to 
> > `2 - a`. [PR126029]
> >
> > a + 1 is more common than 1 << a.
> > 2 - a allows more reassoc optimizations like (2 >> a) - 1 to a == 0.
> >
> > Bootstrapped and tested on x86_64-pc-linux-gnu.
> >
> > PR tree-optimization/126029
> >
> > gcc/ChangeLog:
> >
> > PR tree-optimization/126029
> > * match.pd: If a in (0,1), `1 << a` to `a + 1` and `2 >> a` to `2 - a`.
> >
> > gcc/testsuite/ChangeLog:
> >
> > PR tree-optimization/126029
> > * gcc.dg/pr126029-1.c: New test.
> >
> > Signed-off-by: Kael Franco <[email protected]>
> > ---
> >  gcc/match.pd                      | 13 +++++++++++++
> >  gcc/testsuite/gcc.dg/pr126029-1.c | 16 ++++++++++++++++
> >  2 files changed, 29 insertions(+)
> >  create mode 100644 gcc/testsuite/gcc.dg/pr126029-1.c
> >
> > diff --git a/gcc/match.pd b/gcc/match.pd
> > index ddf3b61638c..4e8b3044594 100644
> > --- a/gcc/match.pd
> > +++ b/gcc/match.pd
> > @@ -5137,12 +5137,25 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> >     (rresult @0 { build_int_cst (type, bitop == BIT_IOR_EXPR ? -1 : 0); 
> > }))))
> >  #endif
> >
> > +/* Fold `2 >> a` into 2 - a for scalar integral types if a is in (0,1).  */
> > +(simplify
> > + (rshift INTEGER_CST@1 zero_one_valued_p@0)
> > + (if (INTEGRAL_TYPE_P (type)
> > +      && wi::eq_p (wi::to_wide (@1), 2))
> && wi::to_wide (@1) == 2
>
> > +  (minus { build_int_cst (type, 2); } (convert:type @0))))
>
> Just reuse @1 here.
>
> > +
> >  /* Fold `1 >> a` into `a == 0` for scalar integral types. */
> >  (simplify
> >   (rshift integer_onep @2)
> >   (if (INTEGRAL_TYPE_P (type))
> >    (convert (eq:boolean_type_node @2 { build_zero_cst (TREE_TYPE (@2)); 
> > }))))
> >
> > +/* Fold `1 << a` into `a + 1` for scalar integral types if a is in (0,1).  
> > */
> > +(simplify
> > + (lshift integer_onep zero_one_valued_p@2)
> > + (if (INTEGRAL_TYPE_P (type))
> > +  (plus (convert:type @2) { build_one_cst (type); })))
>
> If you capture integer_onep (via @0) you can reuse that instead of
> calling build_one_cst.
> Also @2 really should be @1. I don't remember why I did @2 in the
> pattern above this :).

There is one more issue with this. If type is a signed 2bit integer,
then this would cause an integer overflow.
So you will need to specialize that one case too.
I noticed this when looking at the review for the LLVM patch.

Thanks,
Andrea

>
> Thanks,
> Andrea
>
> > +
> >  /* Simplify (CST << x) & 1 to 0 if CST is even or to x == 0 if it is odd.  
> > */
> >  (simplify
> >   (bit_and (lshift INTEGER_CST@1 @0) integer_onep)
> > diff --git a/gcc/testsuite/gcc.dg/pr126029-1.c 
> > b/gcc/testsuite/gcc.dg/pr126029-1.c
> > new file mode 100644
> > index 00000000000..354220adebc
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/pr126029-1.c
> > @@ -0,0 +1,16 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> > +
> > +int
> > +one_lshift_a (_Bool a)
> > +{
> > +  return (1 << a) == (a + 1);
> > +}
> > +
> > +int
> > +two_rshift_a (_Bool a)
> > +{
> > +  return (2 >> a) == (2 - a);
> > +}
> > +
> > +/* { dg-final { scan-tree-dump-times "return 1;" 2 "optimized" } } */
> > --
> > 2.54.0
> >
> >

Reply via email to