Hi all,

Pattern "(x | y) - y" can be optimized to simple "(x & ~y)" andn pattern.

Bootstrapped and tested on aarch64-none-linux-gnu.

OK for master ?

Cheers,
Przemyslaw

gcc/ChangeLog:

        PR tree-optimization/94880
        * match.pd (A | B) - B -> (A & ~B): New simplification.

gcc/testsuite/ChangeLog:

        PR tree-optimization/94880
        * gcc.dg/tree-ssa/pr94880.c: New Test.

diff --git a/gcc/match.pd b/gcc/match.pd
index 
33ee1a920bf4a036cc5fdb3c96b38b52765bdefb..10bf33d8cb215dfb0f54cb0ad02ad0af9d9dea7b
 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1109,6 +1109,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
       && !TYPE_SATURATING (type))
   (bit_ior @0 @1)))
 
+/* (x | y) - y -> (x & ~y) */
+(simplify
+ (minus (bit_ior:cs @0 @1) @1)
+ (bit_and @0 (bit_not @1)))
+
 /* (x | y) - (x ^ y) -> x & y */
 (simplify
  (minus (bit_ior @0 @1) (bit_xor @0 @1))
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94880.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr94880.c
new file mode 100644
index 
0000000000000000000000000000000000000000..f72166181479d43762423e7e153ee1832760cad0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94880.c
@@ -0,0 +1,29 @@
+/* PR tree-optimization/94786 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times "= ~\[xy\]_" 4 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " & \[xy\]_" 4 "optimized" } } */
+
+unsigned
+foo_u(unsigned x, unsigned y)
+{
+  return (x | y) - y;
+}
+
+int
+foo_i(int x, int y)
+{
+  return (x | y) - y;
+}
+
+unsigned long long
+foo_ull(unsigned long long x, unsigned long long y)
+{
+  return (x | y) - y;
+}
+
+long long
+foo_ll(long long x, long long y)
+{
+  return (x | y) - y;
+}

Reply via email to