On 29/06/15 19:58, Jeff Law wrote:
On 06/29/2015 08:24 AM, Tom de Vries wrote:
Hi,
this patch fixes PR66652.
It uses max_loop_iterations in transform_to_exit_first_loop_alt to
ensure that the new loop bound nit + 1 doesn't overflow.
Bootstrapped and reg-tested on x86_64.
OK for trunk?
Thanks,
- Tom
0001-Use-max_loop_iterations-in-transform_to_exit_first_l.patch
Use max_loop_iterations in transform_to_exit_first_loop_alt
2015-06-29 Tom de Vries<t...@codesourcery.com>
PR tree-optimization/66652
* tree-parloops.c (try_transform_to_exit_first_loop_alt): Use
max_loop_iterations to determine if nit + 1 overflows.
* testsuite/libgomp.c/parloops-exit-first-loop-alt-3.c (f): Rewrite
using restrict pointers.
(main): Add arguments to calls to f.
* testsuite/libgomp.c/parloops-exit-first-loop-alt.c: Same.
* gcc.dg/parloops-exit-first-loop-alt-pr66652.c: New test.
* gcc.dg/parloops-exit-first-loop-alt-3.c (f): Rewrite using
restrict
pointers.
* gcc.dg/parloops-exit-first-loop-alt.c: Same.
OK.
Make sure to put the PR marker in the testsuite/ChangeLog entry
True, I abbreviate it in the log, but my commit script (
https://github.com/vries/bin-scripts/blob/master/git-prepare-gnu-commit.sh
) applies the PR line to all the ChangeLog hunks.
and drop
the testsuite/ prefix in the testsuite/ChangeLog entry.
The testsuite/ prefix is used because the it's for the ChangeLog in dir
libgomp.
Committed as attached:
- fixed typo in comment
- updated test-case modifications to be applicable on trunk (given that
there's no approval yet for the fix for PR66642, see
https://gcc.gnu.org/ml/gcc-patches/2015-06/msg01768.html)
- included ChangeLog file changes, given the ChangeLog questions.
Thanks,
- Tom
Use max_loop_iterations in transform_to_exit_first_loop_alt
2015-06-30 Tom de Vries <t...@codesourcery.com>
PR tree-optimization/66652
* tree-parloops.c (try_transform_to_exit_first_loop_alt): Use
max_loop_iterations to determine if nit + 1 overflows.
* testsuite/libgomp.c/parloops-exit-first-loop-alt-3.c (f): Rewrite
using restrict pointers.
(main): Add arguments to calls to f.
* testsuite/libgomp.c/parloops-exit-first-loop-alt.c: Same.
* gcc.dg/parloops-exit-first-loop-alt-pr66652.c: New test.
* gcc.dg/parloops-exit-first-loop-alt-3.c (f): Rewrite using restrict
pointers.
* gcc.dg/parloops-exit-first-loop-alt.c: Same.
---
gcc/ChangeLog | 6 +++++
gcc/testsuite/ChangeLog | 8 ++++++
.../gcc.dg/parloops-exit-first-loop-alt-3.c | 2 +-
.../gcc.dg/parloops-exit-first-loop-alt-pr66652.c | 31 ++++++++++++++++++++++
.../gcc.dg/parloops-exit-first-loop-alt.c | 19 +++++--------
gcc/tree-parloops.c | 31 ++++++++++++++++++++++
libgomp/ChangeLog | 8 ++++++
.../libgomp.c/parloops-exit-first-loop-alt-3.c | 4 +--
.../libgomp.c/parloops-exit-first-loop-alt.c | 5 ++--
9 files changed, 97 insertions(+), 17 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-pr66652.c
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 96f4f8d..1940d04 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2015-06-30 Tom de Vries <t...@codesourcery.com>
+
+ PR tree-optimization/66652
+ * tree-parloops.c (try_transform_to_exit_first_loop_alt): Use
+ max_loop_iterations to determine if nit + 1 overflows.
+
2015-06-30 Bin Cheng <bin.ch...@arm.com>
* tree-ssa-loop-ivopts.c (record_sub_use): Don't reset ssa_name
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9c2f20b..f249a7d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2015-06-30 Tom de Vries <t...@codesourcery.com>
+
+ PR tree-optimization/66652
+ * gcc.dg/parloops-exit-first-loop-alt-pr66652.c: New test.
+ * gcc.dg/parloops-exit-first-loop-alt-3.c (f): Rewrite using restrict
+ pointers.
+ * gcc.dg/parloops-exit-first-loop-alt.c: Same.
+
2015-06-29 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/65977
diff --git a/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-3.c b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-3.c
index b0fde37..fec53a1 100644
--- a/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-3.c
+++ b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-3.c
@@ -7,7 +7,7 @@
unsigned int *a;
unsigned int
-f (unsigned int n)
+f (unsigned int n, unsigned int *__restrict__ a)
{
int i;
unsigned int sum = 1;
diff --git a/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-pr66652.c b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-pr66652.c
new file mode 100644
index 0000000..2ea097d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-pr66652.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target pthread } */
+/* { dg-options "-O2 -ftree-parallelize-loops=2 -fdump-tree-parloops" } */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+unsigned int
+f (unsigned int n, unsigned int sum)
+{
+ unsigned int i;
+
+ i = UINT_MAX;
+ do
+ {
+ sum += i % 13;
+ i++;
+ }
+ while (i < n - 1);
+
+ return sum;
+}
+
+/* Four times % 13:
+ - once in f._loopfn.0
+ - once in the parallel
+ - once in the low iteration count loop
+ - once for a peeled off last iteration following the parallel.
+ In other words, we want try_transform_to_exit_first_loop_alt to fail. */
+/* { dg-final { scan-tree-dump-times "(?n)% 13" 4 "parloops" } } */
diff --git a/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt.c b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt.c
index b36f01b..e088fa1 100644
--- a/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt.c
+++ b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt.c
@@ -4,14 +4,9 @@
/* Variable bound, vector addition. */
-#define N 1000
-
-unsigned int a[N];
-unsigned int b[N];
-unsigned int c[N];
-
void
-f (unsigned int n)
+f (unsigned int n, unsigned int *__restrict__ a, unsigned int *__restrict__ b,
+ unsigned int *__restrict__ c)
{
int i;
@@ -19,9 +14,9 @@ f (unsigned int n)
c[i] = a[i] + b[i];
}
-/* Three times three array accesses:
- - three in f._loopfn.0
- - three in the parallel
- - three in the low iteration count loop
+/* Three times a store:
+ - one in f._loopfn.0
+ - one in the parallel
+ - one in the low iteration count loop
Crucially, none for a peeled off last iteration following the parallel. */
-/* { dg-final { scan-tree-dump-times "(?n)\\\[i" 9 "parloops" } } */
+/* { dg-final { scan-tree-dump-times "(?n)^ \\*_\[0-9\]*" 3 "parloops" } } */
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index ec708c6..21ed17b 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -1801,8 +1801,39 @@ try_transform_to_exit_first_loop_alt (struct loop *loop,
gcc_assert (TREE_CODE (nit) == SSA_NAME);
+ /* Variable nit is the loop bound as returned by canonicalize_loop_ivs, for an
+ iv with base 0 and step 1 that is incremented in the latch, like this:
+
+ <bb header>:
+ # iv_1 = PHI <0 (preheader), iv_2 (latch)>
+ ...
+ if (iv_1 < nit)
+ goto <bb latch>;
+ else
+ goto <bb exit>;
+
+ <bb latch>:
+ iv_2 = iv_1 + 1;
+ goto <bb header>;
+
+ The range of iv_1 is [0, nit]. The latch edge is taken for
+ iv_1 == [0, nit - 1] and the exit edge is taken for iv_1 == nit. So the
+ number of latch executions is equal to nit.
+
+ The function max_loop_iterations gives us the maximum number of latch
+ executions, so it gives us the maximum value of nit. */
+ widest_int nit_max;
+ if (!max_loop_iterations (loop, &nit_max))
+ return false;
+
+ /* Check if nit + 1 overflows. */
+ widest_int type_max = wi::to_widest (TYPE_MAXVAL (nit_type));
+ if (!wi::lts_p (nit_max, type_max))
+ return false;
+
gimple def = SSA_NAME_DEF_STMT (nit);
+ /* Try to find nit + 1, in the form of n in an assignment nit = n - 1. */
if (def
&& is_gimple_assign (def)
&& gimple_assign_rhs_code (def) == PLUS_EXPR)
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index a01f9b2..2c539b8 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,11 @@
+2015-06-30 Tom de Vries <t...@codesourcery.com>
+
+ PR tree-optimization/66652
+ * testsuite/libgomp.c/parloops-exit-first-loop-alt-3.c (f): Rewrite
+ using restrict pointers.
+ (main): Add arguments to calls to f.
+ * testsuite/libgomp.c/parloops-exit-first-loop-alt.c: Same.
+
2015-06-23 Andreas Tobler <andre...@gcc.gnu.org>
* configure.ac: Fix check for header <sys/sysctl.h>.
diff --git a/libgomp/testsuite/libgomp.c/parloops-exit-first-loop-alt-3.c b/libgomp/testsuite/libgomp.c/parloops-exit-first-loop-alt-3.c
index cb5bf9c..7de1377 100644
--- a/libgomp/testsuite/libgomp.c/parloops-exit-first-loop-alt-3.c
+++ b/libgomp/testsuite/libgomp.c/parloops-exit-first-loop-alt-3.c
@@ -10,7 +10,7 @@
unsigned int *a;
unsigned int __attribute__((noclone,noinline))
-f (unsigned int n)
+f (unsigned int n, unsigned int *__restrict__ a)
{
int i;
unsigned int sum = 1;
@@ -32,7 +32,7 @@ main (void)
array[i] = i % 7;
a = &array[0];
- res = f (N);
+ res = f (N, a);
if (res != 11995)
abort ();
diff --git a/libgomp/testsuite/libgomp.c/parloops-exit-first-loop-alt.c b/libgomp/testsuite/libgomp.c/parloops-exit-first-loop-alt.c
index 1c32ea3..07468a9 100644
--- a/libgomp/testsuite/libgomp.c/parloops-exit-first-loop-alt.c
+++ b/libgomp/testsuite/libgomp.c/parloops-exit-first-loop-alt.c
@@ -13,7 +13,8 @@ unsigned int b[N];
unsigned int c[N];
void __attribute__((noclone,noinline))
-f (unsigned int n)
+f (unsigned int n, unsigned int *__restrict__ a, unsigned int *__restrict__ b,
+ unsigned int *__restrict__ c)
{
int i;
@@ -36,7 +37,7 @@ main (void)
c[k] = k * 2;
}
- f (N);
+ f (N, a, b, c);
for (i = 0; i < N; i++)
{
--
1.9.1