[flang-commits] [flang] 08222ca - [Flang][OpenMP] Move char box bounds generation for Maps to DirectiveCommons.h (#165918)
via flang-commits
flang-commits at lists.llvm.org
Mon Nov 10 10:57:57 PST 2025
Author: agozillon
Date: 2025-11-10T19:57:53+01:00
New Revision: 08222caf28b6bcc9376f352b552cecf640e8537e
URL: https://github.com/llvm/llvm-project/commit/08222caf28b6bcc9376f352b552cecf640e8537e
DIFF: https://github.com/llvm/llvm-project/commit/08222caf28b6bcc9376f352b552cecf640e8537e.diff
LOG: [Flang][OpenMP] Move char box bounds generation for Maps to DirectiveCommons.h (#165918)
Currently we generate these bounds in the MapInfoFinalization.cpp pass
as it seems there's a missing case for character strings/arrays (length
parameter) in the DirectiveCommons bounds generation functionality
OpenMP uses for it's map operations.
This PR tries to add this case to the DirectiveCommons function and
remove the need for the bounds generation in the MapInfoFinalization
pass, so that we are generating the bounds in the same place most other
bounds are generated.
Added:
flang/test/Lower/OpenMP/dynamic-len-char-bounds-gen.f90
Modified:
flang/include/flang/Lower/DirectivesCommon.h
flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp
Removed:
################################################################################
diff --git a/flang/include/flang/Lower/DirectivesCommon.h b/flang/include/flang/Lower/DirectivesCommon.h
index 2d6906738773a..b564ee1f64423 100644
--- a/flang/include/flang/Lower/DirectivesCommon.h
+++ b/flang/include/flang/Lower/DirectivesCommon.h
@@ -512,11 +512,19 @@ fir::factory::AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
}
bool dataExvIsAssumedSize =
Fortran::semantics::IsAssumedSizeArray(symRef->get().GetUltimate());
- if (genDefaultBounds &&
- mlir::isa<fir::SequenceType>(fir::unwrapRefType(info.addr.getType())))
+ if (genDefaultBounds && mlir::isa<fir::SequenceType>(
+ fir::unwrapRefType(info.addr.getType()))) {
bounds = fir::factory::genBaseBoundsOps<BoundsOp, BoundsType>(
builder, operandLocation, dataExv, dataExvIsAssumedSize,
strideIncludeLowerExtent);
+ }
+ if (genDefaultBounds && fir::characterWithDynamicLen(
+ fir::unwrapRefType(info.addr.getType())) ||
+ mlir::isa<fir::BoxCharType>(
+ fir::unwrapRefType(info.addr.getType()))) {
+ bounds = {fir::factory::genBoundsOpFromBoxChar<BoundsOp, BoundsType>(
+ builder, operandLocation, dataExv, info)};
+ }
asFortran << symRef->get().name().ToString();
} else { // Unsupported
llvm::report_fatal_error("Unsupported type of OpenACC operand");
diff --git a/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp b/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp
index d60da8971efd9..8382a481ee875 100644
--- a/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp
+++ b/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp
@@ -943,38 +943,6 @@ class MapInfoFinalizationPass
localBoxAllocas.clear();
deferrableDesc.clear();
- // First, walk `omp.map.info` ops to see if any of them have varPtrs
- // with an underlying type of fir.char<k, ?>, i.e a character
- // with dynamic length. If so, check if they need bounds added.
- func->walk([&](mlir::omp::MapInfoOp op) {
- if (!op.getBounds().empty())
- return;
-
- mlir::Value varPtr = op.getVarPtr();
- mlir::Type underlyingVarType = fir::unwrapRefType(varPtr.getType());
-
- if (!fir::characterWithDynamicLen(underlyingVarType))
- return;
-
- fir::factory::AddrAndBoundsInfo info =
- fir::factory::getDataOperandBaseAddr(
- builder, varPtr, /*isOptional=*/false, varPtr.getLoc());
-
- fir::ExtendedValue extendedValue =
- hlfir::translateToExtendedValue(varPtr.getLoc(), builder,
- hlfir::Entity{info.addr},
- /*continguousHint=*/true)
- .first;
- builder.setInsertionPoint(op);
- llvm::SmallVector<mlir::Value> boundsOps =
- fir::factory::genImplicitBoundsOps<mlir::omp::MapBoundsOp,
- mlir::omp::MapBoundsType>(
- builder, info, extendedValue,
- /*dataExvIsAssumedSize=*/false, varPtr.getLoc());
-
- op.getBoundsMutable().append(boundsOps);
- });
-
// Next, walk `omp.map.info` ops to see if any record members should be
// implicitly mapped.
func->walk([&](mlir::omp::MapInfoOp op) {
diff --git a/flang/test/Lower/OpenMP/dynamic-len-char-bounds-gen.f90 b/flang/test/Lower/OpenMP/dynamic-len-char-bounds-gen.f90
new file mode 100644
index 0000000000000..88839221cc6d2
--- /dev/null
+++ b/flang/test/Lower/OpenMP/dynamic-len-char-bounds-gen.f90
@@ -0,0 +1,19 @@
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
+
+subroutine TestCharLenBounds(clen)
+
+ character(len=*) :: clen
+
+ !$omp target map(clen)
+ !$omp end target
+end subroutine TestCharLenBounds
+
+!CHECK: %[[DUMMY:.*]] = fir.dummy_scope : !fir.dscope
+!CHECK: %[[UNBOX:.*]]:2 = fir.unboxchar %{{.*}} : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
+!CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[UNBOX]]#0 typeparams %2#1 dummy_scope %[[DUMMY]] {uniq_name = "_QFtestcharlenboundsEclen"} : (!fir.ref<!fir.char<1,?>>, index, !fir.dscope) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
+!CHECK: %[[LB_START_IDX:.*]] = arith.constant 0 : index
+!CHECK: %[[STRIDE:.*]] = arith.constant 1 : index
+!CHECK: %[[EXTENT:.*]]:2 = fir.unboxchar %[[DECLARE]]#0 : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
+!CHECK: %[[UB:.*]] = arith.subi %[[EXTENT]]#1, %[[STRIDE]] : index
+!CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound(%[[LB_START_IDX]] : index) upper_bound(%[[UB]] : index) extent(%[[EXTENT]]#1 : index) stride(%[[STRIDE]] : index) start_idx(%[[LB_START_IDX]] : index) {stride_in_bytes = true}
+!CHECK: %{{.*}} = omp.map.info {{.*}} bounds(%[[BOUNDS]]) {{.*}}
More information about the flang-commits
mailing list