diff --git a/flang/include/flang/Lower/OpenMP.h b/flang/include/flang/Lower/OpenMP.h --- a/flang/include/flang/Lower/OpenMP.h +++ b/flang/include/flang/Lower/OpenMP.h @@ -52,7 +52,8 @@ void genOpenMPDeclarativeConstruct(AbstractConverter &, pft::Evaluation &, const parser::OpenMPDeclarativeConstruct &); int64_t getCollapseValue(const Fortran::parser::OmpClauseList &clauseList); -void genThreadprivateOp(AbstractConverter &, const pft::Variable &); +void genThreadprivateOpOrInitDeclTarGlobal(AbstractConverter &, + const pft::Variable &); void genOpenMPReduction(AbstractConverter &, const Fortran::parser::OmpClauseList &clauseList); diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -4013,10 +4013,13 @@ void instantiateVar(const Fortran::lower::pft::Variable &var, Fortran::lower::AggregateStoreMap &storeMap) { Fortran::lower::instantiateVariable(*this, var, localSymbols, storeMap); - if (var.hasSymbol() && - var.getSymbol().test( - Fortran::semantics::Symbol::Flag::OmpThreadprivate)) - Fortran::lower::genThreadprivateOp(*this, var); + if (var.hasSymbol()) { + if (var.getSymbol().test( + Fortran::semantics::Symbol::Flag::OmpThreadprivate) || + var.getSymbol().test( + Fortran::semantics::Symbol::Flag::OmpDeclareTarget)) + Fortran::lower::genThreadprivateOpOrInitDeclTarGlobal(*this, var); + } } /// Start translation of a function. diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -2643,16 +2643,20 @@ ompConstruct.u); } -void Fortran::lower::genThreadprivateOp( +void Fortran::lower::genThreadprivateOpOrInitDeclTarGlobal( Fortran::lower::AbstractConverter &converter, const Fortran::lower::pft::Variable &var) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); mlir::Location currentLocation = converter.getCurrentLocation(); const Fortran::semantics::Symbol &sym = var.getSymbol(); + mlir::Value symThreadprivateValue; - if (const Fortran::semantics::Symbol *common = - Fortran::semantics::FindCommonBlockContaining(sym.GetUltimate())) { + bool isDeclareTarget = + var.getSymbol().test(Fortran::semantics::Symbol::Flag::OmpDeclareTarget); + const Fortran::semantics::Symbol *common = + Fortran::semantics::FindCommonBlockContaining(sym.GetUltimate()); + if (!isDeclareTarget && common) { mlir::Value commonValue = converter.getSymbolAddress(*common); if (mlir::isa(commonValue.getDefiningOp())) { // Generate ThreadprivateOp for a common block instead of its members and @@ -2696,11 +2700,14 @@ b.create(currentLocation, undef); }); } - mlir::Value symValue = firOpBuilder.create( - currentLocation, global.resultType(), global.getSymbol()); - symThreadprivateValue = firOpBuilder.create( - currentLocation, symValue.getType(), symValue); - } else { + + if (!isDeclareTarget) { + mlir::Value symValue = firOpBuilder.create( + currentLocation, global.resultType(), global.getSymbol()); + symThreadprivateValue = firOpBuilder.create( + currentLocation, symValue.getType(), symValue); + } + } else if (!isDeclareTarget) { mlir::Value symValue = converter.getSymbolAddress(sym); mlir::Operation *op = symValue.getDefiningOp(); // The symbol may be use-associated multiple times, and nothing needs to be @@ -2712,10 +2719,12 @@ currentLocation, symValue.getType(), symValue); } - fir::ExtendedValue sexv = converter.getSymbolExtendedValue(sym); - fir::ExtendedValue symThreadprivateExv = - getExtendedValue(sexv, symThreadprivateValue); - converter.bindSymbol(sym, symThreadprivateExv); + if (!isDeclareTarget) { + fir::ExtendedValue sexv = converter.getSymbolExtendedValue(sym); + fir::ExtendedValue symThreadprivateExv = + getExtendedValue(sexv, symThreadprivateValue); + converter.bindSymbol(sym, symThreadprivateExv); + } } void handleDeclareTarget(Fortran::lower::AbstractConverter &converter, diff --git a/flang/test/Lower/OpenMP/omp-declare-target-program-var.f90 b/flang/test/Lower/OpenMP/omp-declare-target-program-var.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Lower/OpenMP/omp-declare-target-program-var.f90 @@ -0,0 +1,12 @@ +!RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | FileCheck %s +!RUN: %flang_fc1 -emit-fir -fopenmp -fopenmp-is-device %s -o - | FileCheck %s + +PROGRAM main + ! CHECK-DAG: %0 = fir.alloca f32 {bindc_name = "i", uniq_name = "_QFEi"} + REAL :: I + ! CHECK-DAG: fir.global internal @_QFEi {omp.declare_target = #omp.declaretarget} : f32 { + ! CHECK-DAG: %0 = fir.undefined f32 + ! CHECK-DAG: fir.has_value %0 : f32 + ! CHECK-DAG: } + !$omp declare target(I) +END