[PATCH] match.pd: Optimize ~(X >> Y) to ~X >> Y if ~X can be simplified [PR96688]

Jakub Jelinek jakub@redhat.com
Thu Jan 14 09:09:38 GMT 2021


Hi!

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.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2021-01-13  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.jj	2021-01-13 15:27:13.843788907 +0100
+++ gcc/match.pd	2021-01-13 18:01:09.706568135 +0100
@@ -1109,6 +1109,18 @@ (define_operator_list COND_TERNARY
 	&& 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 */
--- gcc/testsuite/gcc.dg/tree-ssa/pr96688.c.jj	2021-01-13 19:12:26.396363212 +0100
+++ gcc/testsuite/gcc.dg/tree-ssa/pr96688.c	2021-01-13 19:13:32.146628538 +0100
@@ -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);
+}
--- gcc/testsuite/gcc.dg/tree-ssa/reassoc-37.c.jj	2020-01-12 11:54:37.609395365 +0100
+++ gcc/testsuite/gcc.dg/tree-ssa/reassoc-37.c	2021-01-14 10:04:03.100243196 +0100
@@ -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-*-* } } } */
--- gcc/testsuite/gcc.target/i386/pr66821.c.jj	2020-01-12 11:54:37.969389933 +0100
+++ gcc/testsuite/gcc.target/i386/pr66821.c	2021-01-14 10:04:41.210807013 +0100
@@ -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" } } */

	Jakub



More information about the Gcc-patches mailing list