Pattern "(x | y) - y" can be optimized to simple "(x & ~y)" andn
pattern.
Bootstrapped and tested on aarch64-none-linux-gnu.
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.
&& !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))
--- /dev/null
+/* 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;
+}