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>
Showing
- gcc/testsuite/gcc.target/i386/switch-exp-transform-1.c 4 additions, 3 deletionsgcc/testsuite/gcc.target/i386/switch-exp-transform-1.c
- gcc/testsuite/gcc.target/i386/switch-exp-transform-3.c 96 additions, 2 deletionsgcc/testsuite/gcc.target/i386/switch-exp-transform-3.c
- gcc/tree-switch-conversion.cc 120 additions, 32 deletionsgcc/tree-switch-conversion.cc
- gcc/tree-switch-conversion.h 7 additions, 0 deletionsgcc/tree-switch-conversion.h
Loading
Please register or sign in to comment