[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