[flang-commits] [flang] c8e2503 - [Flang][OpenMP] Fix crash privatizing USE'd module variable in BLOCK (#182060)

via flang-commits flang-commits at lists.llvm.org
Mon Feb 23 01:19:08 PST 2026


Author: CHANDRA GHALE
Date: 2026-02-23T14:49:04+05:30
New Revision: c8e2503336409b2eb63b126c2f1039435ec70689

URL: https://github.com/llvm/llvm-project/commit/c8e2503336409b2eb63b126c2f1039435ec70689
DIFF: https://github.com/llvm/llvm-project/commit/c8e2503336409b2eb63b126c2f1039435ec70689.diff

LOG: [Flang][OpenMP] Fix crash privatizing USE'd module variable in BLOCK (#182060)

Module variables accessed via USE inside a BLOCK nested in an OpenMP
construct (parallel do, taskloop) crash during lowering because the host
symbol box doesn't exist yet — the BLOCK hasn't been lowered when
privatization runs.

The fix instantiates the module global on demand in the
DataSharingProcessor before privatization, and adds a fallback from
lookupOneLevelUpSymbol to lookupSymbol in privatizeSymbol for symbols
bound at the current scope level.
 
Fixes : [#161183 ](https://github.com/llvm/llvm-project/issues/161183)

---------

Co-authored-by: Chandra Ghale <ghale at pe31.hpc.amslabs.hpecorp.net>

Added: 
    flang/test/Lower/OpenMP/block-use-predetermined-privatization.f90

Modified: 
    flang/lib/Lower/Support/Utils.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Lower/Support/Utils.cpp b/flang/lib/Lower/Support/Utils.cpp
index 159ce5211dacb..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"
@@ -685,7 +686,17 @@ void privatizeSymbol(
 
   const semantics::Symbol *sym =
       isDoConcurrent ? &symToPrivatize->GetUltimate() : symToPrivatize;
-  const lower::SymbolBox hsb = converter.lookupOneLevelUpSymbol(*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();
@@ -778,7 +789,7 @@ 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);
 
       assert(hsb && "Host symbol box not found");

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:         }


        


More information about the flang-commits mailing list