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.
&& 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))))))
--- /dev/null
+/* { 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" } } */