re PR tree-optimization/92734 (Missing match.pd simplification done by fold_binary_lo...
authorJakub Jelinek <jakub@redhat.com>
Tue, 3 Dec 2019 09:20:43 +0000 (10:20 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 3 Dec 2019 09:20:43 +0000 (10:20 +0100)
PR tree-optimization/92734
* match.pd ((CST1 - A) +- CST2 -> CST3 - A,
CST1 - (CST2 - A) -> CST3 + A): Handle nop casts around
inner subtraction.

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

From-SVN: r278925

gcc/ChangeLog
gcc/match.pd
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr92734.c [new file with mode: 0644]

index a89c4352aa324af6219749669b6fbbf87dc36df1..68d1c288c514a02e2c99f1b44969118cb060dd71 100644 (file)
@@ -1,3 +1,10 @@
+2019-12-03  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/92734
+       * match.pd ((CST1 - A) +- CST2 -> CST3 - A,
+       CST1 - (CST2 - A) -> CST3 + A): Handle nop casts around
+       inner subtraction.
+
 2019-12-03  Uroš Bizjak  <ubizjak@gmail.com>
            Jakub Jelinek  <jakub@redhat.com>
 
index 14f6a9d5078dcda4c244a14580f0293987f046cc..d3312e5f27973dae36d5a5e01093232078ad8220 100644 (file)
@@ -2237,17 +2237,39 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   /* (CST1 - A) +- CST2 -> CST3 - A  */
   (for outer_op (plus minus)
    (simplify
-    (outer_op (minus CONSTANT_CLASS_P@1 @0) CONSTANT_CLASS_P@2)
-    (with { tree cst = const_binop (outer_op, type, @1, @2); }
-     (if (cst && !TREE_OVERFLOW (cst))
-      (minus { cst; } @0)))))
-
-  /* CST1 - (CST2 - A) -> CST3 + A  */
+    (outer_op (nop_convert (minus CONSTANT_CLASS_P@1 @0)) CONSTANT_CLASS_P@2)
+    /* If one of the types wraps, use that one.  */
+    (if (!ANY_INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_WRAPS (type))
+     /* If all 3 captures are CONSTANT_CLASS_P, punt, as we might recurse
+       forever if something doesn't simplify into a constant.  */
+     (if (!CONSTANT_CLASS_P (@0))
+      (minus (outer_op (view_convert @1) @2) (view_convert @0)))
+     (if (!ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+         || TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
+      (view_convert (minus (outer_op @1 (view_convert @2)) @0))
+      (if (types_match (type, @0))
+       (with { tree cst = const_binop (outer_op, type, @1, @2); }
+       (if (cst && !TREE_OVERFLOW (cst))
+        (minus { cst; } @0))))))))
+
+  /* CST1 - (CST2 - A) -> CST3 + A
+     Use view_convert because it is safe for vectors and equivalent for
+     scalars.  */
   (simplify
-   (minus CONSTANT_CLASS_P@1 (minus CONSTANT_CLASS_P@2 @0))
-   (with { tree cst = const_binop (MINUS_EXPR, type, @1, @2); }
-    (if (cst && !TREE_OVERFLOW (cst))
-     (plus { cst; } @0))))
+   (minus CONSTANT_CLASS_P@1 (nop_convert (minus CONSTANT_CLASS_P@2 @0)))
+   /* If one of the types wraps, use that one.  */
+   (if (!ANY_INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_WRAPS (type))
+    /* If all 3 captures are CONSTANT_CLASS_P, punt, as we might recurse
+      forever if something doesn't simplify into a constant.  */
+    (if (!CONSTANT_CLASS_P (@0))
+     (plus (view_convert @0) (minus @1 (view_convert @2))))
+    (if (!ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+        || TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
+     (view_convert (plus @0 (minus (view_convert @1) @2)))
+     (if (types_match (type, @0))
+      (with { tree cst = const_binop (MINUS_EXPR, type, @1, @2); }
+       (if (cst && !TREE_OVERFLOW (cst))
+       (plus { cst; } @0)))))))
 
 /* ((T)(A)) + CST -> (T)(A + CST)  */
 #if GIMPLE
index 2d8c350d57574f297a9167b084b79525901766e8..07193065f7d4d749347606ebf25cd1ed767b070d 100644 (file)
@@ -1,5 +1,8 @@
 2019-12-03  Jakub Jelinek  <jakub@redhat.com>
 
+       PR tree-optimization/92734
+       * gcc.dg/tree-ssa/pr92734.c: New test.
+
        PR target/92744
        * g++.dg/dfp/pr92744.C: New test.
 
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr92734.c b/gcc/testsuite/gcc.dg/tree-ssa/pr92734.c
new file mode 100644 (file)
index 0000000..2921bb4
--- /dev/null
@@ -0,0 +1,31 @@
+/* PR tree-optimization/92734 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-forwprop1" } */
+/* { dg-final { scan-tree-dump-times "return t_\[0-9]*\\\(D\\\);" 4 "forwprop1" } } */
+
+int
+f1 (int t)
+{
+  return 1 - (int) (1U - t);
+}
+
+int
+f2 (int t)
+{
+  int a = 7U - t;
+  return 7 - a;
+}
+
+int
+f3 (int t)
+{
+  int a = 32U - t;
+  return 32 - a;
+}
+
+int
+f4 (int t)
+{
+  int a = 32 - t;
+  return (int) (32 - (unsigned) a);
+}