Hi, The attached patch fixes a defect reported with gcc 5.2 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69414). It is also the case, the issue is present in the gomp4 branch. The patch also adds additional testing.
Committed to gomp4 after bootstrap and regtesting. Thanks, Jim
Index: ChangeLog.gomp =================================================================== --- ChangeLog.gomp (revision 232740) +++ ChangeLog.gomp (revision 232741) @@ -1,3 +1,11 @@ +2016-01-22 James Norris <jnor...@codesourcery.com> + + * oacc-mem.c (delete_copyout, update_dev_host): Fix device address. + * testsuite/libgomp.oacc-c-c++-common/update-1.c: Additional tests. + * testsuite/libgomp.oacc-c-c++-common/update-1-2.c: Likewise. + * testsuite/libgomp.oacc-fortran/update-1.f90: New file. + * testsuite/libgomp.oacc-fortran/update-1-2.f90: Likewise. + 2016-01-22 Nathan Sidwell <nat...@codesourcery.com> * testsuite/libgomp.oacc-c-c++-common/routine-1.c: Specify vector. Index: oacc-mem.c =================================================================== --- oacc-mem.c (revision 232740) +++ oacc-mem.c (revision 232741) @@ -509,7 +509,7 @@ gomp_fatal ("[%p,%d] is not mapped", (void *)h, (int)s); } - d = (void *) (n->tgt->tgt_start + n->tgt_offset); + d = (void *) (n->tgt->tgt_start + n->tgt_offset + h - n->host_start); host_size = n->host_end - n->host_start; @@ -562,7 +562,7 @@ gomp_fatal ("[%p,%d] is not mapped", h, (int)s); } - d = (void *) (n->tgt->tgt_start + n->tgt_offset); + d = (void *) (n->tgt->tgt_start + n->tgt_offset + h - n->host_start); gomp_mutex_unlock (&acc_dev->lock); Index: testsuite/libgomp.oacc-fortran/update-1-2.f90 =================================================================== --- testsuite/libgomp.oacc-fortran/update-1-2.f90 (revision 0) +++ testsuite/libgomp.oacc-fortran/update-1-2.f90 (revision 232741) @@ -0,0 +1,239 @@ +! Copy of update-1.f90 with self exchanged with host for !$acc update + +! { dg-do run } +! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } + +program update + use openacc + implicit none + integer, parameter :: N = 8 + real :: a(N), b(N) + integer i + + do i = 1, N + a(i) = 3.0 + b(i) = 0.0 + end do + + !$acc enter data copyin (a, b) + + !$acc parallel present (a, b) + do i = 1, N + b(i) = a(i) + end do + !$acc end parallel + + !$acc update self (a, b) + + do i = 1, N + if (a(i) .ne. 3.0) call abort + if (b(i) .ne. 3.0) call abort + end do + + if (acc_is_present (a) .neqv. .TRUE.) call abort + if (acc_is_present (b) .neqv. .TRUE.) call abort + + do i = 1, N + a(i) = 5.0 + b(i) = 1.0 + end do + + !$acc update device (a, b) + + !$acc parallel present (a, b) + do i = 1, N + b(i) = a(i) + end do + !$acc end parallel + + !$acc update self (a, b) + + do i = 1, N + if (a(i) .ne. 5.0) call abort + if (b(i) .ne. 5.0) call abort + end do + + if (acc_is_present (a) .neqv. .TRUE.) call abort + if (acc_is_present (b) .neqv. .TRUE.) call abort + + !$acc parallel present (a, b) + do i = 1, N + b(i) = a(i) + end do + !$acc end parallel + + !$acc update self (a, b) + + do i = 1, N + if (a(i) .ne. 5.0) call abort + if (b(i) .ne. 5.0) call abort + end do + + do i = 1, N + a(i) = 6.0 + b(i) = 0.0 + end do + + !$acc update device (a, b) + + do i = 1, N + a(i) = 9.0 + end do + + !$acc parallel present (a, b) + do i = 1, N + b(i) = a(i) + end do + !$acc end parallel + + !$acc update self (a, b) + + do i = 1, N + if (a(i) .ne. 6.0) call abort + if (b(i) .ne. 6.0) call abort + end do + + if (acc_is_present (a) .neqv. .TRUE.) call abort + if (acc_is_present (b) .neqv. .TRUE.) call abort + + do i = 1, N + a(i) = 7.0 + b(i) = 2.0 + end do + + !$acc update device (a, b) + + do i = 1, N + a(i) = 9.0 + end do + + !$acc parallel present (a, b) + do i = 1, N + b(i) = a(i) + end do + !$acc end parallel + + !$acc update self (a, b) + + do i = 1, N + if (a(i) .ne. 7.0) call abort + if (b(i) .ne. 7.0) call abort + end do + + do i = 1, N + a(i) = 9.0 + end do + + !$acc update device (a) + + !$acc parallel present (a, b) + do i = 1, N + b(i) = a(i) + end do + !$acc end parallel + + !$acc update self (a, b) + + do i = 1, N + if (a(i) .ne. 9.0) call abort + if (b(i) .ne. 9.0) call abort + end do + + if (acc_is_present (a) .neqv. .TRUE.) call abort + if (acc_is_present (b) .neqv. .TRUE.) call abort + + do i = 1, N + a(i) = 5.0 + end do + + !$acc update device (a) + + do i = 1, N + a(i) = 6.0 + end do + + !$acc update device (a(1:rshift (N, 1))) + + !$acc parallel present (a, b) + do i = 1, N + b(i) = a(i) + end do + !$acc end parallel + + !$acc update self (a, b) + + do i = 1, rshift (N, 1) + if (a(i) .ne. 6.0) call abort + if (b(i) .ne. 6.0) call abort + end do + + do i = rshift (N, 1) + 1, N + if (a(i) .ne. 5.0) call abort + if (b(i) .ne. 5.0) call abort + end do + + if (acc_is_present (a) .neqv. .TRUE.) call abort + if (acc_is_present (b) .neqv. .TRUE.) call abort + + do i = 1, N + a(i) = 0.0 + end do + + !$acc update device (a(1:4)) + + !$acc parallel present (a) + do i = 1, N + a(i) = a(i) + 1.0 + end do + !$acc end parallel + + !$acc update self (a(5:N)) + + do i = 1, rshift (N, 1) + if (a(i) .ne. 0.0) call abort + end do + + do i = rshift (N, 1) + 1, N + if (a(i) .ne. 6.0) call abort + end do + + !$acc update self (a(1:4)) + + do i = 1, rshift (N, 1) + if (a(i) .ne. 1.0) call abort + end do + + do i = rshift (N, 1) + 1, N + if (a(i) .ne. 6.0) call abort + end do + + a(3) = 9 + a(4) = 9 + a(5) = 9 + a(6) = 9 + + !$acc update device (a(3:6)) + + !$acc parallel present (a(1:N)) + do i = 1, N + a(i) = a(i) + 1.0 + end do + !$acc end parallel + + !$acc update self (a(3:6)) + + do i = 1, 2 + if (a(i) .ne. 1.0) call abort + end do + + do i = 3, 6 + if (a(i) .ne. 10.0) call abort + end do + + do i = 7, N + if (a(i) .ne. 6.0) call abort + end do + !$acc exit data delete (a, b) + +end program + Index: testsuite/libgomp.oacc-fortran/update-1.f90 =================================================================== --- testsuite/libgomp.oacc-fortran/update-1.f90 (revision 0) +++ testsuite/libgomp.oacc-fortran/update-1.f90 (revision 232741) @@ -0,0 +1,242 @@ +! { dg-do run } +! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } + +program update + use openacc + implicit none + integer, parameter :: N = 8 + integer, parameter :: NDIV2 = N / 2 + real :: a(N), b(N) + integer i + + do i = 1, N + a(i) = 3.0 + b(i) = 0.0 + end do + + !$acc enter data copyin (a, b) + + !$acc parallel present (a, b) + do i = 1, N + b(i) = a(i) + end do + !$acc end parallel + + !$acc update host (a, b) + + do i = 1, N + if (a(i) .ne. 3.0) call abort + if (b(i) .ne. 3.0) call abort + end do + + if (acc_is_present (a) .neqv. .TRUE.) call abort + if (acc_is_present (b) .neqv. .TRUE.) call abort + + do i = 1, N + a(i) = 5.0 + b(i) = 1.0 + end do + + !$acc update device (a, b) + + !$acc parallel present (a, b) + do i = 1, N + b(i) = a(i) + end do + !$acc end parallel + + !$acc update host (a, b) + + do i = 1, N + if (a(i) .ne. 5.0) call abort + if (b(i) .ne. 5.0) call abort + end do + + if (acc_is_present (a) .neqv. .TRUE.) call abort + if (acc_is_present (b) .neqv. .TRUE.) call abort + + !$acc parallel present (a, b) + do i = 1, N + b(i) = a(i) + end do + !$acc end parallel + + !$acc update host (a, b) + + do i = 1, N + if (a(i) .ne. 5.0) call abort + if (b(i) .ne. 5.0) call abort + end do + + if (acc_is_present (a) .neqv. .TRUE.) call abort + if (acc_is_present (b) .neqv. .TRUE.) call abort + + do i = 1, N + a(i) = 6.0 + b(i) = 0.0 + end do + + !$acc update device (a, b) + + do i = 1, N + a(i) = 9.0 + end do + + !$acc parallel present (a, b) + do i = 1, N + b(i) = a(i) + end do + !$acc end parallel + + !$acc update host (a, b) + + do i = 1, N + if (a(i) .ne. 6.0) call abort + if (b(i) .ne. 6.0) call abort + end do + + if (acc_is_present (a) .neqv. .TRUE.) call abort + if (acc_is_present (b) .neqv. .TRUE.) call abort + + do i = 1, N + a(i) = 7.0 + b(i) = 2.0 + end do + + !$acc update device (a, b) + + do i = 1, N + a(i) = 9.0 + end do + + !$acc parallel present (a, b) + do i = 1, N + b(i) = a(i) + end do + !$acc end parallel + + !$acc update host (a, b) + + do i = 1, N + if (a(i) .ne. 7.0) call abort + if (b(i) .ne. 7.0) call abort + end do + + do i = 1, N + a(i) = 9.0 + end do + + !$acc update device (a) + + !$acc parallel present (a, b) + do i = 1, N + b(i) = a(i) + end do + !$acc end parallel + + !$acc update host (a, b) + + do i = 1, N + if (a(i) .ne. 9.0) call abort + if (b(i) .ne. 9.0) call abort + end do + + if (acc_is_present (a) .neqv. .TRUE.) call abort + if (acc_is_present (b) .neqv. .TRUE.) call abort + + do i = 1, N + a(i) = 5.0 + end do + + !$acc update device (a) + + do i = 1, N + a(i) = 6.0 + end do + + !$acc update device (a(1:NDIV2)) + + !$acc parallel present (a, b) + do i = 1, N + b(i) = a(i) + end do + !$acc end parallel + + !$acc update host (a, b) + + do i = 1, NDIV2 + if (a(i) .ne. 6.0) call abort + if (b(i) .ne. 6.0) call abort + end do + + do i = NDIV2 + 1, N + if (a(i) .ne. 5.0) call abort + if (b(i) .ne. 5.0) call abort + end do + + if (acc_is_present (a) .neqv. .TRUE.) call abort + if (acc_is_present (b) .neqv. .TRUE.) call abort + + do i = 1, N + a(i) = 0.0 + end do + + !$acc update device (a(1:4)) + + !$acc parallel present (a) + do i = 1, N + a(i) = a(i) + 1.0 + end do + !$acc end parallel + + !$acc update host (a(5:N)) + + do i = 1, NDIV2 + if (a(i) .ne. 0.0) call abort + end do + + do i = NDIV2 + 1, N + if (a(i) .ne. 6.0) call abort + end do + + !$acc update host (a(1:4)) + + do i = 1, NDIV2 + if (a(i) .ne. 1.0) call abort + end do + + do i = NDIV2 + 1, N + if (a(i) .ne. 6.0) call abort + end do + + a(3) = 9 + a(4) = 9 + a(5) = 9 + a(6) = 9 + + !$acc update device (a(3:6)) + + !$acc parallel present (a(1:N)) + do i = 1, N + a(i) = a(i) + 1.0 + end do + !$acc end parallel + + !$acc update host (a(3:6)) + + do i = 1, 2 + if (a(i) .ne. 1.0) call abort + end do + + do i = 3, 6 + if (a(i) .ne. 10.0) call abort + end do + + do i = 7, N + if (a(i) .ne. 6.0) call abort + end do + + !$acc exit data delete (a, b) + +end program + Index: testsuite/libgomp.oacc-c-c++-common/update-1-2.c =================================================================== --- testsuite/libgomp.oacc-c-c++-common/update-1-2.c (revision 232740) +++ testsuite/libgomp.oacc-c-c++-common/update-1-2.c (revision 232741) @@ -13,6 +13,7 @@ main (int argc, char **argv) { int N = 8; + int NDIV2 = N / 2; float *a, *b, *c; float *d_a, *d_b, *d_c; int i; @@ -242,7 +243,7 @@ a[i] = 6.0; } -#pragma acc update device (a[0:N >> 1]) +#pragma acc update device (a[0:NDIV2]) #pragma acc parallel present (a[0:N], b[0:N]) { @@ -254,7 +255,7 @@ #pragma acc update self (a[0:N], b[0:N]) - for (i = 0; i < (N >> 1); i++) + for (i = 0; i < NDIV2; i++) { if (a[i] != 6.0) abort (); @@ -263,7 +264,7 @@ abort (); } - for (i = (N >> 1); i < N; i++) + for (i = NDIV2; i < N; i++) { if (a[i] != 5.0) abort (); @@ -278,5 +279,83 @@ if (!acc_is_present (&b[0], (N * sizeof (float)))) abort (); + for (i = 0; i < N; i++) + { + a[i] = 0.0; + } + +#pragma acc update device (a[0:4]) + +#pragma acc parallel present (a[0:N]) + { + int ii; + + for (ii = 0; ii < N; ii++) + a[ii] = a[ii] + 1.0; + } + +#pragma acc update self (a[4:4]) + + for (i = 0; i < NDIV2; i++) + { + if (a[i] != 0.0) + abort (); + } + + for (i = NDIV2; i < N; i++) + { + if (a[i] != 6.0) + abort (); + } + +#pragma acc update self (a[0:4]) + + for (i = 0; i < NDIV2; i++) + { + if (a[i] != 1.0) + abort (); + } + + for (i = NDIV2; i < N; i++) + { + if (a[i] != 6.0) + abort (); + } + + a[2] = 9; + a[3] = 9; + a[4] = 9; + a[5] = 9; + +#pragma acc update device (a[2:4]) + +#pragma acc parallel present (a[0:N]) + { + int ii; + + for (ii = 0; ii < N; ii++) + a[ii] = a[ii] + 1.0; + } + +#pragma acc update self (a[2:4]) + + for (i = 0; i < 2; i++) + { + if (a[i] != 1.0) + abort (); + } + + for (i = 2; i < 6; i++) + { + if (a[i] != 10.0) + abort (); + } + + for (i = 6; i < N; i++) + { + if (a[i] != 6.0) + abort (); + } + return 0; } Index: testsuite/libgomp.oacc-c-c++-common/update-1.c =================================================================== --- testsuite/libgomp.oacc-c-c++-common/update-1.c (revision 232740) +++ testsuite/libgomp.oacc-c-c++-common/update-1.c (revision 232741) @@ -11,6 +11,7 @@ main (int argc, char **argv) { int N = 8; + int NDIV2 = N / 2; float *a, *b, *c; float *d_a, *d_b, *d_c; int i; @@ -109,7 +110,7 @@ b[ii] = a[ii]; } -#pragma acc update self (a[0:N], b[0:N]) +#pragma acc update host (a[0:N], b[0:N]) for (i = 0; i < N; i++) { @@ -240,7 +241,7 @@ a[i] = 6.0; } -#pragma acc update device (a[0:N >> 1]) +#pragma acc update device (a[0:NDIV2]) #pragma acc parallel present (a[0:N], b[0:N]) { @@ -252,7 +253,7 @@ #pragma acc update host (a[0:N], b[0:N]) - for (i = 0; i < (N >> 1); i++) + for (i = 0; i < NDIV2; i++) { if (a[i] != 6.0) abort (); @@ -261,7 +262,7 @@ abort (); } - for (i = (N >> 1); i < N; i++) + for (i = NDIV2; i < N; i++) { if (a[i] != 5.0) abort (); @@ -276,5 +277,83 @@ if (!acc_is_present (&b[0], (N * sizeof (float)))) abort (); + for (i = 0; i < N; i++) + { + a[i] = 0.0; + } + +#pragma acc update device (a[0:4]) + +#pragma acc parallel present (a[0:N]) + { + int ii; + + for (ii = 0; ii < N; ii++) + a[ii] = a[ii] + 1.0; + } + +#pragma acc update host (a[4:4]) + + for (i = 0; i < NDIV2; i++) + { + if (a[i] != 0.0) + abort (); + } + + for (i = NDIV2; i < N; i++) + { + if (a[i] != 6.0) + abort (); + } + +#pragma acc update host (a[0:4]) + + for (i = 0; i < NDIV2; i++) + { + if (a[i] != 1.0) + abort (); + } + + for (i = NDIV2; i < N; i++) + { + if (a[i] != 6.0) + abort (); + } + + a[2] = 9; + a[3] = 9; + a[4] = 9; + a[5] = 9; + +#pragma acc update device (a[2:4]) + +#pragma acc parallel present (a[0:N]) + { + int ii; + + for (ii = 0; ii < N; ii++) + a[ii] = a[ii] + 1.0; + } + +#pragma acc update host (a[2:4]) + + for (i = 0; i < 2; i++) + { + if (a[i] != 1.0) + abort (); + } + + for (i = 2; i < 6; i++) + { + if (a[i] != 10.0) + abort (); + } + + for (i = 6; i < N; i++) + { + if (a[i] != 6.0) + abort (); + } + return 0; }