PR 102486

gcc/ChangeLog:

         * match.pd (`popcount (X & -X) -> (X & -X) != 0`): New pattern.

gcc/testsuite/ChangeLog:

        * gcc.dg/tree-ssa/pr102486.c: New test.

Signed-off-by: Daniel Barboza <[email protected]>
---

Changes from v1:
- added a 'with' block and defined type0 and type1 to keep the remaining
  lines < 80 chars
- added checks for INTEGRAL_TYPE_P and type_unsigned or truncating
  convert
- changed pattern result to be (convert:type (ne:boolean_type_node ...) 
- moved testcase to gcc/testsuite/gcc.dg/tree-ssa
- v1 link: https://gcc.gnu.org/pipermail/gcc-patches/2025-December/704604.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 45d96844673..9d6dfbfdd6a 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -10541,6 +10541,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
              (popcount:s @1))
       (popcount (log2 @0 @1)))))
 
+/* popcount (X & -X) is (X & -X) != 0.  */
+(simplify
+  (POPCOUNT (convert?@1 (bit_and:c @0 (negate @0))))
+    (with { tree type0 = TREE_TYPE (@0);
+           tree type1 = TREE_TYPE (@1); }
+      (if (INTEGRAL_TYPE_P (type0)
+          && (TYPE_UNSIGNED (type0)
+              || TYPE_PRECISION (type1) <= 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 @1 { build_zero_cst (type1); })))))
+
 #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

Reply via email to