From 8f8762a2e8659c1db802ba001869085c1915498f Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 14 Jan 2021 12:50:33 +0100 Subject: [PATCH] match.pd: Optimize ~(X >> Y) to ~X >> Y if ~X can be simplified [PR96688] This patch optimizes two GIMPLE operations into just one. As mentioned in the PR, there is some risk this might create more expensive constants, but sometimes it will make them on the other side less expensive, it really depends on the exact value. And if it is an important issue, we should do it in md or during expansion. 2021-01-14 Jakub Jelinek PR tree-optimization/96688 * match.pd (~(X >> Y) -> ~X >> Y): New simplification if ~X can be simplified. * gcc.dg/tree-ssa/pr96688.c: New test. * gcc.dg/tree-ssa/reassoc-37.c: Adjust scan-tree-dump regex. * gcc.target/i386/pr66821.c: Likewise. --- gcc/match.pd | 12 +++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr96688.c | 24 ++++++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/reassoc-37.c | 2 +- gcc/testsuite/gcc.target/i386/pr66821.c | 2 +- 4 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr96688.c diff --git a/gcc/match.pd b/gcc/match.pd index 6f7b41fe0ff..f08ab674a70 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1119,6 +1119,18 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && wi::to_wide (@1) != wi::min_value (TYPE_PRECISION (type), SIGNED)) (minus (plus @1 { build_minus_one_cst (type); }) @0)))) + +/* ~(X >> Y) -> ~X >> Y if ~X can be simplified. */ +(simplify + (bit_not (rshift:s @0 @1)) + (if (!TYPE_UNSIGNED (TREE_TYPE (@0))) + (rshift (bit_not! @0) @1) + /* For logical right shifts, this is possible only if @0 doesn't + have MSB set and the logical right shift is changed into + arithmetic shift. */ + (if (!wi::neg_p (tree_nonzero_bits (@0))) + (with { tree stype = signed_type_for (TREE_TYPE (@0)); } + (convert (rshift (bit_not! (convert:stype @0)) @1)))))) #endif /* x + (x & 1) -> (x + 1) & ~1 */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96688.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96688.c new file mode 100644 index 00000000000..acaa0f691c2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96688.c @@ -0,0 +1,24 @@ +/* PR tree-optimization/96688 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times " = -124 >> " 2 "optimized" } } */ +/* { dg-final { scan-tree-dump-times " >> " 3 "optimized" } } */ +/* { dg-final { scan-tree-dump-times " = ~" 1 "optimized" } } */ + +int +foo (int x) +{ + return ~(123 >> x); +} + +unsigned +bar (int x) +{ + return ~(123U >> x); +} + +unsigned +baz (int x) +{ + return ~(~123U >> x); +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-37.c b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-37.c index 624b2a857ec..948fa3b8351 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-37.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-37.c @@ -12,5 +12,5 @@ foo (int x) } /* Check if the tests have been folded into a bit test. */ -/* { dg-final { scan-tree-dump "(8784908|0x0*860c0c)" "optimized" { target i?86-*-* x86_64-*-* } } } */ +/* { dg-final { scan-tree-dump "(8784908|-8784909|0x0*860c0c)" "optimized" { target i?86-*-* x86_64-*-* } } } */ /* { dg-final { scan-tree-dump "(<<|>>)" "optimized" { target i?86-*-* x86_64-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr66821.c b/gcc/testsuite/gcc.target/i386/pr66821.c index a04e86292f4..4195e75e06d 100644 --- a/gcc/testsuite/gcc.target/i386/pr66821.c +++ b/gcc/testsuite/gcc.target/i386/pr66821.c @@ -11,5 +11,5 @@ foo (int x) } /* Check if the tests have been folded into a bit test. */ -/* { dg-final { scan-tree-dump "(8784908|0x0*860c0c)" "optimized" } } */ +/* { dg-final { scan-tree-dump "(8784908|-8784909|0x0*860c0c)" "optimized" } } */ /* { dg-final { scan-tree-dump "(<<|>>)" "optimized" } } */ -- 2.30.2