aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPrzemyslaw Wirkus <Przemyslaw.Wirkus@arm.com>2020-06-19 16:48:55 +0100
committerAlex Coplan <alex.coplan@arm.com>2020-06-19 16:48:55 +0100
commite0bfe016712ace877dd5b057bc1eb06e3c307623 (patch)
tree8b88b3db0c03f40ec236100ea1feee7fcf8fc060 /gcc
parent6d8b2ee568bd17a398781d86aab140b8121aad30 (diff)
downloadgcc-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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/match.pd5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr94880.c29
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;
+}