diff mbox series

[Fortran] OpenMP 5 – permit more sharing clauses for SIMD (PR94690)

Message ID 2d9633f7-546d-02bf-a342-8e791f4e0136@codesourcery.com
State New
Headers show
Series [Fortran] OpenMP 5 – permit more sharing clauses for SIMD (PR94690) | expand

Commit Message

Tobias Burnus May 15, 2020, 10:53 a.m. UTC
Another issue found when looking into PR94690 and its
regression/additional issues.

This patch lifts a restriction of 2.15.1.1. Data-sharing Attribute
Rules for Variables Referenced in a Construct.

OpenMP 4.5 had:
* The loop iteration variable(s) in the associated do-loop(s) of a
   do, parallel do, taskloop, or distribute construct may be listed in
   a *private* or *lastprivate* clause.
* The loop iteration variable in the associated do-loop of a simd
   construct with just one associated do-loop may be listed in a
   *linear* clause with a linear-step that is the increment of the
   associated loop.
* The loop iteration variables in the associated do-loops of a simd
   construct with multiple associated do-loops may be listed in a
   *lastprivate* clause.


OpenMP 5.0 changed this in 2.19.1.1 to
* (unchanged)
* ... a simd construct with just one associated for-loop may be
   listed in a private, lastprivate, or linear ...
* simd construct with multiple associated for-loops may be listed
   in a private or lastprivate clause

Namely: private + lastprivate is now allowed in all cases.

OK for the trunk?

Tobias

PS: The remaining issue of the PR (PR94690) is about predetermined
'private' for loop variables to which complicated rules apply. Those
have been implemented on the ME side which does not recognize Fortran
loops ("while(1)" constructs*); OpenMP-ed loops use "for(..." and those
are handled by the ME.

For that reason, the FE adds a bunch of 'private' but not always to
the right OpenMP construct and not always recognizing that the user
already had specified one. (Causing ICEs or reject value issues.)
teams/distribute + workshare cause the extra complexity.

[* The while(1) loops are used be the FE to match the Fortran semantic
regarding overflowing handling for  "i + step" exceeding INT_MAX
(stop iteration instead of overflowing and continuing).]

-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander Walter

Comments

Jakub Jelinek May 15, 2020, 11:22 a.m. UTC | #1
On Fri, May 15, 2020 at 12:53:41PM +0200, Tobias Burnus wrote:
> [Fortran] OpenMP 5 – permit more sharing clauses for SIMD (PR94690)
> 
> gcc/fortran/
> 	PR fortran/94690
> 	* openmp.c (resolve_omp_do):

I'd hope Martin's script would reject such a commit.  You didn't say what
you've changed.

> gcc/testsuite/
> 	PR fortran/94690
> 	* gfortran.dg/gomp/openmp-simd-4.f90: New test.

Otherwise LGTM, except that I think (but that can be done incrementally)
that it would be highly desirable to have also a runtime testcase that tests
the values after the loop when lastprivate or linear clauses are used
or are predetermined.  Some of that is hopefully already in the testsuite
somewhere (the cases that were valid before), and one really can't test
after private (explicit or predetermined), because the value is undefined.
So that boils down to lastprivate on simd collapse(1) or simd without
collapse, and various kinds of do loops (step 1, -1, constant other,
variable), ideally some that can be actually vectorized.  And that
test doesn't need to be in libgomp, but could be in gfortran.dg/vect/
with -fopenmp-simd.

	Jakub
diff mbox series

Patch

[Fortran] OpenMP 5 – permit more sharing clauses for SIMD (PR94690)

gcc/fortran/
	PR fortran/94690
	* openmp.c (resolve_omp_do):

gcc/testsuite/
	PR fortran/94690
	* gfortran.dg/gomp/openmp-simd-4.f90: New test.

 gcc/fortran/openmp.c                             | 17 +++----
 gcc/testsuite/gfortran.dg/gomp/openmp-simd-4.f90 | 65 ++++++++++++++++++++++++
 2 files changed, 71 insertions(+), 11 deletions(-)

diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 310d4e030d2..b24630827c9 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -5847,26 +5847,21 @@  resolve_omp_do (gfc_code *code)
 		   "at %L", name, &do_code->loc);
       if (code->ext.omp_clauses)
 	for (list = 0; list < OMP_LIST_NUM; list++)
-	  if (!is_simd
+	  if (!is_simd || code->ext.omp_clauses->collapse > 1
 	      ? (list != OMP_LIST_PRIVATE && list != OMP_LIST_LASTPRIVATE)
-	      : code->ext.omp_clauses->collapse > 1
-	      ? (list != OMP_LIST_LASTPRIVATE)
-	      : (list != OMP_LIST_LINEAR))
+	      : (list != OMP_LIST_PRIVATE && list != OMP_LIST_LASTPRIVATE
+		 && list != OMP_LIST_LINEAR))
 	    for (n = code->ext.omp_clauses->lists[list]; n; n = n->next)
 	      if (dovar == n->sym)
 		{
-		  if (!is_simd)
+		  if (!is_simd || code->ext.omp_clauses->collapse > 1)
 		    gfc_error ("%s iteration variable present on clause "
 			       "other than PRIVATE or LASTPRIVATE at %L",
 			       name, &do_code->loc);
-		  else if (code->ext.omp_clauses->collapse > 1)
-		    gfc_error ("%s iteration variable present on clause "
-			       "other than LASTPRIVATE at %L",
-			       name, &do_code->loc);
 		  else
 		    gfc_error ("%s iteration variable present on clause "
-			       "other than LINEAR at %L",
-			       name, &do_code->loc);
+			       "other than PRIVATE, LASTPRIVATE or "
+			       "LINEAR at %L", name, &do_code->loc);
 		  break;
 		}
       if (i > 1)
diff --git a/gcc/testsuite/gfortran.dg/gomp/openmp-simd-4.f90 b/gcc/testsuite/gfortran.dg/gomp/openmp-simd-4.f90
new file mode 100644
index 00000000000..4a17fb9820e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/openmp-simd-4.f90
@@ -0,0 +1,65 @@ 
+! { dg-do compile }
+
+integer :: i, j, k
+integer :: x(5), y(2,5)
+
+!$omp parallel do private(i)
+do i = 1, 5
+  x(i) = 42
+end do
+
+!$omp parallel do lastprivate(i)
+do i = 1, 5
+  x(i) = 42
+end do
+
+
+!$omp simd private(i)
+do i = 1, 5
+  x(i) = 42
+end do
+
+!$omp simd linear(i)
+do i = 1, 5
+  x(i) = 42
+end do
+
+!$omp simd lastprivate(i)
+do i = 1, 5
+  x(i) = 42
+end do
+
+
+!$omp simd private(i) lastprivate(j) collapse(2)
+do i = 1, 5
+  do j = 1, 2
+    y(j, i) = 52
+  end do
+end do
+
+!$omp simd lastprivate(i) private(j) collapse(2)
+do i = 1, 5
+  do j = 1, 2
+    y(j, i) = 52
+  end do
+end do
+
+!$omp parallel do firstprivate(i)
+do i = 1, 5  ! { dg-error "PARALLEL DO iteration variable present on clause other than PRIVATE or LASTPRIVATE" }
+  x(i) = 42
+end do
+
+!$omp parallel do simd firstprivate(i)
+do i = 1, 5  ! { dg-error "PARALLEL DO SIMD iteration variable present on clause other than PRIVATE, LASTPRIVATE or LINEAR" }
+  x(i) = 42
+end do
+
+!$omp simd linear(i) collapse(2)
+do i = 1, 5  ! { dg-error "SIMD iteration variable present on clause other than PRIVATE or LASTPRIVATE" }
+  do j = 1, 2
+    y(j, i) = 52
+  end do
+end do
+
+
+end