]> git.ipfire.org Git - thirdparty/gcc.git/commit
Improve __builtin_popcount* (x) == 1 generation if x is known != 0 [PR90693]
authorJakub Jelinek <jakub@redhat.com>
Fri, 5 Jan 2024 10:16:58 +0000 (11:16 +0100)
committerJakub Jelinek <jakub@redhat.com>
Fri, 5 Jan 2024 10:16:58 +0000 (11:16 +0100)
commit0152637c74c9eab7658483b1cca4e3d584dd4262
tree682cf53b5033c7ec1e8ceaa36aec06f0f9870d81
parent397bdd1ac59a556a9619c2b2bf203f88ff5e97c2
Improve __builtin_popcount* (x) == 1 generation if x is known != 0 [PR90693]

We expand __builtin_popcount* (x) == 1 as
x ^ (x - 1) > x - 1, either unconditionally in tree-ssa-math-opts.cc
if we don't have a direct optab support for popcount, or during
expansion where we compare the costs of comparison of the popcount
against one vs. the above expression.
As mentioned in the PR, if we know from ranger that the argument is
not zero, we can emit x & (x - 1) == 0 test which is same number of
GIMPLE statements, but on many targets cheaper (e.g. whenever an AND
instruction can also set flags on whether result was zero or not).

The following patch does that.

2024-01-05  Jakub Jelinek  <jakub@redhat.com>

PR tree-optimization/90693
* tree-ssa-math-opts.cc (match_single_bit_test): If
tree_expr_nonzero_p (arg), remember it in the second argument to
IFN_POPCOUNT or lower it as arg & (arg - 1) == 0 rather than
arg ^ (arg - 1) > arg - 1.
* internal-fn.cc (expand_POPCOUNT): If second argument to
IFN_POPCOUNT suggests arg is non-zero, try to expand it as
arg & (arg - 1) == 0 rather than arg ^ (arg - 1) > arg - 1.

* gcc.target/i386/pr90693-2.c: New test.
gcc/internal-fn.cc
gcc/testsuite/gcc.target/i386/pr90693-2.c [new file with mode: 0644]
gcc/tree-ssa-math-opts.cc