On Mon, 11 May 2026, Reshma Roy wrote:

> Enabling POPCNT generation for 32-bit pattern from Hacker's Delight
> 
> Pattern 1:
> int Gia_WordCountOnes32c( uint32_t uword )
> {
>   uword = (uword & 0x55555555) + ((uword>>1) & 0x55555555);
>   uword = (uword & 0x33333333) + ((uword>>2) & 0x33333333);
>   uword = (uword & 0x0f0f0f0f) + ((uword>>4) & 0x0f0f0f0f);
>   uword = (uword & 0x00ff00ff) + ((uword>>8) & 0x00ff00ff);
>   return  (uword & 0x0000ffff) + (uword>>16);
>   or
>   return (uword & 0x0000FFFF) + ((uword >> 16) & 0x0000FFFF);
> }
> 
> Pattern 2:
> int pop(unsigned x) {
>   x = x - ((x >> 1) & 0x55555555);
>   x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
>   x = (x + (x >> 4)) & 0x0F0F0F0F;
>   x = x + (x >> 8);
>   x = x + (x >> 16);
>   return x & 0x0000003F;
> }
> 
> Pattern 3:
> int pop(unsigned x) {
>   x = x - ((x >> 1) & 0x55555555);
>   x = x - 3*((x >> 2) & 0x33333333)
>     x = (x + (x >> 4)) & 0x0F0F0F0F;
>   x = x + (x >> 8);
>   x = x + (x >> 16);
>   return x & 0x0000003F;
> }
> 
> gcc/ChangeLog:
> 
>         * match.pd: Add new popcount pattern variants from Hacker's Delight.
> 
> gcc/testsuite/ChangeLog:
> 
>         * gcc.dg/tree-ssa/popcount7.c: New test.
>         * gcc.dg/tree-ssa/popcount7_2.c: New test.
>         * gcc.dg/tree-ssa/popcount8.c: New test.
>         * gcc.dg/tree-ssa/popcount9.c: New test.
> 
> ---
> 
> [Public]
> 
> Hi Richard,
>    The space issues were resolved and the other comment addressed.

OK if the patch passes bootstrap & regtest.

Thanks,
Richard.

