On Mon, Jan 5, 2026 at 2:23 PM Daniel Barboza <[email protected]> wrote: > > The initial idea of this optimization was to reduce it to "X != 0", > checking for either X being an unsigned or a truncating conversion. > Then we discussed reducing it to "(X & -X) != 0" instead. This form > would avoid the potential trapping problems (like -ftrapv) that might > happen in case X is not an unsigned type. > > Then, as suggested by Roger Sayle in bugzilla, we could reduce to just > "-X != 0". Keeping the negated value in the pattern preserves any trapping > or UBs to be handled by other match.pd patterns that are more able to do > the conversion to "X != 0" when applicable. This would also spare us from > a TYPE_UNSIGNED check. > > PR 102486 PR tree-optimization/102486 > > gcc/ChangeLog: > > * match.pd (`popcount (X & -X) -> -X != 0`): New pattern. > > gcc/testsuite/ChangeLog: > > * gcc.dg/tree-ssa/pr102486.c: New test.
Ok. When I get some time I will push this change. Thanks, Andrew > > Signed-off-by: Daniel Barboza <[email protected]> > --- > > Changes from v2: > - changed pattern result from "(X & -X) != 0" to "-X != 0"; > - dropped TYPE_UNSIGNED check; > - added a brief history in the commit msg explaining where did this > pattern come from; > - v2 link: https://gcc.gnu.org/pipermail/gcc-patches/2025-December/704632.html > > > gcc/match.pd | 14 ++++++++++++++ > gcc/testsuite/gcc.dg/tree-ssa/pr102486.c | 14 ++++++++++++++ > 2 files changed, 28 insertions(+) > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr102486.c > > diff --git a/gcc/match.pd b/gcc/match.pd > index ccdc1129e23..d72a3d75b86 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -10558,6 +10558,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (popcount:s @1)) > (popcount (log2 @0 @1))))) > > +/* popcount (X & -X) is -X != 0. */ > +(simplify > + (POPCOUNT (convert?@2 (bit_and:c @0 (negate@1 @0)))) > + (with { tree type0 = TREE_TYPE (@0); > + tree type2 = TREE_TYPE (@2); } > + (if (INTEGRAL_TYPE_P (type0) > + && TYPE_PRECISION (type2) <= TYPE_PRECISION (type0)) > + /* Use an explicit bool conversion to avoid errors when the > + POPCOUNT result is assigned to a type (e.g. int) that > + will generate a "bogus comparison result type" error. */ > + (convert:type > + (ne:boolean_type_node > + (convert:type2 @1) { build_zero_cst (type2); }))))) > + > #if GIMPLE > /* popcount(zext(X)) == popcount(X). */ > (simplify > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr102486.c > b/gcc/testsuite/gcc.dg/tree-ssa/pr102486.c > new file mode 100644 > index 00000000000..aa454d91fae > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr102486.c > @@ -0,0 +1,14 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O1 -fdump-tree-optimized" } */ > + > +int f (unsigned y) > +{ > + return __builtin_popcount (y & -y); > +} > + > +int f2 (int y) > +{ > + return __builtin_popcount (y & -y); > +} > + > +/* { dg-final { scan-tree-dump-times "popcount" 0 "optimized" } } */ > -- > 2.43.0 >
