middle-end: Parity and popcount folding optimizations.
authorRoger Sayle <roger@nextmovesoftware.com>
Tue, 28 Jul 2020 21:55:12 +0000 (22:55 +0100)
committerRoger Sayle <roger@nextmovesoftware.com>
Tue, 28 Jul 2020 21:56:24 +0000 (22:56 +0100)
commit33bf56ddc6a757d2066a50dd9ce8323b379a2a0a
treec874ed6ad71a51bca6395d031550dd4595a65a8b
parentf3665bd1111c1799c0421490b5e655f977570354
middle-end: Parity and popcount folding optimizations.

This patch implements several constant folding optimizations
for __builtin_parity and friends.  We canonicalize popcount(x)&1
as parity(x) in gimple, and potentially convert back again when
we expand to RTL.  parity(~x) is simplified to parity(x), which
is true for all integer modes with an even number of bits.
But probably most usefully, parity(x)^parity(y) can be simplified
to a parity(x^y), requiring only a single libcall or popcount.

This patch optimizes popcount and parity of an argument known to have
at most a single bit set, to be that single bit.  Hence, popcount(x&8)
is simplified to (x>>3)&1.   This generalizes the existing optimization
of popcount(x&1) being simplified to x&1, which is cleaned up with
this patch.

2020-07-28  Roger Sayle  <roger@nextmovesoftware.com>
    Richard Biener  <rguenther@suse.de>

gcc/ChangeLog
* match.pd (popcount(x)&1 -> parity(x)): New simplification.
(parity(~x) -> parity(x)): New simplification.
(parity(x)^parity(y) -> parity(x^y)): New simplification.
(parity(x&1) -> x&1): New simplification.
(popcount(x) -> x>>C): New simplification.

gcc/testsuite/ChangeLog
* gcc.dg/fold-popcount-5.c: New test.
* gcc.dg/fold-parity-1.c: Likewise.
* gcc.dg/fold-parity-2.c: Likewise.
* gcc.dg/fold-parity-3.c: Likewise.
* gcc.dg/fold-parity-4.c: Likewise.
* gcc.dg/fold-parity-5.c: Likewise.
gcc/match.pd
gcc/testsuite/gcc.dg/fold-parity-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/fold-parity-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/fold-parity-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/fold-parity-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/fold-parity-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/fold-popcount-5.c [new file with mode: 0644]