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