[flang-commits] [flang] [Flang][OpenMP] Fix crash privatizing USE'd module variable in BLOCK (PR #182060)
CHANDRA GHALE via flang-commits
flang-commits at lists.llvm.org
Thu Feb 19 22:57:16 PST 2026
https://github.com/chandraghale updated https://github.com/llvm/llvm-project/pull/182060
>From ccf5de87bc50459cb29409da0bcfe7052ccce797 Mon Sep 17 00:00:00 2001
From: Chandra Ghale <ghale at pe31.hpc.amslabs.hpecorp.net>
Date: Wed, 18 Feb 2026 10:29:14 -0600
Subject: [PATCH 1/3] Fix crash privatizing USE'd module variable in BLOCK
---
.../lib/Lower/OpenMP/DataSharingProcessor.cpp | 11 +++++
flang/lib/Lower/Support/Utils.cpp | 7 ++-
.../block-use-predetermined-privatization.f90 | 43 +++++++++++++++++++
3 files changed, 60 insertions(+), 1 deletion(-)
create mode 100644 flang/test/Lower/OpenMP/block-use-predetermined-privatization.f90
diff --git a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
index fcf2ae9337295..d4dc09c0cd5b4 100644
--- a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
@@ -616,6 +616,17 @@ void DataSharingProcessor::privatizeSymbol(
copyFirstPrivateSymbol(symToPrivatize);
return;
}
+ // Module variables accessed via USE inside nested BLOCKs may not yet
+ // be instantiated when the enclosing OpenMP construct's privatization
+ // runs. Instantiate them now so the host symbol box will be available.
+ const auto &ultimate = symToPrivatize->GetUltimate();
+ if (ultimate.owner().kind() == semantics::Scope::Kind::Module &&
+ !symTable.lookupSymbol(ultimate)) {
+ Fortran::lower::AggregateStoreMap storeMap;
+ Fortran::lower::instantiateVariable(
+ converter, Fortran::lower::pft::Variable{ultimate, /*global=*/true},
+ symTable, storeMap);
+ }
Fortran::lower::privatizeSymbol<mlir::omp::PrivateClauseOp,
mlir::omp::PrivateClauseOps>(
diff --git a/flang/lib/Lower/Support/Utils.cpp b/flang/lib/Lower/Support/Utils.cpp
index 159ce5211dacb..5eddf872be60c 100644
--- a/flang/lib/Lower/Support/Utils.cpp
+++ b/flang/lib/Lower/Support/Utils.cpp
@@ -685,7 +685,9 @@ void privatizeSymbol(
const semantics::Symbol *sym =
isDoConcurrent ? &symToPrivatize->GetUltimate() : symToPrivatize;
- const lower::SymbolBox hsb = converter.lookupOneLevelUpSymbol(*sym);
+ lower::SymbolBox hsb = converter.lookupOneLevelUpSymbol(*sym);
+ if (!hsb)
+ hsb = symTable.lookupSymbol(*sym);
assert(hsb && "Host symbol box not found");
mlir::Location symLoc = hsb.getAddr().getLoc();
@@ -780,6 +782,9 @@ void privatizeSymbol(
if (needsInitialization) {
lower::SymbolBox hsb = converter.lookupOneLevelUpSymbol(
isDoConcurrent ? symToPrivatize->GetUltimate() : *symToPrivatize);
+ if (!hsb)
+ hsb = symTable.lookupSymbol(
+ isDoConcurrent ? symToPrivatize->GetUltimate() : *symToPrivatize);
assert(hsb && "Host symbol box not found");
hlfir::Entity entity{hsb.getAddr()};
diff --git a/flang/test/Lower/OpenMP/block-use-predetermined-privatization.f90 b/flang/test/Lower/OpenMP/block-use-predetermined-privatization.f90
new file mode 100644
index 0000000000000..4509b98c344ab
--- /dev/null
+++ b/flang/test/Lower/OpenMP/block-use-predetermined-privatization.f90
@@ -0,0 +1,43 @@
+! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
+
+module m
+ integer :: n
+end module
+
+program p
+ integer :: i
+
+ !$omp parallel do
+ do i=1,2
+ block
+ use m
+ do n=1,2
+ end do
+ end block
+ end do
+end program p
+
+! Verify the privatizer recipe for the module variable is created.
+! CHECK: omp.private {type = private} @[[N_PRIV:.*QMmEn_private.*]] : i32
+! CHECK: omp.private {type = private} @[[I_PRIV:.*Ei_private.*]] : i32
+
+! Verify the module global exists.
+! CHECK: fir.global @_QMmEn : i32
+
+! CHECK-LABEL: func.func @_QQmain()
+! CHECK: %[[I_ALLOC:.*]] = fir.alloca i32 {bindc_name = "i"
+! CHECK: %[[I_DECL:.*]]:2 = hlfir.declare %[[I_ALLOC]] {uniq_name = "_QFEi"}
+! CHECK: omp.parallel {
+
+! Verify the module variable is instantiated inside the parallel region.
+! CHECK: %[[N_ADDR:.*]] = fir.address_of(@_QMmEn) : !fir.ref<i32>
+! CHECK: %[[N_DECL:.*]]:2 = hlfir.declare %[[N_ADDR]] {uniq_name = "_QMmEn"}
+
+! Verify the wsloop privatizes both i and n.
+! CHECK: omp.wsloop private(@[[I_PRIV]] %[[I_DECL]]#0 -> %{{.*}}, @[[N_PRIV]] %[[N_DECL]]#0 -> %{{.*}} : !fir.ref<i32>, !fir.ref<i32>) {
+! CHECK: omp.loop_nest (%{{.*}}) : i32 =
+! CHECK: fir.do_loop
+! CHECK: omp.yield
+! CHECK: }
+! CHECK: omp.terminator
+! CHECK: }
>From 5bf478e75c4b7bd38e6a6b7aa0e12885c31a8eed Mon Sep 17 00:00:00 2001
From: Chandra Ghale <ghale at pe31.hpc.amslabs.hpecorp.net>
Date: Fri, 20 Feb 2026 00:26:42 -0600
Subject: [PATCH 2/3] Address review comments
---
.../lib/Lower/OpenMP/DataSharingProcessor.cpp | 11 ----------
flang/lib/Lower/Support/Utils.cpp | 20 ++++++++++++-------
2 files changed, 13 insertions(+), 18 deletions(-)
diff --git a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
index d4dc09c0cd5b4..fcf2ae9337295 100644
--- a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
@@ -616,17 +616,6 @@ void DataSharingProcessor::privatizeSymbol(
copyFirstPrivateSymbol(symToPrivatize);
return;
}
- // Module variables accessed via USE inside nested BLOCKs may not yet
- // be instantiated when the enclosing OpenMP construct's privatization
- // runs. Instantiate them now so the host symbol box will be available.
- const auto &ultimate = symToPrivatize->GetUltimate();
- if (ultimate.owner().kind() == semantics::Scope::Kind::Module &&
- !symTable.lookupSymbol(ultimate)) {
- Fortran::lower::AggregateStoreMap storeMap;
- Fortran::lower::instantiateVariable(
- converter, Fortran::lower::pft::Variable{ultimate, /*global=*/true},
- symTable, storeMap);
- }
Fortran::lower::privatizeSymbol<mlir::omp::PrivateClauseOp,
mlir::omp::PrivateClauseOps>(
diff --git a/flang/lib/Lower/Support/Utils.cpp b/flang/lib/Lower/Support/Utils.cpp
index 5eddf872be60c..c012f841ae30a 100644
--- a/flang/lib/Lower/Support/Utils.cpp
+++ b/flang/lib/Lower/Support/Utils.cpp
@@ -685,9 +685,18 @@ void privatizeSymbol(
const semantics::Symbol *sym =
isDoConcurrent ? &symToPrivatize->GetUltimate() : symToPrivatize;
- lower::SymbolBox hsb = converter.lookupOneLevelUpSymbol(*sym);
- if (!hsb)
- hsb = symTable.lookupSymbol(*sym);
+ // Module variables accessed via USE inside nested BLOCKs may not be
+ // instantiated yet. Ensure they are bound before looking up the host box.
+ const auto &ultimate = sym->GetUltimate();
+ if (ultimate.owner().kind() == semantics::Scope::Kind::Module &&
+ !symTable.lookupSymbol(ultimate)) {
+ Fortran::lower::AggregateStoreMap storeMap;
+ Fortran::lower::instantiateVariable(
+ converter,
+ Fortran::lower::pft::Variable{ultimate, /*global=*/true},
+ symTable, storeMap);
+ }
+ lower::SymbolBox hsb = symTable.lookupSymbol(*sym);
assert(hsb && "Host symbol box not found");
mlir::Location symLoc = hsb.getAddr().getLoc();
@@ -780,11 +789,8 @@ void privatizeSymbol(
mlir::isa<fir::BaseBoxType>(allocType) ||
mlir::isa<fir::BoxCharType>(allocType);
if (needsInitialization) {
- lower::SymbolBox hsb = converter.lookupOneLevelUpSymbol(
+ lower::SymbolBox hsb = symTable.lookupSymbol(
isDoConcurrent ? symToPrivatize->GetUltimate() : *symToPrivatize);
- if (!hsb)
- hsb = symTable.lookupSymbol(
- isDoConcurrent ? symToPrivatize->GetUltimate() : *symToPrivatize);
assert(hsb && "Host symbol box not found");
hlfir::Entity entity{hsb.getAddr()};
>From a4e5d3bbab164582d82d2f4861c6db0140a1750a Mon Sep 17 00:00:00 2001
From: Chandra Ghale <ghale at pe31.hpc.amslabs.hpecorp.net>
Date: Fri, 20 Feb 2026 00:30:40 -0600
Subject: [PATCH 3/3] code formatting
---
flang/lib/Lower/Support/Utils.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/flang/lib/Lower/Support/Utils.cpp b/flang/lib/Lower/Support/Utils.cpp
index c012f841ae30a..384636a659875 100644
--- a/flang/lib/Lower/Support/Utils.cpp
+++ b/flang/lib/Lower/Support/Utils.cpp
@@ -16,6 +16,7 @@
#include "flang/Lower/AbstractConverter.h"
#include "flang/Lower/ConvertVariable.h"
#include "flang/Lower/IterationSpace.h"
+#include "flang/Lower/PFTBuilder.h"
#include "flang/Lower/Support/PrivateReductionUtils.h"
#include "flang/Optimizer/Builder/HLFIRTools.h"
#include "flang/Optimizer/Builder/Todo.h"
@@ -692,8 +693,7 @@ void privatizeSymbol(
!symTable.lookupSymbol(ultimate)) {
Fortran::lower::AggregateStoreMap storeMap;
Fortran::lower::instantiateVariable(
- converter,
- Fortran::lower::pft::Variable{ultimate, /*global=*/true},
+ converter, Fortran::lower::pft::Variable{ultimate, /*global=*/true},
symTable, storeMap);
}
lower::SymbolBox hsb = symTable.lookupSymbol(*sym);
More information about the flang-commits
mailing list