[gcc r14-12786] match.pd: Fix .PARITY(~x) simplification [PR126471]

Jakub Jelinek via Gcc-cvs <[email protected]> Sat, 1 Aug 2026 10:29:15 +0000 (GMT)
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:8910ccc73acd643917b6a00968d65865ffd1795b

commit r14-12786-g8910ccc73acd643917b6a00968d65865ffd1795b
Author: Jakub Jelinek <[email protected]>
Date:   Thu Jul 30 09:52:45 2026 +0200

    match.pd: Fix .PARITY(~x) simplification [PR126471]
    
    The parity(~X) simpliciation to parity(X) is incorrect for types with
    odd element precision, in that case parity(~X) is equivalent to
    parity(X) ^ 1.
    The following patch fixes this.
    
    2026-07-30  Jakub Jelinek  <[email protected]>
    
            PR tree-optimization/126471
            * match.pd (parity(~X) is parity(X)): Only optimize this way
            if element_precision is even, otherwise optimize into parity(X) ^ 1.
    
            * gcc.dg/bitint-139.c: New test.
    
    Reviewed-by: Andrea Pinski <[email protected]>
    (cherry picked from commit 1f4cc0f7a14b52fdfbd02ac890cc7aedbdfb1979)

Diff:
---
 gcc/match.pd                      |  6 ++++--
 gcc/testsuite/gcc.dg/bitint-139.c | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/gcc/match.pd b/gcc/match.pd
index 2ab43a773b36..72004f144d84 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -9037,10 +9037,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 #endif
 
 /* PARITY simplifications.  */
-/* parity(~X) is parity(X).  */
+/* parity(~X) is parity(X) for even precision and parity(X) ^ 1 otherwise.  */
 (simplify
   (PARITY (bit_not @0))
-  (PARITY @0))
+  (if ((element_precision (TREE_TYPE (@0)) & 1) == 0)
+   (PARITY @0)
+   (bit_xor (PARITY:type @0) { build_one_cst (type); })))
 
 /* parity(bswap(x)) is parity(x).  */
 (for parity (PARITY)
diff --git a/gcc/testsuite/gcc.dg/bitint-139.c b/gcc/testsuite/gcc.dg/bitint-139.c
new file mode 100644
index 000000000000..f71b90e70633
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/bitint-139.c
@@ -0,0 +1,36 @@
+/* PR tree-optimization/126471 */
+/* { dg-do run { target bitint575 } } */
+/* { dg-options "-O2" } */
+
+[[gnu::noipa]] int
+foo (unsigned _BitInt(129) x)
+{
+  return __builtin_parityg (~x);
+}
+
+[[gnu::noipa]] int
+bar (unsigned _BitInt(7) x)
+{
+  return __builtin_parityg (~x);
+}
+
+[[gnu::noipa]] int
+baz (unsigned _BitInt(256) x)
+{
+  return __builtin_parityg (~x);
+}
+
+int
+main ()
+{
+  if (foo (0) != 1
+      || foo (~(unsigned _BitInt(129)) 0) != 0
+      || foo (1) != 0
+      || bar (0) != 1
+      || bar (~(unsigned _BitInt(7)) 0) != 0
+      || bar (1) != 0
+      || baz (0) != 0
+      || baz (~(unsigned _BitInt(256)) 0) != 0
+      || baz (1) != 1)
+    __builtin_abort ();
+}