diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index be6004d57b36f..51018b8122e81 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -954,6 +954,13 @@ class FirConverter : public Fortran::lower::AbstractConverter { // Do a regular lookup. if (Fortran::semantics::IsProcedure(sym)) return symMap->lookupSymbol(sym); + + // Commonblock names are not variables, but in some lowerings (like + // OpenMP) it is useful to maintain the address of the commonblock in an + // MLIR value and query it. hlfir.declare need not be created for these. + if (sym.detailsIf()) + return symMap->lookupSymbol(sym); + return {}; } if (Fortran::lower::SymbolBox v = symMap->lookupSymbol(sym)) diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp index b0dcf4d4256a8..20c99558b1a9d 100644 --- a/flang/lib/Lower/ConvertVariable.cpp +++ b/flang/lib/Lower/ConvertVariable.cpp @@ -1470,8 +1470,12 @@ static void genDeclareSymbol(Fortran::lower::AbstractConverter &converter, // would add too much complexity to hlfir.declare to support this case, and // this would bring very little (the only point being debug info, that are not // yet emitted) since alias analysis is meaningless for those. + // Commonblock names are not variables, but in some lowerings (like OpenMP) it + // is useful to maintain the address of the commonblock in an MLIR value and + // query it. hlfir.declare need not be created for these. if (converter.getLoweringOptions().getLowerToHighLevelFIR() && - !Fortran::semantics::IsProcedure(sym)) { + !Fortran::semantics::IsProcedure(sym) && + !sym.detailsIf()) { fir::FirOpBuilder &builder = converter.getFirOpBuilder(); const mlir::Location loc = genLocation(converter, sym); mlir::Value shapeOrShift; @@ -1521,7 +1525,8 @@ void Fortran::lower::genDeclareSymbol( Fortran::lower::SymMap &symMap, const Fortran::semantics::Symbol &sym, const fir::ExtendedValue &exv, bool force) { if (converter.getLoweringOptions().getLowerToHighLevelFIR() && - !Fortran::semantics::IsProcedure(sym)) { + !Fortran::semantics::IsProcedure(sym) && + !sym.detailsIf()) { fir::FirOpBuilder &builder = converter.getFirOpBuilder(); const mlir::Location loc = genLocation(converter, sym); fir::FortranVariableFlagsAttr attributes = diff --git a/flang/test/Lower/OpenMP/threadprivate-common-block-hlfir.f90 b/flang/test/Lower/OpenMP/threadprivate-common-block-hlfir.f90 new file mode 100644 index 0000000000000..29e3e277dc896 --- /dev/null +++ b/flang/test/Lower/OpenMP/threadprivate-common-block-hlfir.f90 @@ -0,0 +1,29 @@ +! Simple test for lowering of OpenMP Threadprivate Directive with HLFIR. +! Test for common block. + +!RUN: %flang_fc1 -flang-experimental-hlfir -emit-hlfir -fopenmp %s -o - | FileCheck %s +!RUN: bbc -hlfir -emit-hlfir -fopenmp %s -o - | FileCheck %s + + +!CHECK: %[[CBLK_ADDR:.*]] = fir.address_of(@_QCblk) : !fir.ref> +!CHECK: {{.*}} = omp.threadprivate %[[CBLK_ADDR]] : !fir.ref> -> !fir.ref> +!CHECK: omp.parallel { +!CHECK: %[[TP_PARALLEL:.*]] = omp.threadprivate %[[CBLK_ADDR]] : !fir.ref> -> !fir.ref> +!CHECK: %[[TP_PARALLEL_ADDR:.*]] = fir.convert %[[TP_PARALLEL]] : (!fir.ref>) -> !fir.ref> +!CHECK: %[[A_ADDR:.*]] = fir.coordinate_of %[[TP_PARALLEL_ADDR]], %c0_1 : (!fir.ref>, index) -> !fir.ref +!CHECK: %[[A_ADDR_CVT:.*]] = fir.convert %[[A_ADDR]] : (!fir.ref) -> !fir.ref +!CHECK: %[[A_DECL:.*]]:2 = hlfir.declare %[[A_ADDR_CVT]] {uniq_name = "_QFsub_commonblockEa"} : (!fir.ref) -> (!fir.ref, !fir.ref) +!CHECK: %[[A_VAL:.*]] = fir.load %[[A_DECL]]#0 : !fir.ref +!CHECK: {{.*}} = fir.call @_FortranAioOutputInteger32({{.*}}, %[[A_VAL]]) fastmath : (!fir.ref, i32) -> i1 +!CHECK: omp.terminator +!CHECK: } + +subroutine sub_commonblock() + integer:: a + common /blk/ a + !$omp threadprivate(/blk/) + + !$omp parallel + print *, a + !$omp end parallel +end