aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2019-12-02 08:51:49 +0000
committerJakub Jelinek <jakub@redhat.com>2019-12-02 08:51:49 +0000
commit02e688f0e850db35366a26a525e2876f93ffafd6 (patch)
tree39451dd44a61601d97dcf6462ceede232af61ca9
parente1e48f0146c6ef6d839702cf59961c5a48333947 (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@278894 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/match.pd32
-rw-r--r--gcc/testsuite/ChangeLog11
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr92712-1.c21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr92712-2.c66
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr92712-3.c36
-rw-r--r--gcc/testsuite/gfortran.dg/loop_versioning_1.f902
-rw-r--r--gcc/testsuite/gfortran.dg/loop_versioning_10.f902
-rw-r--r--gcc/testsuite/gfortran.dg/loop_versioning_6.f906
9 files changed, 179 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0765ee2be12..9b324211554 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
@@ -4543,7 +4552,7 @@
(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.
diff --git a/gcc/match.pd b/gcc/match.pd
index eabd01fc115..14f6a9d5078 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -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))))))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index bb36544cfe4..12abe735bbf 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..c19ff5cf29c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr92712-1.c
@@ -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
index 00000000000..2710ff36cc1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr92712-2.c
@@ -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
index 00000000000..27749a125a7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr92712-3.c
@@ -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;
+}
diff --git a/gcc/testsuite/gfortran.dg/loop_versioning_1.f90 b/gcc/testsuite/gfortran.dg/loop_versioning_1.f90
index 144a193d708..e80f8920d00 100644
--- a/gcc/testsuite/gfortran.dg/loop_versioning_1.f90
+++ b/gcc/testsuite/gfortran.dg/loop_versioning_1.f90
@@ -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" } }
diff --git a/gcc/testsuite/gfortran.dg/loop_versioning_10.f90 b/gcc/testsuite/gfortran.dg/loop_versioning_10.f90
index 5803527bb3c..3d921d6c993 100644
--- a/gcc/testsuite/gfortran.dg/loop_versioning_10.f90
+++ b/gcc/testsuite/gfortran.dg/loop_versioning_10.f90
@@ -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" } }
diff --git a/gcc/testsuite/gfortran.dg/loop_versioning_6.f90 b/gcc/testsuite/gfortran.dg/loop_versioning_6.f90
index 450a79c1fdf..163d225cb49 100644
--- a/gcc/testsuite/gfortran.dg/loop_versioning_6.f90
+++ b/gcc/testsuite/gfortran.dg/loop_versioning_6.f90
@@ -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 } } } }