The patch simplifies expressions (a - 1) & -a, (a - 1) | -a, and (a - 1) ^ -a
to the constants 0, -1, and -1, respectively.
Currently, GCC does not perform these simplifications.
Bootstrapped and tested on x86-linux-gnu with no regressions.
gcc/ChangeLog:
* match.pd: New pattern.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/bitops-11.c: New test.
CONFIDENTIALITY: The contents of this e-mail are confidential and intended only
for the above addressee(s). If you are not the intended recipient, or the
person responsible for delivering it to the intended recipient, copying or
delivering it to anyone else or using it in any unauthorized manner is
prohibited and may be unlawful. If you receive this e-mail by mistake, please
notify the sender and the systems administrator at [email protected]
immediately.
---
gcc/match.pd | 11 +++++++++++
gcc/testsuite/gcc.dg/tree-ssa/bitops-11.c | 23 +++++++++++++++++++++++
2 files changed, 34 insertions(+)
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/bitops-11.c
diff --git a/gcc/match.pd b/gcc/match.pd
index c10bf9a7b80..6d95ceaa194 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1472,6 +1472,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(bit_and:c @0 (bit_not (bit_xor:c @0 @1)))
(bit_and @0 @1))
+/* Transform:
+ (a - 1) & -a -> 0.
+ (a - 1) | -a -> -1.
+ (a - 1) ^ -a -> -1. */
+(for bit_op (bit_ior bit_xor bit_and)
+ (simplify
+ (bit_op:c (plus @0 integer_minus_onep) (negate @0))
+ (if (bit_op == BIT_AND_EXPR)
+ { build_zero_cst (type); }
+ { build_minus_one_cst (type); })))
+
/* a & (a == b) --> a & b (boolean version of the above). */
(simplify
(bit_and:c @0 (nop_convert? (eq:c @0 @1)))
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bitops-11.c b/gcc/testsuite/gcc.dg/tree-ssa/bitops-11.c
new file mode 100644
index 00000000000..c2d646e2b8d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/bitops-11.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
+
+int foo1(int a)
+{
+ return (a - 1) & -a;
+}
+
+int foo2(int a)
+{
+ return (a - 1) | -a;
+}
+
+int foo3(int a)
+{
+ return (a - 1) ^ -a;
+}
+
+/* { dg-final { scan-tree-dump-not "bit_and_expr, " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "bit_ior_expr, " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "bit_xor_expr, " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "negate_expr, " "optimized" } } */
+
--
2.43.0