aboutsummaryrefslogtreecommitdiff
path: root/gcc/match.pd
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/match.pd')
-rw-r--r--gcc/match.pd20
1 files changed, 20 insertions, 0 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index 50f4c88..8a71141 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4760,3 +4760,23 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(negate (IFN_FNMS@3 @0 @1 @2))
(if (single_use (@3))
(IFN_FMA @0 @1 @2))))
+
+/* POPCOUNT simplifications. */
+(for popcount (BUILT_IN_POPCOUNT BUILT_IN_POPCOUNTL BUILT_IN_POPCOUNTLL
+ BUILT_IN_POPCOUNTIMAX)
+ /* popcount(X&1) is nop_expr(X&1). */
+ (simplify
+ (popcount @0)
+ (if (tree_nonzero_bits (@0) == 1)
+ (convert @0)))
+ /* popcount(X) + popcount(Y) is popcount(X|Y) when X&Y must be zero. */
+ (simplify
+ (plus (popcount:s @0) (popcount:s @1))
+ (if (wi::bit_and (tree_nonzero_bits (@0), tree_nonzero_bits (@1)) == 0)
+ (popcount (bit_ior @0 @1))))
+ /* popcount(X) == 0 is X == 0, and related (in)equalities. */
+ (for cmp (le eq ne gt)
+ rep (eq eq ne ne)
+ (simplify
+ (cmp (popcount @0) integer_zerop)
+ (rep @0 { build_zero_cst (TREE_TYPE (@0)); }))))