diff --git a/gcc/match.pd b/gcc/match.pd index 53ced346bbd..43f3d7ab0fa 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 00000000000..f7216618147 --- /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; +}