Hi,

A small patch to fix PR119468. Bootstrapped and regtested on
powerpc64le-linux. Ok for trunk?

Thanks and regards,
Avinash Jayakar

This patch aims to fix PR119468 by emitting better code for parity
builtin. Currently the following code:

bool parity(unsigned long long l)
{
    return __builtin_parityll(l);
}
with O2 flag and even if the target supports popcntd emits,
  popcntb 3,3
  prtyd 3,3
  extsw 3,3

With this patch, if there is support for popcntd (2.06) instruction, we emit
  popcntd 3,3
  rldicl 3,3,0,63
Making use of the existing instruction and reducing the latency compared
to existing code generated.

2025-12-05  Avinash Jayakar  <[email protected]>

gcc/ChangeLog:
        PR 119468
        * config/rs6000/rs6000.cc (rs6000_emit_parity): Add code to
          generate popcntd if available.

gcc/testsuite/ChangeLog:
        PR target/119468
        * gcc.target/powerpc/pr119468.c: New test.
---
 gcc/config/rs6000/rs6000.cc                 |  8 ++++++++
 gcc/testsuite/gcc.target/powerpc/pr119468.c | 16 ++++++++++++++++
 2 files changed, 24 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr119468.c

diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index bf899adc531..c9b2d88a363 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -23233,6 +23233,14 @@ rs6000_emit_parity (rtx dst, rtx src)
 
   tmp = gen_reg_rtx (mode);
 
+  /* Use ISA 2.06 insn popcntd if we can. */
+  if (mode == DImode && TARGET_POPCNTD)
+    {
+      emit_insn (gen_popcntddi2 (tmp, src));
+      emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
+      return;
+    }
+
   /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can.  */
   if (TARGET_CMPB)
     {
diff --git a/gcc/testsuite/gcc.target/powerpc/pr119468.c 
b/gcc/testsuite/gcc.target/powerpc/pr119468.c
new file mode 100644
index 00000000000..f43319210b7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr119468.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-options "-O2 -mdejagnu-cpu=power7" } */
+
+bool foo(unsigned long long x)
+{
+  return __builtin_parityll(x);
+}
+
+bool parity2(unsigned long long l)
+{
+  return __builtin_popcountll(l) & 1;
+}
+
+/* { dg-final { scan-assembler-times "popcntd" 2 } } */
+/* { dg-final { scan-assembler-not "popcntb" } } */
+/* { dg-final { scan-assembler-times "rldicl" 2 } } */
-- 
2.51.0

Reply via email to