AMD General > -----Original Message----- > From: Richard Biener <[email protected]> > Sent: Tuesday, May 12, 2026 1:27 PM > To: Roy, Reshma <[email protected]> > Cc: [email protected]; Kumar, Venkataramanan > <[email protected]> > Subject: Re: [PATCH v4] 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, 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. >
Hi Richards, The patch passes bootstrap and regression tests. The patch has been pushed. Thanks, Reshma Roy > 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)
