From: Jakub Jelinek Date: Thu, 30 Jul 2026 07:52:45 +0000 (+0200) Subject: match.pd: Fix .PARITY(~x) simplification [PR126471] X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1f4cc0f7a14b52fdfbd02ac890cc7aedbdfb1979;p=thirdparty%2Fgcc.git 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 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 --- diff --git a/gcc/match.pd b/gcc/match.pd index 4b2a360966c..d6702f66733 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -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 index 00000000000..f71b90e7063 --- /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 (); +}