On 12/29/25 7:22 PM, Andrew Pinski wrote:
On Mon, Dec 29, 2025 at 12:14 PM Daniel Barboza
<[email protected]> wrote:

         PR 102486

gcc/ChangeLog:

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

gcc/testsuite/ChangeLog:

         * gcc.dg/torture/pr102486.c: New test.

Signed-off-by: Daniel Barboza <[email protected]>
---
  gcc/match.pd                            |  8 ++++++++
  gcc/testsuite/gcc.dg/torture/pr102486.c | 15 +++++++++++++++
  2 files changed, 23 insertions(+)
  create mode 100644 gcc/testsuite/gcc.dg/torture/pr102486.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 45d96844673..6b01aaea9b6 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -10541,6 +10541,14 @@ 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))))
+  /* 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:boolean_type_node (ne @1 { build_zero_cst (TREE_TYPE (@1)); })))

I think this needs a `convert` at the new pattern.

Do you mean this?

  (convert? (POPCOUNT (convert?@1 (bit_and:c @0 (negate @0)))))

Because if I do that I won't be able to match one of the tests I'm
adding in the testsuite because there's not explicit convert/cast in
the popcount call to match.

If I do this:

  (convert (POPCOUNT (convert?@1 (bit_and:c @0 (negate @0)))))


Then I got no matches in the testcase. Thanks,

Daniel

Also I think this is wrong for vector types so it needs a check that
type is an INTEGRAL_TYPE_P.

+
  #if GIMPLE
  /* popcount(zext(X)) == popcount(X).  */
  (simplify
diff --git a/gcc/testsuite/gcc.dg/torture/pr102486.c 
b/gcc/testsuite/gcc.dg/torture/pr102486.c
new file mode 100644
index 00000000000..d900149e011
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr102486.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-tree-optimized" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-fno-fat-lto-objects" } { "" } } */

No reason to run this under torture. Just put it as
`gcc.dg/tree-ssa/pr102486.c` and `-O1` to the dg-options.

Thanks,
Andrew Pinski

+
+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