aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Pinski <apinski@marvell.com>2023-08-22 18:41:56 -0700
committerAndrew Pinski <apinski@marvell.com>2023-08-23 23:52:25 -0700
commitddd64a6ec3b38e18aefb9fcba50c0d9297e5e711 (patch)
treeac4cf56bde5bfabf623576c3289dcc91a86f995b
parent7e05cd632fab458717af4d4431c9f7e43ad062ad (diff)
downloadgcc-ddd64a6ec3b38e18aefb9fcba50c0d9297e5e711.zip
gcc-ddd64a6ec3b38e18aefb9fcba50c0d9297e5e711.tar.gz
gcc-ddd64a6ec3b38e18aefb9fcba50c0d9297e5e711.tar.bz2
MATCH: remove negate for 1bit types
For 1bit types, negate is either undefined or don't change the value. In either cases we want to remove them. This patch adds a match pattern to do that. Also converting to a 1bit type we can remove the negate just like we already do for `&1` so this patch adds that too. OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. Notes on the testcases: This patch is the last part to fix PR 95929; cond-bool-2.c testcase. bit1neg-1.c is a 1bit-field testcase where we could remove the assignment all the way in one case (which happened on the RTL level for some targets but not all). cond-bool-2.c is the reduced testcase of PR 95929. PR tree-optimization/95929 gcc/ChangeLog: * match.pd (convert?(-a)): New pattern for 1bit integer types. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/bit1neg-1.c: New test. * gcc.dg/tree-ssa/cond-bool-1.c: New test. * gcc.dg/tree-ssa/cond-bool-2.c: New test.
-rw-r--r--gcc/match.pd12
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/bit1neg-1.c23
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cond-bool-1.c21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cond-bool-2.c26
4 files changed, 82 insertions, 0 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index 6e08302..890f050 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -9082,6 +9082,18 @@ and,
(if (!TYPE_OVERFLOW_SANITIZED (type))
(bit_and @0 @1)))
+/* `-a` is just `a` if the type is 1bit wide or when converting
+ to a 1bit type; similar to the above transformation of `(-x)&1`.
+ This is used mostly with the transformation of
+ `a ? ~b : b` into `(-a)^b`.
+ It also can show up with bitfields. */
+(simplify
+ (convert? (negate @0))
+ (if (INTEGRAL_TYPE_P (type)
+ && TYPE_PRECISION (type) == 1
+ && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@0)))
+ (convert @0)))
+
/* Optimize
c1 = VEC_PERM_EXPR (a, a, mask)
c2 = VEC_PERM_EXPR (b, b, mask)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bit1neg-1.c b/gcc/testsuite/gcc.dg/tree-ssa/bit1neg-1.c
new file mode 100644
index 0000000..2f123fb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/bit1neg-1.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+struct f
+{
+ int a:1;
+};
+
+void g(struct f *a)
+{
+ int t = a->a;
+ t = -t;
+ a->a = t;
+}
+void g1(struct f *a, int b)
+{
+ int t = b;
+ t = -t;
+ a->a = t;
+}
+/* the 2 negates should have been removed as this is basically the same
+ as (-a) & 1. */
+/* { dg-final { scan-tree-dump-not " = -" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cond-bool-1.c b/gcc/testsuite/gcc.dg/tree-ssa/cond-bool-1.c
new file mode 100644
index 0000000..752a303
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cond-bool-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
+_Bool f1(int a, int b)
+{
+ _Bool _1 = b != 0;
+ _Bool _2 = a != 0;
+ _Bool _8 = a == 0;
+ _Bool _13;
+ if (_1) _13 = _8; else _13 = _2;
+ return _13;
+}
+
+/* We should be able to optimize this to (a != 0) ^ (b != 0) */
+/* There should be no negate_expr nor gimple_cond here. */
+
+/* { dg-final { scan-tree-dump-not "negate_expr, " "optimized" } } */
+/* { dg-final { scan-tree-dump-times "ne_expr, " 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-not "gimple_cond " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "gimple_phi " "optimized" } } */
+/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "gimple_assign " 3 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cond-bool-2.c b/gcc/testsuite/gcc.dg/tree-ssa/cond-bool-2.c
new file mode 100644
index 0000000..b3e7e25
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cond-bool-2.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
+
+/* PR tree-optimization/95929 */
+
+
+static inline _Bool nand(_Bool a, _Bool b)
+{
+ return !(a && b);
+}
+
+_Bool f(int a, int b)
+{
+ return nand(nand(b, nand(a, a)), nand(a, nand(b, b)));
+}
+
+/* We should be able to optimize this to (a != 0) ^ (b != 0) */
+/* There should be no negate_expr nor gimple_cond here. */
+
+/* { dg-final { scan-tree-dump-not "negate_expr, " "optimized" } } */
+/* { dg-final { scan-tree-dump-times "ne_expr, " 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-not "gimple_cond " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "cond_expr, " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "gimple_phi " "optimized" } } */
+/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "gimple_assign " 3 "optimized" } } */