match.pd: Fix popcount (X) + popcount (Y) simplification [PR112719]
Since my PR112566 r14-5557 changes the following testcase ICEs, because .POPCOUNT (x) + .POPCOUNT (y) has a simplification attempted even when x and y have incompatible types (different precisions). Note, with _BitInt it can ICE already starting with r14-5435 and I think as a latent problem it exists for years, because IFN_POPCOUNT calls inherently can have different argument types and return type is always the same. The following patch fixes it by using widest_int during the analysis (which is where it was ICEing) and if it is optimizable, casting to the wider type so that bit_ior has matching argument types. 2023-11-28 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/112719 * match.pd (popcount (X) + popcount (Y) -> POPCOUNT (X | Y)): Deal with argument types with different precisions.
This commit is contained in:
parent
594ef1ff70
commit
03877e7ecc
2 changed files with 25 additions and 2 deletions
|
@ -8732,8 +8732,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|
|||
(simplify
|
||||
(plus (POPCOUNT:s @0) (POPCOUNT:s @1))
|
||||
(if (INTEGRAL_TYPE_P (type)
|
||||
&& wi::bit_and (tree_nonzero_bits (@0), tree_nonzero_bits (@1)) == 0)
|
||||
(POPCOUNT (bit_ior @0 @1))))
|
||||
&& (wi::bit_and (widest_int::from (tree_nonzero_bits (@0), UNSIGNED),
|
||||
widest_int::from (tree_nonzero_bits (@1), UNSIGNED))
|
||||
== 0))
|
||||
(with { tree utype = TREE_TYPE (@0);
|
||||
if (TYPE_PRECISION (utype) < TYPE_PRECISION (TREE_TYPE (@1)))
|
||||
utype = TREE_TYPE (@1); }
|
||||
(POPCOUNT (bit_ior (convert:utype @0) (convert:utype @1))))))
|
||||
|
||||
/* popcount(X) == 0 is X == 0, and related (in)equalities. */
|
||||
(for popcount (POPCOUNT)
|
||||
|
|
18
gcc/testsuite/gcc.dg/pr112719.c
Normal file
18
gcc/testsuite/gcc.dg/pr112719.c
Normal file
|
@ -0,0 +1,18 @@
|
|||
/* PR tree-optimization/112719 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O" } */
|
||||
/* { dg-additional-options "-msse4" { target i?86-*-* x86_64-*-* } } */
|
||||
|
||||
int
|
||||
foo (unsigned int a, unsigned short b)
|
||||
{
|
||||
return __builtin_popcountl (a) + __builtin_popcountl (b);
|
||||
}
|
||||
|
||||
int
|
||||
bar (unsigned int a, unsigned short b)
|
||||
{
|
||||
a &= 0xaaaaaaaaUL;
|
||||
b &= 0x5555;
|
||||
return __builtin_popcountll (a) + __builtin_popcountll (b);
|
||||
}
|
Loading…
Add table
Reference in a new issue