[gcc r17-2897] match: Fix incorrect identification of POPCOUNT pattern [PR126466]

Venkataramanan Kumar via Gcc-cvs <[email protected]> Mon, 3 Aug 2026 11:24:51 +0000 (GMT)
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:7decbb57670c3c0f6136be00456fe9c8a41f7aed

commit r17-2897-g7decbb57670c3c0f6136be00456fe9c8a41f7aed
Author: Reshma Roy <[email protected]>
Date:   Thu Jul 30 12:19:08 2026 +0530

    match: Fix incorrect identification of POPCOUNT pattern [PR126466]
    
    This fixes r17-489-g8ca1e887847e2f, which added a third 32-bit
    Hacker's Delight popcount matcher.  Its predicate checked
    compare_tree_int (@5, 0x0F0F0F0F) twice and never validated the
    final outer AND constant (@7), so any mask was accepted once the
    earlier constants matched.
    
    Require compare_tree_int (@7, 0x0000003F) so only the intended
    popcount idiom is folded to IFN_POPCOUNT.
    
    gcc/ChangeLog:
    
            PR tree-optimization/126466
            * match.pd: Fix incorrect POPCOUNT identification in the third
            32-bit Hacker's Delight matcher.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/tree-ssa/popcount10.c: New test.

Diff:
---
 gcc/match.pd                               |  2 +-
 gcc/testsuite/gcc.dg/tree-ssa/popcount10.c | 20 ++++++++++++++++++++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/gcc/match.pd b/gcc/match.pd
index cfaead7c67dd..00a0adaba87e 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -11258,7 +11258,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 	&& compare_tree_int (@1, 0x55555555) == 0
 	&& compare_tree_int (@3, 0x33333333) == 0
 	&& compare_tree_int (@5, 0x0F0F0F0F) == 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))))))
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/popcount10.c b/gcc/testsuite/gcc.dg/tree-ssa/popcount10.c
new file mode 100644
index 000000000000..ed8946186901
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/popcount10.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  = 0x0000FFFFUL;
+
+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-not "\.POPCOUNT" "optimized" } } */