re PR tree-optimization/92712 (Performance regression with assumed values)
authorJakub Jelinek <jakub@gcc.gnu.org>
Mon, 2 Dec 2019 08:51:49 +0000 (09:51 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 2 Dec 2019 08:51:49 +0000 (09:51 +0100)
PR tree-optimization/92712
* match.pd ((A * B) +- A -> (B +- 1) * A,
A +- (A * B) -> (1 +- B) * A): Allow optimizing signed integers
even when we don't know anything about range of A, but do know
something about range of B and the simplification won't introduce
new UB.

* gcc.dg/tree-ssa/pr92712-1.c: New test.
* gcc.dg/tree-ssa/pr92712-2.c: New test.
* gcc.dg/tree-ssa/pr92712-3.c: New test.
* gfortran.dg/loop_versioning_1.f90: Adjust expected number of
likely to be innermost dimension messages.
* gfortran.dg/loop_versioning_10.f90: Likewise.
* gfortran.dg/loop_versioning_6.f90: Likewise.

From-SVN: r278894

gcc/ChangeLog
gcc/match.pd
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr92712-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/pr92712-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/pr92712-3.c [new file with mode: 0644]
gcc/testsuite/gfortran.dg/loop_versioning_1.f90
gcc/testsuite/gfortran.dg/loop_versioning_10.f90
gcc/testsuite/gfortran.dg/loop_versioning_6.f90

index 0765ee2be1201be8d72fd7079cea43591a1ea4c1..9b3242115540412484060c829b6aea84bce33775 100644 (file)
@@ -1,4 +1,13 @@
-2019-12-02  Feng Xue <fxue@os.amperecomputing.com>
+2019-12-02  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/92712
+       * match.pd ((A * B) +- A -> (B +- 1) * A,
+       A +- (A * B) -> (1 +- B) * A): Allow optimizing signed integers
+       even when we don't know anything about range of A, but do know
+       something about range of B and the simplification won't introduce
+       new UB.
+
+2019-12-02  Feng Xue  <fxue@os.amperecomputing.com>
 
        PR ipa/92133
        * doc/invoke.texi (ipa-cp-max-recursive-depth): Document new option.
        (lto_free_file_name_hash): New function.
        * lto-streamer.h (lto_free_file_name_hash): New.
 
-2019-11-07  Feng Xue <fxue@os.amperecomputing.com>
+2019-11-07  Feng Xue  <fxue@os.amperecomputing.com>
 
        PR tree-optimization/89134
        * doc/invoke.texi (min-loop-cond-split-prob): Document new --params.
index eabd01fc115b5a64ea93441e1265d1675afd3d29..14f6a9d5078dcda4c244a14580f0293987f046cc 100644 (file)
@@ -2480,18 +2480,42 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
     (plusminus @0 (mult:c@3 @0 @2))
     (if ((!ANY_INTEGRAL_TYPE_P (type)
          || TYPE_OVERFLOW_WRAPS (type)
+         /* For @0 + @0*@2 this transformation would introduce UB
+            (where there was none before) for @0 in [-1,0] and @2 max.
+            For @0 - @0*@2 this transformation would introduce UB
+            for @0 0 and @2 in [min,min+1] or @0 -1 and @2 min+1.  */
          || (INTEGRAL_TYPE_P (type)
-             && tree_expr_nonzero_p (@0)
-             && expr_not_equal_to (@0, wi::minus_one (TYPE_PRECISION (type)))))
+             && ((tree_expr_nonzero_p (@0)
+                  && expr_not_equal_to (@0,
+                               wi::minus_one (TYPE_PRECISION (type))))
+                 || (plusminus == PLUS_EXPR
+                     ? expr_not_equal_to (@2,
+                           wi::max_value (TYPE_PRECISION (type), SIGNED))
+                     /* Let's ignore the @0 -1 and @2 min case.  */
+                     : (expr_not_equal_to (@2,
+                           wi::min_value (TYPE_PRECISION (type), SIGNED))
+                        && expr_not_equal_to (@2,
+                               wi::min_value (TYPE_PRECISION (type), SIGNED)
+                               + 1))))))
         && single_use (@3))
      (mult (plusminus { build_one_cst (type); } @2) @0)))
    (simplify
     (plusminus (mult:c@3 @0 @2) @0)
     (if ((!ANY_INTEGRAL_TYPE_P (type)
          || TYPE_OVERFLOW_WRAPS (type)
+         /* For @0*@2 + @0 this transformation would introduce UB
+            (where there was none before) for @0 in [-1,0] and @2 max.
+            For @0*@2 - @0 this transformation would introduce UB
+            for @0 0 and @2 min.  */
          || (INTEGRAL_TYPE_P (type)
-             && tree_expr_nonzero_p (@0)
-             && expr_not_equal_to (@0, wi::minus_one (TYPE_PRECISION (type)))))
+             && ((tree_expr_nonzero_p (@0)
+                  && (plusminus == MINUS_EXPR
+                      || expr_not_equal_to (@0,
+                               wi::minus_one (TYPE_PRECISION (type)))))
+                 || expr_not_equal_to (@2,
+                       (plusminus == PLUS_EXPR
+                        ? wi::max_value (TYPE_PRECISION (type), SIGNED)
+                        : wi::min_value (TYPE_PRECISION (type), SIGNED))))))
         && single_use (@3))
      (mult (plusminus @2 { build_one_cst (type); }) @0))))))
 
