Hi!

The following optimizations also can't handle nop conversions between the
inner and outer addition/subtraction, and even -fwrapv doesn't help there,
only simplify-rtx.c is able to do something about those.

Implemented thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
ok for trunk?

2019-12-04  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/92734
        * match.pd ((A +- B) - A -> +- B, (A +- B) -+ B -> A,
        A - (A +- B) -> -+ B, A +- (B -+ A) -> +- B): Handle nop_convert.

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

--- gcc/match.pd.jj     2019-12-03 10:20:00.244913801 +0100
+++ gcc/match.pd        2019-12-03 13:36:01.084435697 +0100
@@ -2159,20 +2159,26 @@ (define_operator_list COND_TERNARY
   /* A - (A +- B)       -> -+ B */
   /* A +- (B -+ A)      ->  +- B */
   (simplify
-    (minus (plus:c @0 @1) @0)
-    @1)
+   (minus (nop_convert (plus:c (nop_convert @0) @1)) @0)
+   (view_convert @1))
   (simplify
-    (minus (minus @0 @1) @0)
-    (negate @1))
+   (minus (nop_convert (minus (nop_convert @0) @1)) @0)
+   (if (!ANY_INTEGRAL_TYPE_P (type)
+       || TYPE_OVERFLOW_WRAPS (type))
+   (negate (view_convert @1))
+   (view_convert (negate @1))))
   (simplify
-    (plus:c (minus @0 @1) @1)
-    @0)
+   (plus:c (nop_convert (minus @0 (nop_convert @1))) @1)
+   (view_convert @0))
   (simplify
-   (minus @0 (plus:c @0 @1))
-   (negate @1))
+   (minus @0 (nop_convert (plus:c (nop_convert @0) @1)))
+    (if (!ANY_INTEGRAL_TYPE_P (type)
+        || TYPE_OVERFLOW_WRAPS (type))
+     (negate (view_convert @1))
+     (view_convert (negate @1))))
   (simplify
-   (minus @0 (minus @0 @1))
-   @1)
+   (minus @0 (nop_convert (minus (nop_convert @0) @1)))
+   (view_convert @1))
   /* (A +- B) + (C - A)   -> C +- B */
   /* (A +  B) - (A - C)   -> B + C */
   /* More cases are handled with comparisons.  */
--- gcc/testsuite/gcc.dg/tree-ssa/pr92734-2.c.jj        2019-12-03 
13:56:05.036800119 +0100
+++ gcc/testsuite/gcc.dg/tree-ssa/pr92734-2.c   2019-12-03 13:55:43.035140773 
+0100
@@ -0,0 +1,76 @@
+/* PR tree-optimization/92734 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* Verify there are no binary additions or subtractions left.  There can
+   be just casts and negations.  */
+/* { dg-final { scan-tree-dump-not " \[+-] " "optimized" } } */
+
+int
+f1 (int x, unsigned y)
+{
+  int a = x + y;
+  return a - x;
+}
+
+unsigned
+f2 (unsigned x, int y)
+{
+  unsigned a = (int) x + y;
+  return a - x;
+}
+
+int
+f3 (int x, unsigned y)
+{
+  int a = x - y;
+  return a - x;
+}
+
+unsigned
+f4 (unsigned x, int y)
+{
+  unsigned a = (int) x - y;
+  return a - x;
+}
+
+int
+f5 (unsigned x, int y)
+{
+  int a = x - y;
+  return a + y;
+}
+
+unsigned
+f6 (int x, unsigned y)
+{
+  unsigned a = x - (int) y;
+  return a + y;
+}
+
+int
+f7 (int x, unsigned y)
+{
+  int a = x + y;
+  return x - a;
+}
+
+unsigned
+f8 (unsigned x, int y)
+{
+  unsigned a = (int) x + y;
+  return x - a;
+}
+
+int
+f9 (int x, unsigned y)
+{
+  int a = x - y;
+  return x - a;
+}
+
+unsigned
+f10 (unsigned x, int y)
+{
+  unsigned a = (int) x - y;
+  return x - a;
+}

        Jakub

Reply via email to