From 295474b744f444bc9bb00b34bb2a1ea879604ab5 Mon Sep 17 00:00:00 2001 From: Akash Banerjee Date: Wed, 15 Nov 2023 22:12:31 +0000 Subject: [PATCH] [Flang][OpenMP] Remove use of non reference values from MapInfoOp This patch removes the `val` field from the MapInfoOp. Previously when lowering TargetOp, the bounds information for the BoxValues were also being mapped. Instead these ops are now duplicated inside the target region to prevent mapping of non reference typed values. --- flang/lib/Lower/OpenMP.cpp | 176 +++++++++--------- flang/test/Lower/OpenMP/FIR/array-bounds.f90 | 4 +- flang/test/Lower/OpenMP/FIR/target.f90 | 76 ++++++-- flang/test/Lower/OpenMP/array-bounds.f90 | 4 +- flang/test/Lower/OpenMP/target.f90 | 73 +++++--- mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td | 15 +- mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp | 9 - .../OpenMP/OpenMPToLLVMIRTranslation.cpp | 41 ++-- mlir/test/Dialect/OpenMP/invalid.mlir | 36 ---- .../offloading/fortran/constant-arr-index.f90 | 6 +- ...y.f90 => target-region-implicit-array.f90} | 9 +- 11 files changed, 221 insertions(+), 228 deletions(-) rename openmp/libomptarget/test/offloading/fortran/{basic-target-region-array.f90 => target-region-implicit-array.f90} (87%) diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index f6a61ba3a528e..7ac6f06f250a5 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -28,6 +28,7 @@ #include "flang/Semantics/tools.h" #include "mlir/Dialect/OpenMP/OpenMPDialect.h" #include "mlir/Dialect/SCF/IR/SCF.h" +#include "mlir/Transforms/RegionUtils.h" #include "llvm/Frontend/OpenMP/OMPConstants.h" #include "llvm/Support/CommandLine.h" @@ -1709,9 +1710,9 @@ static mlir::omp::MapInfoOp createMapInfoOp(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value baseAddr, std::stringstream &name, mlir::SmallVector bounds, uint64_t mapType, - mlir::omp::VariableCaptureKind mapCaptureType, mlir::Type retTy, - bool isVal = false) { - mlir::Value val, varPtr, varPtrPtr; + mlir::omp::VariableCaptureKind mapCaptureType, + mlir::Type retTy) { + mlir::Value varPtr, varPtrPtr; mlir::TypeAttr varType; if (auto boxTy = baseAddr.getType().dyn_cast()) { @@ -1719,16 +1720,12 @@ createMapInfoOp(fir::FirOpBuilder &builder, mlir::Location loc, retTy = baseAddr.getType(); } - if (isVal) - val = baseAddr; - else - varPtr = baseAddr; - - if (auto ptrType = llvm::dyn_cast(retTy)) - varType = mlir::TypeAttr::get(ptrType.getElementType()); + varPtr = baseAddr; + varType = mlir::TypeAttr::get( + llvm::cast(retTy).getElementType()); mlir::omp::MapInfoOp op = builder.create( - loc, retTy, val, varPtr, varType, varPtrPtr, bounds, + loc, retTy, varPtr, varType, varPtrPtr, bounds, builder.getIntegerAttr(builder.getIntegerType(64, false), mapType), builder.getAttr(mapCaptureType), builder.getStringAttr(name.str())); @@ -2489,21 +2486,27 @@ static void genBodyOfTargetOp( fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); mlir::Region ®ion = targetOp.getRegion(); - firOpBuilder.createBlock(®ion, {}, mapSymTypes, mapSymLocs); + auto *regionBlock = + firOpBuilder.createBlock(®ion, {}, mapSymTypes, mapSymLocs); unsigned argIndex = 0; - unsigned blockArgsIndex = mapSymbols.size(); - - // The block arguments contain the map_operands followed by the bounds in - // order. This returns a vector containing the next 'n' block arguments for - // the bounds. - auto extractBoundArgs = [&](auto n) { - llvm::SmallVector argExtents; - while (n--) { - argExtents.push_back(fir::getBase(region.getArgument(blockArgsIndex))); - blockArgsIndex++; + + // Clones the `bounds` placing them inside the target region and returns them. + auto cloneBound = [&](mlir::Value bound) { + if (mlir::isMemoryEffectFree(bound.getDefiningOp())) { + mlir::Operation *clonedOp = bound.getDefiningOp()->clone(); + regionBlock->push_back(clonedOp); + return clonedOp->getResult(0); } - return argExtents; + TODO(converter.getCurrentLocation(), + "target map clause operand unsupported bound type"); + }; + + auto cloneBounds = [cloneBound](llvm::ArrayRef bounds) { + llvm::SmallVector clonedBounds; + for (mlir::Value bound : bounds) + clonedBounds.emplace_back(cloneBound(bound)); + return clonedBounds; }; // Bind the symbols to their corresponding block arguments. @@ -2512,34 +2515,31 @@ static void genBodyOfTargetOp( fir::ExtendedValue extVal = converter.getSymbolExtendedValue(*sym); extVal.match( [&](const fir::BoxValue &v) { - converter.bindSymbol( - *sym, - fir::BoxValue(arg, extractBoundArgs(v.getLBounds().size()), - v.getExplicitParameters(), v.getExplicitExtents())); + converter.bindSymbol(*sym, + fir::BoxValue(arg, cloneBounds(v.getLBounds()), + v.getExplicitParameters(), + v.getExplicitExtents())); }, [&](const fir::MutableBoxValue &v) { converter.bindSymbol( - *sym, - fir::MutableBoxValue(arg, extractBoundArgs(v.getLBounds().size()), - v.getMutableProperties())); + *sym, fir::MutableBoxValue(arg, cloneBounds(v.getLBounds()), + v.getMutableProperties())); }, [&](const fir::ArrayBoxValue &v) { converter.bindSymbol( - *sym, - fir::ArrayBoxValue(arg, extractBoundArgs(v.getExtents().size()), - extractBoundArgs(v.getLBounds().size()), - v.getSourceBox())); + *sym, fir::ArrayBoxValue(arg, cloneBounds(v.getExtents()), + cloneBounds(v.getLBounds()), + v.getSourceBox())); }, [&](const fir::CharArrayBoxValue &v) { converter.bindSymbol( - *sym, - fir::CharArrayBoxValue(arg, extractBoundArgs(1).front(), - extractBoundArgs(v.getExtents().size()), - extractBoundArgs(v.getLBounds().size()))); + *sym, fir::CharArrayBoxValue(arg, cloneBound(v.getLen()), + cloneBounds(v.getExtents()), + cloneBounds(v.getLBounds()))); }, [&](const fir::CharBoxValue &v) { - converter.bindSymbol( - *sym, fir::CharBoxValue(arg, extractBoundArgs(1).front())); + converter.bindSymbol(*sym, + fir::CharBoxValue(arg, cloneBound(v.getLen()))); }, [&](const fir::UnboxedValue &v) { converter.bindSymbol(*sym, arg); }, [&](const auto &) { @@ -2549,6 +2549,55 @@ static void genBodyOfTargetOp( argIndex++; } + // Check if cloning the bounds introduced any dependency on the outer region. + // If so, then either clone them as well if they are MemoryEffectFree, or else + // copy them to a new temporary and add them to the map and block_argument + // lists and replace their uses with the new temporary. + llvm::SetVector valuesDefinedAbove; + mlir::getUsedValuesDefinedAbove(region, valuesDefinedAbove); + while (!valuesDefinedAbove.empty()) { + for (mlir::Value val : valuesDefinedAbove) { + mlir::Operation *valOp = val.getDefiningOp(); + if (mlir::isMemoryEffectFree(valOp)) { + mlir::Operation *clonedOp = valOp->clone(); + regionBlock->push_front(clonedOp); + val.replaceUsesWithIf( + clonedOp->getResult(0), [regionBlock](mlir::OpOperand &use) { + return use.getOwner()->getBlock() == regionBlock; + }); + } else { + auto savedIP = firOpBuilder.getInsertionPoint(); + firOpBuilder.setInsertionPointAfter(valOp); + auto copyVal = + firOpBuilder.createTemporary(val.getLoc(), val.getType()); + firOpBuilder.createStoreWithConvert(copyVal.getLoc(), val, copyVal); + + llvm::SmallVector bounds; + std::stringstream name; + firOpBuilder.setInsertionPoint(targetOp); + mlir::Value mapOp = createMapInfoOp( + firOpBuilder, copyVal.getLoc(), copyVal, name, bounds, + static_cast< + std::underlying_type_t>( + llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT), + mlir::omp::VariableCaptureKind::ByCopy, copyVal.getType()); + targetOp.getMapOperandsMutable().append(mapOp); + mlir::Value clonedValArg = + region.addArgument(copyVal.getType(), copyVal.getLoc()); + firOpBuilder.setInsertionPointToStart(regionBlock); + auto loadOp = firOpBuilder.create(clonedValArg.getLoc(), + clonedValArg); + val.replaceUsesWithIf( + loadOp->getResult(0), [regionBlock](mlir::OpOperand &use) { + return use.getOwner()->getBlock() == regionBlock; + }); + firOpBuilder.setInsertionPoint(regionBlock, savedIP); + } + } + valuesDefinedAbove.clear(); + mlir::getUsedValuesDefinedAbove(region, valuesDefinedAbove); + } + // Insert dummy instruction to remember the insertion position. The // marker will be deleted since there are not uses. // In the HLFIR flow there are hlfir.declares inserted above while @@ -2671,53 +2720,6 @@ genTargetOp(Fortran::lower::AbstractConverter &converter, }; Fortran::lower::pft::visitAllSymbols(eval, captureImplicitMap); - // Add the bounds and extents for box values to mapOperands - auto addMapInfoForBounds = [&](const auto &bounds) { - for (auto &val : bounds) { - mapSymLocs.push_back(val.getLoc()); - mapSymTypes.push_back(val.getType()); - - llvm::SmallVector bounds; - std::stringstream name; - - mlir::Value mapOp = createMapInfoOp( - converter.getFirOpBuilder(), val.getLoc(), val, name, bounds, - static_cast< - std::underlying_type_t>( - llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT), - mlir::omp::VariableCaptureKind::ByCopy, val.getType(), true); - mapOperands.push_back(mapOp); - } - }; - - for (const Fortran::semantics::Symbol *sym : mapSymbols) { - fir::ExtendedValue extVal = converter.getSymbolExtendedValue(*sym); - extVal.match( - [&](const fir::BoxValue &v) { addMapInfoForBounds(v.getLBounds()); }, - [&](const fir::MutableBoxValue &v) { - addMapInfoForBounds(v.getLBounds()); - }, - [&](const fir::ArrayBoxValue &v) { - addMapInfoForBounds(v.getExtents()); - addMapInfoForBounds(v.getLBounds()); - }, - [&](const fir::CharArrayBoxValue &v) { - llvm::SmallVector len; - len.push_back(v.getLen()); - addMapInfoForBounds(len); - addMapInfoForBounds(v.getExtents()); - addMapInfoForBounds(v.getLBounds()); - }, - [&](const fir::CharBoxValue &v) { - llvm::SmallVector len; - len.push_back(v.getLen()); - addMapInfoForBounds(len); - }, - [&](const auto &) { - // Nothing to do for non-box values. - }); - } - auto targetOp = converter.getFirOpBuilder().create( currentLocation, ifClauseOperand, deviceOperand, threadLimitOperand, nowaitAttr, mapOperands); diff --git a/flang/test/Lower/OpenMP/FIR/array-bounds.f90 b/flang/test/Lower/OpenMP/FIR/array-bounds.f90 index 02b5ebcee0226..8acc973882146 100644 --- a/flang/test/Lower/OpenMP/FIR/array-bounds.f90 +++ b/flang/test/Lower/OpenMP/FIR/array-bounds.f90 @@ -16,7 +16,7 @@ !ALL: %[[BOUNDS1:.*]] = omp.bounds lower_bound(%[[C5]] : index) upper_bound(%[[C6]] : index) stride(%[[C4]] : index) start_idx(%[[C4]] : index) !ALL: %[[MAP1:.*]] = omp.map_info var_ptr(%[[WRITE]] : !fir.ref>, !fir.array<10xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS1]]) -> !fir.ref> {name = "sp_write(2:5)"} !ALL: %[[MAP2:.*]] = omp.map_info var_ptr(%[[ITER]] : !fir.ref, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref {name = "i"} -!ALL: omp.target map_entries(%[[MAP0]] -> %{{.*}}, %[[MAP1]] -> %{{.*}}, %[[MAP2]] -> %{{.*}}, %{{.*}} -> %{{.*}}, %{{.*}} -> %{{.*}} : !fir.ref>, !fir.ref>, !fir.ref, index, index) { +!ALL: omp.target map_entries(%[[MAP0]] -> %{{.*}}, %[[MAP1]] -> %{{.*}}, %[[MAP2]] -> %{{.*}} : !fir.ref>, !fir.ref>, !fir.ref) { subroutine read_write_section() integer :: sp_read(10) = (/1,2,3,4,5,6,7,8,9,10/) @@ -64,7 +64,7 @@ end subroutine assumed_shape_array !ALL: %[[BOUNDS:.*]] = omp.bounds lower_bound(%[[C1]] : index) upper_bound(%[[C2]] : index) stride(%[[C0]] : index) start_idx(%[[C0]] : index) !ALL: %[[MAP:.*]] = omp.map_info var_ptr(%[[ARG0]] : !fir.ref>, !fir.array) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref> {name = "arr_read_write(2:5)"} !ALL: %[[MAP2:.*]] = omp.map_info var_ptr(%[[ALLOCA]] : !fir.ref, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref {name = "i"} -!ALL: omp.target map_entries(%[[MAP]] -> %{{.*}}, %[[MAP2]] -> %{{.*}}, %{{.*}} -> %{{.*}} : !fir.ref>, !fir.ref, index) { +!ALL: omp.target map_entries(%[[MAP]] -> %{{.*}}, %[[MAP2]] -> %{{.*}} : !fir.ref>, !fir.ref) { subroutine assumed_size_array(arr_read_write) integer, intent(inout) :: arr_read_write(*) diff --git a/flang/test/Lower/OpenMP/FIR/target.f90 b/flang/test/Lower/OpenMP/FIR/target.f90 index cf3b6fff0cb74..2034ac84334e5 100644 --- a/flang/test/Lower/OpenMP/FIR/target.f90 +++ b/flang/test/Lower/OpenMP/FIR/target.f90 @@ -189,8 +189,8 @@ subroutine omp_target integer :: a(1024) !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) !CHECK: %[[MAP:.*]] = omp.map_info var_ptr(%[[VAL_0]] : !fir.ref>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref> {name = "a"} - !CHECK: omp.target map_entries(%[[MAP]] -> %[[ARG_0:.*]], %{{.*}} -> %{{.*}} : !fir.ref>, index) { - !CHECK: ^bb0(%[[ARG_0]]: !fir.ref>, %{{.*}}: index): + !CHECK: omp.target map_entries(%[[MAP]] -> %[[ARG_0:.*]] : !fir.ref>) { + !CHECK: ^bb0(%[[ARG_0]]: !fir.ref>): !$omp target map(tofrom: a) !CHECK: %[[VAL_1:.*]] = arith.constant 10 : i32 !CHECK: %[[VAL_2:.*]] = arith.constant 1 : i64 @@ -213,8 +213,8 @@ subroutine omp_target_implicit !CHECK: %[[VAL_0:.*]] = fir.alloca !fir.array<1024xi32> {bindc_name = "a", uniq_name = "_QFomp_target_implicitEa"} integer :: a(1024) !CHECK: %[[MAP:.*]] = omp.map_info var_ptr(%[[VAL_0]] : !fir.ref>, !fir.array<1024xi32>) map_clauses(implicit, tofrom) capture(ByRef) bounds(%{{.*}}) -> !fir.ref> {name = "a"} - !CHECK: omp.target map_entries(%[[MAP]] -> %[[ARG_0:.*]], %{{.*}} -> %{{.*}} : !fir.ref>, index) { - !CHECK: ^bb0(%[[ARG_0]]: !fir.ref>, %{{.*}}: index): + !CHECK: omp.target map_entries(%[[MAP]] -> %[[ARG_0:.*]] : !fir.ref>) { + !CHECK: ^bb0(%[[ARG_0]]: !fir.ref>): !$omp target !CHECK: %[[VAL_5:.*]] = fir.coordinate_of %[[ARG_0]], %{{.*}} : (!fir.ref>, i64) -> !fir.ref a(1) = 10 @@ -249,22 +249,62 @@ end subroutine omp_target_implicit_nested ! Target implicit capture with bounds !=============================================================================== -!CHECK-LABEL: func.func @_QPomp_target_implicit_bounds(%{{.*}}: !fir.ref {fir.bindc_name = "n"}) { + +!CHECK-LABEL: func.func @_QPomp_target_implicit_bounds( +!CHECK: %[[VAL_0:.*]]: !fir.ref {fir.bindc_name = "n"}) { subroutine omp_target_implicit_bounds(n) - !CHECK: %[[VAL_1:.*]] = arith.select %{{.*}}, %{{.*}}, %{{.*}} : index - !CHECK: %[[VAL_2:.*]] = arith.select %{{.*}}, %{{.*}}, %{{.*}} : index - !CHECK: %[[VAL_3:.*]] = fir.alloca !fir.array, %[[VAL_1]] {bindc_name = "a", uniq_name = "_QFomp_target_implicit_boundsEa"} + !CHECK: %[[VAL_COPY:.*]] = fir.alloca i32 + !CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref + !CHECK: fir.store %[[VAL_1]] to %[[VAL_COPY]] : !fir.ref + !CHECK: %[[VAL_2:.*]] = fir.convert %[[VAL_1]] : (i32) -> i64 + !CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (i64) -> index + !CHECK: %[[VAL_4:.*]] = arith.constant 0 : index + !CHECK: %[[VAL_5:.*]] = arith.cmpi sgt, %[[VAL_3]], %[[VAL_4]] : index + !CHECK: %[[VAL_6:.*]] = arith.select %[[VAL_5]], %[[VAL_3]], %[[VAL_4]] : index + !CHECK: %[[VAL_7:.*]] = arith.constant 1024 : i64 + !CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (i64) -> index + !CHECK: %[[VAL_9:.*]] = arith.constant 0 : index + !CHECK: %[[VAL_10:.*]] = arith.cmpi sgt, %[[VAL_8]], %[[VAL_9]] : index + !CHECK: %[[VAL_11:.*]] = arith.select %[[VAL_10]], %[[VAL_8]], %[[VAL_9]] : index + !CHECK: %[[VAL_12:.*]] = fir.alloca !fir.array, %[[VAL_6]] {bindc_name = "a", uniq_name = "_QFomp_target_implicit_boundsEa"} integer :: n integer :: a(n, 1024) - !CHECK: %[[VAL_4:.*]] = omp.map_info var_ptr(%[[VAL_3]] : !fir.ref>, !fir.array) map_clauses(implicit, tofrom) capture(ByRef) bounds(%{{.*}}) -> !fir.ref> {name = "a"} - !CHECK: %[[VAL_5:.*]] = omp.map_info val(%[[VAL_1]] : index) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> index {name = ""} - !CHECK: %[[VAL_6:.*]] = omp.map_info val(%[[VAL_2]] : index) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> index {name = ""} - !CHECK: omp.target map_entries(%[[VAL_4]] -> %[[ARG_1:.*]], %[[VAL_5]] -> %[[ARG_2:.*]], %[[VAL_6]] -> %[[ARG_3:.*]] : !fir.ref>, index, index) { - !CHECK: ^bb0(%[[ARG_1]]: !fir.ref>, %[[ARG_2]]: index, %[[ARG_3]]: index): + !CHECK: %[[VAL_13:.*]] = arith.constant 1 : index + !CHECK: %[[VAL_14:.*]] = arith.constant 0 : index + !CHECK: %[[VAL_15:.*]] = arith.subi %[[VAL_6]], %[[VAL_13]] : index + !CHECK: %[[VAL_16:.*]] = omp.bounds lower_bound(%[[VAL_14]] : index) upper_bound(%[[VAL_15]] : index) extent(%[[VAL_6]] : index) stride(%[[VAL_13]] : index) start_idx(%[[VAL_13]] : index) + !CHECK: %[[VAL_17:.*]] = arith.constant 0 : index + !CHECK: %[[VAL_18:.*]] = arith.subi %[[VAL_11]], %[[VAL_13]] : index + !CHECK: %[[VAL_19:.*]] = omp.bounds lower_bound(%[[VAL_17]] : index) upper_bound(%[[VAL_18]] : index) extent(%[[VAL_11]] : index) stride(%[[VAL_13]] : index) start_idx(%[[VAL_13]] : index) + !CHECK: %[[VAL_20:.*]] = omp.map_info var_ptr(%[[VAL_12]] : !fir.ref>, !fir.array) map_clauses(implicit, tofrom) capture(ByRef) bounds(%[[VAL_16]], %[[VAL_19]]) -> !fir.ref> {name = "a"} + !CHECK: %[[VAL_21:.*]] = omp.map_info var_ptr(%[[VAL_COPY]] : !fir.ref, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref {name = ""} + !CHECK: omp.target map_entries(%[[VAL_20]] -> %[[VAL_22:.*]], %[[VAL_21]] -> %[[VAL_23:.*]] : !fir.ref>, !fir.ref) { + !CHECK: ^bb0(%[[VAL_22]]: !fir.ref>, %[[VAL_23]]: !fir.ref): !$omp target - !CHECK: %{{.*}} = fir.convert %[[ARG_1]] : (!fir.ref>) -> !fir.ref> - !CHECK: %{{.*}} = arith.muli %{{.*}}, %[[ARG_2]] : index - a(11,22) = 33 + !CHECK: %[[VAL_24:.*]] = fir.load %[[VAL_23]] : !fir.ref + !CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_24]] : (i32) -> i64 + !CHECK: %[[VAL_26:.*]] = arith.constant 0 : index + !CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_25]] : (i64) -> index + !CHECK: %[[VAL_28:.*]] = arith.cmpi sgt, %[[VAL_27]], %[[VAL_26]] : index + !CHECK: %[[VAL_29:.*]] = arith.select %[[VAL_28]], %[[VAL_27]], %[[VAL_26]] : index + !CHECK: %[[VAL_30:.*]] = arith.constant 33 : i32 + !CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_22]] : (!fir.ref>) -> !fir.ref> + !CHECK: %[[VAL_32:.*]] = arith.constant 1 : index + !CHECK: %[[VAL_33:.*]] = arith.constant 0 : index + !CHECK: %[[VAL_34:.*]] = arith.constant 11 : i64 + !CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_34]] : (i64) -> index + !CHECK: %[[VAL_36:.*]] = arith.subi %[[VAL_35]], %[[VAL_32]] : index + !CHECK: %[[VAL_37:.*]] = arith.muli %[[VAL_32]], %[[VAL_36]] : index + !CHECK: %[[VAL_38:.*]] = arith.addi %[[VAL_37]], %[[VAL_33]] : index + !CHECK: %[[VAL_39:.*]] = arith.muli %[[VAL_32]], %[[VAL_29]] : index + !CHECK: %[[VAL_40:.*]] = arith.constant 22 : i64 + !CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_40]] : (i64) -> index + !CHECK: %[[VAL_42:.*]] = arith.subi %[[VAL_41]], %[[VAL_32]] : index + !CHECK: %[[VAL_43:.*]] = arith.muli %[[VAL_39]], %[[VAL_42]] : index + !CHECK: %[[VAL_44:.*]] = arith.addi %[[VAL_43]], %[[VAL_38]] : index + !CHECK: %[[VAL_45:.*]] = fir.coordinate_of %[[VAL_31]], %[[VAL_44]] : (!fir.ref>, index) -> !fir.ref + !CHECK: fir.store %[[VAL_30]] to %[[VAL_45]] : !fir.ref + a(11, 22) = 33 !CHECK: omp.terminator !$omp end target !CHECK: } @@ -344,8 +384,8 @@ subroutine omp_target_parallel_do !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound(%[[C0]] : index) upper_bound(%[[SUB]] : index) extent(%[[C1024]] : index) stride(%[[C1]] : index) start_idx(%[[C1]] : index) !CHECK: %[[MAP1:.*]] = omp.map_info var_ptr(%[[VAL_0]] : !fir.ref>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref> {name = "a"} !CHECK: %[[MAP2:.*]] = omp.map_info var_ptr(%[[VAL_1]] : !fir.ref, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref {name = "i"} - !CHECK: omp.target map_entries(%[[MAP1]] -> %[[VAL_2:.*]], %[[MAP2]] -> %[[VAL_3:.*]], %{{.*}} -> %{{.*}} : !fir.ref>, !fir.ref, index) { - !CHECK: ^bb0(%[[VAL_2]]: !fir.ref>, %[[VAL_3]]: !fir.ref, %{{.*}}: index): + !CHECK: omp.target map_entries(%[[MAP1]] -> %[[VAL_2:.*]], %[[MAP2]] -> %[[VAL_3:.*]] : !fir.ref>, !fir.ref) { + !CHECK: ^bb0(%[[VAL_2]]: !fir.ref>, %[[VAL_3]]: !fir.ref): !CHECK-NEXT: omp.parallel !$omp target parallel do map(tofrom: a) !CHECK: %[[VAL_4:.*]] = fir.alloca i32 {adapt.valuebyref, pinned} diff --git a/flang/test/Lower/OpenMP/array-bounds.f90 b/flang/test/Lower/OpenMP/array-bounds.f90 index d0c584bec6044..c0e50acb8e37c 100644 --- a/flang/test/Lower/OpenMP/array-bounds.f90 +++ b/flang/test/Lower/OpenMP/array-bounds.f90 @@ -22,7 +22,7 @@ !HOST: %[[C6:.*]] = arith.constant 4 : index !HOST: %[[BOUNDS1:.*]] = omp.bounds lower_bound(%[[C5]] : index) upper_bound(%[[C6]] : index) stride(%[[C4]] : index) start_idx(%[[C4]] : index) !HOST: %[[MAP1:.*]] = omp.map_info var_ptr(%[[WRITE_DECL]]#1 : !fir.ref>, !fir.array<10xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS1]]) -> !fir.ref> {name = "sp_write(2:5)"} -!HOST: omp.target map_entries(%[[MAP0]] -> %{{.*}}, %[[MAP1]] -> %{{.*}}, {{.*}} -> {{.*}}, {{.*}} -> {{.*}}, {{.*}} -> {{.*}} : !fir.ref>, !fir.ref>, !fir.ref, index, index) { +!HOST: omp.target map_entries(%[[MAP0]] -> %{{.*}}, %[[MAP1]] -> %{{.*}}, {{.*}} -> {{.*}} : !fir.ref>, !fir.ref>, !fir.ref) { subroutine read_write_section() integer :: sp_read(10) = (/1,2,3,4,5,6,7,8,9,10/) @@ -73,7 +73,7 @@ end subroutine assumed_shape_array !HOST: %[[C2:.*]] = arith.constant 4 : index !HOST: %[[BOUNDS:.*]] = omp.bounds lower_bound(%[[C1]] : index) upper_bound(%[[C2]] : index) stride(%[[C0]] : index) start_idx(%[[C0]] : index) !HOST: %[[MAP:.*]] = omp.map_info var_ptr(%[[ARG0_DECL]]#1 : !fir.ref>, !fir.array) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref> {name = "arr_read_write(2:5)"} -!HOST: omp.target map_entries(%[[MAP]] -> %{{.*}}, {{.*}} -> {{.*}}, {{.*}} -> {{.*}} : !fir.ref>, !fir.ref, index) { +!HOST: omp.target map_entries(%[[MAP]] -> %{{.*}}, {{.*}} -> {{.*}} : !fir.ref>, !fir.ref) { subroutine assumed_size_array(arr_read_write) integer, intent(inout) :: arr_read_write(*) diff --git a/flang/test/Lower/OpenMP/target.f90 b/flang/test/Lower/OpenMP/target.f90 index 86f456b847df9..26b4d595d5229 100644 --- a/flang/test/Lower/OpenMP/target.f90 +++ b/flang/test/Lower/OpenMP/target.f90 @@ -191,10 +191,11 @@ subroutine omp_target integer :: a(1024) !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) !CHECK: %[[MAP:.*]] = omp.map_info var_ptr(%[[VAL_1]]#1 : !fir.ref>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref> {name = "a"} - !CHECK: omp.target map_entries(%[[MAP]] -> %[[ARG_0:.*]], %{{.*}} -> %[[ARG_1:.*]] : !fir.ref>, index) { - !CHECK: ^bb0(%[[ARG_0]]: !fir.ref>, %[[ARG_1]]: index): + !CHECK: omp.target map_entries(%[[MAP]] -> %[[ARG_0:.*]] : !fir.ref>) { + !CHECK: ^bb0(%[[ARG_0]]: !fir.ref>): !$omp target map(tofrom: a) - !CHECK: %[[VAL_2:.*]] = fir.shape %[[ARG_1]] : (index) -> !fir.shape<1> + !CHECK: %[[VAL_7:.*]] = arith.constant 1024 : index + !CHECK: %[[VAL_2:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1> !CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[ARG_0]](%[[VAL_2]]) {uniq_name = "_QFomp_targetEa"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) !CHECK: %[[VAL_4:.*]] = arith.constant 10 : i32 !CHECK: %[[VAL_5:.*]] = arith.constant 1 : index @@ -218,10 +219,10 @@ subroutine omp_target_implicit !CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_1]](%[[VAL_2]]) {uniq_name = "_QFomp_target_implicitEa"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) integer :: a(1024) !CHECK: %[[VAL_4:.*]] = omp.map_info var_ptr(%[[VAL_3]]#1 : !fir.ref>, !fir.array<1024xi32>) map_clauses(implicit, tofrom) capture(ByRef) bounds(%{{.*}}) -> !fir.ref> {name = "a"} - !CHECK: %[[VAL_5:.*]] = omp.map_info val(%[[VAL_0]] : index) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> index {name = ""} - !CHECK: omp.target map_entries(%[[VAL_4]] -> %[[VAL_6:.*]], %[[VAL_5]] -> %[[VAL_7:.*]] : !fir.ref>, index) { - !CHECK: ^bb0(%[[VAL_6]]: !fir.ref>, %[[VAL_7]]: index): + !CHECK: omp.target map_entries(%[[VAL_4]] -> %[[VAL_6:.*]] : !fir.ref>) { + !CHECK: ^bb0(%[[VAL_6]]: !fir.ref>): !$omp target + !CHECK: %[[VAL_7:.*]] = arith.constant 1024 : index !CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1> !CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_6]](%[[VAL_8]]) {uniq_name = "_QFomp_target_implicitEa"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) !CHECK: %[[VAL_10:.*]] = arith.constant 10 : i32 @@ -265,29 +266,45 @@ end subroutine omp_target_implicit_nested ! Target implicit capture with bounds !=============================================================================== -!CHECK-LABEL: func.func @_QPomp_target_implicit_bounds(%{{.*}}: !fir.ref {fir.bindc_name = "n"}) { +!CHECK-LABEL: func.func @_QPomp_target_implicit_bounds( +!CHECK: %[[VAL_0:.*]]: !fir.ref {fir.bindc_name = "n"}) { subroutine omp_target_implicit_bounds(n) - !CHECK: %[[VAL_1:.*]] = arith.select %{{.*}}, %{{.*}}, %{{.*}} : index - !CHECK: %[[VAL_2:.*]] = arith.select %{{.*}}, %{{.*}}, %{{.*}} : index - !CHECK: %[[VAL_3:.*]] = fir.alloca !fir.array, %[[VAL_1]] {bindc_name = "a", uniq_name = "_QFomp_target_implicit_boundsEa"} - !CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_1]], %[[VAL_2]] : (index, index) -> !fir.shape<2> - !CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_3]](%[[VAL_4]]) {uniq_name = "_QFomp_target_implicit_boundsEa"} : (!fir.ref>, !fir.shape<2>) -> (!fir.box>, !fir.ref>) + !CHECK: %[[VAL_COPY:.*]] = fir.alloca i32 + !CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFomp_target_implicit_boundsEn"} : (!fir.ref) -> (!fir.ref, !fir.ref) + !CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref + !CHECK: fir.store %[[VAL_2]] to %[[VAL_COPY]] : !fir.ref + !CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (i32) -> i64 + !CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (i64) -> index + !CHECK: %[[VAL_5:.*]] = arith.constant 0 : index + !CHECK: %[[VAL_6:.*]] = arith.cmpi sgt, %[[VAL_4]], %[[VAL_5]] : index + !CHECK: %[[VAL_7:.*]] = arith.select %[[VAL_6]], %[[VAL_4]], %[[VAL_5]] : index + !CHECK: %[[VAL_8:.*]] = fir.alloca !fir.array, %[[VAL_7]] {bindc_name = "a", uniq_name = "_QFomp_target_implicit_boundsEa"} + !CHECK: %[[VAL_9:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1> + !CHECK: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_8]](%[[VAL_9]]) {uniq_name = "_QFomp_target_implicit_boundsEa"} : (!fir.ref>, !fir.shape<1>) -> (!fir.box>, !fir.ref>) + !CHECK: %[[VAL_11:.*]] = arith.constant 1 : index + !CHECK: %[[VAL_12:.*]] = arith.constant 0 : index + !CHECK: %[[VAL_13:.*]] = arith.subi %[[VAL_7]], %[[VAL_11]] : index integer :: n - integer :: a(n, 1024) - !CHECK: %[[VAL_6:.*]] = omp.map_info var_ptr(%[[VAL_5]]#1 : !fir.ref>, !fir.array) map_clauses(implicit, tofrom) capture(ByRef) bounds(%{{.*}}) -> !fir.ref> {name = "a"} - !CHECK: %[[VAL_7:.*]] = omp.map_info val(%[[VAL_1]] : index) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> index {name = ""} - !CHECK: %[[VAL_8:.*]] = omp.map_info val(%[[VAL_2]] : index) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> index {name = ""} - !CHECK: omp.target map_entries(%[[VAL_6]] -> %[[ARG_1:.*]], %[[VAL_7]] -> %[[ARG_2:.*]], %[[VAL_8]] -> %[[ARG_3:.*]] : !fir.ref>, index, index) { - !CHECK: ^bb0(%[[ARG_1]]: !fir.ref>, %[[ARG_2]]: index, %[[ARG_3]]: index): + integer :: a(n) + !CHECK: %[[VAL_14:.*]] = omp.bounds lower_bound(%[[VAL_12]] : index) upper_bound(%[[VAL_13]] : index) extent(%[[VAL_7]] : index) stride(%[[VAL_11]] : index) start_idx(%[[VAL_11]] : index) + !CHECK: %[[VAL_15:.*]] = omp.map_info var_ptr(%[[VAL_10]]#1 : !fir.ref>, !fir.array) map_clauses(implicit, tofrom) capture(ByRef) bounds(%[[VAL_14]]) -> !fir.ref> {name = "a"} + !CHECK: %[[VAL_16:.*]] = omp.map_info var_ptr(%[[VAL_COPY]] : !fir.ref, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref {name = ""} + !CHECK: omp.target map_entries(%[[VAL_15]] -> %[[VAL_17:.*]], %[[VAL_16]] -> %[[VAL_18:.*]] : !fir.ref>, !fir.ref) { + !CHECK: ^bb0(%[[VAL_17]]: !fir.ref>, %[[VAL_18]]: !fir.ref): !$omp target - !CHECK: %[[VAL_9:.*]] = fir.shape %[[ARG_2]], %[[ARG_3]] : (index, index) -> !fir.shape<2> - !CHECK: %[[VAL_10:.*]]:2 = hlfir.declare %[[ARG_1]](%[[VAL_9]]) {uniq_name = "_QFomp_target_implicit_boundsEa"} : (!fir.ref>, !fir.shape<2>) -> (!fir.box>, !fir.ref>) - !CHECK: %[[VAL_11:.*]] = arith.constant 33 : i32 - !CHECK: %[[VAL_12:.*]] = arith.constant 11 : index - !CHECK: %[[VAL_13:.*]] = arith.constant 22 : index - !CHECK: %[[VAL_14:.*]] = hlfir.designate %[[VAL_10]]#0 (%[[VAL_12]], %[[VAL_13]]) : (!fir.box>, index, index) -> !fir.ref - !CHECK: hlfir.assign %[[VAL_11]] to %[[VAL_14]] : i32, !fir.ref - a(11, 22) = 33 + !CHECK: %[[VAL_19:.*]] = fir.load %[[VAL_18]] : !fir.ref + !CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_19]] : (i32) -> i64 + !CHECK: %[[VAL_21:.*]] = arith.constant 0 : index + !CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (i64) -> index + !CHECK: %[[VAL_23:.*]] = arith.cmpi sgt, %[[VAL_22]], %[[VAL_21]] : index + !CHECK: %[[VAL_24:.*]] = arith.select %[[VAL_23]], %[[VAL_22]], %[[VAL_21]] : index + !CHECK: %[[VAL_25:.*]] = fir.shape %[[VAL_24]] : (index) -> !fir.shape<1> + !CHECK: %[[VAL_26:.*]]:2 = hlfir.declare %[[VAL_17]](%[[VAL_25]]) {uniq_name = "_QFomp_target_implicit_boundsEa"} : (!fir.ref>, !fir.shape<1>) -> (!fir.box>, !fir.ref>) + !CHECK: %[[VAL_27:.*]] = arith.constant 22 : i32 + !CHECK: %[[VAL_28:.*]] = arith.constant 11 : index + !CHECK: %[[VAL_29:.*]] = hlfir.designate %[[VAL_26]]#0 (%[[VAL_28]]) : (!fir.box>, index) -> !fir.ref + !CHECK: hlfir.assign %[[VAL_27]] to %[[VAL_29]] : i32, !fir.ref + a(11) = 22 !CHECK: omp.terminator !$omp end target !CHECK: } @@ -396,8 +413,8 @@ subroutine omp_target_parallel_do !CHECK: %[[SUB:.*]] = arith.subi %[[C1024]], %[[C1]] : index !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound(%[[C0]] : index) upper_bound(%[[SUB]] : index) extent(%[[C1024]] : index) stride(%[[C1]] : index) start_idx(%[[C1]] : index) !CHECK: %[[MAP:.*]] = omp.map_info var_ptr(%[[VAL_0_DECL]]#1 : !fir.ref>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref> {name = "a"} - !CHECK: omp.target map_entries(%[[MAP]] -> %[[ARG_0:.*]], %{{.*}} -> %{{.*}}, %{{.*}} -> %{{.*}} : !fir.ref>, !fir.ref, index) { - !CHECK: ^bb0(%[[ARG_0]]: !fir.ref>, %{{.*}}: !fir.ref, %{{.*}}: index): + !CHECK: omp.target map_entries(%[[MAP]] -> %[[ARG_0:.*]], %{{.*}} -> %{{.*}} : !fir.ref>, !fir.ref) { + !CHECK: ^bb0(%[[ARG_0]]: !fir.ref>, %{{.*}}: !fir.ref): !CHECK: %[[VAL_0_DECL:.*]]:2 = hlfir.declare %[[ARG_0]](%{{.*}}) {uniq_name = "_QFomp_target_parallel_doEa"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) !CHECK: omp.parallel !$omp target parallel do map(tofrom: a) diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td index bfb58b98884c7..8ff5380f71ad4 100644 --- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td +++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td @@ -1145,15 +1145,14 @@ def DataBoundsOp : OpenMP_Op<"bounds", } def MapInfoOp : OpenMP_Op<"map_info", [AttrSizedOperandSegments]> { - let arguments = (ins Optional:$val, - Optional:$var_ptr, - OptionalAttr:$var_type, + let arguments = (ins OpenMP_PointerLikeType:$var_ptr, + TypeAttr:$var_type, Optional:$var_ptr_ptr, Variadic:$bounds, /* rank-0 to rank-{n-1} */ OptionalAttr:$map_type, OptionalAttr:$map_capture_type, OptionalAttr:$name); - let results = (outs AnyType:$omp_ptr); + let results = (outs OpenMP_PointerLikeType:$omp_ptr); let description = [{ The MapInfoOp captures information relating to individual OpenMP map clauses @@ -1184,9 +1183,8 @@ def MapInfoOp : OpenMP_Op<"map_info", [AttrSizedOperandSegments]> { ``` Description of arguments: - - `val`: The value to copy. - `var_ptr`: The address of variable to copy. - - `var_type`: The type of the variable/value to copy. + - `var_type`: The type of the variable to copy. - `var_ptr_ptr`: Used when the variable copied is a member of a class, structure or derived type and refers to the originating struct. - `bounds`: Used when copying slices of array's, pointers or pointer members of @@ -1202,10 +1200,9 @@ def MapInfoOp : OpenMP_Op<"map_info", [AttrSizedOperandSegments]> { }]; let assemblyFormat = [{ + `var_ptr` `(` $var_ptr `:` type($var_ptr) `,` $var_type `)` oilist( - `val` `(` $val `:` type($val) `)` - | `var_ptr` `(` $var_ptr `:` type($var_ptr) `,` $var_type `)` - | `var_ptr_ptr` `(` $var_ptr_ptr `:` type($var_ptr_ptr) `)` + `var_ptr_ptr` `(` $var_ptr_ptr `:` type($var_ptr_ptr) `)` | `map_clauses` `(` custom($map_type) `)` | `capture` `(` custom($map_capture_type) `)` | `bounds` `(` $bounds `)` diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp index 480af0e1307c1..20df0099cbd24 100644 --- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp +++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp @@ -890,15 +890,6 @@ static LogicalResult verifyMapClause(Operation *op, OperandRange mapOperands) { if (auto MapInfoOp = mlir::dyn_cast(mapOp.getDefiningOp())) { - if (MapInfoOp.getVal() && MapInfoOp.getVarPtr()) - emitError(op->getLoc(), "only one of val or var_ptr must be used"); - - if (!MapInfoOp.getVal() && !MapInfoOp.getVarPtr()) - emitError(op->getLoc(), "missing val or var_ptr"); - - if (!MapInfoOp.getVarPtr() && MapInfoOp.getVarType().has_value()) - emitError(op->getLoc(), "var_type supplied without var_ptr"); - if (!MapInfoOp.getMapType().has_value()) emitError(op->getLoc(), "missing map type for map operand"); diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp index b1305201166a0..a310d38b26cb1 100644 --- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp @@ -1733,13 +1733,13 @@ void collectMapDataFromMapOperands(MapInfoData &mapData, "missing map info operation or incorrect map info operation type"); if (auto mapOp = mlir::dyn_cast_if_present( mapValue.getDefiningOp())) { - mapData.OriginalValue.push_back(moduleTranslation.lookupValue( - mapOp.getVarPtr() ? mapOp.getVarPtr() : mapOp.getVal())); + mapData.OriginalValue.push_back( + moduleTranslation.lookupValue(mapOp.getVarPtr())); mapData.Pointers.push_back(mapData.OriginalValue.back()); - if (llvm::Value *refPtr = getRefPtrIfDeclareTarget( - mapOp.getVarPtr() ? mapOp.getVarPtr() : mapOp.getVal(), - moduleTranslation)) { // declare target + if (llvm::Value *refPtr = + getRefPtrIfDeclareTarget(mapOp.getVarPtr(), + moduleTranslation)) { // declare target mapData.IsDeclareTarget.push_back(true); mapData.BasePointers.push_back(refPtr); } else { // regular mapped variable @@ -1747,14 +1747,10 @@ void collectMapDataFromMapOperands(MapInfoData &mapData, mapData.BasePointers.push_back(mapData.OriginalValue.back()); } - mapData.Sizes.push_back( - getSizeInBytes(dl, - mapOp.getVal() ? mapOp.getVal().getType() - : mapOp.getVarType().value(), - mapOp, builder, moduleTranslation)); - mapData.BaseType.push_back(moduleTranslation.convertType( - mapOp.getVal() ? mapOp.getVal().getType() - : mapOp.getVarType().value())); + mapData.Sizes.push_back(getSizeInBytes(dl, mapOp.getVarType(), mapOp, + builder, moduleTranslation)); + mapData.BaseType.push_back( + moduleTranslation.convertType(mapOp.getVarType())); mapData.MapClause.push_back(mapOp.getOperation()); mapData.Types.push_back( llvm::omp::OpenMPOffloadMappingFlags(mapOp.getMapType().value())); @@ -1804,8 +1800,7 @@ static void genMapInfos(llvm::IRBuilderBase &builder, if (auto mapInfoOp = dyn_cast(mapData.MapClause[i])) if (mapInfoOp.getMapCaptureType().value() == mlir::omp::VariableCaptureKind::ByCopy && - !(mapInfoOp.getVarType().has_value() && - mapInfoOp.getVarType()->isa())) + !mapInfoOp.getVarType().isa()) mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_LITERAL; combinedInfo.BasePointers.emplace_back(mapData.BasePointers[i]); @@ -2337,19 +2332,7 @@ convertOmpTarget(Operation &opInst, llvm::IRBuilderBase &builder, DataLayout dl = DataLayout(opInst.getParentOfType()); SmallVector mapOperands = targetOp.getMapOperands(); - // Remove mapOperands/blockArgs that have no use inside the region. - assert(mapOperands.size() == targetRegion.getNumArguments() && - "Number of mapOperands must be same as block_arguments"); - for (size_t i = 0; i < mapOperands.size(); i++) { - if (targetRegion.getArgument(i).use_empty()) { - targetRegion.eraseArgument(i); - mapOperands.erase(&mapOperands[i]); - i--; - } - } - LogicalResult bodyGenStatus = success(); - using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy; auto bodyCB = [&](InsertPointTy allocaIP, InsertPointTy codeGenIP) -> InsertPointTy { @@ -2358,8 +2341,8 @@ convertOmpTarget(Operation &opInst, llvm::IRBuilderBase &builder, for (auto &mapOp : mapOperands) { auto mapInfoOp = mlir::dyn_cast(mapOp.getDefiningOp()); - llvm::Value *mapOpValue = moduleTranslation.lookupValue( - mapInfoOp.getVarPtr() ? mapInfoOp.getVarPtr() : mapInfoOp.getVal()); + llvm::Value *mapOpValue = + moduleTranslation.lookupValue(mapInfoOp.getVarPtr()); const auto &arg = targetRegion.front().getArgument(argIndex); moduleTranslation.mapValue(arg, mapOpValue); argIndex++; diff --git a/mlir/test/Dialect/OpenMP/invalid.mlir b/mlir/test/Dialect/OpenMP/invalid.mlir index 42e9fb1c64bae..e54808f6cfdee 100644 --- a/mlir/test/Dialect/OpenMP/invalid.mlir +++ b/mlir/test/Dialect/OpenMP/invalid.mlir @@ -1658,40 +1658,4 @@ func.func @omp_target_exit_data(%map1: memref) { return } -// ----- - -func.func @omp_map1(%map1: memref, %map2: i32) { - %mapv = omp.map_info var_ptr(%map1 : memref, tensor) val(%map2 : i32) map_clauses(tofrom) capture(ByRef) -> memref {name = ""} - // expected-error @below {{only one of val or var_ptr must be used}} - omp.target map_entries(%mapv -> %arg0: memref) { - ^bb0(%arg0: memref): - omp.terminator - } - return -} - -// ----- - -func.func @omp_map2(%map1: memref, %map2: i32) { - %mapv = omp.map_info var_ptr( : , tensor) val(%map2 : i32) map_clauses(tofrom) capture(ByRef) -> memref {name = ""} - // expected-error @below {{var_type supplied without var_ptr}} - omp.target map_entries(%mapv -> %arg0: memref) { - ^bb0(%arg0: memref): - omp.terminator - } - return -} - -// ----- - -func.func @omp_map3(%map1: memref, %map2: i32) { - %mapv = omp.map_info map_clauses(tofrom) capture(ByRef) -> memref {name = ""} - // expected-error @below {{missing val or var_ptr}} - omp.target map_entries(%mapv -> %arg0: memref) { - ^bb0(%arg0: memref): - omp.terminator - } - return -} - llvm.mlir.global internal @_QFsubEx() : i32 diff --git a/openmp/libomptarget/test/offloading/fortran/constant-arr-index.f90 b/openmp/libomptarget/test/offloading/fortran/constant-arr-index.f90 index 91dc30cf9604c..9064f60896f10 100644 --- a/openmp/libomptarget/test/offloading/fortran/constant-arr-index.f90 +++ b/openmp/libomptarget/test/offloading/fortran/constant-arr-index.f90 @@ -1,5 +1,5 @@ ! Basic offloading test with a target region -! that checks constant indexing on device +! that checks constant indexing on device ! correctly works (regression test for prior ! bug). ! REQUIRES: flang, amdgcn-amd-amdhsa @@ -19,8 +19,8 @@ program main sp(5) = 10 !$omp end target - ! print *, sp(1) - ! print *, sp(5) + print *, sp(1) + print *, sp(5) end program ! CHECK: 20 diff --git a/openmp/libomptarget/test/offloading/fortran/basic-target-region-array.f90 b/openmp/libomptarget/test/offloading/fortran/target-region-implicit-array.f90 similarity index 87% rename from openmp/libomptarget/test/offloading/fortran/basic-target-region-array.f90 rename to openmp/libomptarget/test/offloading/fortran/target-region-implicit-array.f90 index 9b10e4c7650d0..5ef2547545e4b 100644 --- a/openmp/libomptarget/test/offloading/fortran/basic-target-region-array.f90 +++ b/openmp/libomptarget/test/offloading/fortran/target-region-implicit-array.f90 @@ -13,14 +13,13 @@ program main integer :: i = 1 integer :: j = 11 - !$omp target map(tofrom:x, i, j) - do while (i <= j) + !$omp target + do i = 1, j x(i) = i; - i = i + 1 - end do + end do !$omp end target PRINT *, x(:) end program main - + ! CHECK: 1 2 3 4 5 6 7 8 9 10