From 9ebc3467fe890c71fdb59aa123c40a050e82bdf8 Mon Sep 17 00:00:00 2001 From: Yury Gribov Date: Tue, 13 Jun 2017 11:19:23 +0000 Subject: [PATCH] match.pd: New pattern. 2017-06-13 Yury Gribov gcc/ * match.pd: New pattern. gcc/testsuite/ * c-c++-common/fold-masked-cmp-3.c: New test. From-SVN: r249151 --- gcc/ChangeLog | 4 +++ gcc/match.pd | 28 +++++++++++++++++++ gcc/testsuite/ChangeLog | 4 +++ .../c-c++-common/fold-masked-cmp-3.c | 16 +++++++++++ 4 files changed, 52 insertions(+) create mode 100644 gcc/testsuite/c-c++-common/fold-masked-cmp-3.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4567036291c..d1f54c03b21 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2017-06-13 Yury Gribov + + * match.pd: New pattern. + 2017-06-13 Yury Gribov * tree-vrp.c (is_masked_range_test): New function. diff --git a/gcc/match.pd b/gcc/match.pd index 54a8e0449f8..244e9eb5257 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -2741,6 +2741,34 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) || VECTOR_INTEGER_TYPE_P (TREE_TYPE (@0))) { constant_boolean_node (false, type); }))) +/* A & (2**N - 1) <= 2**K - 1 -> A & (2**N - 2**K) == 0 + A & (2**N - 1) > 2**K - 1 -> A & (2**N - 2**K) != 0 + + Note that comparisons + A & (2**N - 1) < 2**K -> A & (2**N - 2**K) == 0 + A & (2**N - 1) >= 2**K -> A & (2**N - 2**K) != 0 + will be canonicalized to above so there's no need to + consider them here. + */ + +(for cmp (le gt) + eqcmp (eq ne) + (simplify + (cmp (bit_and@0 @1 INTEGER_CST@2) INTEGER_CST@3) + (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))) + (with + { + tree ty = TREE_TYPE (@0); + unsigned prec = TYPE_PRECISION (ty); + wide_int mask = wi::to_wide (@2, prec); + wide_int rhs = wi::to_wide (@3, prec); + signop sgn = TYPE_SIGN (ty); + } + (if ((mask & (mask + 1)) == 0 && wi::gt_p (rhs, 0, sgn) + && (rhs & (rhs + 1)) == 0 && wi::ge_p (mask, rhs, sgn)) + (eqcmp (bit_and @1 { wide_int_to_tree (ty, mask - rhs); }) + { build_zero_cst (ty); })))))) + /* -A CMP -B -> B CMP A. */ (for cmp (tcc_comparison) scmp (swapped_tcc_comparison) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 678b89287cc..71b89de0fbd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2017-06-12 Yury Gribov + + * c-c++-common/fold-masked-cmp-3.c: New test. + 2017-06-13 Yury Gribov PR tree-optimization/67328 diff --git a/gcc/testsuite/c-c++-common/fold-masked-cmp-3.c b/gcc/testsuite/c-c++-common/fold-masked-cmp-3.c new file mode 100644 index 00000000000..98900ec33b3 --- /dev/null +++ b/gcc/testsuite/c-c++-common/fold-masked-cmp-3.c @@ -0,0 +1,16 @@ +/* { dg-do compile { target x86_64-*-* } } */ +/* { dg-options "-fdump-tree-original" } */ + +void foo (int *p, int x) +{ + if ((x & 0xff) <= 7) + *p = 0; +} + +void bar (int *p, int x) +{ + if ((x & 0xff) < 8) + *p = 0; +} + +/* { dg-final { scan-tree-dump-times "(x & .*) == 0" 2 "original" } } */