aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/match.pd7
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr96669-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr96669-2.c30
3 files changed, 38 insertions, 1 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index 84c4ee6..7158e98 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -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. */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96669-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96669-1.c
index a1efba7..6a95a6b 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr96669-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96669-1.c
@@ -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
index 0000000..47b885f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96669-2.c
@@ -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);
+}