This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][TREE] Match.pd "compare-and-not" patterns.
- From: Alex Velenko <alex dot velenko at arm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: marcus dot shawcroft at arm dot com
- Date: Mon, 9 Feb 2015 15:46:34 +0000
- Subject: [PATCH][TREE] Match.pd "compare-and-not" patterns.
- Authentication-results: sourceware.org; auth=none
Hi,
This patch adds match.pd "compare-and-not" simplication patterns.
This is a generic transformation reducing variable accesses.
Done full regression run on arm-none-eabi, aarch64-none-elf,
aarch64_be-none-elf and bootstrapped on x86.
Is patch ok?
2015-02-09 Alex Velenko <Alex.Velenko@arm.com>
gcc/
* match.pd ((X & Y) == X): New pattern.
((X & Y) == Y): New pattern.
gcc/testsuite
* gcc.dg/match-and-not.c: New testcase.
diff --git a/gcc/match.pd b/gcc/match.pd
index 81c4ee6..b4fa6e9 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -377,6 +377,24 @@ along with GCC; see the file COPYING3. If not see
&& TYPE_PRECISION (TREE_TYPE (@1)) == 1)
(le @0 @1)))
+/* If arg1 and arg2 are integers
+ (X & Y) == X -> (X & ~Y) == 0.
+ (X & Y) == Y -> (~X & Y) == 0. */
+(simplify
+ (eq (bit_and @0 @1) @0)
+ (if ((INTEGRAL_TYPE_P (TREE_TYPE (@0)))
+ && !(CONSTANT_CLASS_P (@0))
+ && (INTEGRAL_TYPE_P (TREE_TYPE (@1)))
+ && !(CONSTANT_CLASS_P (@1)))
+ (eq (bit_and @0 (bit_not @1)) { build_zero_cst (TREE_TYPE (@0)); })))
+(simplify
+ (eq (bit_and @0 @1) @1)
+ (if ((INTEGRAL_TYPE_P (TREE_TYPE (@0)))
+ && !(CONSTANT_CLASS_P (@0))
+ && (INTEGRAL_TYPE_P (TREE_TYPE (@1)))
+ && !(CONSTANT_CLASS_P (@1)))
+ (eq (bit_and (bit_not @0) @1) { build_zero_cst (TREE_TYPE (@1)); })))
+
/* ~~x -> x */
(simplify
(bit_not (bit_not @0))
diff --git a/gcc/testsuite/gcc.dg/match-and-not.c b/gcc/testsuite/gcc.dg/match-and-not.c
new file mode 100644
index 0000000..62d993e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/match-and-not.c
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+/* { dg-options "-O1 -fdump-tree-original" } */
+
+extern void abort (void);
+
+/* (x & y) == x -> (x & ~y) == 0. */
+int __attribute__ ((noinline))
+f1 (int x, int y)
+{
+ return (x & y) == x;
+}
+
+int __attribute__ ((noinline))
+f2 (int x, int y)
+{
+ return (x & y) == y;
+}
+
+int
+main ()
+{
+ if (!f1 (21, 85))
+ abort ();
+
+ if (!f2 (85, 84))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "\\(~y & x\\) == 0" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "\\(~x & y\\) == 0" 1 "original" } } */
+/* { dg-final { cleanup-tree-dump "original" } } */