diff options
author | Andrew Pinski <quic_apinski@quicinc.com> | 2025-01-14 19:38:47 -0800 |
---|---|---|
committer | Andrew Pinski <quic_apinski@quicinc.com> | 2025-01-15 15:20:58 -0800 |
commit | 903ab914dd48c3131ded0cf427da50c23168024c (patch) | |
tree | f72fae09cc8b310759c0d01bc925c9627a63c6fc /gcc/match.pd | |
parent | c340ff207f0fd297231e9d5c093c06c11b84bede (diff) | |
download | gcc-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.pd | 16 |
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) |