OpenACC 3.0 ("2.14.4. Update Directive") states:

  Noncontiguous subarrays may appear. It is implementation-specific
  whether noncontiguous regions are updated by using one transfer for
  each contiguous subregion, or whether the non-contiguous data is
  packed, transferred once, and unpacked, or whether one or more larger
  subarrays (no larger than the smallest contiguous region that contains
  the specified subarray) are updated.

This patch relaxes some conditions in the Fortran front-end so that
strided accesses are permitted for update directives.

Tested with offloading to AMD GCN. OK for mainline?

Thanks,

Julian

2020-02-02  Julian Brown  <jul...@codesourcery.com>

gcc/fortran/
        * openmp.c (resolve_omp_clauses): Omit OpenACC update in
        contiguity check and stride-specified error.

gcc/testsuite/
        * gfortran.dg/goacc/array-with-dt-2.f90: New test.
---
 gcc/fortran/openmp.c                                |  5 +++--
 gcc/testsuite/gfortran.dg/goacc/array-with-dt-2.f90 | 10 ++++++++++
 2 files changed, 13 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/goacc/array-with-dt-2.f90

diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 9a3a8f63b5e..1c8c5315329 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))
@@ -5224,7 +5225,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
+
-- 
2.29.2

Reply via email to