> 
> Original Message-----
> > From: Richard Biener <[email protected]>
> > Sent: Friday, May 8, 2026 12:16 PM
> > To: Roy, Reshma <[email protected]>
> > Cc: [email protected]; Kumar, Venkataramanan
> > <[email protected]>
> > Subject: Re: [PATCH v3] Enabling POPCNT generation for 32-bit patterns.
> > 
> > Caution: This message originated from an External Source. Use proper caution
> > when opening attachments, clicking links, or responding.
> > 
> > 
> > On Thu, 7 May 2026, Reshma Roy wrote:
> > 
> > > Enabling POPCNT generation for 32-bit pattern from Hacker's Delight
> > >
> > > Pattern 1:
> > > int Gia_WordCountOnes32c( uint32_t uword ) {
> > >   uword = (uword & 0x55555555) + ((uword>>1) & 0x55555555);
> > >   uword = (uword & 0x33333333) + ((uword>>2) & 0x33333333);
> > >   uword = (uword & 0x0f0f0f0f) + ((uword>>4) & 0x0f0f0f0f);
> > >   uword = (uword & 0x00ff00ff) + ((uword>>8) & 0x00ff00ff);
> > >   return  (uword & 0x0000ffff) + (uword>>16);
> > >   or
> > >   return (uword & 0x0000FFFF) + ((uword >> 16) & 0x0000FFFF); }
> > >
> > > Pattern 2:
> > > int pop(unsigned x) {
> > >   x = x - ((x >> 1) & 0x55555555);
> > >   x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
> > >   x = (x + (x >> 4)) & 0x0F0F0F0F;
> > >   x = x + (x >> 8);
> > >   x = x + (x >> 16);
> > >   return x & 0x0000003F;
> > > }
> > >
> > > Pattern 3:
> > > int pop(unsigned x) {
> > >   x = x - ((x >> 1) & 0x55555555);
> > >   x = x - 3*((x >> 2) & 0x33333333)
> > >     x = (x + (x >> 4)) & 0x0F0F0F0F;
> > >   x = x + (x >> 8);
> > >   x = x + (x >> 16);
> > >   return x & 0x0000003F;
> > > }
> > >
> > > gcc/ChangeLog:
> > >
> > > * match.pd: Add new popcount pattern variants from Hacker's Delight.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > > * gcc.dg/tree-ssa/popcount7.c: New test.
> > > * gcc.dg/tree-ssa/popcount7_2.c: New test.
> > > * gcc.dg/tree-ssa/popcount8.c: New test.
> > > * gcc.dg/tree-ssa/popcount9.c: New test.
> > >
> > > ---
> > >
> > > [Public]
> > >
> > > Hi Richard,
> > >
> > >    The following changes were made in patch v3 based on your comments.
> > >
> > >  - Match only 32-bit unsigned types, not 16???32 with shifted masks.
> > >  - Use compare_tree_int for all constant checks.
> > >  - Merged the extra #if GIMPLE into the existing popcount block.
> > >
> > >
> > > > -----Original Message-----
> > > > From: Richard Biener <[email protected]>
> > > > Sent: Monday, May 4, 2026 7:36 PM
> > > > To: Roy, Reshma <[email protected]>
> > > > Cc: [email protected]; Kumar, Venkataramanan
> > > > <[email protected]>
> > > > Subject: Re: [PATCH v2] Enabling POPCNT generation for 32-bit patterns.
> > > >
> > > > Caution: This message originated from an External Source. Use proper
> > > > caution when opening attachments, clicking links, or responding.
> > > >
> > > >
> > > > On Mon, 4 May 2026, Reshma Roy wrote:
> > > >
> > > > > Enabling POPCNT generation for 32-bit pattern from Hacker's
> > > > > Delight
> > > > >
> > > > > Pattern 1:
> > > > > int Gia_WordCountOnes32c( uint32_t uword ) {
> > > > >   uword = (uword & 0x55555555) + ((uword>>1) & 0x55555555);
> > > > >   uword = (uword & 0x33333333) + ((uword>>2) & 0x33333333);
> > > > >   uword = (uword & 0x0f0f0f0f) + ((uword>>4) & 0x0f0f0f0f);
> > > > >   uword = (uword & 0x00ff00ff) + ((uword>>8) & 0x00ff00ff);
> > > > >   return  (uword & 0x0000ffff) + (uword>>16);
> > > > >   or
> > > > >   return (uword & 0x0000FFFF) + ((uword >> 16) & 0x0000FFFF); }
> > > > >
> > > > > Pattern 2:
> > > > > int pop(unsigned x) {
> > > > >   x = x - ((x >> 1) & 0x55555555);
> > > > >   x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
> > > > >   x = (x + (x >> 4)) & 0x0F0F0F0F;
> > > > >   x = x + (x >> 8);
> > > > >   x = x + (x >> 16);
> > > > >   return x & 0x0000003F;
> > > > > }
> > > > >
> > > > > Pattern 3:
> > > > > int pop(unsigned x) {
> > > > >   x = x - ((x >> 1) & 0x55555555);
> > > > >   x = x - 3*((x >> 2) & 0x33333333)
> > > > >     x = (x + (x >> 4)) & 0x0F0F0F0F;
> > > > >   x = x + (x >> 8);
> > > > >   x = x + (x >> 16);
> > > > >   return x & 0x0000003F;
> > > > > }
> > > > >
> > > > > gcc/ChangeLog:
> > > > >
> > > > > * match.pd: Add new popcount pattern variants from Hacker's Delight.
> > > > >
> > > > > gcc/testsuite/ChangeLog:
> > > > >
> > > > > * gcc.dg/tree-ssa/popcount7.c: New test.
> > > > > * gcc.dg/tree-ssa/popcount7_2.c: New test.
> > > > > * gcc.dg/tree-ssa/popcount8.c: New test.
> > > > > * gcc.dg/tree-ssa/popcount9.c: New test.
> > > > >
> > > > > ---
> > > > >
> > > > > [Public]
> > > > >
> > > > > Hi Richard,
> > > > >
> > > > >    I have rebased this patch and am reposting it now after the
> > > > > release. Please let
> > > > me know if you have any further feedback.
> > > > >
> > > > >    Bootstrapped and tested on x86.
> > > > >
> > > > > Thank You,
> > > > > Reshma Roy
> > > > >
> > > > >
> > > > >  gcc/match.pd                                | 187 
> > > > > ++++++++++++++++++++
> > > > >  gcc/testsuite/gcc.dg/tree-ssa/popcount7.c   |  23 +++
> > > > >  gcc/testsuite/gcc.dg/tree-ssa/popcount7_2.c |  23 +++
> > > > >  gcc/testsuite/gcc.dg/tree-ssa/popcount8.c   |  22 +++
> > > > >  gcc/testsuite/gcc.dg/tree-ssa/popcount9.c   |  22 +++
> > > > >  5 files changed, 277 insertions(+)  create mode 100644
> > > > > gcc/testsuite/gcc.dg/tree-ssa/popcount7.c
> > > > >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/popcount7_2.c
> > > > >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/popcount8.c
> > > > >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/popcount9.c
> > > > >
> > > > > diff --git a/gcc/match.pd b/gcc/match.pd index
> > > > > 7db8ce7580f..d36dfefcd07 100644
> > > > > --- a/gcc/match.pd
> > > > > +++ b/gcc/match.pd
> > > > > @@ -11167,6 +11167,193 @@ DEFINE_INT_AND_FLOAT_ROUND_FN
> > (RINT)
> > > > >     (plus (CTZ:type (convert:utype @0)) { build_one_cst (type);
> > > > > })))) #endif
> > > > >
> > > > > +#if GIMPLE
> > > > > +/* To recognize the popcnt pattern for 32-bit from Hacker's Delight
> > > > > +   int Gia_WordCountOnes32c ( uint32_t uword)
> > > > > +   {
> > > > > +   uword = (uword & 0x55555555) + ((uword>>1) & 0x55555555);
> > > > > +   uword = (uword & 0x33333333) + ((uword>>2) & 0x33333333);
> > > > > +   uword = (uword & 0x0f0f0f0f) + ((uword>>4) & 0x0f0f0f0f);
> > > > > +   uword = (uword & 0x00ff00ff) + ((uword>>8) & 0x00ff00ff);
> > > > > +   return (uword & 0x0000ffff) + (uword>>16);
> > > > > +   or
> > > > > +   return (uword & 0x0000ffff) + ((uword>>16) & 0x0000ffff);
> > > > > +   }
> > > > > +*/
> > > > > +
> > > > > +  (simplify
> > > > > +     (plus:c
> > > > > +       (bit_and @step_4 INTEGER_CST@9)
> > > > > +       (rshift
> > > > > +      (plus:c@step4
> > > > > +        (bit_and @step3 INTEGER_CST@7)
> > > > > +     (bit_and
> > > > > +        (rshift
> > > > > +           (plus:c@step3
> > > > > +               (bit_and @step2 INTEGER_CST@5)
> > > > > +               (bit_and
> > > > > +                  (rshift
> > > > > +                     (plus:c@step2
> > > > > +                        (bit_and @step1 INTEGER_CST@3)
> > > > > +                        (bit_and
> > > > > +                           (rshift
> > > > > +                               (plus:c@step1
> > > > > +                                   (bit_and @0 INTEGER_CST@1)
> > > > > +                                   (bit_and (rshift @0 
> > > > > INTEGER_CST@2) @1))
> > > > > +                               INTEGER_CST@4)
> > > > > +                           INTEGER_CST@3))
> > > > > +                     INTEGER_CST@6)
> > > > > +                  INTEGER_CST@5))
> > > > > +           INTEGER_CST@8)
> > > > > +        INTEGER_CST@7))
> > > > > +      INTEGER_CST@10))
> > > > > +   (with {
> > > > > +    unsigned prec = TYPE_PRECISION (type);
> > > > > +    int shift = prec & 31 ;
> > > > > +    unsigned HOST_WIDE_INT c1 = HOST_WIDE_INT_UC (0x55555555) >>
> > > > shift;
> > > > > +    unsigned HOST_WIDE_INT c2 = HOST_WIDE_INT_UC (0x33333333) >>
> > > > shift;
> > > > > +    unsigned HOST_WIDE_INT c3 = HOST_WIDE_INT_UC (0x0F0F0F0F)
> > >>
> > > > shift;
> > > > > +    unsigned HOST_WIDE_INT c4 = HOST_WIDE_INT_UC (0x00FF00FF)
> > >>
> > > > shift;
> > > > > +    unsigned HOST_WIDE_INT c5 = HOST_WIDE_INT_UC (0x0000FFFF)
> > >>
> > > > shift;
> > > > > +    }
> > > > > +    (if (prec >= 16
> > > > > +      && prec <= 32
> > > >
> > > > Does this really work for prec != 32?  Similar below.
> > > No. Hence the patch is updated for 32 bit alone.
> > > >
> > > > > +      && pow2p_hwi (prec)
> > > > > +      && TYPE_UNSIGNED (type)
> > > > > +      && integer_onep (@2)
> > > > > +      && wi::to_widest (@4) == 2
> > > > > +      && wi::to_widest (@6) == 4
> > > > > +      && wi::to_widest (@8) == 8
> > > > > +      && wi::to_widest (@10) == 16
> > > > > +      && tree_to_uhwi (@1) == c1
> > > > > +      && tree_to_uhwi (@3) == c2
> > > > > +      && tree_to_uhwi (@5) == c3
> > > > > +      && tree_to_uhwi (@7) == c4
> > > > > +      && tree_to_uhwi (@9) == c5)
> > > > > +       (if (direct_internal_fn_supported_p (IFN_POPCOUNT, type,
> > > > > +                                         OPTIMIZE_FOR_BOTH))
> > > > > +     (convert (IFN_POPCOUNT:type @0)))))) #endif #if GIMPLE
> > > >
> > > > Please merge the #ifs, specifically insert the new patterns in the
> > > > existing block doing
> > > > 64- and 32-bits branchless implementations of popcount.
> > > Done.
> > > >
> > > > > +/*To recognize the popcnt pattern for 32-bit from Hacker's
> > > > > +Delight int pop (unsigned x) { x = x - ((x >> 1) & 0x55555555); x
> > > > > += (x &
> > > > > +0x33333333) + ((x >> 2) & 0x33333333); x = x - 3*((x >> 2) &
> > > > > +0x33333333); x = (x + (x >> 4)) & 0x0F0F0F0F; x = x + (x >> 8); x
> > > > > += x
> > > > > ++ (x >> 16); return x & 0x0000003F } */ (simplify  (bit_and
> > > > > +   (plus
> > > > > +    (rshift @step4 INTEGER_CST@10)
> > > > > +     (plus:c@step4
> > > > > +     (rshift @step3 INTEGER_CST@8)
> > > > > +        (bit_and@step3
> > > > > +          (plus
> > > > > +             (rshift @step2 INTEGER_CST@6)
> > > > > +                (plus:c@step2
> > > > > +                   (bit_and @step1 INTEGER_CST@3)
> > > > > +                   (bit_and
> > > > > +                       (rshift
> > > > > +                         (minus@step1
> > > > > +                          @0
> > > > > +                          (bit_and (rshift @0 INTEGER_CST@2) 
> > > > > INTEGER_CST@1))
> > > > > +                         INTEGER_CST@4)
> > > > > +                      INTEGER_CST@3)))
> > > > > +          INTEGER_CST@5)))
> > > > > +   INTEGER_CST@7)
> > > > > + (with {
> > > > > +   unsigned prec = TYPE_PRECISION (type);
> > > > > +   int shift = prec & 31 ;
> > > > > +   unsigned HOST_WIDE_INT c1 = HOST_WIDE_INT_UC (0x55555555) >>
> > > > shift;
> > > > > +   unsigned HOST_WIDE_INT c2 = HOST_WIDE_INT_UC (0x33333333) >>
> > > > shift;
> > > > > +   unsigned HOST_WIDE_INT c3 = HOST_WIDE_INT_UC (0x0F0F0F0F) >>
> > > > shift;
> > > > > +   unsigned HOST_WIDE_INT c4 = HOST_WIDE_INT_UC (0x0000003F) >>
> > > > shift;
> > > > > +   }
> > > > > +   (if (prec >= 16
> > > > > +     && prec <= 32
> > > > > +     && pow2p_hwi (prec)
> > > > > +     && TYPE_UNSIGNED (type)
> > > > > +     && integer_onep (@2)
> > > >
> > > > I think you can use compare_tree_int (@2, 1) and similar for all of
> > > > the checks.  At least they should all use the same way of testing
> > > > for a constant, not three different ones.
> > > Updated the patch to use compare_tree_int() for all the checks.
> > > >
> > > > > +     && wi::to_widest (@4) == 2
> > > > > +     && wi::to_widest (@6) == 4
> > > > > +     && wi::to_widest (@8) == 8
> > > > > +     && wi::to_widest (@10) == 16
> > > > > +     && tree_to_uhwi (@1) == c1
> > > > > +     && tree_to_uhwi (@3) == c2
> > > > > +     && tree_to_uhwi (@5) == c3
> > > > > +     && tree_to_uhwi (@7) == c4)
> > > > > +     (if (direct_internal_fn_supported_p (IFN_POPCOUNT, type,
> > > > > +                                       OPTIMIZE_FOR_BOTH))
> > > > > +     (convert (IFN_POPCOUNT:type @0)))))) #endif #if GIMPLE
> > > > > +
> > > > > +/*To recognize the popcnt pattern for 32-bit from Hacker's
> > > > > +Delight /*int pop (unsigned x) {
> > > > > +  x = x - ((x >> 1) & 0x55555555);
> > > > > +  x = x - 3*((x >> 2) & 0x33333333)
> > > > > +  x = (x + (x >> 4)) & 0x0F0F0F0F;
> > > > > +  x = x + (x >> 8);
> > > > > +  x = x + (x >> 16);
> > > > > +  return x & 0x0000003F;
> > > > > +}
> > > > > +*/
> > > > > +(simplify
> > > > > + (bit_and
> > > > > +   (plus
> > > > > +    (rshift @step4 INTEGER_CST@10)
> > > > > +     (plus:c@step4
> > > > > +     (rshift @step3 INTEGER_CST@8)
> > > > > +        (bit_and@step3
> > > > > +           (plus
> > > > > +             (rshift @step2 INTEGER_CST@6)
> > > > > +             (minus@step2
> > > > > +                @step1
> > > > > +                (mult:c
> > > > > +                   (bit_and
> > > > > +                     (rshift
> > > > > +                       (minus@step1
> > > > > +                          @0
> > > > > +                          (bit_and (rshift @0 INTEGER_CST@2) 
> > > > > INTEGER_CST@1))
> > > > > +                       INTEGER_CST@4)
> > > > > +                     INTEGER_CST@3)
> > > > > +                   INTEGER_CST@11)))
> > > > > +           INTEGER_CST@5)))
> > > > > +   INTEGER_CST@7)
> > > > > + (with {
> > > > > +   unsigned prec = TYPE_PRECISION (type);
> > > > > +   int shift = prec & 31 ;
> > > > > +   unsigned HOST_WIDE_INT c1 = HOST_WIDE_INT_UC (0x55555555) >>
> > > > shift;
> > > > > +   unsigned HOST_WIDE_INT c2 = HOST_WIDE_INT_UC (0x33333333) >>
> > > > shift;
> > > > > +   unsigned HOST_WIDE_INT c3 = HOST_WIDE_INT_UC (0x0F0F0F0F) >>
> > > > shift;
> > > > > +   unsigned HOST_WIDE_INT c4 = HOST_WIDE_INT_UC (0x0000003F) >>
> > > > shift;
> > > > > +   }
> > > > > +   (if (prec >= 16
> > > > > +     && prec <= 32
> > > > > +     && pow2p_hwi (prec)
> > > > > +     && TYPE_UNSIGNED (type)
> > > > > +     && integer_onep (@2)
> > > > > +     && wi::to_widest (@4) == 2
> > > > > +     && wi::to_widest (@6) == 4
> > > > > +     && wi::to_widest (@8) == 8
> > > > > +     && wi::to_widest (@10) == 16
> > > > > +     && wi::to_widest (@11) == 3
> > > > > +     && tree_to_uhwi (@1) == c1
> > > > > +     && tree_to_uhwi (@3) == c2
> > > > > +     && tree_to_uhwi (@5) == c3
> > > > > +     && tree_to_uhwi (@7) == c4)
> > > > > +     (if (direct_internal_fn_supported_p (IFN_POPCOUNT, type,
> > > > > +                                       OPTIMIZE_FOR_BOTH))
> > > > > +     (convert (IFN_POPCOUNT:type @0)))))) #endif
> > > > > +
> > > > >  (for ffs (FFS)
> > > > >   /* __builtin_ffs (X) == 0 -> X == 0.
> > > > >      __builtin_ffs (X) == 6 -> (X & 63) == 32.  */ diff --git
> > > > > a/gcc/testsuite/gcc.dg/tree-ssa/popcount7.c
> > > > > b/gcc/testsuite/gcc.dg/tree-ssa/popcount7.c
> > > > > new file mode 100644
> > > > > index 00000000000..c70837fc53b
> > > > > --- /dev/null
> > > > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/popcount7.c
> > > > > @@ -0,0 +1,23 @@
> > > > > +/* { dg-do compile } */
> > > > > +/* { dg-require-effective-target popcount } */
> > > > > +/* { dg-require-effective-target int32plus } */
> > > > > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> > > > > +
> > > > > +const unsigned m1  = 0x55555555UL; const unsigned m2  =
> > > > > +0x33333333UL; const unsigned m3  = 0x0F0F0F0FUL; const unsigned
> > > > > +m4  = 0x00FF00FFUL; const unsigned m5  = 0x0000FFFFUL;
> > > > > +
> > > > > +int Gia_WordCountOnes32c( unsigned uword ) {
> > > > > +  uword = (uword & m1) + ((uword>>1) & m1);
> > > > > +  uword = (uword & m2) + ((uword>>2) & m2);
> > > > > +  uword = (uword & m3) + ((uword>>4) & m3);
> > > > > +  uword = (uword & m4) + ((uword>>8) & m4);
> > > > > +  return  (uword & m5) + (uword>>16); }
> > > > > +
> > > > > +/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" }
> > > > > +} */
> > > > > +
> > > > > +
> > > > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/popcount7_2.c
> > > > > b/gcc/testsuite/gcc.dg/tree-ssa/popcount7_2.c
> > > > > new file mode 100644
> > > > > index 00000000000..fc6c23b411b
> > > > > --- /dev/null
> > > > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/popcount7_2.c
> > > > > @@ -0,0 +1,23 @@
> > > > > +/* { dg-do compile } */
> > > > > +/* { dg-require-effective-target popcount } */
> > > > > +/* { dg-require-effective-target int32plus } */
> > > > > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> > > > > +
> > > > > +const unsigned m1  = 0x55555555UL; const unsigned m2  =
> > > > > +0x33333333UL; const unsigned m3  = 0x0F0F0F0FUL; const unsigned
> > > > > +m4  = 0x00FF00FFUL; const unsigned m5  = 0x0000FFFFUL;
> > > > > +
> > > > > +int Gia_WordCountOnes32c( unsigned uword ) {
> > > > > +  uword = (uword & m1) + ((uword>>1) & m1);
> > > > > +  uword = (uword & m2) + ((uword>>2) & m2);
> > > > > +  uword = (uword & m3) + ((uword>>4) & m3);
> > > > > +  uword = (uword & m4) + ((uword>>8) & m4);
> > > > > +  return  (uword & m5) + ((uword>>16) & m5); }
> > > > > +
> > > > > +/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" }
> > > > > +} */
> > > > > +
> > > > > +
> > > > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/popcount8.c
> > > > > b/gcc/testsuite/gcc.dg/tree-ssa/popcount8.c
> > > > > new file mode 100644
> > > > > index 00000000000..5a12e6892aa
> > > > > --- /dev/null
> > > > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/popcount8.c
> > > > > @@ -0,0 +1,22 @@
> > > > > +/* { dg-do compile } */
> > > > > +/* { dg-require-effective-target popcount } */
> > > > > +/* { dg-require-effective-target int32plus } */
> > > > > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> > > > > +
> > > > > +const unsigned m1  = 0x55555555UL; const unsigned m2  =
> > > > > +0x33333333UL; const unsigned m3  = 0x0F0F0F0FUL; const unsigned
> > > > > +m4  = 0x0000003F;
> > > > > +
> > > > > +int pop32c(unsigned x) {
> > > > > +  x = x - ((x >> 1) & m1);
> > > > > +  x = (x & m2) + ((x >> 2) & m2);
> > > > > +  x = (x + (x >> 4)) & m3;
> > > > > +  x = x + (x >> 8);
> > > > > +  x = x + (x >> 16);
> > > > > +  return x & m4;
> > > > > +}
> > > > > +
> > > > > +/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" }
> > > > > +} */
> > > > > +
> > > > > +
> > > > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/popcount9.c
> > > > > b/gcc/testsuite/gcc.dg/tree-ssa/popcount9.c
> > > > > new file mode 100644
> > > > > index 00000000000..4fb08d34984
> > > > > --- /dev/null
> > > > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/popcount9.c
> > > > > @@ -0,0 +1,22 @@
> > > > > +/* { dg-do compile } */
> > > > > +/* { dg-require-effective-target popcount } */
> > > > > +/* { dg-require-effective-target int32plus } */
> > > > > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> > > > > +
> > > > > +const unsigned m1  = 0x55555555UL; const unsigned m2  =
> > > > > +0x33333333UL; const unsigned m3  = 0x0F0F0F0FUL; const unsigned
> > > > > +m4  = 0x0000003F;
> > > > > +
> > > > > +int popc(unsigned x) {
> > > > > +  x = x - ((x >> 1) & m1);
> > > > > +  x = x - 3*((x >> 2) & m2);
> > > > > +  x = (x + (x >> 4)) & m3;
> > > > > +  x = x + (x >> 8);
> > > > > +  x = x + (x >> 16);
> > > > > +  return x & m4;
> > > > > +}
> > > > > +
> > > > > +/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" }
> > > > > +} */
> > > > > +
> > > > > +
> > > > >
> > > >
> > > > --
> > > > Richard Biener <[email protected]>
> > > > SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461
> > > > Nuernberg, Germany;
> > > > GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG
> > > > Nuernberg)
> > >
> > > Thank You,
> > > Reshma Roy
> > >
> > >  gcc/match.pd                                | 160 ++++++++++++++++++++
> > >  gcc/testsuite/gcc.dg/tree-ssa/popcount7.c   |  23 +++
> > >  gcc/testsuite/gcc.dg/tree-ssa/popcount7_2.c |  23 +++
> > >  gcc/testsuite/gcc.dg/tree-ssa/popcount8.c   |  22 +++
> > >  gcc/testsuite/gcc.dg/tree-ssa/popcount9.c   |  22 +++
> > >  5 files changed, 250 insertions(+)
> > >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/popcount7.c
> > >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/popcount7_2.c
> > >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/popcount8.c
> > >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/popcount9.c
> > >
> > > diff --git a/gcc/match.pd b/gcc/match.pd index
> > > 7db8ce7580f..212ba6a189e 100644
> > > --- a/gcc/match.pd
> > > +++ b/gcc/match.pd
> > > @@ -11165,6 +11165,166 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> > >                                        OPTIMIZE_FOR_SPEED))
> > >    (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); }
> > >     (plus (CTZ:type (convert:utype @0)) { build_one_cst (type); }))))
> > > +
> > > +/* To recognize the popcnt pattern for 32-bit from Hacker's Delight
> > > +   int Gia_WordCountOnes32c ( uint32_t uword)
> > > +   {
> > > +   uword = (uword & 0x55555555) + ((uword>>1) & 0x55555555);
> > > +   uword = (uword & 0x33333333) + ((uword>>2) & 0x33333333);
> > > +   uword = (uword & 0x0f0f0f0f) + ((uword>>4) & 0x0f0f0f0f);
> > > +   uword = (uword & 0x00ff00ff) + ((uword>>8) & 0x00ff00ff);
> > > +   return (uword & 0x0000ffff) + (uword>>16);
> > > +   or
> > > +   return (uword & 0x0000ffff) + ((uword>>16) & 0x0000ffff);
> > > +   }
> > > +*/
> > > +
> > > +  (simplify
> > > +     (plus:c
> > > +       (bit_and @step_4 INTEGER_CST@9)
> > > +       (rshift
> > > +      (plus:c@step4
> > > +        (bit_and @step3 INTEGER_CST@7)
> > > +     (bit_and
> > > +        (rshift
> > > +           (plus:c@step3
> > > +               (bit_and @step2 INTEGER_CST@5)
> > > +               (bit_and
> > > +                  (rshift
> > > +                     (plus:c@step2
> > > +                        (bit_and @step1 INTEGER_CST@3)
> > > +                        (bit_and
> > > +                           (rshift
> > > +                               (plus:c@step1
> > > +                                   (bit_and @0 INTEGER_CST@1)
> > > +                                   (bit_and (rshift @0 INTEGER_CST@2) 
> > > @1))
> > > +                               INTEGER_CST@4)
> > > +                           INTEGER_CST@3))
> > > +                     INTEGER_CST@6)
> > > +                  INTEGER_CST@5))
> > > +           INTEGER_CST@8)
> > > +        INTEGER_CST@7))
> > > +      INTEGER_CST@10))
> > > +   (with {
> > > +    unsigned prec = TYPE_PRECISION (type);
> > > +    }
> > > +    (if (prec == 32
> > > +      && TYPE_UNSIGNED (type)
> > > +      && compare_tree_int (@2, 1) == 0
> > > +      && compare_tree_int (@4, 2) == 0
> > > +      && compare_tree_int (@6, 4) == 0
> > > +      && compare_tree_int (@8, 8) == 0
> > > +      && compare_tree_int (@10, 16) == 0
> > > +      && compare_tree_int (@1, 0x55555555) == 0
> > > +      && compare_tree_int (@3, 0x33333333) == 0
> > > +      && compare_tree_int (@5, 0x0F0F0F0F) == 0
> > > +      && compare_tree_int (@7, 0x00FF00FF) == 0
> > > +      && compare_tree_int (@9, 0x0000FFFF) == 0)
> > > +       (if (direct_internal_fn_supported_p (IFN_POPCOUNT, type,
> > > +                                         OPTIMIZE_FOR_BOTH))
> > > +     (convert (IFN_POPCOUNT:type @0))))))
> > > +
> > > +/*To recognize the popcnt pattern for 32-bit from Hacker's Delight
> > 
> > Please watch formatting of comments, space missing after '/*' here, 
> > indenting of the
> > following
> > 
> Done.
> > > +int pop (unsigned x)
> > > +{
> > > +x = x - ((x >> 1) & 0x55555555);
> > > +x = (x & 0x33333333) + ((x >> 2) & 0x33333333); x = x - 3*((x >> 2) &
> > > +0x33333333);
> > 
> > I don't see this multiplication>
> > 
> Thanks for catching that. x = x - 3*((x >> 2) & 0x33333333); line is from
> pattern 3; it was mistakenly included in the pattern 2 comment. The comment is
> corrected, test cases were unchanged and remain correct.
> 
> > Otherwise looks good to me.
> > 
> > > +x = ( + (x >> 4)) & 0x0F0F0F0F;
> > > +x = x + (x >> 8);
> > > +x = x + (x >> 16);
> > > +return x & 0x0000003F
> > > +}
> > > +*/
> > > +(simplify
> > > + (bit_and
> > > +   (plus
> > > +    (rshift @step4 INTEGER_CST@10)
> > > +     (plus:c@step4
> > > +     (rshift @step3 INTEGER_CST@8)
> > > +        (bit_and@step3
> > > +          (plus
> > > +             (rshift @step2 INTEGER_CST@6)
> > > +                (plus:c@step2
> > > +                   (bit_and @step1 INTEGER_CST@3)
> > > +                   (bit_and
> > > +                       (rshift
> > > +                         (minus@step1
> > > +                          @0
> > > +                          (bit_and (rshift @0 INTEGER_CST@2) 
> > > INTEGER_CST@1))
> > > +                         INTEGER_CST@4)
> > > +                      INTEGER_CST@3)))
> > > +          INTEGER_CST@5)))
> > > +   INTEGER_CST@7)
> > > + (with {
> > > +   unsigned prec = TYPE_PRECISION (type);
> > > +   }
> > > +   (if (prec == 32
> > > +     && TYPE_UNSIGNED (type)
> > > +     && compare_tree_int (@2, 1) == 0
> > > +     && compare_tree_int (@4, 2) == 0
> > > +     && compare_tree_int (@6, 4) == 0
> > > +     && compare_tree_int (@8, 8) == 0
> > > +     && compare_tree_int (@10, 16) == 0
> > > +     && compare_tree_int (@1, 0x55555555) == 0
> > > +     && compare_tree_int (@3, 0x33333333) == 0
> > > +     && compare_tree_int (@5, 0x0F0F0F0F) == 0
> > > +     && compare_tree_int (@7, 0x0000003F) == 0)
> > > +     (if (direct_internal_fn_supported_p (IFN_POPCOUNT, type,
> > > +                                       OPTIMIZE_FOR_BOTH))
> > > +     (convert (IFN_POPCOUNT:type @0))))))
> > > +
> > > +/*To recognize the popcnt pattern for 32-bit from Hacker's Delight
> > > +/*int pop (unsigned x) {
> > > +  x = x - ((x >> 1) & 0x55555555);
> > > +  x = x - 3*((x >> 2) & 0x33333333)
> > > +  x = (x + (x >> 4)) & 0x0F0F0F0F;
> > > +  x = x + (x >> 8);
> > > +  x = x + (x >> 16);
> > > +  return x & 0x0000003F;
> > > +}
> > > +*/
> > > +(simplify
> > > + (bit_and
> > > +   (plus
> > > +    (rshift @step4 INTEGER_CST@10)
> > > +     (plus:c@step4
> > > +     (rshift @step3 INTEGER_CST@8)
> > > +        (bit_and@step3
> > > +           (plus
> > > +             (rshift @step2 INTEGER_CST@6)
> > > +             (minus@step2
> > > +                @step1
> > > +                (mult:c
> > > +                   (bit_and
> > > +                     (rshift
> > > +                       (minus@step1
> > > +                          @0
> > > +                          (bit_and (rshift @0 INTEGER_CST@2) 
> > > INTEGER_CST@1))
> > > +                       INTEGER_CST@4)
> > > +                     INTEGER_CST@3)
> > > +                   INTEGER_CST@11)))
> > > +           INTEGER_CST@5)))
> > > +   INTEGER_CST@7)
> > > + (with {
> > > +   unsigned prec = TYPE_PRECISION (type);
> > > +   }
> > > +   (if (prec == 32
> > > +     && TYPE_UNSIGNED (type)
> > > +     && compare_tree_int (@2, 1) == 0
> > > +     && compare_tree_int (@4, 2) == 0
> > > +     && compare_tree_int (@6, 4) == 0
> > > +     && compare_tree_int (@8, 8) == 0
> > > +     && compare_tree_int (@10, 16) == 0
> > > +     && compare_tree_int (@11, 3) == 0
> > > +     && compare_tree_int (@1, 0x55555555) == 0
> > > +     && compare_tree_int (@3, 0x33333333) == 0
> > > +     && compare_tree_int (@5, 0x0F0F0F0F) == 0
> > > +     && compare_tree_int (@5, 0x0F0F0F0F) == 0)
> > > +     (if (direct_internal_fn_supported_p (IFN_POPCOUNT, type,
> > > +                                       OPTIMIZE_FOR_BOTH))
> > > +     (convert (IFN_POPCOUNT:type @0))))))
> > >  #endif
> > >
> > >  (for ffs (FFS)
> > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/popcount7.c 
> > > b/gcc/testsuite/gcc.dg/tree-
> > ssa/popcount7.c
> > > new file mode 100644
> > > index 00000000000..c70837fc53b
> > > --- /dev/null
> > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/popcount7.c
> > > @@ -0,0 +1,23 @@
> > > +/* { dg-do compile } */
> > > +/* { dg-require-effective-target popcount } */
> > > +/* { dg-require-effective-target int32plus } */
> > > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> > > +
> > > +const unsigned m1  = 0x55555555UL;
> > > +const unsigned m2  = 0x33333333UL;
> > > +const unsigned m3  = 0x0F0F0F0FUL;
> > > +const unsigned m4  = 0x00FF00FFUL;
> > > +const unsigned m5  = 0x0000FFFFUL;
> > > +
> > > +int Gia_WordCountOnes32c( unsigned uword )
> > > +{
> > > +  uword = (uword & m1) + ((uword>>1) & m1);
> > > +  uword = (uword & m2) + ((uword>>2) & m2);
> > > +  uword = (uword & m3) + ((uword>>4) & m3);
> > > +  uword = (uword & m4) + ((uword>>8) & m4);
> > > +  return  (uword & m5) + (uword>>16);
> > > +}
> > > +
> > > +/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" } } */
> > > +
> > > +
> > 
> > Trailing vertical space (also in other testcases)
> > 
> Done.
> > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/popcount7_2.c 
> > > b/gcc/testsuite/gcc.dg/tree-
> > ssa/popcount7_2.c
> > > new file mode 100644
> > > index 00000000000..fc6c23b411b
> > > --- /dev/null
> > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/popcount7_2.c
> > > @@ -0,0 +1,23 @@
> > > +/* { dg-do compile } */
> > > +/* { dg-require-effective-target popcount } */
> > > +/* { dg-require-effective-target int32plus } */
> > > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> > > +
> > > +const unsigned m1  = 0x55555555UL;
> > > +const unsigned m2  = 0x33333333UL;
> > > +const unsigned m3  = 0x0F0F0F0FUL;
> > > +const unsigned m4  = 0x00FF00FFUL;
> > > +const unsigned m5  = 0x0000FFFFUL;
> > > +
> > > +int Gia_WordCountOnes32c( unsigned uword )
> > > +{
> > > +  uword = (uword & m1) + ((uword>>1) & m1);
> > > +  uword = (uword & m2) + ((uword>>2) & m2);
> > > +  uword = (uword & m3) + ((uword>>4) & m3);
> > > +  uword = (uword & m4) + ((uword>>8) & m4);
> > > +  return  (uword & m5) + ((uword>>16) & m5);
> > > +}
> > > +
> > > +/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" } } */
> > > +
> > > +
> > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/popcount8.c 
> > > b/gcc/testsuite/gcc.dg/tree-
> > ssa/popcount8.c
> > > new file mode 100644
> > > index 00000000000..5a12e6892aa
> > > --- /dev/null
> > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/popcount8.c
> > > @@ -0,0 +1,22 @@
> > > +/* { dg-do compile } */
> > > +/* { dg-require-effective-target popcount } */
> > > +/* { dg-require-effective-target int32plus } */
> > > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> > > +
> > > +const unsigned m1  = 0x55555555UL;
> > > +const unsigned m2  = 0x33333333UL;
> > > +const unsigned m3  = 0x0F0F0F0FUL;
> > > +const unsigned m4  = 0x0000003F;
> > > +
> > > +int pop32c(unsigned x) {
> > > +  x = x - ((x >> 1) & m1);
> > > +  x = (x & m2) + ((x >> 2) & m2);
> > > +  x = (x + (x >> 4)) & m3;
> > > +  x = x + (x >> 8);
> > > +  x = x + (x >> 16);
> > > +  return x & m4;
> > > +}
> > > +
> > > +/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" } } */
> > > +
> > > +
> > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/popcount9.c 
> > > b/gcc/testsuite/gcc.dg/tree-
> > ssa/popcount9.c
> > > new file mode 100644
> > > index 00000000000..4fb08d34984
> > > --- /dev/null
> > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/popcount9.c
> > > @@ -0,0 +1,22 @@
> > > +/* { dg-do compile } */
> > > +/* { dg-require-effective-target popcount } */
> > > +/* { dg-require-effective-target int32plus } */
> > > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> > > +
> > > +const unsigned m1  = 0x55555555UL;
> > > +const unsigned m2  = 0x33333333UL;
> > > +const unsigned m3  = 0x0F0F0F0FUL;
> > > +const unsigned m4  = 0x0000003F;
> > > +
> > > +int popc(unsigned x) {
> > > +  x = x - ((x >> 1) & m1);
> > > +  x = x - 3*((x >> 2) & m2);
> > > +  x = (x + (x >> 4)) & m3;
> > > +  x = x + (x >> 8);
> > > +  x = x + (x >> 16);
> > > +  return x & m4;
> > > +}
> > > +
> > > +/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" } } */
> > > +
> > > +
> > >
> > 
> > --
> > Richard Biener <[email protected]>
> > SUSE Software Solutions Germany GmbH,
> > Frankenstrasse 146, 90461 Nuernberg, Germany;
> > GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG
> > Nuernberg)
> 
> Thank You,
>  Reshma Roy
> 
> 
>  gcc/match.pd                                | 159 ++++++++++++++++++++
>  gcc/testsuite/gcc.dg/tree-ssa/popcount7.c   |  21 +++
>  gcc/testsuite/gcc.dg/tree-ssa/popcount7_2.c |  21 +++
>  gcc/testsuite/gcc.dg/tree-ssa/popcount8.c   |  20 +++
>  gcc/testsuite/gcc.dg/tree-ssa/popcount9.c   |  20 +++
>  5 files changed, 241 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/popcount7.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/popcount7_2.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/popcount8.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/popcount9.c
> 
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 198e2e7202e..eed84b0acda 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -11227,6 +11227,165 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>                                        OPTIMIZE_FOR_SPEED))
>    (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); }
>     (plus (CTZ:type (convert:utype @0)) { build_one_cst (type); }))))
> +
> +/* To recognize the popcnt pattern for 32-bit from Hacker's Delight
> +   int Gia_WordCountOnes32c ( uint32_t uword)
> +   {
> +   uword = (uword & 0x55555555) + ((uword>>1) & 0x55555555);
> +   uword = (uword & 0x33333333) + ((uword>>2) & 0x33333333);
> +   uword = (uword & 0x0f0f0f0f) + ((uword>>4) & 0x0f0f0f0f);
> +   uword = (uword & 0x00ff00ff) + ((uword>>8) & 0x00ff00ff);
> +   return (uword & 0x0000ffff) + (uword>>16);
> +   or
> +   return (uword & 0x0000ffff) + ((uword>>16) & 0x0000ffff);
> +   }
> +*/
> +
> +  (simplify
> +     (plus:c
> +       (bit_and @step_4 INTEGER_CST@9)
> +       (rshift
> +      (plus:c@step4
> +        (bit_and @step3 INTEGER_CST@7)
> +     (bit_and
> +        (rshift
> +           (plus:c@step3
> +               (bit_and @step2 INTEGER_CST@5)
> +               (bit_and
> +                  (rshift
> +                     (plus:c@step2
> +                        (bit_and @step1 INTEGER_CST@3)
> +                        (bit_and
> +                           (rshift
> +                               (plus:c@step1
> +                                   (bit_and @0 INTEGER_CST@1)
> +                                   (bit_and (rshift @0 INTEGER_CST@2) @1))
> +                               INTEGER_CST@4)
> +                           INTEGER_CST@3))
> +                     INTEGER_CST@6)
> +                  INTEGER_CST@5))
> +           INTEGER_CST@8)
> +        INTEGER_CST@7))
> +      INTEGER_CST@10))
> +   (with {
> +    unsigned prec = TYPE_PRECISION (type);
> +    }
> +    (if (prec == 32
> +      && TYPE_UNSIGNED (type)
> +      && compare_tree_int (@2, 1) == 0
> +      && compare_tree_int (@4, 2) == 0
> +      && compare_tree_int (@6, 4) == 0
> +      && compare_tree_int (@8, 8) == 0
> +      && compare_tree_int (@10, 16) == 0
> +      && compare_tree_int (@1, 0x55555555) == 0
> +      && compare_tree_int (@3, 0x33333333) == 0
> +      && compare_tree_int (@5, 0x0F0F0F0F) == 0
> +      && compare_tree_int (@7, 0x00FF00FF) == 0
> +      && compare_tree_int (@9, 0x0000FFFF) == 0)
> +       (if (direct_internal_fn_supported_p (IFN_POPCOUNT, type,
> +                                         OPTIMIZE_FOR_BOTH))
> +     (convert (IFN_POPCOUNT:type @0))))))
> +
> +/* To recognize the popcnt pattern for 32-bit from Hacker's Delight
> +   int pop (unsigned x)
> +   {
> +    x = x - ((x >> 1) & 0x55555555);
> +    x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
> +    x = (x + (x >> 4)) & 0x0F0F0F0F;
> +    x = x + (x >> 8);
> +    x = x + (x >> 16);
> +    return x & 0x0000003F
> +   }
> +*/
> +(simplify
> + (bit_and
> +   (plus
> +    (rshift @step4 INTEGER_CST@10)
> +     (plus:c@step4
> +     (rshift @step3 INTEGER_CST@8)
> +        (bit_and@step3
> +          (plus
> +             (rshift @step2 INTEGER_CST@6)
> +                (plus:c@step2
> +                   (bit_and @step1 INTEGER_CST@3)
> +                   (bit_and
> +                       (rshift
> +                         (minus@step1
> +                          @0
> +                          (bit_and (rshift @0 INTEGER_CST@2) INTEGER_CST@1))
> +                         INTEGER_CST@4)
> +                      INTEGER_CST@3)))
> +          INTEGER_CST@5)))
> +   INTEGER_CST@7)
> + (with {
> +   unsigned prec = TYPE_PRECISION (type);
> +   }
> +   (if (prec == 32
> +     && TYPE_UNSIGNED (type)
> +     && compare_tree_int (@2, 1) == 0
> +     && compare_tree_int (@4, 2) == 0
> +     && compare_tree_int (@6, 4) == 0
> +     && compare_tree_int (@8, 8) == 0
> +     && compare_tree_int (@10, 16) == 0
> +     && compare_tree_int (@1, 0x55555555) == 0
> +     && compare_tree_int (@3, 0x33333333) == 0
> +     && compare_tree_int (@5, 0x0F0F0F0F) == 0
> +     && compare_tree_int (@7, 0x0000003F) == 0)
> +     (if (direct_internal_fn_supported_p (IFN_POPCOUNT, type,
> +                                       OPTIMIZE_FOR_BOTH))
> +     (convert (IFN_POPCOUNT:type @0))))))
> +
> +/* To recognize the popcnt pattern for 32-bit from Hacker's Delight
> +   int pop (unsigned x)
> +   {
> +     x = x - ((x >> 1) & 0x55555555);
> +     x = x - 3*((x >> 2) & 0x33333333)
> +     x = (x + (x >> 4)) & 0x0F0F0F0F;
> +     x = x + (x >> 8);
> +     x = x + (x >> 16);
> +     return x & 0x0000003F;
> +   }
> +*/
> +(simplify
> + (bit_and
> +   (plus
> +    (rshift @step4 INTEGER_CST@10)
> +     (plus:c@step4
> +     (rshift @step3 INTEGER_CST@8)
> +        (bit_and@step3
> +           (plus
> +             (rshift @step2 INTEGER_CST@6)
> +             (minus@step2
> +                @step1
> +                (mult:c
> +                   (bit_and
> +                     (rshift
> +                       (minus@step1
> +                          @0
> +                          (bit_and (rshift @0 INTEGER_CST@2) INTEGER_CST@1))
> +                       INTEGER_CST@4)
> +                     INTEGER_CST@3)
> +                   INTEGER_CST@11)))
> +           INTEGER_CST@5)))
> +   INTEGER_CST@7)
> + (with {
> +   unsigned prec = TYPE_PRECISION (type);
> +   }
> +   (if (prec == 32
> +     && TYPE_UNSIGNED (type)
> +     && compare_tree_int (@2, 1) == 0
> +     && compare_tree_int (@4, 2) == 0
> +     && compare_tree_int (@6, 4) == 0
> +     && compare_tree_int (@8, 8) == 0
> +     && compare_tree_int (@10, 16) == 0
> +     && compare_tree_int (@11, 3) == 0
> +     && compare_tree_int (@1, 0x55555555) == 0
> +     && compare_tree_int (@3, 0x33333333) == 0
> +     && compare_tree_int (@5, 0x0F0F0F0F) == 0
> +     && compare_tree_int (@5, 0x0F0F0F0F) == 0)
> +     (if (direct_internal_fn_supported_p (IFN_POPCOUNT, type,
> +                                       OPTIMIZE_FOR_BOTH))
> +     (convert (IFN_POPCOUNT:type @0))))))
>  #endif
>  
>  (for ffs (FFS)
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/popcount7.c 
> b/gcc/testsuite/gcc.dg/tree-ssa/popcount7.c
> new file mode 100644
> index 00000000000..de00961ba1b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/popcount7.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target popcount } */
> +/* { dg-require-effective-target int32plus } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +const unsigned m1  = 0x55555555UL;
> +const unsigned m2  = 0x33333333UL;
> +const unsigned m3  = 0x0F0F0F0FUL;
> +const unsigned m4  = 0x00FF00FFUL;
> +const unsigned m5  = 0x0000FFFFUL;
> +
> +int Gia_WordCountOnes32c( unsigned uword )
> +{
> +  uword = (uword & m1) + ((uword>>1) & m1);
> +  uword = (uword & m2) + ((uword>>2) & m2);
> +  uword = (uword & m3) + ((uword>>4) & m3);
> +  uword = (uword & m4) + ((uword>>8) & m4);
> +  return  (uword & m5) + (uword>>16);
> +}
> +
> +/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/popcount7_2.c 
> b/gcc/testsuite/gcc.dg/tree-ssa/popcount7_2.c
> new file mode 100644
> index 00000000000..ee04070bdb4
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/popcount7_2.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target popcount } */
> +/* { dg-require-effective-target int32plus } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +const unsigned m1  = 0x55555555UL;
> +const unsigned m2  = 0x33333333UL;
> +const unsigned m3  = 0x0F0F0F0FUL;
> +const unsigned m4  = 0x00FF00FFUL;
> +const unsigned m5  = 0x0000FFFFUL;
> +
> +int Gia_WordCountOnes32c( unsigned uword )
> +{
> +  uword = (uword & m1) + ((uword>>1) & m1);
> +  uword = (uword & m2) + ((uword>>2) & m2);
> +  uword = (uword & m3) + ((uword>>4) & m3);
> +  uword = (uword & m4) + ((uword>>8) & m4);
> +  return  (uword & m5) + ((uword>>16) & m5);
> +}
> +
> +/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/popcount8.c 
> b/gcc/testsuite/gcc.dg/tree-ssa/popcount8.c
> new file mode 100644
> index 00000000000..694c333e813
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/popcount8.c
> @@ -0,0 +1,20 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target popcount } */
> +/* { dg-require-effective-target int32plus } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +const unsigned m1  = 0x55555555UL;
> +const unsigned m2  = 0x33333333UL;
> +const unsigned m3  = 0x0F0F0F0FUL;
> +const unsigned m4  = 0x0000003F;
> +
> +int pop32c(unsigned x) {
> +  x = x - ((x >> 1) & m1);
> +  x = (x & m2) + ((x >> 2) & m2);
> +  x = (x + (x >> 4)) & m3;
> +  x = x + (x >> 8);
> +  x = x + (x >> 16);
> +  return x & m4;
> +}
> +
> +/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/popcount9.c 
> b/gcc/testsuite/gcc.dg/tree-ssa/popcount9.c
> new file mode 100644
> index 00000000000..ba904b1d733
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/popcount9.c
> @@ -0,0 +1,20 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target popcount } */
> +/* { dg-require-effective-target int32plus } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +const unsigned m1  = 0x55555555UL;
> +const unsigned m2  = 0x33333333UL;
> +const unsigned m3  = 0x0F0F0F0FUL;
> +const unsigned m4  = 0x0000003F;
> +
> +int popc(unsigned x) {
> +  x = x - ((x >> 1) & m1);
> +  x = x - 3*((x >> 2) & m2);
> +  x = (x + (x >> 4)) & m3;
> +  x = x + (x >> 8);
> +  x = x + (x >> 16);
> +  return x & m4;
> +}
> +
> +/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" } } */
> 

-- 
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)

Reply via email to