[gcc r15-11439] match.pd: Fix .PARITY(~x) simplification [PR126471]
Jakub Jelinek via Gcc-cvs <[email protected]> Sat, 1 Aug 2026 10:16:42 +0000 (GMT)
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:62ee81f37c57cced2ea25d216c4621a4ba7f5456 commit r15-11439-g62ee81f37c57cced2ea25d216c4621a4ba7f5456 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 1af481ecfdab..6ae801234ac3 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -10137,10 +10137,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 (); +}