[flang-commits] [flang] [flang][OpenMP] Fix the privatization of common blocks (PR #200446)
Leandro Lupori via flang-commits
flang-commits at lists.llvm.org
Fri May 29 09:19:21 PDT 2026
https://github.com/luporl created https://github.com/llvm/llvm-project/pull/200446
Common block objects were being replaced on every privatization,
which caused errors for distinct privatizations on nested constructs.
Modifying a common block clone, instead of the original one, fixes the
issue. Cloning is limited to DSA flags because target mapping lowering
expects to find the common block address, through its defining
operation.
Fixes #178790
>From 01ab0981a86f7aa97f38af4feae68361b02ec92e Mon Sep 17 00:00:00 2001
From: Leandro Lupori <leandro.lupori at linaro.org>
Date: Mon, 25 May 2026 17:31:40 -0300
Subject: [PATCH] [flang][OpenMP] Fix the privatization of common blocks
Common block objects were being replaced on every privatization,
which caused errors for distinct privatizations on nested constructs.
Modifying a common block clone, instead of the original one, fixes the
issue. Cloning is limited to DSA flags because target mapping lowering
expects to find the common block address, through its defining
operation.
Fixes #178790
---
flang/lib/Semantics/resolve-directives.cpp | 21 ++++++++++++++++++-
.../test/Lower/OpenMP/nested-commonblock.f90 | 15 +++++++++++++
2 files changed, 35 insertions(+), 1 deletion(-)
create mode 100644 flang/test/Lower/OpenMP/nested-commonblock.f90
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 2fa59adf7f3af..dcdf49f073d79 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -3000,6 +3000,15 @@ void OmpAttributeVisitor::PropagateOmpFlagToEquivalenceSet(
void OmpAttributeVisitor::ResolveOmpCommonBlock(
const parser::Name &name, Symbol::Flag ompFlag) {
+ if (name.symbol) {
+ if (auto *details{name.symbol->detailsIf<CommonBlockDetails>()}) {
+ if (!details->objects().empty()) {
+ // Common block already resolved
+ return;
+ }
+ }
+ }
+
if (auto *symbol{ResolveOmpCommonBlockName(&name)}) {
if (!dataCopyingAttributeFlags.test(ompFlag)) {
CheckMultipleAppearances(name, *symbol, Symbol::Flag::OmpCommonBlock);
@@ -3008,6 +3017,8 @@ void OmpAttributeVisitor::ResolveOmpCommonBlock(
// same meaning as if every explicit member of the common block
// appeared in the list
auto &details{symbol->get<CommonBlockDetails>()};
+ bool cloneCommonBlock{dataSharingAttributeFlags.test(ompFlag)};
+ CommonBlockDetails cloneDetails{symbol->name()};
for (auto [index, object] : llvm::enumerate(details.objects())) {
if (auto *resolvedObject{ResolveOmp(*object, ompFlag, currScope())}) {
if (dataCopyingAttributeFlags.test(ompFlag)) {
@@ -3015,7 +3026,11 @@ void OmpAttributeVisitor::ResolveOmpCommonBlock(
} else {
AddToContextObjectWithExplicitDSA(*resolvedObject, ompFlag);
}
- details.replace_object(*resolvedObject, index);
+ if (cloneCommonBlock) {
+ cloneDetails.add_object(*resolvedObject);
+ } else {
+ details.replace_object(*resolvedObject, index);
+ }
// Propagate the flag to symbols in the equivalence set
if (ompFlag == Symbol::Flag::OmpThreadprivate) {
@@ -3023,6 +3038,10 @@ void OmpAttributeVisitor::ResolveOmpCommonBlock(
}
}
}
+ if (cloneCommonBlock) {
+ name.symbol = &currScope().MakeSymbol(
+ symbol->name(), symbol->attrs(), std::move(cloneDetails));
+ }
} else {
context_.Say(name.source, // 2.15.3
"COMMON block must be declared in the same scoping unit in which the OpenMP directive or clause appears"_err_en_US);
diff --git a/flang/test/Lower/OpenMP/nested-commonblock.f90 b/flang/test/Lower/OpenMP/nested-commonblock.f90
new file mode 100644
index 0000000000000..65c0b6d2ecbd8
--- /dev/null
+++ b/flang/test/Lower/OpenMP/nested-commonblock.f90
@@ -0,0 +1,15 @@
+! RUN: %flang_fc1 -fopenmp -emit-hlfir -o - %s 2>&1 | FileCheck %s
+
+!CHECK-LABEL: func @_QPtest_nested()
+!CHECK: omp.parallel private(@_QFtest_nestedEa_firstprivate_i32 {{.*}}, @_QFtest_nestedEb_firstprivate_i32 {{.*}})
+!CHECK: omp.parallel private(@_QFtest_nestedEa_private_i32 {{.*}}, @_QFtest_nestedEb_private_i32 {{.*}})
+
+subroutine test_nested()
+ integer :: a, b
+ common /com/ a, b
+
+ !$omp parallel firstprivate(/com/)
+ !$omp parallel private(/com/)
+ !$omp end parallel
+ !$omp end parallel
+end subroutine
More information about the flang-commits
mailing list