diff options
author | Andrew Pinski <apinski@marvell.com> | 2023-08-22 18:41:56 -0700 |
---|---|---|
committer | Andrew Pinski <apinski@marvell.com> | 2023-08-23 23:52:25 -0700 |
commit | ddd64a6ec3b38e18aefb9fcba50c0d9297e5e711 (patch) | |
tree | ac4cf56bde5bfabf623576c3289dcc91a86f995b | |
parent | 7e05cd632fab458717af4d4431c9f7e43ad062ad (diff) | |
download | gcc-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.pd | 12 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/bit1neg-1.c | 23 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/cond-bool-1.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/cond-bool-2.c | 26 |
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" } } */ |