index bb36544cfe4383d0f3cb16997190e71600a847db..12abe735bbf855ace983d383e07afedb7d342e7b 100644 (file)
@@ -1,3 +1,14 @@
+2019-12-02  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/92712
+       * gcc.dg/tree-ssa/pr92712-1.c: New test.
+       * gcc.dg/tree-ssa/pr92712-2.c: New test.
+       * gcc.dg/tree-ssa/pr92712-3.c: New test.
+       * gfortran.dg/loop_versioning_1.f90: Adjust expected number of
+       likely to be innermost dimension messages.
+       * gfortran.dg/loop_versioning_10.f90: Likewise.
+       * gfortran.dg/loop_versioning_6.f90: Likewise.
+
 2019-12-02  Feng Xue  <fxue@os.amperecomputing.com>
 
        PR ipa/92133
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr92712-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr92712-1.c
new file mode 100644 (file)
index 0000000..c19ff5c
--- /dev/null
@@ -0,0 +1,21 @@
+/* PR tree-optimization/92712 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump " = \[tv]_\[0-9]*\\\(D\\\) \\* \[tv]_\[0-9]*\\\(D\\\);" "optimized" } } */
+
+static int
+foo (int t, int v)
+{
+  int i, x = 0;
+  for (int i = 0; i < t; ++i)
+    x += v;
+  return x;
+}
+
+int
+bar (int t, int v)
+{
+  if (t < 0)
+    __builtin_unreachable ();
+  return foo (t, v);
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr92712-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr92712-2.c
new file mode 100644 (file)
index 0000000..2710ff3
--- /dev/null
@@ -0,0 +1,66 @@
+/* PR tree-optimization/92712 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-ipa-icf -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times " = \[tv]_\[0-9]*\\\(D\\\) \\* \[tv]_\[0-9]*\\\(D\\\);" 7 "optimized" } } */
+
+int
+f1 (int t, int v)
+{
+  int a = t - 1;
+  int b = a * v;
+  return b + v;
+}
+
+int
+f2 (int t, int v)
+{
+  int a = t - 1;
+  int b = a * v;
+  return v + b;
+}
+
+int
+f3 (int t, int v)
+{
+  int a = t + 1;
+  int b = a * v;
+  return b - v;
+}
+
+int
+f4 (int t, int v)
+{
+  int a = 1 - t;
+  int b = a * v;
+  return v - b;
+}
+
+int
+f5 (int t, int v)
+{
+  if (v == 0 || v == -1)
+    __builtin_unreachable ();
+  int a = t - 1U;
+  int b = a * v;
+  return b + v;
+}
+
+int
+f6 (int t, int v)
+{
+  if (v == 0 || v == -1)
+    __builtin_unreachable ();
+  int a = t - 1U;
+  int b = a * v;
+  return v + b;
+}
+
+int
+f7 (int t, int v)
+{
+  if (v == 0)
+    __builtin_unreachable ();
+  int a = t + 1U;
+  int b = a * v;
+  return b - v;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr92712-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr92712-3.c
new file mode 100644 (file)
index 0000000..27749a1
--- /dev/null
@@ -0,0 +1,36 @@
+/* PR tree-optimization/92712 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-ipa-icf -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-not " = \[tv]_\[0-9]*\\\(D\\\) \\* \[tv]_\[0-9]*\\\(D\\\);" "optimized" } } */
+
+int
+f1 (int t, int v)
+{
+  int a = t - 1U;
+  int b = a * v;
+  return b + v;
+}
+
+int
+f2 (int t, int v)
+{
+  int a = t - 1U;
+  int b = a * v;
+  return v + b;
+}
+
+int
+f3 (int t, int v)
+{
+  int a = t + 1U;
+  int b = a * v;
+  return b - v;
+}
+
+int
+f4 (int t, int v)
+{
+  int a = 1U - t;
+  int b = a * v;
+  return v - b;
+}
index 144a193d70885f838e1c234bde2a69fb49c174f9..e80f8920d00c72feeca0b36e8e97691a57c35852 100644 (file)
@@ -23,6 +23,6 @@ subroutine f3(x, limit, step)
   end do
 end subroutine f3
 
-! { dg-final { scan-tree-dump-times {likely to be the innermost dimension} 2 "lversion" } }
+! { dg-final { scan-tree-dump-times {likely to be the innermost dimension} 1 "lversion" } }
 ! { dg-final { scan-tree-dump-times {want to version containing loop} 3 "lversion" } }
 ! { dg-final { scan-tree-dump-times {versioned this loop} 3 "lversion" } }
index 5803527bb3c19b170cb9a46616b1c55693dd9f4a..3d921d6c993ab92e442357d30ed71c9e7ec574b3 100644 (file)
@@ -26,6 +26,6 @@ subroutine f4(x, i)
   end do
 end subroutine f4
 
-! { dg-final { scan-tree-dump-times {likely to be the innermost dimension} 6 "lversion" } }
+! { dg-final { scan-tree-dump-times {likely to be the innermost dimension} 4 "lversion" } }
 ! { dg-final { scan-tree-dump-times {want to version} 4 "lversion" } }
 ! { dg-final { scan-tree-dump-times {versioned} 4 "lversion" } }
index 450a79c1fdfc4da379518c9d6718ecc62bc22272..163d225cb4905d808e41b1a7492246e4afa1b0ab 100644 (file)
@@ -89,5 +89,7 @@ subroutine f9(x, limit, step)
   end do
 end subroutine f9
 
-! { dg-final { scan-tree-dump-times {want to version containing loop} 9 "lversion" } }
-! { dg-final { scan-tree-dump-times {versioned this loop} 9 "lversion" } }
+! { dg-final { scan-tree-dump-times {want to version containing loop} 9 "lversion" { target lp64 } } }
+! { dg-final { scan-tree-dump-times {versioned this loop} 9 "lversion" { target lp64 } } }
+! { dg-final { scan-tree-dump-times {want to version containing loop} 8 "lversion" { target { ! lp64 } } } }
+! { dg-final { scan-tree-dump-times {versioned this loop} 8 "lversion" { target { ! lp64 } } } }