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  <ja...@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

Reply via email to