This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][TREE] Match.pd "compare-and-not" patterns.


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" } } */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]