diff options
author | Przemyslaw Wirkus <Przemyslaw.Wirkus@arm.com> | 2020-06-19 16:48:55 +0100 |
---|---|---|
committer | Giuliano Belinassi <giuliano.belinassi@usp.br> | 2020-08-17 13:14:14 -0300 |
commit | 66b97a0096476108f7fe21b06ef4e1454072ac49 (patch) | |
tree | 9caad9a1ab44416390c137a9e017bde241e96f7a /gcc | |
parent | 52237c2ace0a379ec258058f764d507e9302a7bc (diff) | |
download | gcc-66b97a0096476108f7fe21b06ef4e1454072ac49.zip gcc-66b97a0096476108f7fe21b06ef4e1454072ac49.tar.gz gcc-66b97a0096476108f7fe21b06ef4e1454072ac49.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.
Diffstat (limited to 'gcc')
-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; +} |