Hi Jakub, attached is a rebased version of this "OpenMP fixes/adjustments" patch. This version removes some of the (ort == C_ORT_OMP || ort == C_ORT_ACC) stuff that's not needed in handle_omp_array_sections_1 and [c_]finish_omp_clauses. Note that this is meant to be patched atop of the recent also posted C++ PR92120 v5 patch: https://gcc.gnu.org/pipermail/gcc-patches/2021-November/584602.html Again, tested without regressions (together with the PR92120 patch), awaiting review. Thanks, Chung-Lin (ChangeLog updated below) On 2021/5/25 9:36 PM, Chung-Lin Tang wrote: > > This patch largely implements three pieces of functionality: > > (1) Per discussion and clarification on the omp-lang mailing list, > standards conforming behavior for mapping array sections should *NOT* also map the base-pointer, > i.e for this code: > >     struct S { int *ptr; ... }; >     struct S s; >     #pragma omp target enter data map(to: s.ptr[:100]) > > Currently we generate after gimplify: > #pragma omp target enter data map(struct:s [len: 1]) map(alloc:s.ptr [len: 8]) \ >                                map(to:*_1 [len: 400]) map(attach:s.ptr [bias: 0]) > > which is deemed incorrect. After this patch, the gimplify results are now adjusted to: > #pragma omp target enter data map(to:*_1 [len: 400]) map(attach:s.ptr [bias: 0]) > (the attach operation is still generated, and if s.ptr is already mapped prior, attachment will happen) > > The correct way of achieving the base-pointer-also-mapped behavior would be to use: > #pragma omp target enter data map(to: s.ptr, s.ptr[:100]) > > This adjustment in behavior required a number of small adjustments here and there in gimplify, including > to accomodate map sequences for C++ references. > > There is also a small Fortran front-end patch involved (hence CCing Tobias and fortran@). > The new gimplify processing changed behavior in handling GOMP_MAP_ALWAYS_POINTER maps such that > the libgomp.fortran/struct-elem-map-1.f90 regressed. It appeared that the Fortran FE was generating > a GOMP_MAP_ALWAYS_POINTER for array types, which didn't seem quite correct, and the pre-patch behavior > was removing this map anyways. I have a small change in trans-openmp.c:gfc_trans_omp_array_section > to not generate the map in this case, and so far no bad test results. > > (2) The second part (though kind of related to the first above) are fixes in libgomp/target.c > to not overwrite attached pointers when handling device<->host copies, mainly for the "always" case. > This behavior is also noted in the 5.0 spec, but not yet properly coded before. > > (3) The third is a set of changes to the C/C++ front-ends to extend the allowed component access syntax > in map clauses. This is actually mainly an effort to allow SPEC HPC to compile, so despite in the long > term the entire map clause syntax parsing is probably going to be revamped, we're still adding this in > for now. These changes are enabled for both OpenACC and OpenMP. 2021-11-19 Chung-Lin Tang gcc/c/ChangeLog: * c-parser.c (struct omp_dim): New struct type for use inside c_parser_omp_variable_list. (c_parser_omp_variable_list): Allow multiple levels of array and component accesses in array section base-pointer expression. (c_parser_omp_clause_to): Set 'allow_deref' to true in call to c_parser_omp_var_list_parens. (c_parser_omp_clause_from): Likewise. * c-typeck.c (handle_omp_array_sections_1): Extend allowed range of base-pointer expressions involving INDIRECT/MEM/ARRAY_REF and POINTER_PLUS_EXPR. (c_finish_omp_clauses): Extend allowed ranged of expressions involving INDIRECT/MEM/ARRAY_REF and POINTER_PLUS_EXPR. gcc/cp/ChangeLog: * parser.c (struct omp_dim): New struct type for use inside cp_parser_omp_var_list_no_open. (cp_parser_omp_var_list_no_open): Allow multiple levels of array and component accesses in array section base-pointer expression. (cp_parser_omp_all_clauses): Set 'allow_deref' to true in call to cp_parser_omp_var_list for to/from clauses. * semantics.c (handle_omp_array_sections_1): Extend allowed range of base-pointer expressions involving INDIRECT/MEM/ARRAY_REF and POINTER_PLUS_EXPR. (handle_omp_array_sections): Adjust pointer map generation of references. (finish_omp_clauses): Extend allowed ranged of expressions involving INDIRECT/MEM/ARRAY_REF and POINTER_PLUS_EXPR. gcc/fortran/ChangeLog: * trans-openmp.c (gfc_trans_omp_array_section): Do not generate GOMP_MAP_ALWAYS_POINTER map for main array maps of ARRAY_TYPE type. gcc/ChangeLog: * gimplify.c (extract_base_bit_offset): Add 'tree *offsetp' parameter, accomodate case where 'offset' return of get_inner_reference is non-NULL. (is_or_contains_p): Further robustify conditions. (omp_target_reorder_clauses): In alloc/to/from sorting phase, also move following GOMP_MAP_ALWAYS_POINTER maps along. Add new sorting phase where we make sure pointers with an attach/detach map are ordered correctly. (gimplify_scan_omp_clauses): Add modifications to avoid creating GOMP_MAP_STRUCT and associated alloc map for attach/detach maps. gcc/testsuite/ChangeLog: * c-c++-common/goacc/deep-copy-arrayofstruct.c: Adjust testcase. * c-c++-common/gomp/target-enter-data-1.c: New testcase. * c-c++-common/gomp/target-implicit-map-2.c: New testcase. libgomp/ChangeLog: * target.c (gomp_map_vars_existing): Make sure attached pointer is not overwritten during cross-host/device copying. (gomp_update): Likewise. (gomp_exit_data): Likewise. * testsuite/libgomp.c++/target-11.C: Adjust testcase. * testsuite/libgomp.c++/target-12.C: Likewise. * testsuite/libgomp.c++/target-15.C: Likewise. * testsuite/libgomp.c++/target-16.C: Likewise. * testsuite/libgomp.c++/target-17.C: Likewise. * testsuite/libgomp.c++/target-21.C: Likewise. * testsuite/libgomp.c++/target-23.C: Likewise. * testsuite/libgomp.c/target-23.c: Likewise. * testsuite/libgomp.c/target-29.c: Likewise. * testsuite/libgomp.c-c++-common/target-implicit-map-2.c: New testcase.