diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index aab17f0589f..797f6c86b62 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -5192,7 +5192,8 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, array isn't contiguous. An expression such as arr(-n:n,-n:n) could be contiguous even if it looks like it may not be. */ - if (list != OMP_LIST_CACHE + if (code->op != EXEC_OACC_UPDATE + && list != OMP_LIST_CACHE && list != OMP_LIST_DEPEND && !gfc_is_simply_contiguous (n->expr, false, true) && gfc_is_not_contiguous (n->expr)) @@ -5230,7 +5231,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, int i; gfc_array_ref *ar = &array_ref->u.ar; for (i = 0; i < ar->dimen; i++) - if (ar->stride[i]) + if (ar->stride[i] && code->op != EXEC_OACC_UPDATE) { gfc_error ("Stride should not be specified for " "array section in %s clause at %L", diff --git a/gcc/testsuite/gfortran.dg/goacc/array-with-dt-2.f90 b/gcc/testsuite/gfortran.dg/goacc/array-with-dt-2.f90 new file mode 100644 index 00000000000..807580d75a9 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/goacc/array-with-dt-2.f90 @@ -0,0 +1,10 @@ +type t + integer, allocatable :: A(:,:) +end type t + +type(t), allocatable :: b(:) + +!$acc update host(b(::2)) +!$acc update host(b(1)%A(::3,::4)) +end + diff --git a/libgomp/testsuite/libgomp.oacc-fortran/array-stride-dt-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/array-stride-dt-1.f90 new file mode 100644 index 00000000000..f04d76d583a --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-fortran/array-stride-dt-1.f90 @@ -0,0 +1,44 @@ +! { dg-do run } + +type t + integer, allocatable :: A(:,:) +end type t + +type(t), allocatable :: b(:) + +integer :: i + +allocate(b(1:20)) +do i=1,20 + allocate(b(i)%A(1:20,1:20)) +end do + +do i=1,20 + b(i)%A(:,:) = 0 +end do + +!$acc enter data copyin(b) +do i=1,20 + !$acc enter data copyin(b(i)%A) +end do + +b(1)%A(:,:) = 5 + +!$acc update device(b(::2)) +!$acc update device(b(1)%A(::3,::4)) + +do i=1,20 + !$acc exit data copyout(b(i)%A) +end do +!$acc exit data copyout(b) + +! This is necessarily conservative because the "update" is allowed to copy +! e.g. the whole of the containing block for a discontinuous update. +! Try to ensure that the update covers a sufficient portion of the array. + +if (any(b(1)%A(::3,::4) .ne. 5)) stop 1 +do i=2,20 + if (any(b(i)%A(:,:) .ne. 0)) stop 2 +end do + +end