[flang-commits] [flang] e643d7e - [mlir][OpenMP] Add iterator support to map/motion clause (#197047)
via flang-commits
flang-commits at lists.llvm.org
Mon Jun 8 10:53:55 PDT 2026
Author: Chi-Chun, Chen
Date: 2026-06-08T12:53:49-05:00
New Revision: e643d7e7a3008e3b97a6d9a1912cd19549b712f2
URL: https://github.com/llvm/llvm-project/commit/e643d7e7a3008e3b97a6d9a1912cd19549b712f2
DIFF: https://github.com/llvm/llvm-project/commit/e643d7e7a3008e3b97a6d9a1912cd19549b712f2.diff
LOG: [mlir][OpenMP] Add iterator support to map/motion clause (#197047)
Extend omp.target_data, omp.target_enter_data, omp.target_exit_data,
and omp.target_update to support `!omp.iterated<Ty>`.
This is part of feature work for llvm#188061
Assisted with copilot
Added:
Modified:
flang/lib/Lower/OpenMP/OpenMP.cpp
flang/lib/Optimizer/OpenMP/LowerWorkdistribute.cpp
flang/lib/Utils/OpenMP.cpp
mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
mlir/test/Dialect/OpenMP/invalid.mlir
mlir/test/Dialect/OpenMP/ops.mlir
mlir/test/Target/LLVMIR/openmp-todo.mlir
Removed:
################################################################################
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index ec4067974f2f0..be876c563433a 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -4589,7 +4589,7 @@ genOpenMPDeclareMapperImpl(lower::AbstractConverter &converter,
List<Clause> clauses = makeClauses(construct.v.Clauses(), semaCtx);
ClauseProcessor cp(converter, semaCtx, clauses);
cp.processMap(loc, stmtCtx, clauseOps);
- mlir::omp::DeclareMapperInfoOp::create(firOpBuilder, loc, clauseOps.mapVars);
+ mlir::omp::DeclareMapperInfoOp::create(firOpBuilder, loc, clauseOps);
}
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
diff --git a/flang/lib/Optimizer/OpenMP/LowerWorkdistribute.cpp b/flang/lib/Optimizer/OpenMP/LowerWorkdistribute.cpp
index fc40e650d9538..687bce4850b39 100644
--- a/flang/lib/Optimizer/OpenMP/LowerWorkdistribute.cpp
+++ b/flang/lib/Optimizer/OpenMP/LowerWorkdistribute.cpp
@@ -749,9 +749,9 @@ FailureOr<omp::TargetOp> splitTargetData(omp::TargetOp targetOp,
auto deviceAddrVars = targetOp.getHasDeviceAddrVars();
auto devicePtrVars = targetOp.getIsDevicePtrVars();
// Create the target data op
- auto targetDataOp =
- omp::TargetDataOp::create(rewriter, loc, device, ifExpr, outerMapInfos,
- deviceAddrVars, devicePtrVars);
+ auto targetDataOp = omp::TargetDataOp::create(
+ rewriter, loc, device, ifExpr, outerMapInfos,
+ /*map_iterated=*/{}, deviceAddrVars, devicePtrVars);
auto taregtDataBlock = rewriter.createBlock(&targetDataOp.getRegion());
mlir::omp::TerminatorOp::create(rewriter, loc);
rewriter.setInsertionPointToStart(taregtDataBlock);
@@ -767,9 +767,10 @@ FailureOr<omp::TargetOp> splitTargetData(omp::TargetOp targetOp,
targetOp.getHostEvalVars(), targetOp.getIfExpr(),
targetOp.getInReductionVars(), targetOp.getInReductionByrefAttr(),
targetOp.getInReductionSymsAttr(), targetOp.getIsDevicePtrVars(),
- innerMapInfos, targetOp.getNowaitAttr(), targetOp.getPrivateVars(),
- targetOp.getPrivateSymsAttr(), targetOp.getPrivateNeedsBarrierAttr(),
- targetOp.getThreadLimitVars(), targetOp.getPrivateMapsAttr());
+ innerMapInfos, targetOp.getMapIterated(), targetOp.getNowaitAttr(),
+ targetOp.getPrivateVars(), targetOp.getPrivateSymsAttr(),
+ targetOp.getPrivateNeedsBarrierAttr(), targetOp.getThreadLimitVars(),
+ targetOp.getPrivateMapsAttr());
rewriter.inlineRegionBefore(targetOp.getRegion(), newTargetOp.getRegion(),
newTargetOp.getRegion().begin());
rewriter.replaceOp(targetOp, targetDataOp);
@@ -1490,10 +1491,10 @@ genPreTargetOp(omp::TargetOp targetOp, SmallVector<Value> &preMapOperands,
targetOp.getDynGroupprivateSize(), targetOp.getHasDeviceAddrVars(),
preHostEvalVars, targetOp.getIfExpr(), targetOp.getInReductionVars(),
targetOp.getInReductionByrefAttr(), targetOp.getInReductionSymsAttr(),
- targetOp.getIsDevicePtrVars(), preMapOperands, targetOp.getNowaitAttr(),
- targetOp.getPrivateVars(), targetOp.getPrivateSymsAttr(),
- targetOp.getPrivateNeedsBarrierAttr(), targetOp.getThreadLimitVars(),
- targetOp.getPrivateMapsAttr());
+ targetOp.getIsDevicePtrVars(), preMapOperands, targetOp.getMapIterated(),
+ targetOp.getNowaitAttr(), targetOp.getPrivateVars(),
+ targetOp.getPrivateSymsAttr(), targetOp.getPrivateNeedsBarrierAttr(),
+ targetOp.getThreadLimitVars(), targetOp.getPrivateMapsAttr());
auto *preTargetBlock = rewriter.createBlock(
&preTargetOp.getRegion(), preTargetOp.getRegion().begin(), {}, {});
IRMapping preMapping;
@@ -1583,10 +1584,10 @@ genIsolatedTargetOp(omp::TargetOp targetOp, SmallVector<Value> &postMapOperands,
targetOp.getDynGroupprivateSize(), targetOp.getHasDeviceAddrVars(),
isolatedHostEvalVars, targetOp.getIfExpr(), targetOp.getInReductionVars(),
targetOp.getInReductionByrefAttr(), targetOp.getInReductionSymsAttr(),
- targetOp.getIsDevicePtrVars(), postMapOperands, targetOp.getNowaitAttr(),
- targetOp.getPrivateVars(), targetOp.getPrivateSymsAttr(),
- targetOp.getPrivateNeedsBarrierAttr(), targetOp.getThreadLimitVars(),
- targetOp.getPrivateMapsAttr());
+ targetOp.getIsDevicePtrVars(), postMapOperands, targetOp.getMapIterated(),
+ targetOp.getNowaitAttr(), targetOp.getPrivateVars(),
+ targetOp.getPrivateSymsAttr(), targetOp.getPrivateNeedsBarrierAttr(),
+ targetOp.getThreadLimitVars(), targetOp.getPrivateMapsAttr());
auto *isolatedTargetBlock =
rewriter.createBlock(&isolatedTargetOp.getRegion(),
isolatedTargetOp.getRegion().begin(), {}, {});
@@ -1666,10 +1667,10 @@ static omp::TargetOp genPostTargetOp(omp::TargetOp targetOp,
targetOp.getDynGroupprivateSize(), targetOp.getHasDeviceAddrVars(),
postHostEvalVars, targetOp.getIfExpr(), targetOp.getInReductionVars(),
targetOp.getInReductionByrefAttr(), targetOp.getInReductionSymsAttr(),
- targetOp.getIsDevicePtrVars(), postMapOperands, targetOp.getNowaitAttr(),
- targetOp.getPrivateVars(), targetOp.getPrivateSymsAttr(),
- targetOp.getPrivateNeedsBarrierAttr(), targetOp.getThreadLimitVars(),
- targetOp.getPrivateMapsAttr());
+ targetOp.getIsDevicePtrVars(), postMapOperands, targetOp.getMapIterated(),
+ targetOp.getNowaitAttr(), targetOp.getPrivateVars(),
+ targetOp.getPrivateSymsAttr(), targetOp.getPrivateNeedsBarrierAttr(),
+ targetOp.getThreadLimitVars(), targetOp.getPrivateMapsAttr());
// Create the block for postTargetOp
auto *postTargetBlock = rewriter.createBlock(
&postTargetOp.getRegion(), postTargetOp.getRegion().begin(), {}, {});
diff --git a/flang/lib/Utils/OpenMP.cpp b/flang/lib/Utils/OpenMP.cpp
index ce457c1086ca2..9c22cc950e3f7 100644
--- a/flang/lib/Utils/OpenMP.cpp
+++ b/flang/lib/Utils/OpenMP.cpp
@@ -216,7 +216,6 @@ mlir::FlatSymbolRefAttr getOrGenImplicitDefaultDeclareMapper(
firOpBuilder, loc, firOpBuilder.getRefType(fieldTy), rec, field);
};
- llvm::SmallVector<mlir::Value> clauseMapVars;
llvm::SmallVector<llvm::SmallVector<int64_t>> memberPlacementIndices;
llvm::SmallVector<mlir::Value> memberMapOps;
@@ -292,8 +291,9 @@ mlir::FlatSymbolRefAttr getOrGenImplicitDefaultDeclareMapper(
captureKind, declareOp.getType(0),
/*partialMap=*/true);
- clauseMapVars.emplace_back(mapOp);
- mlir::omp::DeclareMapperInfoOp::create(firOpBuilder, loc, clauseMapVars);
+ mlir::omp::DeclareMapperInfoOperands clauseOps;
+ clauseOps.mapVars.emplace_back(mapOp);
+ mlir::omp::DeclareMapperInfoOp::create(firOpBuilder, loc, clauseOps);
return mlir::FlatSymbolRefAttr::get(firOpBuilder.getContext(), mapperNameStr);
}
} // namespace Fortran::utils::openmp
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
index 2a2b695e77c0e..71e66018bf10e 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
@@ -903,20 +903,24 @@ class OpenMP_MapClauseSkip<
MapClauseOwningOpInterface
];
- let arguments = (ins
- Variadic<OpenMP_PointerLikeType>:$map_vars
- );
+ let arguments = (ins Variadic<OpenMP_PointerLikeType>:$map_vars,
+ Variadic<OpenMP_IteratedType>:$map_iterated);
// This assembly format should only be used by operations where `map` does not
// define entry block arguments. Otherwise, it must be printed and parsed
// together with the corresponding region.
let optAssemblyFormat = [{
- `map_entries` `(` $map_vars `:` type($map_vars) `)`
+ `map_entries` `(` $map_vars `:` type($map_vars) `)` |
+ `map_iterated` `(` $map_iterated `:` type($map_iterated) `)`
}];
let description = [{
The optional `map_vars` maps data from the current task's data environment
to the device data environment.
+
+ The optional `map_iterated` holds iterator-produced handles (from
+ `omp.iterator`) whose bodies create `omp.map.info` ops, specifying
+ map entries expanded at runtime via an iterator modifier.
}];
}
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
index 0962b330e2f23..51e7080db5b29 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
@@ -1658,6 +1658,7 @@ def TargetOp : OpenMP_Op<"target", traits = [
}] # clausesExtraClassDeclaration;
let assemblyFormat = clausesAssemblyFormat # [{
+ ( `map_iterated` `(` $map_iterated^ `:` type($map_iterated) `)` )?
custom<TargetOpRegion>(
$region, $has_device_addr_vars, type($has_device_addr_vars),
$host_eval_vars, type($host_eval_vars), $in_reduction_vars,
@@ -2124,18 +2125,19 @@ def DeclareMapperOp : OpenMP_Op<"declare_mapper", [
let hasRegionVerifier = 1;
}
-def DeclareMapperInfoOp : OpenMP_Op<"declare_mapper.info", [
- HasParent<"DeclareMapperOp">,
- Terminator
- ], clauses = [
- OpenMP_MapClause
- ]> {
+def DeclareMapperInfoOp : OpenMP_Op<"declare_mapper.info",
+ [AttrSizedOperandSegments,
+ HasParent<"DeclareMapperOp">, Terminator],
+ clauses = [OpenMP_MapClause]> {
let summary = "declare mapper info";
let description = [{
This Op is used to capture the map information related to it's
parent DeclareMapperOp.
}] # clausesDescription;
+ let builders = [OpBuilder<(
+ ins CArg<"const DeclareMapperInfoOperands &">:$clauses)>];
+
let extraClassDeclaration = [{
// Override BlockArgOpenMPOpInterface method because `map` clauses have no
// associated entry block arguments in this operation.
@@ -2553,9 +2555,7 @@ def AffinityEntryOp : OpenMP_Op<"affinity_entry", [Pure]> {
// Iterator Op
//===----------------------------------------------------------------------===//
-def IteratorOp : OpenMP_Op<"iterator",
- [AttrSizedOperandSegments,
- SingleBlockImplicitTerminator<"YieldOp">],
+def IteratorOp : OpenMP_Op<"iterator", [AttrSizedOperandSegments, SingleBlock],
clauses = [OpenMP_LoopRelatedClause]> {
let summary = "OpenMP iterator modifier";
let description = [{
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
index db5fd8f2e3230..7c75791611218 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -2308,87 +2308,118 @@ static ParseResult parseCaptureType(OpAsmParser &parser,
return success();
}
-static LogicalResult verifyMapClause(Operation *op, OperandRange mapVars) {
- llvm::DenseSet<mlir::TypedValue<mlir::omp::PointerLikeType>> updateToVars;
- llvm::DenseSet<mlir::TypedValue<mlir::omp::PointerLikeType>> updateFromVars;
-
- for (auto mapOp : mapVars) {
- if (!mapOp.getDefiningOp())
- return emitError(op->getLoc(), "missing map operation");
-
- if (auto mapInfoOp = mapOp.getDefiningOp<mlir::omp::MapInfoOp>()) {
- mlir::omp::ClauseMapFlags mapTypeBits = mapInfoOp.getMapType();
-
- bool to = mapTypeToBool(mapTypeBits, ClauseMapFlags::to);
- bool from = mapTypeToBool(mapTypeBits, ClauseMapFlags::from);
- bool del = mapTypeToBool(mapTypeBits, ClauseMapFlags::del);
-
- bool always = mapTypeToBool(mapTypeBits, ClauseMapFlags::always);
- bool close = mapTypeToBool(mapTypeBits, ClauseMapFlags::close);
- bool implicit = mapTypeToBool(mapTypeBits, ClauseMapFlags::implicit);
- bool attach = mapTypeToBool(mapTypeBits, ClauseMapFlags::attach);
+static LogicalResult verifyMapInfoForMapClause(
+ Operation *op, mlir::omp::MapInfoOp mapInfoOp,
+ llvm::DenseSet<mlir::TypedValue<mlir::omp::PointerLikeType>> &updateToVars,
+ llvm::DenseSet<mlir::TypedValue<mlir::omp::PointerLikeType>>
+ &updateFromVars) {
+ mlir::omp::ClauseMapFlags mapTypeBits = mapInfoOp.getMapType();
+
+ bool to = mapTypeToBool(mapTypeBits, ClauseMapFlags::to);
+ bool from = mapTypeToBool(mapTypeBits, ClauseMapFlags::from);
+ bool del = mapTypeToBool(mapTypeBits, ClauseMapFlags::del);
+
+ bool always = mapTypeToBool(mapTypeBits, ClauseMapFlags::always);
+ bool close = mapTypeToBool(mapTypeBits, ClauseMapFlags::close);
+ bool implicit = mapTypeToBool(mapTypeBits, ClauseMapFlags::implicit);
+ bool attach = mapTypeToBool(mapTypeBits, ClauseMapFlags::attach);
+
+ if ((isa<TargetDataOp>(op) || isa<TargetOp>(op)) && del)
+ return emitError(op->getLoc(),
+ "to, from, tofrom and alloc map types are permitted");
+
+ if (isa<TargetEnterDataOp>(op) && (from || del))
+ return emitError(op->getLoc(), "to and alloc map types are permitted");
+
+ if (isa<TargetExitDataOp>(op) && to)
+ return emitError(op->getLoc(),
+ "from, release and delete map types are permitted");
+
+ if (isa<TargetUpdateOp>(op)) {
+ if (del) {
+ return emitError(op->getLoc(),
+ "at least one of to or from map types must be "
+ "specified, other map types are not permitted");
+ }
- if ((isa<TargetDataOp>(op) || isa<TargetOp>(op)) && del)
- return emitError(op->getLoc(),
- "to, from, tofrom and alloc map types are permitted");
+ if (!to && !from && !attach) {
+ return emitError(op->getLoc(),
+ "at least one of to or from or attach map types must be "
+ "specified, other map types are not permitted");
+ }
- if (isa<TargetEnterDataOp>(op) && (from || del))
- return emitError(op->getLoc(), "to and alloc map types are permitted");
+ auto updateVar = mapInfoOp.getVarPtr();
- if (isa<TargetExitDataOp>(op) && to)
- return emitError(op->getLoc(),
- "from, release and delete map types are permitted");
+ if ((to && from) || (to && updateFromVars.contains(updateVar)) ||
+ (from && updateToVars.contains(updateVar))) {
+ return emitError(
+ op->getLoc(),
+ "either to or from map types can be specified, not both");
+ }
- if (isa<TargetUpdateOp>(op)) {
- if (del) {
- return emitError(op->getLoc(),
- "at least one of to or from map types must be "
- "specified, other map types are not permitted");
- }
+ if (always || close || implicit) {
+ return emitError(
+ op->getLoc(),
+ "present, mapper and iterator map type modifiers are permitted");
+ }
- if (!to && !from && !attach) {
- return emitError(
- op->getLoc(),
- "at least one of to or from or attach map types must be "
- "specified, other map types are not permitted");
- }
+ // It's possible we have an attach map, in which case if there is no to
+ // or from tied to it, we skip insertion.
+ if (to || from) {
+ to ? updateToVars.insert(updateVar) : updateFromVars.insert(updateVar);
+ }
+ }
- auto updateVar = mapInfoOp.getVarPtr();
+ if ((mapInfoOp.getVarPtrPtr() && !mapInfoOp.getVarPtrPtrType()) ||
+ (!mapInfoOp.getVarPtrPtr() && mapInfoOp.getVarPtrPtrType())) {
+ return emitError(op->getLoc(),
+ "if varPtrPtr or varPtrPtrType is specified, then both "
+ "must be present");
+ }
- if ((to && from) || (to && updateFromVars.contains(updateVar)) ||
- (from && updateToVars.contains(updateVar))) {
- return emitError(
- op->getLoc(),
- "either to or from map types can be specified, not both");
- }
+ return success();
+}
- if (always || close || implicit) {
- return emitError(
- op->getLoc(),
- "present, mapper and iterator map type modifiers are permitted");
- }
+static LogicalResult verifyMapClause(Operation *op, OperandRange mapVars,
+ OperandRange mapIterated) {
+ llvm::DenseSet<mlir::TypedValue<mlir::omp::PointerLikeType>> updateToVars;
+ llvm::DenseSet<mlir::TypedValue<mlir::omp::PointerLikeType>> updateFromVars;
- // It's possible we have an attach map, in which case if there is no to
- // or from tied to it, we skip insertion.
- if (to || from) {
- to ? updateToVars.insert(updateVar)
- : updateFromVars.insert(updateVar);
- }
- }
+ for (auto mapOp : mapVars) {
+ if (!mapOp.getDefiningOp())
+ return emitError(op->getLoc(), "missing map operation");
- if ((mapInfoOp.getVarPtrPtr() && !mapInfoOp.getVarPtrPtrType()) ||
- (!mapInfoOp.getVarPtrPtr() && mapInfoOp.getVarPtrPtrType())) {
- return emitError(
- op->getLoc(),
- "if varPtrPtr or varPtrPtrType is specified, then both "
- "must be present");
- }
+ if (auto mapInfoOp = mapOp.getDefiningOp<mlir::omp::MapInfoOp>()) {
+ if (failed(verifyMapInfoForMapClause(op, mapInfoOp, updateToVars,
+ updateFromVars)))
+ return failure();
} else if (!isa<DeclareMapperInfoOp>(op)) {
return emitError(op->getLoc(),
"map argument is not a map entry operation");
}
}
+ // Verify iterated map entries.
+ for (auto iterVal : mapIterated) {
+ auto iterOp = iterVal.getDefiningOp<mlir::omp::IteratorOp>();
+ if (!iterOp)
+ return op->emitOpError() << "'map_iterated' arguments must be defined by "
+ "'omp.iterator' ops";
+
+ // Check that the iterator body yields a value defined by omp.map.info.
+ auto yieldOp =
+ cast<mlir::omp::YieldOp>(iterOp.getRegion().front().getTerminator());
+ auto yieldedMapInfo =
+ yieldOp.getResults()[0].getDefiningOp<mlir::omp::MapInfoOp>();
+ if (!yieldedMapInfo)
+ return op->emitOpError() << "'map_iterated' iterator body must yield "
+ "a value defined by 'omp.map.info'";
+
+ if (failed(verifyMapInfoForMapClause(op, yieldedMapInfo, updateToVars,
+ updateFromVars)))
+ return failure();
+ }
+
return success();
}
@@ -2448,13 +2479,13 @@ LogicalResult MapInfoOp::verify() {
void TargetDataOp::build(OpBuilder &builder, OperationState &state,
const TargetDataOperands &clauses) {
TargetDataOp::build(builder, state, clauses.device, clauses.ifExpr,
- clauses.mapVars, clauses.useDeviceAddrVars,
- clauses.useDevicePtrVars);
+ clauses.mapVars, clauses.mapIterated,
+ clauses.useDeviceAddrVars, clauses.useDevicePtrVars);
}
LogicalResult TargetDataOp::verify() {
- if (getMapVars().empty() && getUseDevicePtrVars().empty() &&
- getUseDeviceAddrVars().empty()) {
+ if (getMapVars().empty() && getMapIterated().empty() &&
+ getUseDevicePtrVars().empty() && getUseDeviceAddrVars().empty()) {
return ::emitError(this->getLoc(),
"At least one of map, use_device_ptr_vars, or "
"use_device_addr_vars operand must be present");
@@ -2468,7 +2499,7 @@ LogicalResult TargetDataOp::verify() {
getUseDeviceAddrVars())))
return failure();
- return verifyMapClause(*this, getMapVars());
+ return verifyMapClause(*this, getMapVars(), getMapIterated());
}
//===----------------------------------------------------------------------===//
@@ -2483,15 +2514,16 @@ void TargetEnterDataOp::build(
builder, state, makeArrayAttr(ctx, clauses.dependKinds),
clauses.dependVars, makeArrayAttr(ctx, clauses.dependIteratedKinds),
clauses.dependIterated, clauses.device, clauses.ifExpr, clauses.mapVars,
- clauses.nowait);
+ clauses.mapIterated, clauses.nowait);
}
LogicalResult TargetEnterDataOp::verify() {
LogicalResult verifyDependVars =
verifyDependVarList(*this, getDependKinds(), getDependVars(),
getDependIteratedKinds(), getDependIterated());
- return failed(verifyDependVars) ? verifyDependVars
- : verifyMapClause(*this, getMapVars());
+ return failed(verifyDependVars)
+ ? verifyDependVars
+ : verifyMapClause(*this, getMapVars(), getMapIterated());
}
//===----------------------------------------------------------------------===//
@@ -2505,15 +2537,16 @@ void TargetExitDataOp::build(OpBuilder &builder, OperationState &state,
builder, state, makeArrayAttr(ctx, clauses.dependKinds),
clauses.dependVars, makeArrayAttr(ctx, clauses.dependIteratedKinds),
clauses.dependIterated, clauses.device, clauses.ifExpr, clauses.mapVars,
- clauses.nowait);
+ clauses.mapIterated, clauses.nowait);
}
LogicalResult TargetExitDataOp::verify() {
LogicalResult verifyDependVars =
verifyDependVarList(*this, getDependKinds(), getDependVars(),
getDependIteratedKinds(), getDependIterated());
- return failed(verifyDependVars) ? verifyDependVars
- : verifyMapClause(*this, getMapVars());
+ return failed(verifyDependVars)
+ ? verifyDependVars
+ : verifyMapClause(*this, getMapVars(), getMapIterated());
}
//===----------------------------------------------------------------------===//
@@ -2527,15 +2560,16 @@ void TargetUpdateOp::build(OpBuilder &builder, OperationState &state,
clauses.dependVars,
makeArrayAttr(ctx, clauses.dependIteratedKinds),
clauses.dependIterated, clauses.device, clauses.ifExpr,
- clauses.mapVars, clauses.nowait);
+ clauses.mapVars, clauses.mapIterated, clauses.nowait);
}
LogicalResult TargetUpdateOp::verify() {
LogicalResult verifyDependVars =
verifyDependVarList(*this, getDependKinds(), getDependVars(),
getDependIteratedKinds(), getDependIterated());
- return failed(verifyDependVars) ? verifyDependVars
- : verifyMapClause(*this, getMapVars());
+ return failed(verifyDependVars)
+ ? verifyDependVars
+ : verifyMapClause(*this, getMapVars(), getMapIterated());
}
//===----------------------------------------------------------------------===//
@@ -2556,7 +2590,7 @@ void TargetOp::build(OpBuilder &builder, OperationState &state,
clauses.hasDeviceAddrVars, clauses.hostEvalVars, clauses.ifExpr,
/*in_reduction_vars=*/{}, /*in_reduction_byref=*/nullptr,
/*in_reduction_syms=*/nullptr, clauses.isDevicePtrVars, clauses.mapVars,
- clauses.nowait, clauses.privateVars,
+ clauses.mapIterated, clauses.nowait, clauses.privateVars,
makeArrayAttr(ctx, clauses.privateSyms), clauses.privateNeedsBarrier,
clauses.threadLimitVars,
/*private_maps=*/nullptr);
@@ -2572,7 +2606,7 @@ LogicalResult TargetOp::verify() {
getHasDeviceAddrVars())))
return failure();
- if (failed(verifyMapClause(*this, getMapVars())))
+ if (failed(verifyMapClause(*this, getMapVars(), getMapIterated())))
return failure();
if (failed(verifyDynGroupprivateClause(
@@ -3432,8 +3466,14 @@ LogicalResult DistributeOp::verifyRegions() {
// DeclareMapperOp / DeclareMapperInfoOp
//===----------------------------------------------------------------------===//
+void DeclareMapperInfoOp::build(OpBuilder &builder, OperationState &state,
+ const DeclareMapperInfoOperands &clauses) {
+ DeclareMapperInfoOp::build(builder, state, clauses.mapVars,
+ clauses.mapIterated);
+}
+
LogicalResult DeclareMapperInfoOp::verify() {
- return verifyMapClause(*this, getMapVars());
+ return verifyMapClause(*this, getMapVars(), getMapIterated());
}
LogicalResult DeclareMapperOp::verifyRegions() {
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index 6f93ad231cfac..d35e8612e158b 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -413,6 +413,10 @@ static LogicalResult checkImplementationStatus(Operation &op) {
if (op.hasThreadLimitMultiDim())
result = todo("thread_limit with multi-dimensional values");
};
+ auto checkMap = [&todo](auto op, LogicalResult &result) {
+ if (!op.getMapIterated().empty())
+ result = todo("map/motion clause with iterator modifier");
+ };
auto checkDynGroupprivate = [&todo](auto op, LogicalResult &result) {
if (op.getDynGroupprivateSize())
@@ -489,15 +493,23 @@ static LogicalResult checkImplementationStatus(Operation &op) {
if (totalBits > 128)
result = todo("compare for complex types wider than 128 bits");
})
- .Case<omp::TargetEnterDataOp, omp::TargetExitDataOp>(
- [&](auto op) { checkDepend(op, result); })
- .Case([&](omp::TargetUpdateOp op) { checkDepend(op, result); })
+ .Case<omp::TargetEnterDataOp, omp::TargetExitDataOp>([&](auto op) {
+ checkDepend(op, result);
+ checkMap(op, result);
+ })
+ .Case([&](omp::TargetUpdateOp op) {
+ checkDepend(op, result);
+ checkMap(op, result);
+ })
.Case([&](omp::TargetOp op) {
checkAllocate(op, result);
checkBare(op, result);
checkInReduction(op, result);
+ checkMap(op, result);
checkThreadLimit(op, result);
})
+ .Case([&](omp::TargetDataOp op) { checkMap(op, result); })
+ .Case([&](omp::DeclareMapperInfoOp op) { checkMap(op, result); })
.Default([](Operation &) {
// Assume all clauses for an operation can be translated unless they are
// checked above.
@@ -6682,6 +6694,9 @@ emitUserDefinedMapper(Operation *op, llvm::IRBuilderBase &builder,
"function only supported for host device codegen");
auto declMapperOp = cast<omp::DeclareMapperOp>(op);
auto declMapperInfoOp = declMapperOp.getDeclareMapperInfo();
+ if (failed(checkImplementationStatus(*declMapperInfoOp)))
+ return llvm::make_error<PreviouslyReportedError>();
+
DataLayout dl = DataLayout(declMapperOp->getParentOfType<ModuleOp>());
llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder();
llvm::Type *varType = moduleTranslation.convertType(declMapperOp.getType());
diff --git a/mlir/test/Dialect/OpenMP/invalid.mlir b/mlir/test/Dialect/OpenMP/invalid.mlir
index 7ff4755174053..3bfa6ee16a4bd 100644
--- a/mlir/test/Dialect/OpenMP/invalid.mlir
+++ b/mlir/test/Dialect/OpenMP/invalid.mlir
@@ -2911,7 +2911,7 @@ func.func @omp_target_enter_data(%map1: memref<?xi32>) {
func.func @omp_target_enter_data_depend(%a: memref<?xi32>) {
%0 = omp.map.info var_ptr(%a: memref<?xi32>, tensor<?xi32>) map_clauses(to) capture(ByRef) -> memref<?xi32>
// expected-error @below {{op expected as many depend values as depend variables}}
- omp.target_enter_data map_entries(%0: memref<?xi32> ) {operandSegmentSizes = array<i32: 1, 0, 0, 0, 0>}
+ omp.target_enter_data map_entries(%0: memref<?xi32> ) {operandSegmentSizes = array<i32: 1, 0, 0, 0, 0, 0>}
return
}
@@ -2929,7 +2929,7 @@ func.func @omp_target_exit_data(%map1: memref<?xi32>) {
func.func @omp_target_exit_data_depend(%a: memref<?xi32>) {
%0 = omp.map.info var_ptr(%a: memref<?xi32>, tensor<?xi32>) map_clauses(from) capture(ByRef) -> memref<?xi32>
// expected-error @below {{op expected as many depend values as depend variables}}
- omp.target_exit_data map_entries(%0: memref<?xi32> ) {operandSegmentSizes = array<i32: 1, 0, 0, 0, 0>}
+ omp.target_exit_data map_entries(%0: memref<?xi32> ) {operandSegmentSizes = array<i32: 1, 0, 0, 0, 0, 0>}
return
}
@@ -3021,7 +3021,7 @@ llvm.mlir.global internal @_QFsubEx() : i32
func.func @omp_target_update_data_depend(%a: memref<?xi32>) {
%0 = omp.map.info var_ptr(%a: memref<?xi32>, tensor<?xi32>) map_clauses(to) capture(ByRef) -> memref<?xi32>
// expected-error @below {{op expected as many depend values as depend variables}}
- omp.target_update map_entries(%0: memref<?xi32> ) {operandSegmentSizes = array<i32: 1, 0, 0, 0, 0>}
+ omp.target_update map_entries(%0: memref<?xi32> ) {operandSegmentSizes = array<i32: 1, 0, 0, 0, 0, 0>}
return
}
@@ -3123,7 +3123,7 @@ func.func @omp_target_depend(%data_var: memref<i32>) {
// expected-error @below {{op expected as many depend values as depend variables}}
"omp.target"(%data_var) ({
"omp.terminator"() : () -> ()
- }) {depend_kinds = [], operandSegmentSizes = array<i32: 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>} : (memref<i32>) -> ()
+ }) {depend_kinds = [], operandSegmentSizes = array<i32: 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>} : (memref<i32>) -> ()
"func.return"() : () -> ()
}
@@ -3542,11 +3542,11 @@ func.func @target_undefined_privatizer(%arg0: index) {
func.func @target_private_count_mismatch(%arg0: !llvm.ptr) {
// expected-error @below {{inconsistent number of private variables and privatizer op symbols, private vars: 1 vs. privatizer op symbols: 2}}
- "omp.target"(%arg0) ({
+ "omp.target"(%arg0) <{operandSegmentSizes = array<i32: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0>,
+ private_syms = [@x.privatizer, @y.privatizer]}> ({
^bb0(%arg1 : !llvm.ptr):
omp.terminator
- }) {operandSegmentSizes = array<i32: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0>,
- private_syms = [@x.privatizer, @y.privatizer]} : (!llvm.ptr) -> ()
+ }) : (!llvm.ptr) -> ()
return
}
@@ -4456,6 +4456,15 @@ func.func @iterator_missing_yield(%lb : index, %ub : index, %st : index) {
// -----
+func.func @iterator_empty_body(%lb : index, %ub : index, %st : index) {
+ // expected-error at +1 {{expects a non-empty block}}
+ %0 = omp.iterator(%i: index) = (%lb to %ub step %st) {
+ } -> !omp.iterated<index>
+ return
+}
+
+// -----
+
func.func @iterator_yield_wrong_num_operands(%lb : index, %ub : index, %st : index) {
// expected-error at +1 {{omp.yield in omp.iterator region must yield exactly one value}}
%0 = omp.iterator(%i: index) = (%lb to %ub step %st) {
@@ -4474,6 +4483,131 @@ func.func @iterator_yield_type_mismatch(%lb : index, %ub : index, %st : index) {
return
}
+// -----
+
+func.func @map_iterated_not_iterator(%it : !omp.iterated<!llvm.ptr>) {
+ // expected-error @below {{'omp.target_update' op 'map_iterated' arguments must be defined by 'omp.iterator' ops}}
+ omp.target_update map_iterated(%it : !omp.iterated<!llvm.ptr>)
+ return
+}
+
+// -----
+
+func.func @map_iterated_yield_not_map_info(%lb : index, %ub : index, %st : index,
+ %addr : !llvm.ptr) {
+ %it = omp.iterator(%iv: index) = (%lb to %ub step %st) {
+ omp.yield(%addr : !llvm.ptr)
+ } -> !omp.iterated<!llvm.ptr>
+ // expected-error @below {{'omp.target_enter_data' op 'map_iterated' iterator body must yield a value defined by 'omp.map.info'}}
+ omp.target_enter_data map_iterated(%it : !omp.iterated<!llvm.ptr>) {}
+ return
+}
+
+// -----
+
+func.func @map_iterated_yield_not_map_info_exit(%lb : index, %ub : index, %st : index,
+ %addr : !llvm.ptr) {
+ %it = omp.iterator(%iv: index) = (%lb to %ub step %st) {
+ omp.yield(%addr : !llvm.ptr)
+ } -> !omp.iterated<!llvm.ptr>
+ // expected-error @below {{'omp.target_exit_data' op 'map_iterated' iterator body must yield a value defined by 'omp.map.info'}}
+ omp.target_exit_data map_iterated(%it : !omp.iterated<!llvm.ptr>) {}
+ return
+}
+
+// -----
+
+func.func @target_enter_data_map_iterated_invalid_from(%lb : index, %ub : index,
+ %st : index,
+ %addr : !llvm.ptr) {
+ %it = omp.iterator(%iv: index) = (%lb to %ub step %st) {
+ %m = omp.map.info var_ptr(%addr : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""}
+ omp.yield(%m : !llvm.ptr)
+ } -> !omp.iterated<!llvm.ptr>
+ // expected-error @below {{to and alloc map types are permitted}}
+ omp.target_enter_data map_iterated(%it : !omp.iterated<!llvm.ptr>) {}
+ return
+}
+
+// -----
+
+func.func @target_exit_data_map_iterated_invalid_to(%lb : index, %ub : index,
+ %st : index,
+ %addr : !llvm.ptr) {
+ %it = omp.iterator(%iv: index) = (%lb to %ub step %st) {
+ %m = omp.map.info var_ptr(%addr : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""}
+ omp.yield(%m : !llvm.ptr)
+ } -> !omp.iterated<!llvm.ptr>
+ // expected-error @below {{from, release and delete map types are permitted}}
+ omp.target_exit_data map_iterated(%it : !omp.iterated<!llvm.ptr>) {}
+ return
+}
+
+// -----
+
+func.func @target_update_map_iterated_invalid_delete(%lb : index, %ub : index,
+ %st : index,
+ %addr : !llvm.ptr) {
+ %it = omp.iterator(%iv: index) = (%lb to %ub step %st) {
+ %m = omp.map.info var_ptr(%addr : !llvm.ptr, i32) map_clauses(delete) capture(ByRef) -> !llvm.ptr {name = ""}
+ omp.yield(%m : !llvm.ptr)
+ } -> !omp.iterated<!llvm.ptr>
+ // expected-error @below {{at least one of to or from map types must be specified, other map types are not permitted}}
+ omp.target_update map_iterated(%it : !omp.iterated<!llvm.ptr>)
+ return
+}
+
+// -----
+
+func.func @target_update_map_iterated_invalid_conflict(%lb : index, %ub : index,
+ %st : index,
+ %addr : !llvm.ptr) {
+ %mapv = omp.map.info var_ptr(%addr : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""}
+ %it = omp.iterator(%iv: index) = (%lb to %ub step %st) {
+ %m = omp.map.info var_ptr(%addr : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""}
+ omp.yield(%m : !llvm.ptr)
+ } -> !omp.iterated<!llvm.ptr>
+ // expected-error @below {{either to or from map types can be specified, not both}}
+ omp.target_update map_entries(%mapv : !llvm.ptr) map_iterated(%it : !omp.iterated<!llvm.ptr>)
+ return
+}
+
+// -----
+
+func.func @target_data_map_iterated_invalid_delete(%lb : index, %ub : index,
+ %st : index,
+ %addr : !llvm.ptr) {
+ %it = omp.iterator(%iv: index) = (%lb to %ub step %st) {
+ %m = omp.map.info var_ptr(%addr : !llvm.ptr, i32) map_clauses(delete) capture(ByRef) -> !llvm.ptr {name = ""}
+ omp.yield(%m : !llvm.ptr)
+ } -> !omp.iterated<!llvm.ptr>
+ // expected-error @below {{to, from, tofrom and alloc map types are permitted}}
+ omp.target_data map_iterated(%it : !omp.iterated<!llvm.ptr>) {}
+ return
+}
+
+// -----
+
+omp.declare_mapper @declare_mapper_iterated_not_iterator : !llvm.struct<"mapper_type", (i32)> {
+^bb0(%arg: !llvm.ptr, %it: !omp.iterated<!llvm.ptr>):
+ // expected-error @below {{'omp.declare_mapper.info' op 'map_iterated' arguments must be defined by 'omp.iterator' ops}}
+ omp.declare_mapper.info map_iterated(%it : !omp.iterated<!llvm.ptr>)
+}
+
+// -----
+
+omp.declare_mapper @declare_mapper_iterated_yield_not_map_info : !llvm.struct<"mapper_type", (i32)> {
+^bb0(%arg: !llvm.ptr):
+ %lb = arith.constant 0 : index
+ %ub = arith.constant 4 : index
+ %st = arith.constant 1 : index
+ %it = omp.iterator(%iv: index) = (%lb to %ub step %st) {
+ omp.yield(%arg : !llvm.ptr)
+ } -> !omp.iterated<!llvm.ptr>
+ // expected-error @below {{'omp.declare_mapper.info' op 'map_iterated' iterator body must yield a value defined by 'omp.map.info'}}
+ omp.declare_mapper.info map_iterated(%it : !omp.iterated<!llvm.ptr>)
+}
+
// -----
func.func @target_allocmem_invalid_uniq_name(%device : i32) -> () {
// expected-error @below {{op attribute 'uniq_name' failed to satisfy constraint: string attribute}}
diff --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir
index acf6879906e74..4af59f9aff297 100644
--- a/mlir/test/Dialect/OpenMP/ops.mlir
+++ b/mlir/test/Dialect/OpenMP/ops.mlir
@@ -871,7 +871,7 @@ func.func @omp_target(%if_cond : i1, %device : si32, %num_threads : i32, %devic
"omp.target"(%device, %if_cond, %num_threads) ({
// CHECK: omp.terminator
omp.terminator
- }) {nowait, operandSegmentSizes = array<i32: 0,0,0,0,1,0,0,0,1,0,0,0,0,1>} : ( si32, i1, i32 ) -> ()
+ }) {nowait, operandSegmentSizes = array<i32: 0,0,0,0,1,0,0,0,1,0,0,0,0,0,1>} : ( si32, i1, i32 ) -> ()
// Test with optional map clause.
// CHECK: %[[MAP_A:.*]] = omp.map.info var_ptr(%[[VAL_1:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(always, to) capture(ByRef) -> memref<?xi32> {name = ""}
@@ -1001,6 +1001,24 @@ omp.declare_mapper @my_mapper : !llvm.struct<"my_type", (i32)> {
omp.declare_mapper.info map_entries(%decl_map_info : !llvm.ptr)
}
+// CHECK: omp.declare_mapper @my_mapper_iterated : !llvm.struct<"my_iter_type", (i32)>
+omp.declare_mapper @my_mapper_iterated : !llvm.struct<"my_iter_type", (i32)> {
+^bb0(%arg: !llvm.ptr):
+ %lb = arith.constant 0 : index
+ %ub = arith.constant 4 : index
+ %step = arith.constant 1 : index
+ // CHECK: %[[IT:.*]] = omp.iterator(%[[IV:.*]]: index) = (%{{.*}} to %{{.*}} step %{{.*}}) {
+ // CHECK: %[[DECL_MAP_INFO:.*]] = omp.map.info var_ptr(%{{.*}} : !llvm.ptr, !llvm.struct<"my_iter_type", (i32)>) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""}
+ // CHECK: omp.yield(%[[DECL_MAP_INFO]] : !llvm.ptr)
+ // CHECK: } -> !omp.iterated<!llvm.ptr>
+ %it = omp.iterator(%iv: index) = (%lb to %ub step %step) {
+ %decl_map_info = omp.map.info var_ptr(%arg : !llvm.ptr, !llvm.struct<"my_iter_type", (i32)>) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""}
+ omp.yield(%decl_map_info : !llvm.ptr)
+ } -> !omp.iterated<!llvm.ptr>
+ // CHECK: omp.declare_mapper.info map_iterated(%[[IT]] : !omp.iterated<!llvm.ptr>)
+ omp.declare_mapper.info map_iterated(%it : !omp.iterated<!llvm.ptr>)
+}
+
// CHECK-LABEL: func @wsloop_reduction
func.func @wsloop_reduction(%lb : index, %ub : index, %step : index) {
%c1 = arith.constant 1 : i32
@@ -3879,6 +3897,21 @@ func.func @omp_iterator(%s2 : !llvm.struct<(ptr, i64)>) -> () {
return
}
+// CHECK-LABEL: func.func @omp_iterator_explicit_yield
+func.func @omp_iterator_explicit_yield(%value : index) -> () {
+ %lb = arith.constant 0 : index
+ %ub = arith.constant 4 : index
+ %st = arith.constant 1 : index
+
+ // CHECK: omp.iterator(%{{.*}}: index) = (%{{.*}} to %{{.*}} step %{{.*}}) {
+ // CHECK: omp.yield(%{{.*}} : index)
+ // CHECK: } -> !omp.iterated<index>
+ %0 = omp.iterator(%iv: index) = (%lb to %ub step %st) {
+ omp.yield(%value : index)
+ } -> !omp.iterated<index>
+ return
+}
+
// CHECK-LABEL: func.func @omp_iterator_2d
func.func @omp_iterator_2d(%s2 : !llvm.struct<(ptr, i64)>) -> () {
// CHECK: %[[IT:.*]] = omp.iterator(%[[IV0:.*]]: index, %[[IV1:.*]]: index) =
@@ -4052,3 +4085,99 @@ llvm.mlir.global internal @gp() : i32
llvm.mlir.global internal @any() : i32
llvm.mlir.global internal @host() : i32
llvm.mlir.global internal @nohost() : i32
+
+// -----
+
+// CHECK-LABEL: func.func @omp_target_update_map_iterated
+func.func @omp_target_update_map_iterated(%lb : index, %ub : index, %step : index,
+ %addr : !llvm.ptr) -> () {
+ // CHECK: %[[MAP:.*]] = omp.map.info var_ptr(%{{.*}} : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""}
+ %map = omp.map.info var_ptr(%addr : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""}
+
+ // CHECK: %[[IT:.*]] = omp.iterator(%[[IV:.*]]: index) = (%{{.*}} to %{{.*}} step %{{.*}}) {
+ // CHECK: %[[M:.*]] = omp.map.info var_ptr(%{{.*}} : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""}
+ // CHECK: omp.yield(%[[M]] : !llvm.ptr)
+ // CHECK: } -> !omp.iterated<!llvm.ptr>
+ %it = omp.iterator(%iv: index) = (%lb to %ub step %step) {
+ %m = omp.map.info var_ptr(%addr : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""}
+ omp.yield(%m : !llvm.ptr)
+ } -> !omp.iterated<!llvm.ptr>
+
+ // CHECK: omp.target_update map_entries(%[[MAP]] : !llvm.ptr) map_iterated(%[[IT]] : !omp.iterated<!llvm.ptr>)
+ omp.target_update map_entries(%map : !llvm.ptr) map_iterated(%it : !omp.iterated<!llvm.ptr>)
+ return
+}
+
+// -----
+
+// CHECK-LABEL: func.func @omp_target_enter_data_map_iterated
+func.func @omp_target_enter_data_map_iterated(%lb : index, %ub : index, %step : index,
+ %addr : !llvm.ptr) -> () {
+ // CHECK: %[[IT:.*]] = omp.iterator(%[[IV:.*]]: index) = (%{{.*}} to %{{.*}} step %{{.*}}) {
+ // CHECK: omp.yield(%{{.*}} : !llvm.ptr)
+ // CHECK: } -> !omp.iterated<!llvm.ptr>
+ %it = omp.iterator(%iv: index) = (%lb to %ub step %step) {
+ %m = omp.map.info var_ptr(%addr : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""}
+ omp.yield(%m : !llvm.ptr)
+ } -> !omp.iterated<!llvm.ptr>
+
+ // CHECK: omp.target_enter_data map_iterated(%[[IT]] : !omp.iterated<!llvm.ptr>)
+ omp.target_enter_data map_iterated(%it : !omp.iterated<!llvm.ptr>) {}
+ return
+}
+
+// -----
+
+// CHECK-LABEL: func.func @omp_target_exit_data_map_iterated
+func.func @omp_target_exit_data_map_iterated(%lb : index, %ub : index, %step : index,
+ %addr : !llvm.ptr) -> () {
+ // CHECK: %[[IT:.*]] = omp.iterator(%[[IV:.*]]: index) = (%{{.*}} to %{{.*}} step %{{.*}}) {
+ // CHECK: omp.yield(%{{.*}} : !llvm.ptr)
+ // CHECK: } -> !omp.iterated<!llvm.ptr>
+ %it = omp.iterator(%iv: index) = (%lb to %ub step %step) {
+ %m = omp.map.info var_ptr(%addr : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""}
+ omp.yield(%m : !llvm.ptr)
+ } -> !omp.iterated<!llvm.ptr>
+
+ // CHECK: omp.target_exit_data map_iterated(%[[IT]] : !omp.iterated<!llvm.ptr>)
+ omp.target_exit_data map_iterated(%it : !omp.iterated<!llvm.ptr>) {}
+ return
+}
+
+// -----
+
+// CHECK-LABEL: func.func @omp_target_data_map_iterated
+func.func @omp_target_data_map_iterated(%lb : index, %ub : index, %step : index,
+ %addr : !llvm.ptr) -> () {
+ %map = omp.map.info var_ptr(%addr : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""}
+
+ // CHECK: %[[IT:.*]] = omp.iterator
+ %it = omp.iterator(%iv: index) = (%lb to %ub step %step) {
+ %m = omp.map.info var_ptr(%addr : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""}
+ omp.yield(%m : !llvm.ptr)
+ } -> !omp.iterated<!llvm.ptr>
+
+ // CHECK: omp.target_data map_entries(%{{.*}} : !llvm.ptr) map_iterated(%[[IT]] : !omp.iterated<!llvm.ptr>)
+ omp.target_data map_entries(%map : !llvm.ptr) map_iterated(%it : !omp.iterated<!llvm.ptr>) {}
+ return
+}
+
+// -----
+
+// CHECK-LABEL: func.func @omp_target_map_iterated
+func.func @omp_target_map_iterated(%lb : index, %ub : index, %step : index,
+ %addr : !llvm.ptr) -> () {
+ %map = omp.map.info var_ptr(%addr : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""}
+
+ // CHECK: %[[IT:.*]] = omp.iterator
+ %it = omp.iterator(%iv: index) = (%lb to %ub step %step) {
+ %m = omp.map.info var_ptr(%addr : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""}
+ omp.yield(%m : !llvm.ptr)
+ } -> !omp.iterated<!llvm.ptr>
+
+ // CHECK: omp.target map_iterated(%[[IT]] : !omp.iterated<!llvm.ptr>) map_entries(%{{.*}} -> {{.*}} : !llvm.ptr)
+ omp.target map_iterated(%it : !omp.iterated<!llvm.ptr>) map_entries(%map -> %arg0 : !llvm.ptr) {
+ omp.terminator
+ }
+ return
+}
diff --git a/mlir/test/Target/LLVMIR/openmp-todo.mlir b/mlir/test/Target/LLVMIR/openmp-todo.mlir
index 295ba54dbfb38..fa08590978f43 100644
--- a/mlir/test/Target/LLVMIR/openmp-todo.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-todo.mlir
@@ -493,3 +493,110 @@ llvm.func @wsloop_order(%lb : i32, %ub : i32, %step : i32) {
}
llvm.return
}
+
+// -----
+
+llvm.func @target_enter_data_map_iterator(%addr : !llvm.ptr) {
+ %c0 = llvm.mlir.constant(0 : i64) : i64
+ %c10 = llvm.mlir.constant(10 : i64) : i64
+ %c1 = llvm.mlir.constant(1 : i64) : i64
+ %it = omp.iterator(%iv: i64) = (%c0 to %c10 step %c1) {
+ %m = omp.map.info var_ptr(%addr : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""}
+ omp.yield(%m : !llvm.ptr)
+ } -> !omp.iterated<!llvm.ptr>
+ // expected-error at below {{not yet implemented: Unhandled clause map/motion clause with iterator modifier in omp.target_enter_data operation}}
+ // expected-error at below {{LLVM Translation failed for operation: omp.target_enter_data}}
+ omp.target_enter_data map_iterated(%it : !omp.iterated<!llvm.ptr>) {}
+ llvm.return
+}
+
+// -----
+
+llvm.func @target_exit_data_map_iterator(%addr : !llvm.ptr) {
+ %c0 = llvm.mlir.constant(0 : i64) : i64
+ %c10 = llvm.mlir.constant(10 : i64) : i64
+ %c1 = llvm.mlir.constant(1 : i64) : i64
+ %it = omp.iterator(%iv: i64) = (%c0 to %c10 step %c1) {
+ %m = omp.map.info var_ptr(%addr : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""}
+ omp.yield(%m : !llvm.ptr)
+ } -> !omp.iterated<!llvm.ptr>
+ // expected-error at below {{not yet implemented: Unhandled clause map/motion clause with iterator modifier in omp.target_exit_data operation}}
+ // expected-error at below {{LLVM Translation failed for operation: omp.target_exit_data}}
+ omp.target_exit_data map_iterated(%it : !omp.iterated<!llvm.ptr>) {}
+ llvm.return
+}
+
+// -----
+
+llvm.func @target_update_map_iterator(%addr : !llvm.ptr) {
+ %c0 = llvm.mlir.constant(0 : i64) : i64
+ %c10 = llvm.mlir.constant(10 : i64) : i64
+ %c1 = llvm.mlir.constant(1 : i64) : i64
+ %it = omp.iterator(%iv: i64) = (%c0 to %c10 step %c1) {
+ %m = omp.map.info var_ptr(%addr : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""}
+ omp.yield(%m : !llvm.ptr)
+ } -> !omp.iterated<!llvm.ptr>
+ // expected-error at below {{not yet implemented: Unhandled clause map/motion clause with iterator modifier in omp.target_update operation}}
+ // expected-error at below {{LLVM Translation failed for operation: omp.target_update}}
+ omp.target_update map_iterated(%it : !omp.iterated<!llvm.ptr>)
+ llvm.return
+}
+
+// -----
+
+llvm.func @target_map_iterated_unsupported(%addr : !llvm.ptr) {
+ %c0 = llvm.mlir.constant(0 : i64) : i64
+ %c10 = llvm.mlir.constant(10 : i64) : i64
+ %c1 = llvm.mlir.constant(1 : i64) : i64
+ %map = omp.map.info var_ptr(%addr : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""}
+ %it = omp.iterator(%iv: i64) = (%c0 to %c10 step %c1) {
+ %m = omp.map.info var_ptr(%addr : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""}
+ omp.yield(%m : !llvm.ptr)
+ } -> !omp.iterated<!llvm.ptr>
+ // expected-error at below {{not yet implemented: Unhandled clause map/motion clause with iterator modifier in omp.target operation}}
+ // expected-error at below {{LLVM Translation failed for operation: omp.target}}
+ omp.target map_iterated(%it : !omp.iterated<!llvm.ptr>) map_entries(%map -> %arg0 : !llvm.ptr) {
+ omp.terminator
+ }
+ llvm.return
+}
+
+// -----
+
+llvm.func @target_data_map_iterator(%addr : !llvm.ptr) {
+ %c0 = llvm.mlir.constant(0 : i64) : i64
+ %c10 = llvm.mlir.constant(10 : i64) : i64
+ %c1 = llvm.mlir.constant(1 : i64) : i64
+ %it = omp.iterator(%iv: i64) = (%c0 to %c10 step %c1) {
+ %m = omp.map.info var_ptr(%addr : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""}
+ omp.yield(%m : !llvm.ptr)
+ } -> !omp.iterated<!llvm.ptr>
+ // expected-error at below {{not yet implemented: Unhandled clause map/motion clause with iterator modifier in omp.target_data operation}}
+ // expected-error at below {{LLVM Translation failed for operation: omp.target_data}}
+ omp.target_data map_iterated(%it : !omp.iterated<!llvm.ptr>) {}
+ llvm.return
+}
+
+// -----
+
+module attributes {omp.target_triples = ["amdgcn-amd-amdhsa"]} {
+ omp.declare_mapper @mapper_with_iterator : !llvm.struct<"mapper_type", (i32)> {
+ ^bb0(%arg: !llvm.ptr):
+ %c0 = llvm.mlir.constant(0 : i64) : i64
+ %c10 = llvm.mlir.constant(10 : i64) : i64
+ %c1 = llvm.mlir.constant(1 : i64) : i64
+ %it = omp.iterator(%iv: i64) = (%c0 to %c10 step %c1) {
+ %m = omp.map.info var_ptr(%arg : !llvm.ptr, !llvm.struct<"mapper_type", (i32)>) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""}
+ omp.yield(%m : !llvm.ptr)
+ } -> !omp.iterated<!llvm.ptr>
+ // expected-error at below {{not yet implemented: Unhandled clause map/motion clause with iterator modifier in omp.declare_mapper.info operation}}
+ omp.declare_mapper.info map_iterated(%it : !omp.iterated<!llvm.ptr>)
+ }
+
+ llvm.func @target_data_mapper_iterator(%addr : !llvm.ptr) {
+ %map = omp.map.info var_ptr(%addr : !llvm.ptr, !llvm.struct<"mapper_type", (i32)>) map_clauses(tofrom) capture(ByRef) mapper(@mapper_with_iterator) -> !llvm.ptr {name = ""}
+ // expected-error at below {{LLVM Translation failed for operation: omp.target_data}}
+ omp.target_data map_entries(%map : !llvm.ptr) {}
+ llvm.return
+ }
+}
More information about the flang-commits
mailing list