https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104949
--- Comment #1 from Tobias Burnus <burnus at gcc dot gnu.org> ---
The following addition to testcase is needed.
! -------------------------------
!$omp parallel default(A)
!$omp master
if (any (A /= [1,2,3,4,5])) error stop
A(:) = [99,88,77,66,55]
!$omp end master
!$omp end parallel
if (any (A /= [1,2,3,4,5])) error stop
!$omp target defaultmap(firstprivate)
if (any (A /= [1,2,3,4,5])) error stop
A(:) = [99,88,77,66,55]
!$omp end target
if (any (A /= [1,2,3,4,5])) error stop
! -------------------------------
Reason: A different code path for
(a) defaultmap(firstprivate) and default(firstprivate)
For them gfc_omp_finish_clause is invoked
(b) explicit firstprivate(a)
Handled via gfc_trans_omp_clauses -> gfc_trans_omp_variable_list.
but gfc_omp_finish_clause is not called (should it?)
The 'parallel' variant works – and for both variants the
gfc_omp_clause_copy_ctor is invoked for both via lower_rec_input_clauses()'s
the block which follows the 'do_firstprivate:' label.
Both 'target' variants only create 'firstprivate(a)' - but additionally
'firstprivate(a.data)' is needed, including doing a pointer attach.
* * *
Currently, we support either code using attach like:
map(force_to:var) map(force_to:*var.data [len...]) map(attach_detach:var.data
[bias: 0])
or pointer-set/pointer assign like for
map(to:var.data [len:...])
map(to:var [pointer set, len: 64])
map(alloc: var.data [pointer assign, bias: 0])
In my understanding, either code requires that 'var.data' can be found as
host->device lookup, which does not work for firstprivate. And just internally
adding 'a' to the host->device mapping for firstprivate purpose internally does
not handle the following.
a = 5
!$omp target enter data map(to: a)
a = 7
! adding internally 'a' (host)->'a'(firstprivate) mapping to find the 'a.var'
! for the usage in attach/pointer assign does not work as 'a' already exists.
!$omp target firstprivate(a)
! a should be now 7
!$omp end firstprivate
!$omp target
! a is 5
!$omp end target
For the usage in
type t
integer, allocatable :: a, b
end type t
type(t) :: var
!$omp target firstprivate(var)
...
multiple attachments are needed, i.e. just using firstprivate(a)
firstprivate(b) pointer_attach (a.data) and working with index i, i+1, i+2 does
not work.