aboutsummaryrefslogtreecommitdiff
path: root/gcc/match.pd
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-12-31 11:09:26 +0100
committerJakub Jelinek <jakub@redhat.com>2020-12-31 11:09:26 +0100
commitd2eb616a0f7bea78164912aa438c29fe1ef5774a (patch)
treee8a936a3ca8918db0ea67a25b389229d551e53b8 /gcc/match.pd
parent8f12ce2ea3be12de4f83d3c419bdb1dc5036b202 (diff)
downloadgcc-d2eb616a0f7bea78164912aa438c29fe1ef5774a.zip
gcc-d2eb616a0f7bea78164912aa438c29fe1ef5774a.tar.gz
gcc-d2eb616a0f7bea78164912aa438c29fe1ef5774a.tar.bz2
match.pd: Add clz(X) == 0 -> (int)X < 0 etc. simpifications [PR94802]
The following patch adds some clz simplifications. If clz is 0, then the MSB of the argument is set, and if clz is prec-1, then the argument is 1. 2020-12-31 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/94802 * match.pd (clz(X) == 0 -> (int)X < 0): New simplification. (clz(X) == (prec-1) -> X == 1): Likewise. * gcc.dg/tree-ssa/pr94802-1.c: New test.
Diffstat (limited to 'gcc/match.pd')
-rw-r--r--gcc/match.pd33
1 files changed, 33 insertions, 0 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index 1055292..529933f 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -6226,6 +6226,39 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(if (single_use (@3))
(IFN_FMA @0 @1 @2))))
+/* CLZ simplifications. */
+(for clz (CLZ)
+ (for op (eq ne)
+ cmp (lt ge)
+ (simplify
+ (op (clz:s @0) INTEGER_CST@1)
+ (if (integer_zerop (@1))
+ /* clz(X) == 0 is (int)X < 0 and clz(X) != 0 is (int)X >= 0. */
+ (with { tree stype = signed_type_for (TREE_TYPE (@0));
+ HOST_WIDE_INT val = 0;
+#ifdef CLZ_DEFINED_VALUE_AT_ZERO
+ /* Punt on hypothetical weird targets. */
+ if (CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (TREE_TYPE (@0)),
+ val) == 2
+ && val == 0)
+ stype = NULL_TREE;
+#endif
+ }
+ (if (stype)
+ (cmp (convert:stype @0) { build_zero_cst (stype); })))
+ /* clz(X) == (prec-1) is X == 1 and clz(X) != (prec-1) is X != 1. */
+ (with { bool ok = true;
+#ifdef CLZ_DEFINED_VALUE_AT_ZERO
+ /* Punt on hypothetical weird targets. */
+ if (CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (TREE_TYPE (@0)),
+ val) == 2
+ && val == TYPE_PRECISION (TREE_TYPE (@0)) - 1)
+ ok = false;
+#endif
+ }
+ (if (ok && wi::to_wide (@1) == (TYPE_PRECISION (TREE_TYPE (@0)) - 1))
+ (op @0 { build_one_cst (TREE_TYPE (@0)); })))))))
+
/* POPCOUNT simplifications. */
/* popcount(X) + popcount(Y) is popcount(X|Y) when X&Y must be zero. */
(simplify