[flang-commits] [flang] [Flang][OpenMP] Fix default firstprivatization miscategorization of mod file symbols (PR #157009)

via flang-commits flang-commits at lists.llvm.org
Fri Sep 5 15:20:56 PDT 2025


https://github.com/agozillon updated https://github.com/llvm/llvm-project/pull/157009

>From 732d3a9f6bbaf5dd3a0e36c715ef407e2808ddea Mon Sep 17 00:00:00 2001
From: agozillon <Andrew.Gozillon at amd.com>
Date: Thu, 4 Sep 2025 22:58:34 -0500
Subject: [PATCH 1/2] [Flang][OpenMP] Fix default firstprivatization
 miscategorization of mod file symbols

In at least certain cases, notably when equivalence is used (at least for the example
this showed up as a problem in) we currently miscategorize symbols as firstprivate
when they may not be, as they can throw a false positive when a yse symbol from a mod
file is picked up.

The fix to this is to chase up the appropriate symbol to access the correct details.
---
 flang/lib/Semantics/resolve-directives.cpp | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index a08e764ecf936..2eca768766887 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -2517,14 +2517,15 @@ static bool IsTargetCaptureImplicitlyFirstprivatizeable(const Symbol &symbol,
     return false;
   };
 
-  if (checkSymbol(symbol)) {
-    const auto *hostAssoc{symbol.detailsIf<HostAssocDetails>()};
-    if (hostAssoc) {
-      return checkSymbol(hostAssoc->symbol());
-    }
-    return true;
-  }
-  return false;
+  return common::visit(
+      common::visitors{
+          [&](const UseDetails &x) -> bool { return checkSymbol(x.symbol()); },
+          [&](const HostAssocDetails &x) -> bool {
+            return checkSymbol(x.symbol());
+          },
+          [&](const auto &) -> bool { return checkSymbol(symbol); },
+      },
+      symbol.details());
 }
 
 void OmpAttributeVisitor::CreateImplicitSymbols(const Symbol *symbol) {

>From 458047dac14be66765dc77bb4c5e883e8321afb3 Mon Sep 17 00:00:00 2001
From: agozillon <Andrew.Gozillon at amd.com>
Date: Fri, 5 Sep 2025 17:17:47 -0500
Subject: [PATCH 2/2] [Flang][OpenMP] Add test checking module types are not
 incorrectly firstprivatized

---
 .../target-private-implicit-scalar-map-2.f90  | 37 +++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100644 flang/test/Lower/OpenMP/DelayedPrivatization/target-private-implicit-scalar-map-2.f90

diff --git a/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-implicit-scalar-map-2.f90 b/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-implicit-scalar-map-2.f90
new file mode 100644
index 0000000000000..b6c3058e22309
--- /dev/null
+++ b/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-implicit-scalar-map-2.f90
@@ -0,0 +1,37 @@
+! Test that we appropriately categorize types as firstprivate even across
+! module boundaries.
+
+!RUN: split-file %s %t
+
+!RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --enable-delayed-privatization-staging -fopenmp-version=50 %t/imp_scalar_map_module.f90 -o - \
+!RUN: | %flang_fc1 -emit-hlfir -fopenmp -mmlir --enable-delayed-privatization-staging  -fopenmp-version=50 %t/imp_scalar_map_target.f90 -o - \
+!RUN: | FileCheck %t/imp_scalar_map_target.f90
+
+!--- imp_scalar_map_module.f90
+module test_data
+    implicit none
+    integer :: z
+    real :: i(10,10), j(5,5,2), k(25,2)
+    equivalence(j(1,1,1),k(1,1))
+end module
+
+!--- imp_scalar_map_target.f90
+subroutine target_imp_capture
+    use test_data
+    implicit none
+    integer :: x, y
+
+    !$omp target map(tofrom: x)
+        x = y + z + i(1,1) + j(1,1,1) + k(1,1)
+    !$omp end target
+
+end subroutine target_imp_capture
+
+! CHECK-LABEL: func.func @_QPtarget_imp_capture()
+! CHECK:           %[[VAL_0:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> {name = "x"}
+! CHECK:           %[[VAL_1:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<!fir.array<10x10xf32>>, !fir.array<10x10xf32>) map_clauses(implicit, tofrom) capture(ByRef) bounds({{.*}}) -> !fir.ref<!fir.array<10x10xf32>> {name = "i"}
+! CHECK:           %[[VAL_2:.*]] = omp.map.info var_ptr(%{{.*}} : !fir.ptr<!fir.array<5x5x2xf32>>, !fir.array<5x5x2xf32>) map_clauses(implicit, tofrom) capture(ByRef) bounds({{.*}}) -> !fir.ptr<!fir.array<5x5x2xf32>> {name = "j"}
+! CHECK:           %[[VAL_3:.*]] = omp.map.info var_ptr(%{{.*}} : !fir.ptr<!fir.array<25x2xf32>>, !fir.array<25x2xf32>) map_clauses(implicit, tofrom) capture(ByRef) bounds({{.*}}) -> !fir.ptr<!fir.array<25x2xf32>> {name = "k"}
+! CHECK:           %[[VAL_4:.*]] = omp.map.info var_ptr(%{{.*}} : !fir.ref<i32>, i32) map_clauses(to) capture(ByCopy) -> !fir.ref<i32>
+! CHECK:           %[[VAL_5:.*]] = omp.map.info var_ptr(%{{.*}} : !fir.ref<i32>, i32) map_clauses(to) capture(ByCopy) -> !fir.ref<i32>
+! CHECK:           omp.target map_entries(%[[VAL_0]] -> %[[VAL_6:.*]], %[[VAL_1]] -> %[[VAL_7:.*]], %[[VAL_2]] -> %[[VAL_8:.*]], %[[VAL_3]] -> %[[VAL_9:.*]], %[[VAL_4]] -> %[[VAL_10:.*]], %[[VAL_5]] -> %[[VAL_11:.*]] : !fir.ref<i32>, !fir.ref<!fir.array<10x10xf32>>, !fir.ptr<!fir.array<5x5x2xf32>>, !fir.ptr<!fir.array<25x2xf32>>, !fir.ref<i32>, !fir.ref<i32>) private(@_QFtarget_imp_captureEy_firstprivate_i32 %{{.*}}#0 -> %[[VAL_12:.*]] [map_idx=4], @_QMtest_dataEz_firstprivate_i32 %{{.*}}#0 -> %[[VAL_13:.*]] [map_idx=5] : !fir.ref<i32>, !fir.ref<i32>) {



More information about the flang-commits mailing list