On February 9, 2015 4:46:34 PM CET, Alex Velenko <alex.vele...@arm.com> wrote: > >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.vele...@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)
You should be able to combine both patterns with using bit_and:c. Also Isn't it still profitable to do CST & X == X to CST & ~X == 0? It Still makes x single-use. Note that we may have the reverse transforms somewhere (less operations). So it's not at all clear to me that this is profitable gimple-wise. Thoughts? Richard. >+ (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" } } */