[Mlir-commits] [mlir] 771bdfd - [MLIR][OpenMP] Add verification for DeclareTargetInterface (#217294)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Mon Aug 24 04:39:16 PDT 2026


Author: Sergio Afonso
Date: 2026-08-24T12:39:08+01:00
New Revision: 771bdfdab2d66a4eb85b8ea7673cfa30152718b1

URL: https://github.com/llvm/llvm-project/commit/771bdfdab2d66a4eb85b8ea7673cfa30152718b1
DIFF: https://github.com/llvm/llvm-project/commit/771bdfdab2d66a4eb85b8ea7673cfa30152718b1.diff

LOG: [MLIR][OpenMP] Add verification for DeclareTargetInterface (#217294)

This patch introduces checks to ensure the "omp.declare_target"
attribute is only attached to `DeclareTargetInterface` operations, it is
always the right type attribute and its properties do not conflict with
the operation they are attached to.

Added: 
    

Modified: 
    mlir/include/mlir/Dialect/OpenMP/OpenMPDialect.td
    mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
    mlir/test/Dialect/OpenMP/attr.mlir
    mlir/test/Dialect/OpenMP/invalid-interface.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPDialect.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPDialect.td
index 8ef8fcccf2d57..dbc851a5e297c 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPDialect.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPDialect.td
@@ -18,6 +18,7 @@ def OpenMP_Dialect : Dialect {
   let useDefaultAttributePrinterParser = 1;
   let useStrictPropertiesInAssemblyFormat = 1;
   let useDefaultTypePrinterParser = 1;
+  let hasOperationAttrVerify = 1;
 }
 
 #endif  // OPENMP_DIALECT

diff  --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
index c957321771ab7..f06c665c7013b 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -343,6 +343,48 @@ void OpenMPDialect::initialize() {
       mlir::omp::DeclareTargetDefaultModel<mlir::func::FuncOp>>(*getContext());
 }
 
+//===----------------------------------------------------------------------===//
+// Dialect operation attribute verification
+//===----------------------------------------------------------------------===//
+
+static LogicalResult verifyDeclareTargetAttr(Operation *op, Attribute attr) {
+  if (!isa<DeclareTargetInterface>(op))
+    return op->emitError() << "omp.declare_target can only be applied to "
+                              "DeclareTargetInterface ops";
+
+  auto declareTargetAttr = dyn_cast<DeclareTargetAttr>(attr);
+  if (!declareTargetAttr)
+    return op->emitError()
+           << "omp.declare_target must be an #omp.declaretarget attribute";
+
+  if (isa<mlir::FunctionOpInterface>(op)) {
+    if (declareTargetAttr.getAutomap())
+      return op->emitOpError()
+             << "omp.declare_target 'automap' is not valid on functions";
+
+    // TODO: Disallow the `local` clause (OpenMP 6.0).
+    if (declareTargetAttr.getCaptureClause().getValue() ==
+        mlir::omp::DeclareTargetCaptureClause::link)
+      return op->emitOpError()
+             << "omp.declare_target 'link' is not valid on functions";
+  } else {
+    // TODO: Disallow the `indirect` clause (OpenMP 5.1).
+    if (declareTargetAttr.getImplicit())
+      return op->emitOpError()
+             << "omp.declare_target 'implicit' is only valid on functions";
+  }
+  return success();
+}
+
+LogicalResult
+OpenMPDialect::verifyOperationAttribute(Operation *op,
+                                        NamedAttribute attribute) {
+  if (attribute.getName() == "omp.declare_target")
+    return verifyDeclareTargetAttr(op, attribute.getValue());
+
+  return success();
+}
+
 //===----------------------------------------------------------------------===//
 // Parser and printer for Allocate Clause
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/test/Dialect/OpenMP/attr.mlir b/mlir/test/Dialect/OpenMP/attr.mlir
index 61a4e0df2f1ff..8c6f25f3bcaab 100644
--- a/mlir/test/Dialect/OpenMP/attr.mlir
+++ b/mlir/test/Dialect/OpenMP/attr.mlir
@@ -71,12 +71,6 @@ func.func @omp_decl_tar_host_to() -> () attributes {omp.declare_target = #omp.de
   return
 }
 
-// CHECK-LABEL: func @omp_decl_tar_host_link
-// CHECK-SAME: {{.*}} attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (link)>} {
-func.func @omp_decl_tar_host_link() -> () attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (link)>} {
-  return
-}
-
 // CHECK-LABEL: func @omp_decl_tar_host_enter
 // CHECK-SAME: {{.*}} attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (enter)>} {
 func.func @omp_decl_tar_host_enter() -> () attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (enter)>} {
@@ -89,12 +83,6 @@ func.func @omp_decl_tar_nohost_to() -> () attributes {omp.declare_target = #omp.
   return
 }
 
-// CHECK-LABEL: func @omp_decl_tar_nohost_link
-// CHECK-SAME: {{.*}} attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (link)>} {
-func.func @omp_decl_tar_nohost_link() -> () attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (link)>} {
-  return
-}
-
 // CHECK-LABEL: func @omp_decl_tar_nohost_enter
 // CHECK-SAME: {{.*}} attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>} {
 func.func @omp_decl_tar_nohost_enter() -> () attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>} {
@@ -107,12 +95,6 @@ func.func @omp_decl_tar_any_to() -> () attributes {omp.declare_target = #omp.dec
   return
 }
 
-// CHECK-LABEL: func @omp_decl_tar_any_link
-// CHECK-SAME: {{.*}} attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} {
-func.func @omp_decl_tar_any_link() -> () attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} {
-  return
-}
-
 // CHECK-LABEL: func @omp_decl_tar_any_enter
 // CHECK-SAME: {{.*}} attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>} {
 func.func @omp_decl_tar_any_enter() -> () attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>} {

diff  --git a/mlir/test/Dialect/OpenMP/invalid-interface.mlir b/mlir/test/Dialect/OpenMP/invalid-interface.mlir
index 6fe64b0839e66..787b6a7ec00ce 100644
--- a/mlir/test/Dialect/OpenMP/invalid-interface.mlir
+++ b/mlir/test/Dialect/OpenMP/invalid-interface.mlir
@@ -104,3 +104,31 @@ func.func @composable_conditional_combined(%x : i32) {
   } {omp.combined}
   return
 }
+
+// -----
+
+// expected-error @below {{omp.declare_target can only be applied to DeclareTargetInterface ops}}
+%0 = arith.constant { omp.declare_target = #omp.declaretarget<capture_clause = (enter)> } 2 : i32
+
+// -----
+
+// expected-error @below {{omp.declare_target must be an #omp.declaretarget attribute}}
+func.func private @declare_target_attr_type() attributes { omp.declare_target = 10 : i32 }
+
+// -----
+
+// expected-error @below {{omp.declare_target 'automap' is not valid on functions}}
+func.func private @declare_target_automap() attributes { omp.declare_target = #omp.declaretarget<automap = true>}
+
+// -----
+
+// expected-error @below {{omp.declare_target 'link' is not valid on functions}}
+func.func private @declare_target_link() attributes { omp.declare_target = #omp.declaretarget<capture_clause = (link)>}
+
+// -----
+
+// expected-error @below {{omp.declare_target 'implicit' is only valid on functions}}
+llvm.mlir.global @declare_target_implicit() {omp.declare_target = #omp.declaretarget<implicit = true>} : i32 {
+  %0 = llvm.mlir.constant(1 : i32) : i32
+  llvm.return %0 : i32
+}


        


More information about the Mlir-commits mailing list