diff options
author | Przemyslaw Wirkus <Przemyslaw.Wirkus@arm.com> | 2020-06-19 16:48:55 +0100 |
---|---|---|
committer | Alex Coplan <alex.coplan@arm.com> | 2020-06-19 16:48:55 +0100 |
commit | e0bfe016712ace877dd5b057bc1eb06e3c307623 (patch) | |
tree | 8b88b3db0c03f40ec236100ea1feee7fcf8fc060 | |
parent | 6d8b2ee568bd17a398781d86aab140b8121aad30 (diff) | |
download | gcc-e0bfe016712ace877dd5b057bc1eb06e3c307623.zip gcc-e0bfe016712ace877dd5b057bc1eb06e3c307623.tar.gz gcc-e0bfe016712ace877dd5b057bc1eb06e3c307623.tar.bz2 |
Fix PR94880: Failure to recognize andn pattern
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.
-rw-r--r-- | gcc/match.pd | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr94880.c | 29 |
2 files changed, 34 insertions, 0 deletions
diff --git a/gcc/match.pd b/gcc/match.pd index 53ced34..43f3d7a 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 0000000..f721661 --- /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; +} |