[Mlir-commits] [mlir] [MLIR][ODS] Add strict property assembly format mode (PR #196269)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Thu May 7 02:55:58 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir-llvm

Author: Mehdi Amini (joker-eph)

<details>
<summary>Changes</summary>

Introduce a dialect-level ODS flag for strict property handling in declarative assembly formats. It is disabled by default for now, preserving existing parser behavior unless a dialect opts in.

Enable the mode immediately for dialects whose declarative assembly formats already satisfy these binding rules.

When enabled, a property-backed op format must bind every inherent attribute and property directly or include prop-dict.

Generated parsers for opted-in dialects also reject inherent attributes that arrive through attr-dict, preventing Operation::setAttrs from populating properties through that path.

Add mlir-tblgen coverage and document default and strict dialect behavior.

Assisted-by: Codex

---

Patch is 25.98 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/196269.diff


28 Files Affected:

- (modified) mlir/docs/DefiningDialects/Operations.md (+7) 
- (modified) mlir/docs/DefiningDialects/_index.md (+20) 
- (modified) mlir/include/mlir/Dialect/Affine/IR/AffineOps.td (+1) 
- (modified) mlir/include/mlir/Dialect/ArmNeon/ArmNeon.td (+1) 
- (modified) mlir/include/mlir/Dialect/ArmSME/IR/ArmSME.td (+1) 
- (modified) mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td (+1) 
- (modified) mlir/include/mlir/Dialect/Complex/IR/ComplexBase.td (+1) 
- (modified) mlir/include/mlir/Dialect/DLTI/DLTIBase.td (+1) 
- (modified) mlir/include/mlir/Dialect/IRDL/IR/IRDL.td (+1) 
- (modified) mlir/include/mlir/Dialect/Index/IR/IndexDialect.td (+1) 
- (modified) mlir/include/mlir/Dialect/LLVMIR/VCIXOps.td (+1) 
- (modified) mlir/include/mlir/Dialect/LLVMIR/XeVMOps.td (+1) 
- (modified) mlir/include/mlir/Dialect/Linalg/IR/LinalgBase.td (+1) 
- (modified) mlir/include/mlir/Dialect/MLProgram/IR/MLProgramBase.td (+1) 
- (modified) mlir/include/mlir/Dialect/MPI/IR/MPI.td (+1) 
- (modified) mlir/include/mlir/Dialect/Ptr/IR/PtrDialect.td (+1) 
- (modified) mlir/include/mlir/Dialect/Quant/IR/QuantBase.td (+1) 
- (modified) mlir/include/mlir/Dialect/SCF/IR/SCFOps.td (+1) 
- (modified) mlir/include/mlir/Dialect/SMT/IR/SMTDialect.td (+1) 
- (modified) mlir/include/mlir/Dialect/Shard/IR/ShardBase.td (+1) 
- (modified) mlir/include/mlir/Dialect/Tensor/IR/TensorBase.td (+1) 
- (modified) mlir/include/mlir/Dialect/UB/IR/UBOps.td (+1) 
- (modified) mlir/include/mlir/IR/DialectBase.td (+6) 
- (modified) mlir/include/mlir/TableGen/Dialect.h (+4) 
- (modified) mlir/lib/TableGen/Dialect.cpp (+4) 
- (modified) mlir/test/mlir-tblgen/op-format-invalid.td (+26) 
- (modified) mlir/test/mlir-tblgen/op-format.td (+58) 
- (modified) mlir/tools/mlir-tblgen/OpFormatGen.cpp (+57-3) 


``````````diff
diff --git a/mlir/docs/DefiningDialects/Operations.md b/mlir/docs/DefiningDialects/Operations.md
index b64bffdf72ae3..d7dd0fa27305e 100644
--- a/mlir/docs/DefiningDialects/Operations.md
+++ b/mlir/docs/DefiningDialects/Operations.md
@@ -748,6 +748,10 @@ The available directives are as follows:
         printed as part of the attribute dictionary unless a `prop-dict` is
         present.
     -   Discardable attributes are always part of the `attr-dict`.
+    -   For dialects that set `useStrictPropertiesInAssemblyFormat`,
+        `attr-dict` only carries discardable attributes for property-backed
+        operations. Inherent attributes must be bound directly in the format or
+        covered by `prop-dict`.
 
 *   `attr-dict-with-keyword`
 
@@ -1091,6 +1095,9 @@ to:
     directives.
 1.  Unless all non-attribute properties appear in the format, the `prop-dict`
     directive must be present.
+1.  For dialects that set `useStrictPropertiesInAssemblyFormat`, every inherent
+    attribute and property must either appear in the format or be covered by the
+    `prop-dict` directive.
 1.  The `attr-dict` directive must always be present.
 1.  Must not contain overlapping information; e.g. multiple instances of
     'attr-dict', types, operands, etc.
diff --git a/mlir/docs/DefiningDialects/_index.md b/mlir/docs/DefiningDialects/_index.md
index 987b51b4ab4ef..d4ffd066a61cd 100644
--- a/mlir/docs/DefiningDialects/_index.md
+++ b/mlir/docs/DefiningDialects/_index.md
@@ -272,6 +272,26 @@ void *MyDialect::getRegisteredInterfaceForOp(TypeID typeID, StringAttr opName);
 For a more detail description of the expected usages of this hook, view the detailed 
 [interface documentation](../Interfaces.md/#dialect-fallback-for-opinterface).
 
+### Strict Property Assembly Formats
+
+Dialects can set `useStrictPropertiesInAssemblyFormat` to require declarative
+assembly formats for property-backed operations to account for all inherent
+attributes and properties:
+
+```tablegen
+def MyDialect : Dialect {
+  let useStrictPropertiesInAssemblyFormat = 1;
+}
+```
+
+This mode is disabled by default for now. When enabled, an operation format must
+either bind every inherent attribute and property directly in the format or
+include the `prop-dict` directive. Generated parsers also reject inherent
+attributes that arrive through `attr-dict`, so `attr-dict` only carries
+discardable attributes for these formats. See the
+[declarative assembly format](Operations.md/#declarative-assembly-format)
+documentation for the corresponding format requirements.
+
 ### Default Attribute/Type Parsers and Printers 
 
 When a dialect registers an Attribute or Type, it must also override the respective
diff --git a/mlir/include/mlir/Dialect/Affine/IR/AffineOps.td b/mlir/include/mlir/Dialect/Affine/IR/AffineOps.td
index b2a4cf7f488bd..493f448eab9d7 100644
--- a/mlir/include/mlir/Dialect/Affine/IR/AffineOps.td
+++ b/mlir/include/mlir/Dialect/Affine/IR/AffineOps.td
@@ -23,6 +23,7 @@ include "mlir/Interfaces/SideEffectInterfaces.td"
 
 def Affine_Dialect : Dialect {
   let name = "affine";
+  let useStrictPropertiesInAssemblyFormat = 1;
   let cppNamespace = "::mlir::affine";
   let hasConstantMaterializer = 1;
   let dependentDialects = ["arith::ArithDialect", "ub::UBDialect"];
diff --git a/mlir/include/mlir/Dialect/ArmNeon/ArmNeon.td b/mlir/include/mlir/Dialect/ArmNeon/ArmNeon.td
index ce86ff2cfd922..fd0fa7ecf9b0d 100644
--- a/mlir/include/mlir/Dialect/ArmNeon/ArmNeon.td
+++ b/mlir/include/mlir/Dialect/ArmNeon/ArmNeon.td
@@ -23,6 +23,7 @@ include "mlir/IR/OpBase.td"
 
 def ArmNeon_Dialect : Dialect {
   let name = "arm_neon";
+  let useStrictPropertiesInAssemblyFormat = 1;
   let cppNamespace = "::mlir::arm_neon";
 
   // Note: this does not need to depend on LLVMDialect as long as functions in
diff --git a/mlir/include/mlir/Dialect/ArmSME/IR/ArmSME.td b/mlir/include/mlir/Dialect/ArmSME/IR/ArmSME.td
index ffafb2569310e..f937af9c35a71 100644
--- a/mlir/include/mlir/Dialect/ArmSME/IR/ArmSME.td
+++ b/mlir/include/mlir/Dialect/ArmSME/IR/ArmSME.td
@@ -23,6 +23,7 @@ include "mlir/Dialect/LLVMIR/LLVMOpBase.td"
 
 def ArmSME_Dialect : Dialect {
   let name = "arm_sme";
+  let useStrictPropertiesInAssemblyFormat = 1;
   let cppNamespace = "::mlir::arm_sme";
   let summary = "Basic dialect to target Arm SME architectures";
   let description = [{
diff --git a/mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td b/mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td
index 81da6f125643a..95f8fa8c10db1 100644
--- a/mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td
+++ b/mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td
@@ -22,6 +22,7 @@ include "mlir/Dialect/LLVMIR/LLVMOpBase.td"
 
 def ArmSVE_Dialect : Dialect {
   let name = "arm_sve";
+  let useStrictPropertiesInAssemblyFormat = 1;
   let cppNamespace = "::mlir::arm_sve";
   let summary = "Basic dialect to target Arm SVE architectures";
   let description = [{
diff --git a/mlir/include/mlir/Dialect/Complex/IR/ComplexBase.td b/mlir/include/mlir/Dialect/Complex/IR/ComplexBase.td
index c8af498f44829..4efe1bcc620c2 100644
--- a/mlir/include/mlir/Dialect/Complex/IR/ComplexBase.td
+++ b/mlir/include/mlir/Dialect/Complex/IR/ComplexBase.td
@@ -14,6 +14,7 @@ include "mlir/IR/OpBase.td"
 
 def Complex_Dialect : Dialect {
   let name = "complex";
+  let useStrictPropertiesInAssemblyFormat = 1;
   let cppNamespace = "::mlir::complex";
   let description = [{
     The complex dialect is intended to hold complex numbers creation and
diff --git a/mlir/include/mlir/Dialect/DLTI/DLTIBase.td b/mlir/include/mlir/Dialect/DLTI/DLTIBase.td
index 3754f3699c7fd..f7c9be4fd7880 100644
--- a/mlir/include/mlir/Dialect/DLTI/DLTIBase.td
+++ b/mlir/include/mlir/Dialect/DLTI/DLTIBase.td
@@ -76,6 +76,7 @@ def DLTI_Dialect : Dialect {
   }];
 
   let useDefaultAttributePrinterParser = 1;
+  let useStrictPropertiesInAssemblyFormat = 1;
 }
 
 def HasDefaultDLTIDataLayout : NativeOpTrait<"HasDefaultDLTIDataLayout"> {
diff --git a/mlir/include/mlir/Dialect/IRDL/IR/IRDL.td b/mlir/include/mlir/Dialect/IRDL/IR/IRDL.td
index e822969fc575e..f554358ed373d 100644
--- a/mlir/include/mlir/Dialect/IRDL/IR/IRDL.td
+++ b/mlir/include/mlir/Dialect/IRDL/IR/IRDL.td
@@ -74,6 +74,7 @@ def IRDL_Dialect : Dialect {
 
   let name = "irdl";
   let cppNamespace = "::mlir::irdl";
+  let useStrictPropertiesInAssemblyFormat = 1;
 }
 
 #endif // MLIR_DIALECT_IRDL_IR_IRDL
diff --git a/mlir/include/mlir/Dialect/Index/IR/IndexDialect.td b/mlir/include/mlir/Dialect/Index/IR/IndexDialect.td
index be0fea79ee392..df6087818cc8f 100644
--- a/mlir/include/mlir/Dialect/Index/IR/IndexDialect.td
+++ b/mlir/include/mlir/Dialect/Index/IR/IndexDialect.td
@@ -83,6 +83,7 @@ def IndexDialect : Dialect {
 
   let hasConstantMaterializer = 1;
   let useDefaultAttributePrinterParser = 1;
+  let useStrictPropertiesInAssemblyFormat = 1;
 }
 
 #endif // INDEX_DIALECT
diff --git a/mlir/include/mlir/Dialect/LLVMIR/VCIXOps.td b/mlir/include/mlir/Dialect/LLVMIR/VCIXOps.td
index 27d9a32dd8e03..02f80bbd56451 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/VCIXOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/VCIXOps.td
@@ -31,6 +31,7 @@ def VCIX_Dialect : Dialect {
   let name = "vcix";
   let cppNamespace = "::mlir::vcix";
   let dependentDialects = ["LLVM::LLVMDialect"];
+  let useStrictPropertiesInAssemblyFormat = 1;
   let description = [{
      The SiFive Vector Coprocessor Interface (VCIX) provides a flexible mechanism
      to extend application processors with custom coprocessors and
diff --git a/mlir/include/mlir/Dialect/LLVMIR/XeVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/XeVMOps.td
index d2dc51198be32..0e4e77b44cee0 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/XeVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/XeVMOps.td
@@ -37,6 +37,7 @@ def XeVM_Dialect : Dialect {
   }];
 
   let useDefaultAttributePrinterParser = 1;
+  let useStrictPropertiesInAssemblyFormat = 1;
 }
 
 class XeVM_Attr<string attrName, string attrMnemonic, list<Trait> traits = []>
diff --git a/mlir/include/mlir/Dialect/Linalg/IR/LinalgBase.td b/mlir/include/mlir/Dialect/Linalg/IR/LinalgBase.td
index a459656b982e6..55b62b643b0e9 100644
--- a/mlir/include/mlir/Dialect/Linalg/IR/LinalgBase.td
+++ b/mlir/include/mlir/Dialect/Linalg/IR/LinalgBase.td
@@ -43,6 +43,7 @@ def Linalg_Dialect : Dialect {
     "tensor::TensorDialect",
   ];
   let useDefaultAttributePrinterParser = 1;
+  let useStrictPropertiesInAssemblyFormat = 1;
   let hasCanonicalizer = 1;
   let hasOperationAttrVerify = 1;
   let hasConstantMaterializer = 1;
diff --git a/mlir/include/mlir/Dialect/MLProgram/IR/MLProgramBase.td b/mlir/include/mlir/Dialect/MLProgram/IR/MLProgramBase.td
index a585059020eaf..5ed346aeade5d 100644
--- a/mlir/include/mlir/Dialect/MLProgram/IR/MLProgramBase.td
+++ b/mlir/include/mlir/Dialect/MLProgram/IR/MLProgramBase.td
@@ -13,6 +13,7 @@ include "mlir/IR/OpBase.td"
 
 def MLProgram_Dialect : Dialect {
   let name = "ml_program";
+  let useStrictPropertiesInAssemblyFormat = 1;
   let cppNamespace = "::mlir::ml_program";
   let description = [{
     The MLProgram dialect contains structural operations and types for
diff --git a/mlir/include/mlir/Dialect/MPI/IR/MPI.td b/mlir/include/mlir/Dialect/MPI/IR/MPI.td
index 0c62a1794e19e..6869df20936d4 100644
--- a/mlir/include/mlir/Dialect/MPI/IR/MPI.td
+++ b/mlir/include/mlir/Dialect/MPI/IR/MPI.td
@@ -15,6 +15,7 @@ include "mlir/IR/EnumAttr.td"
 
 def MPI_Dialect : Dialect {
   let name = "mpi";
+  let useStrictPropertiesInAssemblyFormat = 1;
   let cppNamespace = "::mlir::mpi";
   let description = [{
     This dialect models the Message Passing Interface (MPI), version 
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrDialect.td b/mlir/include/mlir/Dialect/Ptr/IR/PtrDialect.td
index c98df5775195a..bf1f1a3c89f5a 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrDialect.td
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrDialect.td
@@ -20,6 +20,7 @@ include "mlir/IR/OpBase.td"
 
 def Ptr_Dialect : Dialect {
   let name = "ptr";
+  let useStrictPropertiesInAssemblyFormat = 1;
   let summary = "Pointer dialect";
   let description = [{
     The pointer dialect provides types and operations for representing and
diff --git a/mlir/include/mlir/Dialect/Quant/IR/QuantBase.td b/mlir/include/mlir/Dialect/Quant/IR/QuantBase.td
index 23bf5cf15e256..8c5aca9a9fd09 100644
--- a/mlir/include/mlir/Dialect/Quant/IR/QuantBase.td
+++ b/mlir/include/mlir/Dialect/Quant/IR/QuantBase.td
@@ -17,6 +17,7 @@ include "mlir/IR/OpBase.td"
 
 def Quant_Dialect : Dialect {
   let name = "quant";
+  let useStrictPropertiesInAssemblyFormat = 1;
   let description = [{
     The `quant` dialect offers a framework for defining and manipulating
     quantized values. Central to this framework is the `!quant.uniform` data
diff --git a/mlir/include/mlir/Dialect/SCF/IR/SCFOps.td b/mlir/include/mlir/Dialect/SCF/IR/SCFOps.td
index 0b33ecb48b7f2..96ec7fa761ca9 100644
--- a/mlir/include/mlir/Dialect/SCF/IR/SCFOps.td
+++ b/mlir/include/mlir/Dialect/SCF/IR/SCFOps.td
@@ -27,6 +27,7 @@ include "mlir/Interfaces/ViewLikeInterface.td"
 def SCF_Dialect : Dialect {
   let name = "scf";
   let cppNamespace = "::mlir::scf";
+  let useStrictPropertiesInAssemblyFormat = 1;
 
   let description = [{
     The `scf` (structured control flow) dialect contains operations that
diff --git a/mlir/include/mlir/Dialect/SMT/IR/SMTDialect.td b/mlir/include/mlir/Dialect/SMT/IR/SMTDialect.td
index 00f170659946e..4b33b07da30c1 100644
--- a/mlir/include/mlir/Dialect/SMT/IR/SMTDialect.td
+++ b/mlir/include/mlir/Dialect/SMT/IR/SMTDialect.td
@@ -13,6 +13,7 @@ include "mlir/IR/DialectBase.td"
 
 def SMTDialect : Dialect {
   let name = "smt";
+  let useStrictPropertiesInAssemblyFormat = 1;
   let summary = "a dialect that models satisfiability modulo theories";
   let cppNamespace = "mlir::smt";
 
diff --git a/mlir/include/mlir/Dialect/Shard/IR/ShardBase.td b/mlir/include/mlir/Dialect/Shard/IR/ShardBase.td
index 41ae31807c825..9af607f7bca5b 100644
--- a/mlir/include/mlir/Dialect/Shard/IR/ShardBase.td
+++ b/mlir/include/mlir/Dialect/Shard/IR/ShardBase.td
@@ -21,6 +21,7 @@ include "mlir/IR/EnumAttr.td"
 
 def Shard_Dialect : Dialect {
   let name = "shard";
+  let useStrictPropertiesInAssemblyFormat = 1;
   let cppNamespace = "::mlir::shard";
 
   let description = [{
diff --git a/mlir/include/mlir/Dialect/Tensor/IR/TensorBase.td b/mlir/include/mlir/Dialect/Tensor/IR/TensorBase.td
index 9d0add92737f3..900ad5f40830c 100644
--- a/mlir/include/mlir/Dialect/Tensor/IR/TensorBase.td
+++ b/mlir/include/mlir/Dialect/Tensor/IR/TensorBase.td
@@ -13,6 +13,7 @@ include "mlir/IR/OpBase.td"
 
 def Tensor_Dialect : Dialect {
   let name = "tensor";
+  let useStrictPropertiesInAssemblyFormat = 1;
   let cppNamespace = "::mlir::tensor";
 
   let description = [{
diff --git a/mlir/include/mlir/Dialect/UB/IR/UBOps.td b/mlir/include/mlir/Dialect/UB/IR/UBOps.td
index 1bff39add691e..666301799256b 100644
--- a/mlir/include/mlir/Dialect/UB/IR/UBOps.td
+++ b/mlir/include/mlir/Dialect/UB/IR/UBOps.td
@@ -20,6 +20,7 @@ def UB_Dialect : Dialect {
 
   let hasConstantMaterializer = 1;
   let useDefaultAttributePrinterParser = 1;
+  let useStrictPropertiesInAssemblyFormat = 1;
 }
 
 // Base class for UB dialect attributes.
diff --git a/mlir/include/mlir/IR/DialectBase.td b/mlir/include/mlir/IR/DialectBase.td
index efa09a43ec581..3b41e841eb3ad 100644
--- a/mlir/include/mlir/IR/DialectBase.td
+++ b/mlir/include/mlir/IR/DialectBase.td
@@ -55,6 +55,12 @@ class Dialect {
   // dialect declaration.
   code extraClassDeclaration = "";
 
+  // If this dialect should require declarative parsers for property-backed
+  // operations to bind every inherent attribute and property directly in the
+  // custom assembly format, or otherwise cover them with `prop-dict`. This
+  // stricter mode is disabled by default for now.
+  bit useStrictPropertiesInAssemblyFormat = 0;
+
   // If this dialect overrides the hook for materializing constants.
   bit hasConstantMaterializer = 0;
 
diff --git a/mlir/include/mlir/TableGen/Dialect.h b/mlir/include/mlir/TableGen/Dialect.h
index 30f9d690b678d..68230196b17cc 100644
--- a/mlir/include/mlir/TableGen/Dialect.h
+++ b/mlir/include/mlir/TableGen/Dialect.h
@@ -54,6 +54,10 @@ class Dialect {
   // Returns the dialects extra class declaration code.
   std::optional<StringRef> getExtraClassDeclaration() const;
 
+  /// Returns true if this dialect uses strict properties in declarative
+  /// assembly formats.
+  bool useStrictPropertiesInAssemblyFormat() const;
+
   /// Returns true if this dialect has a canonicalizer.
   bool hasCanonicalizer() const;
 
diff --git a/mlir/lib/TableGen/Dialect.cpp b/mlir/lib/TableGen/Dialect.cpp
index 7aaf4dd57c50e..84530bfa4f6fd 100644
--- a/mlir/lib/TableGen/Dialect.cpp
+++ b/mlir/lib/TableGen/Dialect.cpp
@@ -62,6 +62,10 @@ std::optional<StringRef> Dialect::getExtraClassDeclaration() const {
   return value.empty() ? std::optional<StringRef>() : value;
 }
 
+bool Dialect::useStrictPropertiesInAssemblyFormat() const {
+  return def->getValueAsBit("useStrictPropertiesInAssemblyFormat");
+}
+
 bool Dialect::hasCanonicalizer() const {
   return def->getValueAsBit("hasCanonicalizer");
 }
diff --git a/mlir/test/mlir-tblgen/op-format-invalid.td b/mlir/test/mlir-tblgen/op-format-invalid.td
index 59446bb9d7019..1944bc4feb634 100644
--- a/mlir/test/mlir-tblgen/op-format-invalid.td
+++ b/mlir/test/mlir-tblgen/op-format-invalid.td
@@ -8,10 +8,18 @@ include "mlir/Interfaces/InferTypeOpInterface.td"
 def TestDialect : Dialect {
   let name = "test";
 }
+def TestStrictPropertiesDialect : Dialect {
+  let name = "test_strict_properties";
+  let useStrictPropertiesInAssemblyFormat = 1;
+}
 class TestFormat_Op<string fmt, list<Trait> traits = []>
     : Op<TestDialect, "format_op", traits> {
   let assemblyFormat = fmt;
 }
+class TestStrictPropertiesFormat_Op<string fmt, list<Trait> traits = []>
+    : Op<TestStrictPropertiesDialect, "format_op", traits> {
+  let assemblyFormat = fmt;
+}
 
 //===----------------------------------------------------------------------===//
 // Directives
@@ -37,6 +45,24 @@ def DirectiveAttrDictInvalidD : TestFormat_Op<[{
   type(attr-dict)
 }]>;
 
+// CHECK: error: strict properties in assembly format requires prop-dict
+// CHECK-SAME: unless all inherent attributes and properties are bound in the
+// CHECK-SAME: custom assembly format; missing attribute 'attr'
+def DirectiveAttrDictInvalidE : TestStrictPropertiesFormat_Op<[{
+  attr-dict
+}]> {
+  let arguments = (ins I64Attr:$attr);
+}
+
+// CHECK: error: strict properties in assembly format requires prop-dict
+// CHECK-SAME: unless all inherent attributes and properties are bound in the
+// CHECK-SAME: custom assembly format; missing property 'prop'
+def DirectiveAttrDictInvalidF : TestStrictPropertiesFormat_Op<[{
+  attr-dict
+}]> {
+  let arguments = (ins IntProp<"int64_t">:$prop);
+}
+
 //===----------------------------------------------------------------------===//
 // custom
 //===----------------------------------------------------------------------===//
diff --git a/mlir/test/mlir-tblgen/op-format.td b/mlir/test/mlir-tblgen/op-format.td
index 1790737a3a349..1e2f6896217dd 100644
--- a/mlir/test/mlir-tblgen/op-format.td
+++ b/mlir/test/mlir-tblgen/op-format.td
@@ -5,10 +5,18 @@ include "mlir/IR/OpBase.td"
 def TestDialect : Dialect {
   let name = "test";
 }
+def TestStrictPropertiesDialect : Dialect {
+  let name = "test_strict_properties";
+  let useStrictPropertiesInAssemblyFormat = 1;
+}
 class TestFormat_Op<string fmt, list<Trait> traits = []>
     : Op<TestDialect, "format_op", traits> {
   let assemblyFormat = fmt;
 }
+class TestStrictPropertiesFormat_Op<string fmt, list<Trait> traits = []>
+    : Op<TestStrictPropertiesDialect, "format_op", traits> {
+  let assemblyFormat = fmt;
+}
 
 //===----------------------------------------------------------------------===//
 // Directives
@@ -18,6 +26,50 @@ class TestFormat_Op<string fmt, list<Trait> traits = []>
 // custom
 //===----------------------------------------------------------------------===//
 
+// CHECK-LABEL: AttrDictDefaultInherentAttr::parse
+// CHECK: verifyInherentAttrs
+def AttrDictDefaultInherentAttr : TestFormat_Op<[{
+  $attr attr-dict
+}]>, Arguments<(ins I64Attr:$attr)>;
+
+// CHECK-LABEL: AttrDictStrictInferredSegmentAttr::parse
+// CHECK: result.getOrAddProperties<AttrDictStrictInferredSegmentAttr::Properties>().segment_sizes = parser.getBuilder().getDenseI32ArrayAttr(inputsOperandGroupSizes);
+// CHECK-LABEL: AttrDictStrictInferredSegmentAttr::print
+// CHECK: elidedAttrs.push_back("segment_sizes");
+def AttrDictStrictInferredSegmentAttr : TestStrictPropertiesFormat_Op<[{
+  custom<Foo>($inputs, type($inputs)) attr-dict
+}]>, Arguments<(ins VariadicOfVariadic<I64, "segment_sizes">:$inputs,
+                    DenseI32ArrayAttr:$segment_sizes)>;
+
+def PropDictStrictInferredSegmentAttr : TestStrictPropertiesFormat_Op<[{
+  custom<Foo>($inputs, type($inputs)) prop-dict attr-dict
+}]>, Arguments<(ins VariadicOfVariadic<I64, "segment_sizes">:$inputs,
+                    DenseI32ArrayAttr:$segment_sizes)>;
+
+// CHECK-LABEL: AttrDictStrictInherentAttr::parse
+// CHECK-NOT: verifyInherentAttrs
+// CHECK: if (result.attributes.get("attr"))
+// CHECK-NEXT: return parser.emitError(loc, "inherent attribute 'attr' cannot
+// CHECK-SAME: be parsed from attr-dict when strict properties in assembly
+// CHECK-SAME: format is enabled");
+// CHECK-NOT: verifyInherentAttrs
+// CHECK: return ::mlir::success();
+def AttrDictStrictInherentAttr : TestStrictPropertiesFormat_Op<[{
+  $attr attr-dict
+}]>, Arguments<(ins I64Attr:$attr)>;
+
+def AttrDictStrictProperty : TestStrictPropertiesFormat_Op<[{
+  $prop attr-dict
+}]>, Arguments<(ins IntProp<"int64_t">:$prop)>;
+
+def AttrDictStrictPropDict : TestStrictPropertiesFormat_Op<[{
+  prop-dict attr-dict
+}]>, Arguments<(ins IntProp<"int64_t">:$prop)>;
+
+def AttrDictStrictPropDictInherentAttr : TestStrictPropertiesFormat_Op<[{
+  prop-dict attr-dict
+}]>, Arguments<(ins I64Attr:$attr)>;
+
 // CHECK-LABEL: CustomStringLiteralA::parse
 // CHECK: parseFoo({{.*}}, parser.getBuilder().getI1Type())
 // CHECK-LABEL: CustomStringLiteralA::print
@@ -110,6 +162,12 @@ def OptionalGroupD : TestFormat_Op<[{
   (custom<Custom>($a, $b)^)? attr-dict
 }], [AttrSizedOperandSegments]>, Arguments<(ins Optional<I64>:$a, Optional<I64>:$b)>;
 
+// CHECK-LABEL: PropDictStrictInferredSegmentAttr::setPropertiesFromParsed...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/196269


More information about the Mlir-commits mailing list