diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index 625a8c83c369..1f280a02a655 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -1494,13 +1494,26 @@ genParallelOp(lower::AbstractConverter &converter, lower::SymMap &symTable, allSymbols.append(dsp.getAllSymbolsToPrivatize().begin(), dsp.getAllSymbolsToPrivatize().end()); - for (auto [arg, prv] : llvm::zip_equal(allSymbols, region.getArguments())) { - converter.bindSymbol(*arg, hlfir::translateToExtendedValue( - loc, firOpBuilder, hlfir::Entity{prv}, - /*contiguousHint=*/ - evaluate::IsSimplyContiguous( - *arg, converter.getFoldingContext())) - .first); + unsigned argIdx = 0; + for (const semantics::Symbol *arg : allSymbols) { + auto bind = [&](const semantics::Symbol *sym) { + mlir::BlockArgument blockArg = region.getArgument(argIdx); + ++argIdx; + converter.bindSymbol(*sym, + hlfir::translateToExtendedValue( + loc, firOpBuilder, hlfir::Entity{blockArg}, + /*contiguousHint=*/ + evaluate::IsSimplyContiguous( + *sym, converter.getFoldingContext())) + .first); + }; + + if (const auto *commonDet = + arg->detailsIf()) { + for (const auto &mem : commonDet->objects()) + bind(&*mem); + } else + bind(arg); } return allSymbols; diff --git a/flang/test/Lower/OpenMP/firstprivate-commonblock.f90 b/flang/test/Lower/OpenMP/firstprivate-commonblock.f90 index d0fcdac76ad7..0fa0d2bc3249 100644 --- a/flang/test/Lower/OpenMP/firstprivate-commonblock.f90 +++ b/flang/test/Lower/OpenMP/firstprivate-commonblock.f90 @@ -1,4 +1,6 @@ -! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -emit-hlfir -fopenmp \ +! RUN: -mmlir --openmp-enable-delayed-privatization=true -o - %s 2>&1 \ +! RUN: | FileCheck %s !CHECK: func.func @_QPfirstprivate_common() { !CHECK: %[[val_0:.*]] = fir.address_of(@c_) : !fir.ref> @@ -12,15 +14,9 @@ !CHECK: %[[val_5:.*]] = fir.coordinate_of %[[val_4]], %[[val_c4]] : (!fir.ref>, index) -> !fir.ref !CHECK: %[[val_6:.*]] = fir.convert %[[val_5]] : (!fir.ref) -> !fir.ref !CHECK: %[[VAL_6_DECL:.*]]:2 = hlfir.declare %[[val_6]] {uniq_name = "_QFfirstprivate_commonEy"} : (!fir.ref) -> (!fir.ref, !fir.ref) -!CHECK: omp.parallel { -!CHECK: %[[val_7:.*]] = fir.alloca f32 {bindc_name = "x", pinned, uniq_name = "_QFfirstprivate_commonEx"} +!CHECK: omp.parallel private(@{{.*}} %{{.*}}#0 -> %[[val_7:.*]] : {{.*}}, @{{.*}} %{{.*}}#0 -> %[[val_9:.*]] : {{.*}}) { !CHECK: %[[VAL_7_DECL:.*]]:2 = hlfir.declare %[[val_7]] {uniq_name = "_QFfirstprivate_commonEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) -!CHECK: %[[val_8:.*]] = fir.load %[[VAL_3_DECL]]#0 : !fir.ref -!CHECK: hlfir.assign %[[val_8]] to %[[VAL_7_DECL]]#0 temporary_lhs : f32, !fir.ref -!CHECK: %[[val_9:.*]] = fir.alloca f32 {bindc_name = "y", pinned, uniq_name = "_QFfirstprivate_commonEy"} !CHECK: %[[VAL_9_DECL:.*]]:2 = hlfir.declare %[[val_9]] {uniq_name = "_QFfirstprivate_commonEy"} : (!fir.ref) -> (!fir.ref, !fir.ref) -!CHECK: %[[val_10:.*]] = fir.load %[[VAL_6_DECL]]#0 : !fir.ref -!CHECK: hlfir.assign %[[val_10]] to %[[VAL_9_DECL]]#0 temporary_lhs : f32, !fir.ref !CHECK: omp.terminator !CHECK: } !CHECK: return diff --git a/flang/test/Lower/OpenMP/private-commonblock.f90 b/flang/test/Lower/OpenMP/private-commonblock.f90 index ee580594f7c3..20f6cf57c2ae 100644 --- a/flang/test/Lower/OpenMP/private-commonblock.f90 +++ b/flang/test/Lower/OpenMP/private-commonblock.f90 @@ -1,10 +1,10 @@ -! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -emit-hlfir -fopenmp \ +! RUN: -mmlir --openmp-enable-delayed-privatization=true -o - %s 2>&1 \ +! RUN: | FileCheck %s !CHECK: func.func @_QPprivate_common() { -!CHECK: omp.parallel { -!CHECK: %[[X:.*]] = fir.alloca f32 {bindc_name = "x", pinned, uniq_name = "_QFprivate_commonEx"} +!CHECK: omp.parallel private(@{{.*}} %{{.*}}#0 -> %[[X:.*]] : {{.*}}, @{{.*}} %{{.*}}#0 -> %[[Y:.*]] : {{.*}}) { !CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFprivate_commonEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) -!CHECK: %[[Y:.*]] = fir.alloca f32 {bindc_name = "y", pinned, uniq_name = "_QFprivate_commonEy"} !CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %[[Y]] {uniq_name = "_QFprivate_commonEy"} : (!fir.ref) -> (!fir.ref, !fir.ref) !CHECK: omp.terminator !CHECK: } @@ -48,17 +48,13 @@ end subroutine !CHECK: %[[D_REF:.*]] = fir.convert %[[D_DECL]]#1 : (!fir.ref>>) -> !fir.ref> !CHECK: %[[D_BOX:.*]] = fir.emboxchar %[[D_REF]], %[[TP5]] : (!fir.ref>, index) -> !fir.boxchar<1> !CHECK: fir.call @_QPsub1(%[[A_DECL]]#1, %[[B_DECL]]#1, %[[C_BOX]], %[[D_BOX]]) fastmath : (!fir.ref, !fir.ref>, !fir.boxchar<1>, !fir.boxchar<1>) -> () -!CHECK: omp.parallel { -!CHECK: %[[A_PVT_REF:.*]] = fir.alloca i32 {bindc_name = "a", pinned, uniq_name = "_QFprivate_clause_commonblockEa"} +!CHECK: omp.parallel private(@{{.*}} %{{.*}}#0 -> %[[A_PVT_REF:.*]] : {{.*}}, @{{.*}} %{{.*}}#0 -> %[[B_PVT_REF:.*]] : {{.*}}, @{{.*}} %{{.*}}#0 -> %[[C_PVT_REF:.*]] : {{.*}}, @{{.*}} %{{.*}}#0 -> %[[D_PVT_REF:.*]] : {{.*}}) { !CHECK: %[[A_PVT_DECL:.*]]:2 = hlfir.declare %[[A_PVT_REF]] {uniq_name = "_QFprivate_clause_commonblockEa"} : (!fir.ref) -> (!fir.ref, !fir.ref) -!CHECK: %[[B_PVT_REF:.*]] = fir.alloca !fir.array<10xf32> {bindc_name = "b", pinned, uniq_name = "_QFprivate_clause_commonblockEb"} -!CHECK: %[[SH10:.*]] = fir.shape %c10 : (index) -> !fir.shape<1> +!CHECK: %[[SH10:.*]] = fir.shape %c10{{.*}} : (index) -> !fir.shape<1> !CHECK: %[[B_PVT_DECL:.*]]:2 = hlfir.declare %[[B_PVT_REF]](%[[SH10]]) {uniq_name = "_QFprivate_clause_commonblockEb"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) -!CHECK: %[[C_PVT_REF:.*]] = fir.alloca !fir.char<1,5> {bindc_name = "c", pinned, uniq_name = "_QFprivate_clause_commonblockEc"} !CHECK: %[[C_PVT_DECL:.*]]:2 = hlfir.declare %[[C_PVT_REF]] typeparams %{{.*}} {uniq_name = "_QFprivate_clause_commonblockEc"} : (!fir.ref>, index) -> (!fir.ref>, !fir.ref>) -!CHECK: %[[D_PVT_REF:.*]] = fir.alloca !fir.array<5x!fir.char<1,5>> {bindc_name = "d", pinned, uniq_name = "_QFprivate_clause_commonblockEd"} -!CHECK: %[[SH5:.*]] = fir.shape %c5_1 : (index) -> !fir.shape<1> -!CHECK: %[[D_PVT_DECL:.*]]:2 = hlfir.declare %[[D_PVT_REF]](%[[SH5]]) typeparams %[[TP5]] {uniq_name = "_QFprivate_clause_commonblockEd"} : (!fir.ref>>, !fir.shape<1>, index) -> (!fir.ref>>, !fir.ref>>) +!CHECK: %[[SH5:.*]] = fir.shape %c5{{.*}} : (index) -> !fir.shape<1> +!CHECK: %[[D_PVT_DECL:.*]]:2 = hlfir.declare %[[D_PVT_REF]](%[[SH5]]) typeparams %c5{{.*}} {uniq_name = "_QFprivate_clause_commonblockEd"} : (!fir.ref>>, !fir.shape<1>, index) -> (!fir.ref>>, !fir.ref>>) !CHECK: %[[C_PVT_BOX:.*]] = fir.emboxchar %[[C_PVT_DECL]]#1, %{{.*}} : (!fir.ref>, index) -> !fir.boxchar<1> !CHECK: %[[D_PVT_REF:.*]] = fir.convert %[[D_PVT_DECL]]#1 : (!fir.ref>>) -> !fir.ref> !CHECK: %[[D_PVT_BOX:.*]] = fir.emboxchar %[[D_PVT_REF]], %{{.*}} : (!fir.ref>, index) -> !fir.boxchar<1> @@ -98,10 +94,8 @@ end subroutine !CHECK: %[[C_ADDR:.*]] = fir.box_addr %[[C_BOX]] : (!fir.box>>) -> !fir.ptr> !CHECK: %[[C_REF:.*]] = fir.convert %[[C_ADDR]] : (!fir.ptr>) -> !fir.ref> !CHECK: fir.call @_QPsub4(%[[C_REF]], %[[A_DECL]]#1) fastmath : (!fir.ref>, !fir.ref) -> () -!CHECK: omp.parallel { -!CHECK: %[[C_PVT_REF:.*]] = fir.alloca !fir.box>> {bindc_name = "c", pinned, uniq_name = "_QFprivate_clause_commonblock_pointerEc"} +!CHECK: omp.parallel private(@{{.*}} %{{.*}}#0 -> %[[C_PVT_REF:.*]] : {{.*}}, @{{.*}} %{{.*}}#0 -> %[[A_PVT_REF:.*]] : {{.*}}) { !CHECK: %[[C_PVT_DECL:.*]]:2 = hlfir.declare %[[C_PVT_REF]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QFprivate_clause_commonblock_pointerEc"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) -!CHECK: %[[A_PVT_REF:.*]] = fir.alloca i32 {bindc_name = "a", pinned, uniq_name = "_QFprivate_clause_commonblock_pointerEa"} !CHECK: %[[A_PVT_DECL:.*]]:2 = hlfir.declare %[[A_PVT_REF]] {uniq_name = "_QFprivate_clause_commonblock_pointerEa"} : (!fir.ref) -> (!fir.ref, !fir.ref) !CHECK: %[[C_PVT_BOX:.*]] = fir.load %[[C_PVT_DECL]]#0 : !fir.ref>>> !CHECK: %[[C_PVT_ADDR:.*]] = fir.box_addr %[[C_PVT_BOX]] : (!fir.box>>) -> !fir.ptr>