match.pd: Optimize ((cst << x) & 1) [PR96669]
authorJakub Jelinek <jakub@redhat.com>
Sat, 16 Jan 2021 08:21:52 +0000 (09:21 +0100)
committerJakub Jelinek <jakub@redhat.com>
Sat, 16 Jan 2021 08:21:52 +0000 (09:21 +0100)
While we had a ((1 << x) & 1) != 0 to x == 0 optimization already,
this patch adds ((cst << x) & 1) optimization too, this time the
second constant must be 1 though, not some power of two, but the first
one can be any constant.  If it is even, the result is false, if it is
odd, the result is x == 0.

2021-01-16  Jakub Jelinek  <jakub@redhat.com>

PR tree-optimization/96669
* match.pd ((CST << x) & 1 -> x == 0): New simplification.

* gcc.dg/tree-ssa/pr96669-1.c: Adjust regexp.
* gcc.dg/tree-ssa/pr96669-2.c: New test.

gcc/match.pd
gcc/testsuite/gcc.dg/tree-ssa/pr96669-1.c
gcc/testsuite/gcc.dg/tree-ssa/pr96669-2.c [new file with mode: 0644]

index 84c4ee66a79fe026ff1351e7b12af0e40ee25777..7158e983d218a3dc13aaca28cba86513e2959e5d 100644 (file)
@@ -3117,6 +3117,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
       (op @0 { build_int_cst (TREE_TYPE (@1), low); })))))))
 
 
+/* Simplify (CST << x) & 1 to 0 if CST is even or to x == 0 if it is odd.  */
+(simplify
+ (bit_and (lshift INTEGER_CST@1 @0) integer_onep)
+  (if ((wi::to_wide (@1) & 1) != 0)
+   (convert (eq:boolean_type_node @0 { build_zero_cst (TREE_TYPE (@0)); }))
+   { build_zero_cst (type); }))
+
 /* Simplify ((C << x) & D) != 0 where C and D are power of two constants,
    either to false if D is smaller (unsigned comparison) than C, or to
    x == log2 (D) - log2 (C).  Similarly for right shifts.  */
index a1efba76770cf556ab47307c8330d09c530da3ba..6a95a6ba8c17c62a67d8347cc60a5c345fa45155 100644 (file)
@@ -1,7 +1,7 @@
 /* PR tree-optimization/96669 */
 /* { dg-do compile } */
 /* { dg-options "-O2 -fdump-tree-original" } */
-/* { dg-final { scan-tree-dump "return a == 0;" "original" } } */
+/* { dg-final { scan-tree-dump "a == 0" "original" } } */
 /* { dg-final { scan-tree-dump "return 1;" "original" } } */
 /* { dg-final { scan-tree-dump "return c == 3;" "original" } } */
 /* { dg-final { scan-tree-dump "return d != 1;" "original" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96669-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96669-2.c
new file mode 100644 (file)
index 0000000..47b885f
--- /dev/null
@@ -0,0 +1,30 @@
+/* PR tree-optimization/96669 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-original" } */
+/* { dg-final { scan-tree-dump "a == 0" "original" } } */
+/* { dg-final { scan-tree-dump-times "return 0;" 2 "original" } } */
+/* { dg-final { scan-tree-dump "c == 0" "original" } } */
+
+int
+f1 (int a)
+{
+  return ((1 << a) & 1);
+}
+
+int
+f2 (int b)
+{
+  return ((2 << b) & 1);
+}
+
+int
+f3 (int c)
+{
+  return ((35 << c) & 1);
+}
+
+int
+f4 (int d)
+{
+  return ((42 << d) & 1);
+}