match.pd: Optimize ~(X >> Y) to ~X >> Y if ~X can be simplified [PR96688]
authorJakub Jelinek <jakub@redhat.com>
Thu, 14 Jan 2021 11:50:33 +0000 (12:50 +0100)
committerJakub Jelinek <jakub@redhat.com>
Thu, 14 Jan 2021 11:50:33 +0000 (12:50 +0100)
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.

gcc/match.pd
gcc/testsuite/gcc.dg/tree-ssa/pr96688.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/reassoc-37.c
gcc/testsuite/gcc.target/i386/pr66821.c

index 6f7b41fe0ff16fb657c565f659ebde061ecf3382..f08ab674a7064ddb41e73e42c9428ef2bd0c2ca1 100644 (file)
@@ -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 (file)
index 0000000..acaa0f6
--- /dev/null
@@ -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);
+}
index 624b2a857ec308c2e26a8d83a49a329214797b98..948fa3b83517d2681fc41adc160362ce23339103 100644 (file)
@@ -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-*-* } } } */
index a04e86292f4ef5ff7fc119eb3bc1ac7e1b5e8d55..4195e75e06d4ee678003210ac7582fa78dec0692 100644 (file)
@@ -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" } } */