]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
match.pd: Fix .PARITY(~x) simplification [PR126471]
authorJakub Jelinek <jakub@redhat.com>
Thu, 30 Jul 2026 07:52:45 +0000 (09:52 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 30 Jul 2026 07:52:45 +0000 (09:52 +0200)
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  <jakub@redhat.com>

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 <andrew.pinski@oss.qualcomm.com>
gcc/match.pd
gcc/testsuite/gcc.dg/bitint-139.c [new file with mode: 0644]

index 4b2a360966c9742b235283e97e0a21e8c7178935..d6702f66733ddda2064d654f3ed573b6554379be 100644 (file)
@@ -10749,10 +10749,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 (file)
index 0000000..f71b90e
--- /dev/null
@@ -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 ();
+}