On 6/9/2026 11:08 AM, Kael Andrew Franco wrote: > From 712dd974acd5a972d74e62e8eec902de9c557a26 Mon Sep 17 00:00:00 2001 > From: Kael Andrew Alonzo Franco <[email protected]> > Date: Tue, 9 Jun 2026 05:59:57 -0400 > Subject: [PATCH] match: Optimize bit_ior/bit_and {bit_not} rshift to min/max > [PR125641] > > Fold x | (x >> (TYPE_PRECISION (type) - 1)) to max (x, -1) > Fold x | (~ (x >> (TYPE_PRECISION (type) - 1))) to min (x, -1) > Fold x & (x >> (TYPE_PRECISION (type) - 1)) to min (x, 0) > Fold x & (~ (x >> (TYPE_PRECISION (type) - 1))) to max (x, 0) > > Bootstrapped and tested on x86_64-pc-linux-gnu > > PR tree-optimization/125641 > > gcc/ChangeLog: > > PR tree-optimization/125641 > * match.pd: Add bit_ior/bit_and {bit_not} rshift to min/max. > > gcc/testsuite/ChangeLog: > > PR tree-optimization/125641 > * gcc.dg/pr125641.c: New test. > > Signed-off-by: Kael Franco <[email protected]> > --- > gcc/match.pd | 23 +++++++++++++++++++ > gcc/testsuite/gcc.dg/pr125641.c | 40 +++++++++++++++++++++++++++++++++ > 2 files changed, 63 insertions(+) > create mode 100644 gcc/testsuite/gcc.dg/pr125641.c > > diff --git a/gcc/match.pd b/gcc/match.pd > index e0d7ef80e14..015a12c6055 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -5043,6 +5043,29 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (op @0 { build_int_cst (TREE_TYPE (@1), prec - 1); }))) > (op @0 { build_int_cst (TREE_TYPE (@1), low); }))))))) > > +/* Fold x | (x >> (TYPE_PRECISION (type) - 1)) to max (x, -1) > + Fold x | (~ (x >> (TYPE_PRECISION (type) - 1))) to min (x, -1) > + Fold x & (x >> (TYPE_PRECISION (type) - 1)) to min (x, 0) > + Fold x & (~ (x >> (TYPE_PRECISION (type) - 1))) to max (x, 0) > +*/ > +#ifdef GIMPLE > +(for bitop (bit_ior bit_and) > + result (max min) > + rresult (min max) > + (simplify > + (bitop:c @0 (rshift @0 INTEGER_CST@1)) > + (if (INTEGRAL_TYPE_P (type) > + && !TYPE_UNSIGNED (type) > + && wi::eq_p (wi::to_wide (@1), TYPE_PRECISION (type) - 1)) > + (result @0 { build_int_cst (type, bitop == BIT_IOR_EXPR ? -1 : 0); }))) > + (simplify > + (bitop:c @0 (bit_not (rshift @0 INTEGER_CST@1))) > + (if (INTEGRAL_TYPE_P (type) > + && !TYPE_UNSIGNED (type) > + && wi::eq_p (wi::to_wide (@1), TYPE_PRECISION (type) - 1)) > + (rresult @0 { build_int_cst (type, bitop == BIT_IOR_EXPR ? -1 : 0); })))) > +#endif > + > /* Fold `1 >> a` into `a == 0` for scalar integral types. */ > (simplify > (rshift integer_onep @2) > diff --git a/gcc/testsuite/gcc.dg/pr125641.c b/gcc/testsuite/gcc.dg/pr125641.c > new file mode 100644 > index 00000000000..690d1c70d1f > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr125641.c > @@ -0,0 +1,40 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-optimized" } */ So the test assumes 32bit integers (via the " >> 31"). It seems like
(sizeof (int) * 8) - 1 Would be better. Otherwise it looks sensible to me. I'll ack/push one the testsuite is cleaned up. Jeff
