aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2021-01-14 12:50:33 +0100
committerJakub Jelinek <jakub@redhat.com>2021-01-14 12:50:33 +0100
commit8f8762a2e8659c1db802ba001869085c1915498f (patch)
treeca73185066382b0e83e9d96cb388dd6cad1af760 /gcc
parente45c41988bfd655b1df7cff8fcf111dc6fb732e3 (diff)
downloadgcc-8f8762a2e8659c1db802ba001869085c1915498f.zip
gcc-8f8762a2e8659c1db802ba001869085c1915498f.tar.gz
gcc-8f8762a2e8659c1db802ba001869085c1915498f.tar.bz2
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 <jakub@redhat.com> 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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/match.pd12
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr96688.c24
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/reassoc-37.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr66821.c2
4 files changed, 38 insertions, 2 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index 6f7b41f..f08ab67 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 0000000..acaa0f6
--- /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 624b2a8..948fa3b 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 a04e862..4195e75 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" } } */