aboutsummaryrefslogtreecommitdiff
path: root/gcc/match.pd
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2023-11-28 10:14:55 +0100
committerJakub Jelinek <jakub@redhat.com>2023-11-28 10:14:55 +0100
commit03877e7eccd2734ca93a2d13aa2abf55e0aec923 (patch)
tree7da4dbc1c5d83219b9e31fd3b2eda0c5af36f2a9 /gcc/match.pd
parent594ef1ff707866bcdc1f077c5d078a5bd250320f (diff)
downloadgcc-03877e7eccd2734ca93a2d13aa2abf55e0aec923.zip
gcc-03877e7eccd2734ca93a2d13aa2abf55e0aec923.tar.gz
gcc-03877e7eccd2734ca93a2d13aa2abf55e0aec923.tar.bz2
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.
Diffstat (limited to 'gcc/match.pd')
-rw-r--r--gcc/match.pd9
1 files changed, 7 insertions, 2 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index 95225e4..0382fd5 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -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)