Fortran: Fix OpenMP's 'if(simd:' etc. conditions
authorTobias Burnus <tobias@codesourcery.com>
Thu, 20 Aug 2020 11:33:21 +0000 (13:33 +0200)
committerTobias Burnus <tobias@codesourcery.com>
Thu, 20 Aug 2020 11:33:40 +0000 (13:33 +0200)
gcc/fortran/ChangeLog:

* openmp.c (gfc_match_omp_clauses): Re-order 'if' clause pasing
to avoid creating spurious symbols.

libgomp/ChangeLog:

* testsuite/libgomp.fortran/lastprivate-conditional-10.f90: New test.

gcc/fortran/openmp.c
gcc/testsuite/gfortran.dg/gomp/pr67500.f90 [new file with mode: 0644]
libgomp/testsuite/libgomp.fortran/lastprivate-conditional-10.f90 [new file with mode: 0644]

index 4d33a450a33d04c0080899de21004ce1ce0b624d..50983737af4e1c66b9721ce654d96bc151dd7b33 100644 (file)
@@ -1299,8 +1299,6 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
              && c->if_expr == NULL
              && gfc_match ("if ( ") == MATCH_YES)
            {
-             if (gfc_match ("%e )", &c->if_expr) == MATCH_YES)
-               continue;
              if (!openacc)
                {
                  /* This should match the enum gfc_omp_if_kind order.  */
@@ -1323,6 +1321,8 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
                  if (i < OMP_IF_LAST)
                    continue;
                }
+             if (gfc_match ("%e )", &c->if_expr) == MATCH_YES)
+               continue;
              gfc_current_locus = old_loc;
            }
          if ((mask & OMP_CLAUSE_IF_PRESENT)
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr67500.f90 b/gcc/testsuite/gfortran.dg/gomp/pr67500.f90
new file mode 100644 (file)
index 0000000..1cecdc4
--- /dev/null
@@ -0,0 +1,57 @@
+! Fortran version of PR c/67500
+! { dg-do compile }
+
+subroutine f1
+  !$omp declare simd simdlen(d)   ! { dg-error "requires a scalar INTEGER expression" }
+end subroutine
+
+subroutine f2
+  !$omp declare simd simdlen(0.5)  ! { dg-error "requires a scalar INTEGER expression" }
+end
+
+subroutine f3 (i)
+  !$omp declare simd simdlen(-2)   ! { dg-warning "INTEGER expression of SIMDLEN clause at .1. must be positive" }
+end subroutine
+
+subroutine f4
+  !$omp declare simd simdlen(0)           ! { dg-warning "INTEGER expression of SIMDLEN clause at .1. must be positive" }
+end
+
+subroutine foo(p, d, n)
+  integer, allocatable :: p(:)
+  real, value :: d
+  integer, value :: n
+  integer :: i
+
+  !$omp simd safelen(d)     ! { dg-error "requires a scalar INTEGER expression" }
+  do i = 1, 16
+  end do
+
+  !$omp simd safelen(0.5)   ! { dg-error "requires a scalar INTEGER expression" }
+  do i = 1, 16
+  end do
+
+  !$omp simd safelen(-2)    ! { dg-warning "INTEGER expression of SAFELEN clause at .1. must be positive" }
+  do i = 1, 16
+  end do
+
+  !$omp simd safelen(0)     ! { dg-warning "INTEGER expression of SAFELEN clause at .1. must be positive" }
+  do i = 1, 16
+  end do
+
+  !$omp simd aligned(p:n)   ! { dg-error "requires a scalar positive constant integer alignment expression" }
+  do i = 1, 16
+  end do
+
+  !$omp simd aligned(p:0.5)  ! { dg-error "requires a scalar positive constant integer alignment expression" }
+  do i = 1, 16
+  end do
+
+  !$omp simd aligned(p:-2)  ! { dg-error "requires a scalar positive constant integer alignment expression" }
+  do i = 1, 16
+  end do
+
+  !$omp simd aligned(p:0)    ! { dg-error "requires a scalar positive constant integer alignment expression" }
+  do i = 1, 16
+  end do
+end
diff --git a/libgomp/testsuite/libgomp.fortran/lastprivate-conditional-10.f90 b/libgomp/testsuite/libgomp.fortran/lastprivate-conditional-10.f90
new file mode 100644 (file)
index 0000000..116166c
--- /dev/null
@@ -0,0 +1,63 @@
+! { dg-do run }
+! Fortran version of libgomp.c-c++-common/lastprivate-conditional-10.c
+
+module m
+  implicit none
+  integer :: v = 0
+  integer :: x = 0
+contains
+  integer function foo (a)
+    integer, contiguous :: a(0:)
+    integer i
+
+    !$omp parallel do simd lastprivate (conditional: x) schedule(simd : static) if (simd : .false.)
+    do i = 0, 127
+      if (a(i) /= 0) x = a(i)
+    end do
+    foo = x
+  end
+
+  integer function bar (a, b)
+    integer, contiguous :: a(0:), b(0:)
+    integer :: i
+    !$omp parallel
+    !$omp do simd lastprivate (conditional: x, v) schedule(static, 16) simdlen (1)
+    do i = 16, 127
+      if (a(i) /= 0) x = a(i);
+      if (b(i) /= 0) v = b(i) + 10;
+    end do
+    !$omp end parallel
+    bar = x
+  end
+
+  integer function baz (a)
+    integer, contiguous :: a(0:)
+    integer :: i
+    !$omp parallel do simd if (simd : .false.) lastprivate (conditional: x) schedule(simd : dynamic, 16)
+    do i = 0, 127
+      if (a(i) /= 0) x = a(i) + 5
+    end do
+    baz = x
+  end
+end module m
+
+program main
+  use m
+  implicit none
+  integer :: a(0:127), b(0:127), i
+  do i = 0, 127
+      if (mod(i, 11) == 2) then
+         a(i) =  i + 10
+      else
+        a(i) = 0
+      endif
+      if (mod(i, 13) == 5) then
+        b(i) = i * 2
+      else
+        b(i) = 0
+      endif
+  end do
+  if (foo (a) /= 133) stop 1
+  if (bar (b, a) /= 244 .or. v /= 143) stop 2
+  if (baz (b) /= 249) stop 3
+end