diff --git a/flang/include/flang/Lower/AbstractConverter.h b/flang/include/flang/Lower/AbstractConverter.h index fa67729fe0366..980fde8813732 100644 --- a/flang/include/flang/Lower/AbstractConverter.h +++ b/flang/include/flang/Lower/AbstractConverter.h @@ -118,6 +118,10 @@ class AbstractConverter { const Fortran::semantics::Symbol &sym, mlir::OpBuilder::InsertPoint *copyAssignIP = nullptr) = 0; + /// For a given symbol, check if it is present in the inner-most + /// level of the symbol map. + virtual bool isPresentShallowLookup(Fortran::semantics::Symbol &sym) = 0; + /// Collect the set of symbols with \p flag in \p eval /// region if \p collectSymbols is true. Likewise, collect the /// set of the host symbols with \p flag of the associated symbols in \p eval diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index 8eb5e6865b832..16458f2a5ed41 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -603,6 +603,10 @@ class FirConverter : public Fortran::lower::AbstractConverter { std::nullopt); } + bool isPresentShallowLookup(Fortran::semantics::Symbol &sym) override final { + return bool(shallowLookupSymbol(sym)); + } + bool createHostAssociateVarClone( const Fortran::semantics::Symbol &sym) override final { mlir::Location loc = genLocation(sym.name()); diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index 4b202401eb278..945066549299d 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -1592,7 +1592,8 @@ bool ClauseProcessor::processCopyin() const { mlir::OpBuilder::InsertPoint *copyAssignIP = nullptr) { assert(sym->has() && "No host-association found"); - converter.copyHostAssociateVar(*sym, copyAssignIP); + if (converter.isPresentShallowLookup(*sym)) + converter.copyHostAssociateVar(*sym, copyAssignIP); }; bool hasCopyin = findRepeatableClause( [&](const ClauseTy::Copyin *copyinClause, diff --git a/flang/test/Lower/OpenMP/FIR/copyin.f90 b/flang/test/Lower/OpenMP/FIR/copyin.f90 index 2b3f382240958..7de0fb0e3b96a 100644 --- a/flang/test/Lower/OpenMP/FIR/copyin.f90 +++ b/flang/test/Lower/OpenMP/FIR/copyin.f90 @@ -310,3 +310,43 @@ subroutine common_2() end do !$omp end parallel do end subroutine + +!CHECK: func.func @_QPcommon_3() { +!CHECK: %[[val_0:.*]] = fir.address_of(@blk_) : !fir.ref> +!CHECK: %[[val_1:.*]] = omp.threadprivate %[[val_0]] : !fir.ref> -> !fir.ref> +!CHECK: %[[val_2:.*]] = fir.convert %[[val_1]] : (!fir.ref>) -> !fir.ref> +!CHECK: %[[val_c4:.*]] = arith.constant 4 : index +!CHECK: %[[val_3:.*]] = fir.coordinate_of %[[val_2]], %[[val_c4]] : (!fir.ref>, index) -> !fir.ref +!CHECK: %[[val_4:.*]] = fir.convert %[[val_3]] : (!fir.ref) -> !fir.ref +!CHECK: omp.parallel { +!CHECK: %[[val_5:.*]] = omp.threadprivate %[[val_0]] : !fir.ref> -> !fir.ref> +!CHECK: %[[val_6:.*]] = fir.convert %[[val_5]] : (!fir.ref>) -> !fir.ref> +!CHECK: %[[val_c4_0:.*]] = arith.constant 4 : index +!CHECK: %[[val_7:.*]] = fir.coordinate_of %[[val_6]], %[[val_c4_0]] : (!fir.ref>, index) -> !fir.ref +!CHECK: %[[val_8:.*]] = fir.convert %[[val_7]] : (!fir.ref) -> !fir.ref +!CHECK: %[[val_9:.*]] = fir.load %[[val_4]] : !fir.ref +!CHECK: fir.store %[[val_9]] to %[[val_8]] : !fir.ref +!CHECK: omp.barrier +!CHECK: omp.sections { +!CHECK: omp.section { +!CHECK: %[[val_10:.*]] = fir.load %[[val_8]] : !fir.ref +!CHECK: %[[val_c3_i32:.*]] = arith.constant 3 : i32 +!CHECK: %[[val_11:.*]] = arith.addi %[[val_10]], %[[val_c3_i32]] : i32 +!CHECK: fir.store %[[val_11]] to %[[val_8]] : !fir.ref +!CHECK: omp.terminator +!CHECK: } +!CHECK: omp.terminator +!CHECK: } +!CHECK: return +!CHECK: } +subroutine common_3() + integer :: x + integer :: y + common /blk/ x, y + !$omp threadprivate (/blk/) + + !$omp parallel sections copyin(/blk/) + !$omp section + y = y + 3 + !$omp end parallel sections +end subroutine