aboutsummaryrefslogtreecommitdiff
path: root/gcc/match.pd
diff options
context:
space:
mode:
authorAndrew Pinski <quic_apinski@quicinc.com>2025-01-14 19:38:47 -0800
committerAndrew Pinski <quic_apinski@quicinc.com>2025-01-15 15:20:58 -0800
commit903ab914dd48c3131ded0cf427da50c23168024c (patch)
treef72fae09cc8b310759c0d01bc925c9627a63c6fc /gcc/match.pd
parentc340ff207f0fd297231e9d5c093c06c11b84bede (diff)
downloadgcc-903ab914dd48c3131ded0cf427da50c23168024c.zip
gcc-903ab914dd48c3131ded0cf427da50c23168024c.tar.gz
gcc-903ab914dd48c3131ded0cf427da50c23168024c.tar.bz2
match: Simplify `1 >> x` into `x == 0` [PR102705]
This in this PR we have missed optimization where we miss that, `1 >> x` and `(1 >> x) ^ 1` can't be equal. There are a few ways of optimizing this, the easiest and simpliest is to simplify `1 >> x` into just `x == 0` as those are equivalant (if we ignore out of range values for x). we already have an optimization for `(1 >> X) !=/== 0` so the only difference here is we don't need the `!=/== 0` part to do the transformation. So this removes the `(1 >> X) !=/== 0` transformation and just adds a simplfied `1 >> x` -> `x == 0` one. Bootstrapped and tested on x86_64-linux-gnu. PR tree-optimization/102705 gcc/ChangeLog: * match.pd (`(1 >> X) != 0`): Remove pattern. (`1 >> x`): New pattern. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr105832-2.c: Update testcase. * gcc.dg/tree-ssa/pr96669-1.c: Likewise. * gcc.dg/tree-ssa/pr102705-1.c: New test. * gcc.dg/tree-ssa/pr102705-2.c: New test. Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
Diffstat (limited to 'gcc/match.pd')
-rw-r--r--gcc/match.pd16
1 files changed, 8 insertions, 8 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index 1719308..b6cbb85 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4998,6 +4998,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(op @0 { build_int_cst (TREE_TYPE (@1), prec - 1); })))
(op @0 { build_int_cst (TREE_TYPE (@1), low); })))))))
+/* Fold `1 >> a` into `a == 0` for scalar integral types. */
+(simplify
+ (rshift integer_onep @2)
+ (if (INTEGRAL_TYPE_P (type))
+ (convert (eq:boolean_type_node @2 { build_zero_cst (TREE_TYPE (@2)); }))))
/* Simplify (CST << x) & 1 to 0 if CST is even or to x == 0 if it is odd. */
(simplify
@@ -5009,7 +5014,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
/* Simplify ((C << x) & D) != 0 where C and D are power of two constants,
either to false if D is smaller (unsigned comparison) than C, or to
x == log2 (D) - log2 (C). Similarly for right shifts.
- Note for `(1 >> x)`, the & 1 has been removed so matching that seperately. */
+ Note `(1 >> x)`, the & 1 has been removed so but will have been
+ already folded above. */
(for cmp (ne eq)
icmp (eq ne)
(simplify
@@ -5026,13 +5032,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
int c2 = wi::clz (wi::to_wide (@2)); }
(if (c1 > c2)
{ constant_boolean_node (cmp == NE_EXPR ? false : true, type); }
- (icmp @0 { build_int_cst (TREE_TYPE (@0), c2 - c1); })))))
- /* `(1 >> X) != 0` -> `X == 0` */
- /* `(1 >> X) == 0` -> `X != 0` */
- (simplify
- (cmp (rshift integer_onep@1 @0) integer_zerop)
- (if (INTEGRAL_TYPE_P (TREE_TYPE (@1)))
- (icmp @0 { build_zero_cst (TREE_TYPE (@0)); }))))
+ (icmp @0 { build_int_cst (TREE_TYPE (@0), c2 - c1); }))))))
/* (CST1 << A) == CST2 -> A == ctz (CST2) - ctz (CST1)
(CST1 << A) != CST2 -> A != ctz (CST2) - ctz (CST1)