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.
(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. */
/* 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" } } */
--- /dev/null
+/* 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);
+}