diff --git a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir --- a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir +++ b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir @@ -321,6 +321,19 @@ // ----- +func.func @_QPomp_target_data_empty() { + %0 = fir.alloca !fir.array<1024xi32> {bindc_name = "a", uniq_name = "_QFomp_target_data_emptyEa"} + omp.target_data use_device_addr(%0 : !fir.ref>) { + } + return +} + +// CHECK-LABEL: llvm.func @_QPomp_target_data_empty +// CHECK: omp.target_data use_device_addr(%1 : !llvm.ptr>) { +// CHECK: } + +// ----- + func.func @_QPomp_target() { %0 = fir.alloca !fir.array<512xi32> {bindc_name = "a", uniq_name = "_QFomp_targetEa"} %c64_i32 = arith.constant 64 : i32 diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td --- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td +++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td @@ -1041,15 +1041,16 @@ Variadic:$use_device_ptr, Variadic:$use_device_addr, Variadic:$map_operands, - I64ArrayAttr:$map_types); + OptionalAttr:$map_types); let regions = (region AnyRegion:$region); let assemblyFormat = [{ oilist(`if` `(` $if_expr `:` type($if_expr) `)` - | `device` `(` $device `:` type($device) `)`) - `map` `(` custom($map_operands, type($map_operands), $map_types) `)` - oilist(`use_device_ptr` `(` $use_device_ptr `:` type($use_device_ptr) `)` + | `device` `(` $device `:` type($device) `)` + | `map` + `(` custom($map_operands, type($map_operands), $map_types) `)` + | `use_device_ptr` `(` $use_device_ptr `:` type($use_device_ptr) `)` | `use_device_addr` `(` $use_device_addr `:` type($use_device_addr) `)`) $region attr-dict }]; diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp --- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp +++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp @@ -800,11 +800,22 @@ std::underlying_type_t>( flag); }; - if (!map_types.has_value()) - return success(); + if (!map_types) { + if (!map_operands.empty()) + return emitError(op->getLoc(), "missing mapTypes"); + else + return success(); + } + + if (map_operands.empty() && !map_types->empty()) + return emitError(op->getLoc(), "missing mapOperands"); + + if (map_types->empty() && !map_operands.empty()) + return emitError(op->getLoc(), "missing mapTypes"); if (map_operands.size() != map_types->size()) - return failure(); + return emitError(op->getLoc(), + "mismatch in number of mapOperands and mapTypes"); for (const auto &mapTypeOp : *map_types) { int64_t mapTypeBits = 0x00; @@ -835,6 +846,11 @@ } LogicalResult DataOp::verify() { + if (getMapOperands().empty() && getUseDevicePtr().empty() && + getUseDeviceAddr().empty()) { + return ::emitError(this->getLoc(), "At least one of map, useDevicePtr, or " + "useDeviceAddr operand must be present"); + } return verifyMapClause(*this, getMapOperands(), getMapTypes()); } diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp --- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp @@ -1437,7 +1437,8 @@ deviceID = intAttr.getInt(); mapOperands = dataOp.getMapOperands(); - mapTypes = dataOp.getMapTypes(); + if (dataOp.getMapTypes()) + mapTypes = dataOp.getMapTypes().value(); return success(); }) .Case([&](omp::EnterDataOp enterDataOp) { diff --git a/mlir/test/Dialect/OpenMP/invalid.mlir b/mlir/test/Dialect/OpenMP/invalid.mlir --- a/mlir/test/Dialect/OpenMP/invalid.mlir +++ b/mlir/test/Dialect/OpenMP/invalid.mlir @@ -1630,6 +1630,14 @@ // ----- +func.func @omp_target_data() { + // expected-error @below {{At least one of map, useDevicePtr, or useDeviceAddr operand must be present}} + omp.target_data {} + return +} + +// ----- + func.func @omp_target_enter_data(%map1: memref) { // expected-error @below {{to and alloc map types are permitted}} omp.target_enter_data map((from -> %map1 : memref)){}