]> git.ipfire.org Git - thirdparty/gcc.git/commit
gimple ssa: switchconv: Use __builtin_popcount and support more types in exp transfor...
authorFilip Kastl <fkastl@suse.cz>
Wed, 28 Aug 2024 13:47:44 +0000 (15:47 +0200)
committerFilip Kastl <fkastl@suse.cz>
Wed, 28 Aug 2024 13:50:40 +0000 (15:50 +0200)
commit1c4b9826bd0d5ac471543c68f097d80b1969f599
treed80671ba94823d9c9830709449e5de32f688314d
parent4246cf4f18053eeb47cb2a241fffa9a41573916e
gimple ssa: switchconv: Use __builtin_popcount and support more types in exp transform [PR116355]

The gen_pow2p function generates (a & -a) == a as a fallback for
POPCOUNT (a) == 1.  Not only is the bitmagic not equivalent to
POPCOUNT (a) == 1 but it also introduces UB (consider signed
a = INT_MIN).

This patch rewrites gen_pow2p to always use __builtin_popcount instead.
This means that what the end result GIMPLE code is gets decided by an
already existing machinery in a later pass.  That is a cleaner solution
I think.  This existing machinery also uses a ^ (a - 1) > a - 1 which is
the correct bitmagic.

While rewriting gen_pow2p I had to add logic for converting the
operand's type to a type that __builtin_popcount accepts.  I naturally
also added this logic to gen_log2.  Thanks to this, exponential index
transform gains the capability to handle all operand types with
precision at most that of long long int.

gcc/ChangeLog:

PR tree-optimization/116355
* tree-switch-conversion.cc (can_log2): Add capability to
suggest converting the operand to a different type.
(gen_log2): Add capability to generate a conversion in case the
operand is of a type incompatible with the logarithm operation.
(can_pow2p): New function.
(gen_pow2p): Rewrite to use __builtin_popcount instead of
manually inserting an internal fn call or bitmagic.  Also add
capability to generate a conversion.
(switch_conversion::is_exp_index_transform_viable): Call
can_pow2p.  Store types suggested by can_log2 and gen_log2.
(switch_conversion::exp_index_transform): Params of gen_pow2p
and gen_log2 changed so update their calls.
* tree-switch-conversion.h: Add m_exp_index_transform_log2_type
and m_exp_index_transform_pow2p_type to switch_conversion class
to track type conversions needed to generate the "is power of 2"
and logarithm operations.

gcc/testsuite/ChangeLog:

PR tree-optimization/116355
* gcc.target/i386/switch-exp-transform-1.c: Don't test for
presence of POPCOUNT internal fn after switch conversion.  Test
for it after __builtin_popcount has had a chance to get
expanded.
* gcc.target/i386/switch-exp-transform-3.c: Also test char and
short.

Signed-off-by: Filip Kastl <fkastl@suse.cz>
gcc/testsuite/gcc.target/i386/switch-exp-transform-1.c
gcc/testsuite/gcc.target/i386/switch-exp-transform-3.c
gcc/tree-switch-conversion.cc
gcc/tree-switch-conversion.h