[PATCH] match.pd: Optimize ~(~X +- Y) into (X -+ Y) [PR94921]

Jakub Jelinek jakub@redhat.com
Wed May 6 07:47:02 GMT 2020


Hi!

According to my verification proglet, this transformation for signed types
with undefined overflow doesn't introduce nor remove any UB cases, so should
be valid even for signed integral types.
Not using a for because of the :c on plus which can't be there on minus.

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

2020-05-06  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/94921
	* match.pd (~(~X - Y) -> X + Y, ~(~X + Y) -> X - Y): New
	simplifications.

	* gcc.dg/tree-ssa/pr94921.c: New test.

--- gcc/match.pd.jj	2020-05-05 11:36:17.510911674 +0200
+++ gcc/match.pd	2020-05-05 16:48:59.496883197 +0200
@@ -1010,6 +1010,14 @@ (define_operator_list COND_TERNARY
   @0))
 #endif
 
+/* ~(~X - Y) -> X + Y and ~(~X + Y) -> X - Y.  */
+(simplify
+ (bit_not (minus (bit_not @0) @1))
+ (plus @0 @1))
+(simplify
+ (bit_not (plus:c (bit_not @0) @1))
+ (minus @0 @1))
+
 /* x + (x & 1) -> (x + 1) & ~1 */
 (simplify
  (plus:c @0 (bit_and:s @0 integer_onep@1))
--- gcc/testsuite/gcc.dg/tree-ssa/pr94921.c.jj	2020-05-05 16:58:32.913192128 +0200
+++ gcc/testsuite/gcc.dg/tree-ssa/pr94921.c	2020-05-05 16:59:26.231384053 +0200
@@ -0,0 +1,18 @@
+/* PR tree-optimization/94921 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump " \[ab]_\[0-9]+\\\(D\\\) \\+ \[ab]_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump " c_\[0-9]+\\\(D\\\) - d_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-not " ~\[abcd]\?_\[0-9]\+" "optimized" } } */
+
+int
+foo (int a, int b)
+{
+  return ~(~a - b);
+}
+
+int
+bar (int c, int d)
+{
+  return ~(~c + d);
+}

	Jakub



More information about the Gcc-patches mailing list