match.pd: New pattern.
authorYury Gribov <tetra2005@gmail.com>
Tue, 13 Jun 2017 11:19:23 +0000 (11:19 +0000)
committerMaxim Ostapenko <chefmax@gcc.gnu.org>
Tue, 13 Jun 2017 11:19:23 +0000 (14:19 +0300)
2017-06-13  Yury Gribov  <tetra2005@gmail.com>

gcc/
* match.pd: New pattern.

gcc/testsuite/
* c-c++-common/fold-masked-cmp-3.c: New test.

From-SVN: r249151

gcc/ChangeLog
gcc/match.pd
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/fold-masked-cmp-3.c [new file with mode: 0644]

index 4567036291cafbbbd35b01a400e44330bb64b17c..d1f54c03b210fd73da30e296d7a8590acaa17563 100644 (file)
@@ -1,3 +1,7 @@
+2017-06-13  Yury Gribov  <tetra2005@gmail.com>
+
+       * match.pd: New pattern.
+
 2017-06-13  Yury Gribov  <tetra2005@gmail.com>
 
        * tree-vrp.c (is_masked_range_test): New function.
index 54a8e0449f8301ffaf553c139bbd2d7ccb1e8648..244e9eb52573dd59c36633aaf518b74b94df1a77 100644 (file)
@@ -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)
index 678b89287ccd9744142ad35f2df7bc5aa897c33f..71b89de0fbdb4f40b72a4de2c1c40f1a83e56f43 100644 (file)
@@ -1,3 +1,7 @@
+2017-06-12  Yury Gribov  <tetra2005@gmail.com>
+
+       * c-c++-common/fold-masked-cmp-3.c: New test.
+
 2017-06-13  Yury Gribov  <tetra2005@gmail.com>
 
        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 (file)
index 0000000..98900ec
--- /dev/null
@@ -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" } } */