* [PATCH] MATCH: Transform `(1 >> X) !=/== 0` into `X ==/!= 0`
@ 2023-09-03 16:25 Andrew Pinski
2023-09-05 7:12 ` Jeff Law
0 siblings, 1 reply; 2+ messages in thread
From: Andrew Pinski @ 2023-09-03 16:25 UTC (permalink / raw)
To: gcc-patches; +Cc: Andrew Pinski
We currently have a pattern for handling `(C >> X) & D == 0`
but if C is 1 and D is 1, the `& 1` might have been removed.
gcc/ChangeLog:
PR tree-optimization/105832
* match.pd (`(1 >> X) != 0`): New pattern
gcc/testsuite/ChangeLog:
PR tree-optimization/105832
* gcc.dg/tree-ssa/pr105832-1.c: New test.
* gcc.dg/tree-ssa/pr105832-2.c: New test.
* gcc.dg/tree-ssa/pr105832-3.c: New test.
---
gcc/match.pd | 10 ++++-
gcc/testsuite/gcc.dg/tree-ssa/pr105832-1.c | 25 ++++++++++++
gcc/testsuite/gcc.dg/tree-ssa/pr105832-2.c | 30 ++++++++++++++
gcc/testsuite/gcc.dg/tree-ssa/pr105832-3.c | 46 ++++++++++++++++++++++
4 files changed, 109 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr105832-1.c
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr105832-2.c
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr105832-3.c
diff --git a/gcc/match.pd b/gcc/match.pd
index 5270e4104ac..e9ce48ea7fa 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4026,7 +4026,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
/* 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. */
+ x == log2 (D) - log2 (C). Similarly for right shifts.
+ Note for `(1 >> x)`, the & 1 has been removed so matching that seperately. */
(for cmp (ne eq)
icmp (eq ne)
(simplify
@@ -4043,7 +4044,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
int c2 = wi::clz (wi::to_wide (@2)); }
(if (c1 > c2)
{ constant_boolean_node (cmp == NE_EXPR ? false : true, type); }
- (icmp @0 { build_int_cst (TREE_TYPE (@0), c2 - c1); }))))))
+ (icmp @0 { build_int_cst (TREE_TYPE (@0), c2 - c1); })))))
+ /* `(1 >> X) != 0` -> `X == 0` */
+ /* `(1 >> X) == 0` -> `X != 0` */
+ (simplify
+ (cmp (rshift integer_onep @0) integer_zerop)
+ (icmp @0 { build_zero_cst (TREE_TYPE (@0)); })))
/* (CST1 << A) == CST2 -> A == ctz (CST2) - ctz (CST1)
(CST1 << A) != CST2 -> A != ctz (CST2) - ctz (CST1)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr105832-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr105832-1.c
new file mode 100644
index 00000000000..d7029d39c85
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr105832-1.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-optimized" } */
+/* PR tree-optimization/105832 */
+
+void foo(void);
+
+static struct {
+ short a;
+ signed char b;
+} c;
+
+static signed char d;
+
+int main() {
+ signed char g = c.b > 4U ? c.b : c.b << 2;
+ for (int h = 0; h < 5; h++) {
+ d = (g >= 2 || 1 >> g) ? g : g << 1;
+ if (d && 1 == g)
+ foo();
+ c.a = 0;
+ }
+}
+
+/* The call of foo should have been removed. */
+/* { dg-final { scan-tree-dump-not "foo " "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr105832-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr105832-2.c
new file mode 100644
index 00000000000..2d2a33e2755
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr105832-2.c
@@ -0,0 +1,30 @@
+/* PR tree-optimization/105832 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-original" } */
+/* { dg-final { scan-tree-dump "return a == 0;" "original" } } */
+/* { dg-final { scan-tree-dump "return b == 0;" "original" } } */
+/* { dg-final { scan-tree-dump "return c != 0;" "original" } } */
+/* { dg-final { scan-tree-dump "return d != 0;" "original" } } */
+
+int
+f1 (int a)
+{
+ return (1 >> a) != 0;
+}
+
+int
+f2 (int b)
+{
+ return ((1 >> b) & 1) != 0;
+}
+int
+f3 (int c)
+{
+ return (1 >> c) == 0;
+}
+
+int
+f4 (int d)
+{
+ return ((1 >> d) & 1) == 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr105832-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr105832-3.c
new file mode 100644
index 00000000000..2bdd9afcbc7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr105832-3.c
@@ -0,0 +1,46 @@
+/* PR tree-optimization/105832 */
+/* { dg-do compile } */
+/* Disable the first forwprop1 as that will catch f2/f4 even though `&1`
+ will be removed during evrp. */
+/* { dg-options "-O2 -fdisable-tree-forwprop1 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump "a_\[0-9]+\\(D\\) == 0" "optimized" } } */
+/* { dg-final { scan-tree-dump "b_\[0-9]+\\(D\\) == 0" "optimized" } } */
+/* { dg-final { scan-tree-dump "c_\[0-9]+\\(D\\) != 0" "optimized" } } */
+/* { dg-final { scan-tree-dump "d_\[0-9]+\\(D\\) != 0" "optimized" } } */
+
+int g(void);
+int h(void);
+
+int
+f1 (int a)
+{
+ int t = 1 >> a;
+ if (t != 0) return g();
+ return h();
+}
+
+int
+f2 (int b)
+{
+ int t = 1 >> b;
+ t &= 1;
+ if (t != 0) return g();
+ return h();
+}
+
+int
+f3 (int c)
+{
+ int t = 1 >> c;
+ if (t == 0) return g();
+ return h();
+}
+
+int
+f4 (int d)
+{
+ int t = 1 >> d;
+ t &= 1;
+ if (t == 0) return g();
+ return h();
+}
--
2.31.1
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] MATCH: Transform `(1 >> X) !=/== 0` into `X ==/!= 0`
2023-09-03 16:25 [PATCH] MATCH: Transform `(1 >> X) !=/== 0` into `X ==/!= 0` Andrew Pinski
@ 2023-09-05 7:12 ` Jeff Law
0 siblings, 0 replies; 2+ messages in thread
From: Jeff Law @ 2023-09-05 7:12 UTC (permalink / raw)
To: Andrew Pinski, gcc-patches
On 9/3/23 10:25, Andrew Pinski via Gcc-patches wrote:
> We currently have a pattern for handling `(C >> X) & D == 0`
> but if C is 1 and D is 1, the `& 1` might have been removed.
>
> gcc/ChangeLog:
>
> PR tree-optimization/105832
> * match.pd (`(1 >> X) != 0`): New pattern
OK
jeff
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2023-09-05 7:12 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-03 16:25 [PATCH] MATCH: Transform `(1 >> X) !=/== 0` into `X ==/!= 0` Andrew Pinski
2023-09-05 7:12 ` Jeff Law
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).