[Mlir-commits] [mlir] [mlir][irdl] Introduce names in IRDL value lists (PR #123525)

Théo Degioanni llvmlistbot at llvm.org
Sun Jan 19 12:33:32 PST 2025


https://github.com/Moxinilian updated https://github.com/llvm/llvm-project/pull/123525

>From 73cb178a23f7cb6ea63552543a2adf69e1f80eb4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Th=C3=A9o=20Degioanni?=
 <theo.degioanni.llvm.deluge062 at simplelogin.fr>
Date: Sun, 19 Jan 2025 20:42:34 +0100
Subject: [PATCH 1/4] add names to IRDL values

---
 mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td  |  80 ++++---
 mlir/lib/Dialect/IRDL/IR/IRDL.cpp             | 202 +++++++++++++++---
 mlir/test/Dialect/IRDL/cmath.irdl.mlir        |  20 +-
 mlir/test/Dialect/IRDL/cpred.irdl.mlir        |   4 +-
 mlir/test/Dialect/IRDL/cyclic-types.irdl.mlir |  12 +-
 mlir/test/Dialect/IRDL/invalid.irdl.mlir      | 125 ++++++++++-
 mlir/test/Dialect/IRDL/regions-ops.irdl.mlir  |  32 ++-
 mlir/test/Dialect/IRDL/test-type.irdl.mlir    |   8 +-
 mlir/test/Dialect/IRDL/testd.irdl.mlir        |  56 ++---
 .../Dialect/IRDL/variadics-error.irdl.mlir    |  12 +-
 mlir/test/Dialect/IRDL/variadics.irdl.mlir    |  32 +--
 .../tools/tblgen-to-irdl/OpDefinitionsGen.cpp |  18 +-
 12 files changed, 451 insertions(+), 150 deletions(-)

diff --git a/mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td b/mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td
index c7fcb55120c827..54d25099a68e2f 100644
--- a/mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td
+++ b/mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td
@@ -20,6 +20,7 @@ include "IRDLInterfaces.td"
 include "mlir/Interfaces/SideEffectInterfaces.td"
 include "mlir/Interfaces/InferTypeOpInterface.td"
 include "mlir/IR/SymbolInterfaces.td"
+include "mlir/IR/BuiltinAttributes.td"
 
 class IRDL_Op<string mnemonic, list<Trait> traits = []>
     : Op<IRDL_Dialect, mnemonic, traits>;
@@ -133,7 +134,7 @@ def IRDL_ParametersOp : IRDL_Op<"parameters",
     "Define the constraints on parameters of a type/attribute definition";
   let description = [{
     `irdl.parameters` defines the constraints on parameters of a type or
-    attribute definition.
+    attribute definition. Each parameter is named after an identifier.
 
     Example:
 
@@ -143,17 +144,19 @@ def IRDL_ParametersOp : IRDL_Op<"parameters",
         %0 = irdl.is i32
         %1 = irdl.is i64
         %2 = irdl.any_of(%0, %1)
-        irdl.parameters(%2)
+        irdl.parameters(elem: %2)
       }
     }
     ```
 
     The above program defines a type `complex` inside the dialect `cmath`. The
-    type has a single parameter that should be either `i32` or `i64`.
+    type has a single parameter `elem` that should be either `i32` or `i64`.
   }];
 
-  let arguments = (ins Variadic<IRDL_AttributeType>:$args);
-  let assemblyFormat = " `(` $args `)` attr-dict ";
+  let arguments = (ins Variadic<IRDL_AttributeType>:$args,
+                        StrArrayAttr:$names);
+  let assemblyFormat = " `` custom<NamedValueList>($args, $names) attr-dict ";
+  let hasVerifier = true;
 }
 
 //===----------------------------------------------------------------------===//
@@ -198,16 +201,17 @@ def IRDL_OperationOp : IRDL_Op<"operation",
   let regions = (region SizedRegion<1>:$body);
   let assemblyFormat =
     "$sym_name attr-dict-with-keyword custom<SingleBlockRegion>($body)";
+  let hasRegionVerifier = true;
 }
 
 def IRDL_OperandsOp : IRDL_Op<"operands", [HasParent<"OperationOp">]> {
   let summary = "Define the operands of an operation";
   let description = [{
     `irdl.operands` define the operands of the `irdl.operation` parent operation
-    definition.
+    definition. Each operand is named after an identifier.
 
     In the following example, `irdl.operands` defines the operands of the
-    `norm` operation:
+    `mul` operation:
 
     ```mlir
     irdl.dialect @cmath {
@@ -217,8 +221,8 @@ def IRDL_OperandsOp : IRDL_Op<"operands", [HasParent<"OperationOp">]> {
       irdl.operation @mul {
         %0 = irdl.any
         %1 = irdl.parametric @cmath::@complex<%0>
-        irdl.results(%1)
-        irdl.operands(%1, %1)
+        irdl.results(res: %1)
+        irdl.operands(lhs: %1, rhs: %1)
       }
     }
     ```
@@ -228,11 +232,11 @@ def IRDL_OperandsOp : IRDL_Op<"operands", [HasParent<"OperationOp">]> {
 
     The operands can also be marked as variadic or optional:
     ```mlir
-    irdl.operands(%0, single %1, optional %2, variadic %3)
+    irdl.operands(foo: %0, bar: single %1, baz: optional %2, qux: variadic %3)
     ```
 
-    Here, %0 and %1 are required single operands, %2 is an optional operand,
-    and %3 is a variadic operand.
+    Here, foo and bar are required single operands, baz is an optional operand,
+    and qux is a variadic operand.
 
     When more than one operand is marked as optional or variadic, the operation
     will expect a 'operandSegmentSizes' attribute that defines the number of
@@ -240,9 +244,10 @@ def IRDL_OperandsOp : IRDL_Op<"operands", [HasParent<"OperationOp">]> {
   }];
 
   let arguments = (ins Variadic<IRDL_AttributeType>:$args,
-                        VariadicityArrayAttr:$variadicity);
+                       StrArrayAttr:$names,
+                       VariadicityArrayAttr:$variadicity);
   let assemblyFormat =
-    "`` custom<ValuesWithVariadicity>($args, $variadicity) attr-dict";
+    " `` custom<NamedValueListWithVariadicity>($args, $names, $variadicity) attr-dict";
   let hasVerifier = true;
 }
 
@@ -250,21 +255,22 @@ def IRDL_ResultsOp : IRDL_Op<"results", [HasParent<"OperationOp">]> {
   let summary = "Define the results of an operation";
   let description = [{
     `irdl.results` define the results of the `irdl.operation` parent operation
-    definition.
+    definition. Each result is named after an identifier.
 
     In the following example, `irdl.results` defines the results of the
-    `norm` operation:
+    `get_values` operation:
 
     ```mlir
     irdl.dialect @cmath {
 
       irdl.type @complex { /* ... */ }
 
+      /// Returns the real and imaginary parts of a complex number.
       irdl.operation @get_values {
         %0 = irdl.any
         %1 = irdl.parametric @cmath::@complex<%0>
-        irdl.results(%0, %0)
-        irdl.operands(%1)
+        irdl.results(re: %0, im: %0)
+        irdl.operands(complex: %1)
       }
     }
     ```
@@ -274,11 +280,11 @@ def IRDL_ResultsOp : IRDL_Op<"results", [HasParent<"OperationOp">]> {
 
     The results can also be marked as variadic or optional:
     ```mlir
-    irdl.results(%0, single %1, optional %2, variadic %3)
+    irdl.results(foo: %0, bar: single %1, baz: optional %2, qux: variadic %3)
     ```
 
-    Here, %0 and %1 are required single results, %2 is an optional result,
-    and %3 is a variadic result.
+    Here, foo and bar are required single results, baz is an optional result,
+    and qux is a variadic result.
 
     When more than one result is marked as optional or variadic, the operation
     will expect a 'resultSegmentSizes' attribute that defines the number of
@@ -286,9 +292,10 @@ def IRDL_ResultsOp : IRDL_Op<"results", [HasParent<"OperationOp">]> {
   }];
 
   let arguments = (ins Variadic<IRDL_AttributeType>:$args,
+                        StrArrayAttr:$names,
                         VariadicityArrayAttr:$variadicity);
   let assemblyFormat =
-    " `` custom<ValuesWithVariadicity>($args, $variadicity) attr-dict";
+    " `` custom<NamedValueListWithVariadicity>($args, $names, $variadicity) attr-dict";
   let hasVerifier = true;
 }
 
@@ -297,7 +304,7 @@ def IRDL_AttributesOp : IRDL_Op<"attributes", [HasParent<"OperationOp">]> {
 
   let description = [{
     `irdl.attributes` defines the attributes of the `irdl.operation` parent
-    operation definition.
+    operation definition. Each attribute is named after an identifier.
 
     In the following example, `irdl.attributes` defines the attributes of the
     `attr_op` operation:
@@ -335,7 +342,8 @@ def IRDL_RegionOp : IRDL_Op<"region",
   let summary = "Define a region of an operation";
   let description = [{
     The irdl.region construct defines a set of characteristics
-    that a region of an operation should satify.
+    that a region of an operation should satify. Each region is named after
+    an identifier.
 
     These characteristics include constraints for the entry block arguments
     of the region and the total number of blocks it contains.
@@ -360,7 +368,7 @@ def IRDL_RegionOp : IRDL_Op<"region",
           %r2 = irdl.region(%v0, %v1)
           %r3 = irdl.region with size 3
 
-          irdl.regions(%r0, %r1, %r2, %r3)
+          irdl.regions(foo: %r0, bar: %r1, baz: %r2, qux: %r3)
       }
     }
     ```
@@ -368,11 +376,11 @@ def IRDL_RegionOp : IRDL_Op<"region",
     The above snippet demonstrates an operation named `@op_with_regions`,
     which is constrained to have four regions.
 
-    * Region `%r0` doesn't have any constraints on the arguments
+    * Region `foo` doesn't have any constraints on the arguments
       or the number of blocks.
-    * Region `%r1` should have an empty set of arguments.
-    * Region `%r2` should have two arguments of types `i32` and `i64`.
-    * Region `%r3` should contain exactly three blocks.
+    * Region `bar` should have an empty set of arguments.
+    * Region `baz` should have two arguments of types `i32` and `i64`.
+    * Region `qux` should contain exactly three blocks.
   }];
   let arguments = (ins Variadic<IRDL_AttributeType>:$entryBlockArgs,
                     OptionalAttr<I32Attr>:$numberOfBlocks,
@@ -391,7 +399,8 @@ def IRDL_RegionsOp : IRDL_Op<"regions", [HasParent<"OperationOp">]> {
   let summary = "Define the regions of an operation";
   let description = [{
     `irdl.regions` defines the regions of an operation by accepting
-    values produced by `irdl.region` operation as arguments.
+    values produced by `irdl.region` operation as arguments. Each
+    region has an identifier as name.
 
     Example:
 
@@ -401,18 +410,19 @@ def IRDL_RegionsOp : IRDL_Op<"regions", [HasParent<"OperationOp">]> {
         %r1 = irdl.region with size 3
         %0 = irdl.any
         %r2 = irdl.region(%0)
-        irdl.regions(%r1, %r2)
+        irdl.regions(foo: %r1, bar: %r2)
       }
     }
     ```
 
     In the snippet above the operation is constrained to have two regions.
-    The first region should contain three blocks.
-    The second region should have one region with one argument.
+    The first region (`foo`) should contain three blocks.
+    The second region (`bar`) should have one region with one argument.
   }];
 
-  let arguments = (ins Variadic<IRDL_RegionType>:$args);
-  let assemblyFormat = " `(` $args `)` attr-dict ";
+  let arguments = (ins Variadic<IRDL_RegionType>:$args, StrArrayAttr:$names);
+  let assemblyFormat = " `` custom<NamedValueList>($args, $names) attr-dict ";
+  let hasVerifier = true;
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Dialect/IRDL/IR/IRDL.cpp b/mlir/lib/Dialect/IRDL/IR/IRDL.cpp
index c5c44d97ce0911..dfa55f86635941 100644
--- a/mlir/lib/Dialect/IRDL/IR/IRDL.cpp
+++ b/mlir/lib/Dialect/IRDL/IR/IRDL.cpp
@@ -18,6 +18,9 @@
 #include "mlir/IR/Operation.h"
 #include "mlir/Support/LLVM.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SetOperations.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/TypeSwitch.h"
 #include "llvm/IR/Metadata.h"
 #include "llvm/Support/Casting.h"
@@ -49,7 +52,7 @@ void IRDLDialect::initialize() {
 }
 
 //===----------------------------------------------------------------------===//
-// Parsing/Printing
+// Parsing/Printing/Verifying
 //===----------------------------------------------------------------------===//
 
 /// Parse a region, and add a single block if the region is empty.
@@ -78,30 +81,104 @@ LogicalResult DialectOp::verify() {
   return success();
 }
 
-LogicalResult OperandsOp::verify() {
-  size_t numVariadicities = getVariadicity().size();
-  size_t numOperands = getNumOperands();
+LogicalResult OperationOp::verifyRegions() {
+  // Stores pairs of value kinds and the list of names of values of this kind in
+  // the operation.
+  SmallVector<std::tuple<StringRef, DenseSet<StringRef>>> valueNames;
+
+  auto insertNames = [&](StringRef kind, ArrayAttr names) {
+    DenseSet<StringRef> nameSet;
+    nameSet.reserve(names.size());
+    for (auto name : names)
+      nameSet.insert(llvm::cast<StringAttr>(name).getValue());
+    valueNames.emplace_back(kind, std::move(nameSet));
+  };
 
-  if (numOperands != numVariadicities)
-    return emitOpError()
-           << "the number of operands and their variadicities must be "
+  getBody().walk([&](Operation *op) {
+    TypeSwitch<Operation *>(op)
+        .Case<OperandsOp>(
+            [&](OperandsOp op) { insertNames("operands", op.getNames()); })
+        .Case<ResultsOp>(
+            [&](ResultsOp op) { insertNames("results", op.getNames()); })
+        .Case<RegionsOp>(
+            [&](RegionsOp op) { insertNames("regions", op.getNames()); });
+  });
+
+  // Verify that no two operand, result or region share the same name.
+  for (size_t i : llvm::seq(valueNames.size())) {
+    for (size_t j : llvm::seq(i + 1, valueNames.size())) {
+      auto &[lhs, lhsSet] = valueNames[i];
+      auto &[rhs, rhsSet] = valueNames[j];
+      llvm::set_intersect(lhsSet, rhsSet);
+      if (!lhsSet.empty())
+        return emitOpError("contains a value named '")
+               << *lhsSet.begin() << "' for both its " << lhs << " and " << rhs;
+    }
+  }
+
+  return success();
+}
+
+static LogicalResult verifyNames(Operation *op, StringRef kindName,
+                                 ArrayAttr names, size_t numOperands) {
+  if (numOperands != names.size())
+    return op->emitOpError()
+           << "the number of " << kindName
+           << "s and their names must be "
               "the same, but got "
-           << numOperands << " and " << numVariadicities << " respectively";
+           << numOperands << " and " << names.size() << " respectively";
+
+  DenseMap<StringRef, size_t> nameMap;
+  for (auto [i, name] : llvm::enumerate(names)) {
+    StringRef nameRef = llvm::cast<StringAttr>(name).getValue();
+    if (nameRef.size() == 0)
+      return op->emitOpError()
+             << "name of " << kindName << " number " << i << " is empty";
+    if (!llvm::isAlpha(nameRef[0]) && nameRef[0] != '_')
+      return op->emitOpError()
+             << "name of " << kindName << " number " << i
+             << " must start with either a letter or an underscore";
+    if (llvm::any_of(nameRef,
+                     [](char c) { return !llvm::isAlnum(c) && c != '_'; }))
+      return op->emitOpError()
+             << "name of " << kindName << " number " << i
+             << " must contain only letters, digits and underscores";
+    if (nameMap.contains(nameRef))
+      return op->emitOpError() << "name of " << kindName << " number " << i
+                               << " is a duplicate of the name of " << kindName
+                               << " number " << nameMap[nameRef];
+    nameMap.insert({nameRef, i});
+  }
 
   return success();
 }
 
-LogicalResult ResultsOp::verify() {
-  size_t numVariadicities = getVariadicity().size();
-  size_t numOperands = this->getNumOperands();
+LogicalResult ParametersOp::verify() {
+  return verifyNames(*this, "parameter", getNames(), getNumOperands());
+}
+
+template <typename ValueListOp>
+static LogicalResult verifyOperandsResultsCommon(ValueListOp op,
+                                                 StringRef kindName) {
+  size_t numVariadicities = op.getVariadicity().size();
+  size_t numOperands = op.getNumOperands();
 
   if (numOperands != numVariadicities)
-    return emitOpError()
-           << "the number of operands and their variadicities must be "
+    return op.emitOpError()
+           << "the number of " << kindName
+           << "s and their variadicities must be "
               "the same, but got "
            << numOperands << " and " << numVariadicities << " respectively";
 
-  return success();
+  return verifyNames(op, kindName, op.getNames(), numOperands);
+}
+
+LogicalResult OperandsOp::verify() {
+  return verifyOperandsResultsCommon(*this, "operand");
+}
+
+LogicalResult ResultsOp::verify() {
+  return verifyOperandsResultsCommon(*this, "result");
 }
 
 LogicalResult AttributesOp::verify() {
@@ -196,56 +273,111 @@ parseValueWithVariadicity(OpAsmParser &p,
   return success();
 }
 
-/// Parse a list of values with their variadicities first. By default, the
-/// variadicity is single.
-///
-/// values-with-variadicity ::=
-///   `(` (value-with-variadicity (`,` value-with-variadicity)*)? `)`
-/// value-with-variadicity ::= ("single" | "optional" | "variadic")? ssa-value
-static ParseResult parseValuesWithVariadicity(
+static ParseResult parseNamedValueListImpl(
     OpAsmParser &p, SmallVectorImpl<OpAsmParser::UnresolvedOperand> &operands,
-    VariadicityArrayAttr &variadicityAttr) {
+    ArrayAttr &valueNamesAttr, VariadicityArrayAttr *variadicityAttr) {
   Builder &builder = p.getBuilder();
   MLIRContext *ctx = builder.getContext();
+  SmallVector<Attribute> valueNames;
   SmallVector<VariadicityAttr> variadicities;
 
   // Parse a single value with its variadicity
   auto parseOne = [&] {
+    StringRef name;
     OpAsmParser::UnresolvedOperand operand;
     VariadicityAttr variadicity;
-    if (parseValueWithVariadicity(p, operand, variadicity))
+    if (p.parseKeyword(&name) || p.parseColon())
       return failure();
+
+    if (variadicityAttr) {
+      if (parseValueWithVariadicity(p, operand, variadicity))
+        return failure();
+      variadicities.push_back(variadicity);
+    } else {
+      if (p.parseOperand(operand))
+        return failure();
+    }
+
+    valueNames.push_back(StringAttr::get(ctx, name));
     operands.push_back(operand);
-    variadicities.push_back(variadicity);
     return success();
   };
 
   if (p.parseCommaSeparatedList(OpAsmParser::Delimiter::Paren, parseOne))
     return failure();
-  variadicityAttr = VariadicityArrayAttr::get(ctx, variadicities);
+  valueNamesAttr = ArrayAttr::get(ctx, valueNames);
+  if (variadicityAttr)
+    *variadicityAttr = VariadicityArrayAttr::get(ctx, variadicities);
   return success();
 }
 
-/// Print a list of values with their variadicities first. By default, the
+/// Parse a list of named values.
+///
+/// values ::=
+///   `(` (named-value (`,` named-value)*)? `)`
+/// named-value := bare-id `:` ssa-value
+static ParseResult
+parseNamedValueList(OpAsmParser &p,
+                    SmallVectorImpl<OpAsmParser::UnresolvedOperand> &operands,
+                    ArrayAttr &valueNamesAttr) {
+  return parseNamedValueListImpl(p, operands, valueNamesAttr, nullptr);
+}
+
+/// Parse a list of named values with their variadicities first. By default, the
 /// variadicity is single.
 ///
 /// values-with-variadicity ::=
 ///   `(` (value-with-variadicity (`,` value-with-variadicity)*)? `)`
-/// value-with-variadicity ::= ("single" | "optional" | "variadic")? ssa-value
-static void printValuesWithVariadicity(OpAsmPrinter &p, Operation *op,
-                                       OperandRange operands,
-                                       VariadicityArrayAttr variadicityAttr) {
+/// value-with-variadicity
+///   ::= bare-id `:` ("single" | "optional" | "variadic")? ssa-value
+static ParseResult parseNamedValueListWithVariadicity(
+    OpAsmParser &p, SmallVectorImpl<OpAsmParser::UnresolvedOperand> &operands,
+    ArrayAttr &valueNamesAttr, VariadicityArrayAttr &variadicityAttr) {
+  return parseNamedValueListImpl(p, operands, valueNamesAttr, &variadicityAttr);
+}
+
+static void printNamedValueListImpl(OpAsmPrinter &p, Operation *op,
+                                    OperandRange operands,
+                                    ArrayAttr valueNamesAttr,
+                                    VariadicityArrayAttr variadicityAttr) {
   p << "(";
   interleaveComma(llvm::seq<int>(0, operands.size()), p, [&](int i) {
-    Variadicity variadicity = variadicityAttr[i].getValue();
-    if (variadicity != Variadicity::single) {
-      p << stringifyVariadicity(variadicity) << " ";
+    p << llvm::cast<StringAttr>(valueNamesAttr[i]).getValue() << ": ";
+    if (variadicityAttr) {
+      Variadicity variadicity = variadicityAttr[i].getValue();
+      if (variadicity != Variadicity::single) {
+        p << stringifyVariadicity(variadicity) << " ";
+      }
     }
     p << operands[i];
   });
   p << ")";
 }
 
+/// Print a list of named values.
+///
+/// values ::=
+///   `(` (named-value (`,` named-value)*)? `)`
+/// named-value := bare-id `:` ssa-value
+static void printNamedValueList(OpAsmPrinter &p, Operation *op,
+                                OperandRange operands,
+                                ArrayAttr valueNamesAttr) {
+  printNamedValueListImpl(p, op, operands, valueNamesAttr, nullptr);
+}
+
+/// Print a list of named values with their variadicities first. By default, the
+/// variadicity is single.
+///
+/// values-with-variadicity ::=
+///   `(` (value-with-variadicity (`,` value-with-variadicity)*)? `)`
+/// value-with-variadicity ::=
+///   bare-id `:` ("single" | "optional" | "variadic")? ssa-value
+static void printNamedValueListWithVariadicity(
+    OpAsmPrinter &p, Operation *op, OperandRange operands,
+    ArrayAttr valueNamesAttr, VariadicityArrayAttr variadicityAttr) {
+  printNamedValueListImpl(p, op, operands, valueNamesAttr, variadicityAttr);
+}
+
 static ParseResult
 parseAttributesOp(OpAsmParser &p,
                   SmallVectorImpl<OpAsmParser::UnresolvedOperand> &attrOperands,
@@ -285,6 +417,10 @@ LogicalResult RegionOp::verify() {
   return success();
 }
 
+LogicalResult RegionsOp::verify() {
+  return verifyNames(*this, "region", getNames(), getNumOperands());
+}
+
 #include "mlir/Dialect/IRDL/IR/IRDLInterfaces.cpp.inc"
 
 #define GET_TYPEDEF_CLASSES
diff --git a/mlir/test/Dialect/IRDL/cmath.irdl.mlir b/mlir/test/Dialect/IRDL/cmath.irdl.mlir
index 0b7e220ceb90c3..1d6286ef5a4c1d 100644
--- a/mlir/test/Dialect/IRDL/cmath.irdl.mlir
+++ b/mlir/test/Dialect/IRDL/cmath.irdl.mlir
@@ -8,26 +8,26 @@ module {
     // CHECK:   %[[v0:[^ ]*]] = irdl.is f32
     // CHECK:   %[[v1:[^ ]*]] = irdl.is f64
     // CHECK:   %[[v2:[^ ]*]] = irdl.any_of(%[[v0]], %[[v1]])
-    // CHECK:   irdl.parameters(%[[v2]])
+    // CHECK:   irdl.parameters(elem: %[[v2]])
     // CHECK: }
     irdl.type @complex {
       %0 = irdl.is f32
       %1 = irdl.is f64
       %2 = irdl.any_of(%0, %1)
-      irdl.parameters(%2)
+      irdl.parameters(elem: %2)
     }
 
     // CHECK: irdl.operation @norm {
     // CHECK:   %[[v0:[^ ]*]] = irdl.any
     // CHECK:   %[[v1:[^ ]*]] = irdl.parametric @cmath::@complex<%[[v0]]>
-    // CHECK:   irdl.operands(%[[v1]])
-    // CHECK:   irdl.results(%[[v0]])
+    // CHECK:   irdl.operands(complex: %[[v1]])
+    // CHECK:   irdl.results(norm: %[[v0]])
     // CHECK: }
     irdl.operation @norm {
       %0 = irdl.any
       %1 = irdl.parametric @cmath::@complex<%0>
-      irdl.operands(%1)
-      irdl.results(%0)
+      irdl.operands(complex: %1)
+      irdl.results(norm: %0)
     }
 
     // CHECK: irdl.operation @mul {
@@ -35,16 +35,16 @@ module {
     // CHECK:   %[[v1:[^ ]*]] = irdl.is f64
     // CHECK:   %[[v2:[^ ]*]] = irdl.any_of(%[[v0]], %[[v1]])
     // CHECK:   %[[v3:[^ ]*]] = irdl.parametric @cmath::@complex<%[[v2]]>
-    // CHECK:   irdl.operands(%[[v3]], %[[v3]])
-    // CHECK:   irdl.results(%[[v3]])
+    // CHECK:   irdl.operands(lhs: %[[v3]], rhs: %[[v3]])
+    // CHECK:   irdl.results(res: %[[v3]])
     // CHECK: }
     irdl.operation @mul {
       %0 = irdl.is f32
       %1 = irdl.is f64
       %2 = irdl.any_of(%0, %1)
       %3 = irdl.parametric @cmath::@complex<%2>
-      irdl.operands(%3, %3)
-      irdl.results(%3)
+      irdl.operands(lhs: %3, rhs: %3)
+      irdl.results(res: %3)
     }
 
   }
diff --git a/mlir/test/Dialect/IRDL/cpred.irdl.mlir b/mlir/test/Dialect/IRDL/cpred.irdl.mlir
index 129793e565d271..c0ce2b9023c30a 100644
--- a/mlir/test/Dialect/IRDL/cpred.irdl.mlir
+++ b/mlir/test/Dialect/IRDL/cpred.irdl.mlir
@@ -7,8 +7,8 @@ module {
     irdl.type @type {
       %0 = irdl.c_pred "::llvm::isa<::mlir::IntegerAttr>($_self)"
       // CHECK: %{{.*}} = irdl.c_pred "::llvm::isa<::mlir::IntegerAttr>($_self)"
-      irdl.parameters(%0)
-      // CHECK: irdl.parameters(%{{.*}})
+      irdl.parameters(foo: %0)
+      // CHECK: irdl.parameters(foo: %{{.*}})
     }
   }
 }
diff --git a/mlir/test/Dialect/IRDL/cyclic-types.irdl.mlir b/mlir/test/Dialect/IRDL/cyclic-types.irdl.mlir
index cbcc248bf00b13..7c0b94e675a11a 100644
--- a/mlir/test/Dialect/IRDL/cyclic-types.irdl.mlir
+++ b/mlir/test/Dialect/IRDL/cyclic-types.irdl.mlir
@@ -9,14 +9,14 @@ irdl.dialect @testd {
   // CHECK:   %[[v1:[^ ]*]] = irdl.parametric @testd::@self_referencing<%[[v0]]>
   // CHECK:   %[[v2:[^ ]*]] = irdl.is i32
   // CHECK:   %[[v3:[^ ]*]] = irdl.any_of(%[[v1]], %[[v2]])
-  // CHECK:   irdl.parameters(%[[v3]])
+  // CHECK:   irdl.parameters(foo: %[[v3]])
   // CHECK: }
   irdl.type @self_referencing {
     %0 = irdl.any
     %1 = irdl.parametric @testd::@self_referencing<%0>
     %2 = irdl.is i32
     %3 = irdl.any_of(%1, %2)
-    irdl.parameters(%3)
+    irdl.parameters(foo: %3)
   }
 
 
@@ -25,13 +25,13 @@ irdl.dialect @testd {
   // CHECK:   %[[v1:[^ ]*]] = irdl.parametric @testd::@type2<%[[v0]]>
   // CHECK:   %[[v2:[^ ]*]] = irdl.is i32
   // CHECK:   %[[v3:[^ ]*]] = irdl.any_of(%[[v1]], %[[v2]])
-  // CHECK:   irdl.parameters(%[[v3]])
+  // CHECK:   irdl.parameters(foo: %[[v3]])
   irdl.type @type1 {
     %0 = irdl.any
     %1 = irdl.parametric @testd::@type2<%0>
     %2 = irdl.is i32
     %3 = irdl.any_of(%1, %2)
-    irdl.parameters(%3)
+    irdl.parameters(foo: %3)
   }
 
   // CHECK:   irdl.type @type2 {
@@ -39,12 +39,12 @@ irdl.dialect @testd {
   // CHECK:   %[[v1:[^ ]*]] = irdl.parametric @testd::@type1<%[[v0]]>
   // CHECK:   %[[v2:[^ ]*]] = irdl.is i32
   // CHECK:   %[[v3:[^ ]*]] = irdl.any_of(%[[v1]], %[[v2]])
-  // CHECK:   irdl.parameters(%[[v3]])
+  // CHECK:   irdl.parameters(foo: %[[v3]])
   irdl.type @type2 {
       %0 = irdl.any
       %1 = irdl.parametric @testd::@type1<%0>
       %2 = irdl.is i32
       %3 = irdl.any_of(%1, %2)
-      irdl.parameters(%3)
+      irdl.parameters(foo: %3)
   }
 }
diff --git a/mlir/test/Dialect/IRDL/invalid.irdl.mlir b/mlir/test/Dialect/IRDL/invalid.irdl.mlir
index 93ad6193587509..0f91d49d243f7c 100644
--- a/mlir/test/Dialect/IRDL/invalid.irdl.mlir
+++ b/mlir/test/Dialect/IRDL/invalid.irdl.mlir
@@ -2,11 +2,126 @@
 
 // Testing invalid IRDL IRs
 
+irdl.dialect @testd {
+  irdl.type @type {
+    %0 = irdl.any
+    // expected-error at +1 {{expected valid keyword}}
+    irdl.parameters(%0)
+  }
+}
+
+// -----
+
+irdl.dialect @testd {
+  irdl.type @type {
+    %0 = irdl.any
+    // expected-error at +1 {{expected valid keyword}}
+    irdl.parameters(123: %0)
+  }
+}
+
+// -----
+
+irdl.dialect @testd {
+  irdl.type @type {
+    %0 = irdl.any
+    // expected-error at +1 {{name of parameter number 0 must contain only letters, digits and underscores}}
+    irdl.parameters(test$test: %0)
+  }
+}
+
+// -----
+
+irdl.dialect @testd {
+  irdl.operation @op {
+    %0 = irdl.any
+    // expected-error at +1 {{name of result number 0 must contain only letters, digits and underscores}}
+    irdl.results(test$test: %0)
+  }
+}
+
+// -----
+
+irdl.dialect @testd {
+  irdl.operation @op {
+    %0 = irdl.any
+    // expected-error at +1 {{name of operand number 0 must contain only letters, digits and underscores}}
+    irdl.operands(test$test: %0)
+  }
+}
+
+// -----
+
+irdl.dialect @testd {
+  irdl.type @type {
+    %0 = irdl.any
+    // expected-error at +1 {{name of parameter number 2 is a duplicate of the name of parameter number 0}}
+    irdl.parameters(foo: %0, bar: %0, foo: %0)
+  }
+}
+
+// -----
+
+irdl.dialect @testd {
+  irdl.operation @op {
+    %0 = irdl.any
+    // expected-error at +1 {{name of result number 2 is a duplicate of the name of result number 0}}
+    irdl.results(foo: %0, bar: %0, foo: %0)
+  }
+}
+
+// -----
+
+irdl.dialect @testd {
+  irdl.operation @op {
+    %0 = irdl.any
+    // expected-error at +1 {{name of operand number 2 is a duplicate of the name of operand number 0}}
+    irdl.operands(foo: %0, bar: %0, foo: %0)
+  }
+}
+
+// -----
+
+irdl.dialect @testd {
+  // expected-error at +1 {{contains a value named 'foo' for both its operands and results}}
+  irdl.operation @op {
+    %0 = irdl.any
+    irdl.operands(foo: %0)
+    irdl.results(foo: %0)
+  }
+}
+
+// -----
+
+irdl.dialect @testd {
+  // expected-error at +1 {{contains a value named 'bar' for both its regions and results}}
+  irdl.operation @op {
+    %0 = irdl.any
+    %1 = irdl.region
+    irdl.regions(bar: %1)
+    irdl.results(bar: %0)
+  }
+}
+
+// -----
+
+irdl.dialect @testd {
+  // expected-error at +1 {{contains a value named 'baz' for both its regions and operands}}
+  irdl.operation @op {
+    %0 = irdl.any
+    %1 = irdl.region
+    irdl.regions(baz: %1)
+    irdl.operands(baz: %0)
+  }
+}
+
+// -----
+
 irdl.dialect @testd {
   irdl.type @type {
     // expected-error at +1 {{symbol '@foo' not found}}
     %0 = irdl.base @foo
-    irdl.parameters(%0)
+    irdl.parameters(foo: %0)
   }
 }
 
@@ -16,7 +131,7 @@ irdl.dialect @testd {
   irdl.type @type {
     // expected-error at +1 {{the base type or attribute name should start with '!' or '#'}}
     %0 = irdl.base "builtin.integer"
-    irdl.parameters(%0)
+    irdl.parameters(foo: %0)
   }
 }
 
@@ -26,7 +141,7 @@ irdl.dialect @testd {
   irdl.type @type {
     // expected-error at +1 {{the base type or attribute name should start with '!' or '#'}}
     %0 = irdl.base ""
-    irdl.parameters(%0)
+    irdl.parameters(foo: %0)
   }
 }
 
@@ -36,7 +151,7 @@ irdl.dialect @testd {
   irdl.type @type {
     // expected-error at +1 {{the base type or attribute should be specified by either a name}}
     %0 = irdl.base
-    irdl.parameters(%0)
+    irdl.parameters(foo: %0)
   }
 }
 
@@ -48,6 +163,6 @@ irdl.dialect @invalid_parametric {
   irdl.operation @foo {
     // expected-error at +1 {{symbol '@not_a_type_or_attr' does not refer to a type or attribute definition}}
     %param = irdl.parametric @not_a_type_or_attr<>
-    irdl.results(%param)
+    irdl.results(foo: %param)
   }
 }
diff --git a/mlir/test/Dialect/IRDL/regions-ops.irdl.mlir b/mlir/test/Dialect/IRDL/regions-ops.irdl.mlir
index 762f992e786d48..563d96c16f0fb7 100644
--- a/mlir/test/Dialect/IRDL/regions-ops.irdl.mlir
+++ b/mlir/test/Dialect/IRDL/regions-ops.irdl.mlir
@@ -9,11 +9,41 @@ irdl.dialect @testRegionOpNegativeNumber {
 
 // -----
 
+irdl.dialect @testRegionsOpMissingName {
+    irdl.operation @op {
+        %r1 = irdl.region
+        // expected-error @below {{expected valid keyword}}
+        irdl.regions(%r1)
+    }
+}
+
+// -----
+
+irdl.dialect @testRegionsOpWrongName {
+    irdl.operation @op {
+        %r1 = irdl.region
+        // expected-error @below {{name of region number 0 must contain only letters, digits and underscores}}
+        irdl.regions(test$test: %r1)
+    }
+}
+
+// -----
+
+irdl.dialect @testRegionsDuplicateName {
+    irdl.operation @op {
+        %r1 = irdl.region
+        // expected-error @below {{name of region number 2 is a duplicate of the name of region number 0}}
+        irdl.regions(foo: %r1, bar: %r1, foo: %r1)
+    }
+}
+
+// -----
+
 irdl.dialect @testRegionsOpWrongOperation {
     irdl.operation @op {
         // expected-note @below {{prior use here}}
         %r1 = irdl.any
         // expected-error @below {{use of value '%r1' expects different type than prior uses: '!irdl.region' vs '!irdl.attribute'}}
-        irdl.regions(%r1)
+        irdl.regions(foo: %r1)
     }
 }
diff --git a/mlir/test/Dialect/IRDL/test-type.irdl.mlir b/mlir/test/Dialect/IRDL/test-type.irdl.mlir
index 1bcfb0b8e20be2..1d471a673d8d4a 100644
--- a/mlir/test/Dialect/IRDL/test-type.irdl.mlir
+++ b/mlir/test/Dialect/IRDL/test-type.irdl.mlir
@@ -11,23 +11,23 @@ module {
     // CHECK:   %[[v1:[^ ]*]] = irdl.is i32
     // CHECK:   %[[v2:[^ ]*]] = irdl.is i64
     // CHECK:   %[[v3:[^ ]*]] = irdl.any_of(%[[v1]], %[[v2]])
-    // CHECK:   irdl.parameters(%[[v0]], %[[v3]])
+    // CHECK:   irdl.parameters(foo: %[[v0]], bar: %[[v3]])
     // CHECK: }
     irdl.type @parametrized {
       %0 = irdl.any
       %1 = irdl.is i32
       %2 = irdl.is i64
       %3 = irdl.any_of(%1, %2)
-      irdl.parameters(%0, %3)
+      irdl.parameters(foo: %0, bar: %3)
     }
 
     // CHECK: irdl.operation @any {
     // CHECK:   %[[v0:[^ ]*]] = irdl.any
-    // CHECK:   irdl.results(%[[v0]])
+    // CHECK:   irdl.results(foo: %[[v0]])
     // CHECK: }
     irdl.operation @any {
       %0 = irdl.any
-      irdl.results(%0)
+      irdl.results(foo: %0)
     }
   }
 }
diff --git a/mlir/test/Dialect/IRDL/testd.irdl.mlir b/mlir/test/Dialect/IRDL/testd.irdl.mlir
index aeb1a83747eccb..45156db867fcbc 100644
--- a/mlir/test/Dialect/IRDL/testd.irdl.mlir
+++ b/mlir/test/Dialect/IRDL/testd.irdl.mlir
@@ -4,51 +4,51 @@
 irdl.dialect @testd {
   // CHECK: irdl.type @parametric {
   // CHECK:   %[[v0:[^ ]*]] = irdl.any
-  // CHECK:   irdl.parameters(%[[v0]])
+  // CHECK:   irdl.parameters(foo: %[[v0]])
   // CHECK: }
   irdl.type @parametric {
     %0 = irdl.any
-    irdl.parameters(%0)
+    irdl.parameters(foo: %0)
   }
 
   // CHECK: irdl.attribute @parametric_attr {
   // CHECK:  %[[v0:[^ ]*]] = irdl.any
-  // CHECK:  irdl.parameters(%[[v0]])
+  // CHECK:  irdl.parameters(foo: %[[v0]])
   // CHECK: }
   irdl.attribute @parametric_attr {
     %0 = irdl.any
-    irdl.parameters(%0)
+    irdl.parameters(foo: %0)
   }
 
   // CHECK: irdl.type @attr_in_type_out {
   // CHECK:   %[[v0:[^ ]*]] = irdl.any
-  // CHECK:   irdl.parameters(%[[v0]])
+  // CHECK:   irdl.parameters(foo: %[[v0]])
   // CHECK: }
   irdl.type @attr_in_type_out {
     %0 = irdl.any
-    irdl.parameters(%0)
+    irdl.parameters(foo: %0)
   }
 
   // CHECK: irdl.operation @eq {
   // CHECK:   %[[v0:[^ ]*]] = irdl.is i32
-  // CHECK:   irdl.results(%[[v0]])
+  // CHECK:   irdl.results(foo: %[[v0]])
   // CHECK: }
   irdl.operation @eq {
     %0 = irdl.is i32
-    irdl.results(%0)
+    irdl.results(foo: %0)
   }
 
   // CHECK: irdl.operation @anyof {
   // CHECK:   %[[v0:[^ ]*]] = irdl.is i32
   // CHECK:   %[[v1:[^ ]*]] = irdl.is i64
   // CHECK:   %[[v2:[^ ]*]] = irdl.any_of(%[[v0]], %[[v1]])
-  // CHECK:   irdl.results(%[[v2]])
+  // CHECK:   irdl.results(foo: %[[v2]])
   // CHECK: }
   irdl.operation @anyof {
     %0 = irdl.is i32
     %1 = irdl.is i64
     %2 = irdl.any_of(%0, %1)
-    irdl.results(%2)
+    irdl.results(foo: %2)
   }
 
   // CHECK: irdl.operation @all_of {
@@ -56,32 +56,32 @@ irdl.dialect @testd {
   // CHECK:   %[[v1:[^ ]*]] = irdl.is i64
   // CHECK:   %[[v2:[^ ]*]] = irdl.any_of(%[[v0]], %[[v1]])
   // CHECK:   %[[v3:[^ ]*]] = irdl.all_of(%[[v2]], %[[v1]])
-  // CHECK:   irdl.results(%[[v3]])
+  // CHECK:   irdl.results(foo: %[[v3]])
   // CHECK: }
   irdl.operation @all_of {
     %0 = irdl.is i32
     %1 = irdl.is i64
     %2 = irdl.any_of(%0, %1)
     %3 = irdl.all_of(%2, %1)
-    irdl.results(%3)
+    irdl.results(foo: %3)
   }
 
   // CHECK: irdl.operation @any {
   // CHECK:   %[[v0:[^ ]*]] = irdl.any
-  // CHECK:   irdl.results(%[[v0]])
+  // CHECK:   irdl.results(foo: %[[v0]])
   // CHECK: }
   irdl.operation @any {
     %0 = irdl.any
-    irdl.results(%0)
+    irdl.results(foo: %0)
   }
 
   // CHECK: irdl.operation @dyn_type_base {
   // CHECK:   %[[v1:[^ ]*]] = irdl.base @testd::@parametric
-  // CHECK:   irdl.results(%[[v1]])
+  // CHECK:   irdl.results(foo: %[[v1]])
   // CHECK: }
   irdl.operation @dyn_type_base {
     %0 = irdl.base @testd::@parametric
-    irdl.results(%0)
+    irdl.results(foo: %0)
   }
 
   // CHECK: irdl.operation @dyn_attr_base {
@@ -95,11 +95,11 @@ irdl.dialect @testd {
 
   // CHECK: irdl.operation @named_type_base {
   // CHECK:   %[[v1:[^ ]*]] = irdl.base "!builtin.integer"
-  // CHECK:   irdl.results(%[[v1]])
+  // CHECK:   irdl.results(foo: %[[v1]])
   // CHECK: }
   irdl.operation @named_type_base {
     %0 = irdl.base "!builtin.integer"
-    irdl.results(%0)
+    irdl.results(foo: %0)
   }
 
   // CHECK: irdl.operation @named_attr_base {
@@ -116,27 +116,27 @@ irdl.dialect @testd {
   // CHECK:   %[[v1:[^ ]*]] = irdl.is i64
   // CHECK:   %[[v2:[^ ]*]] = irdl.any_of(%[[v0]], %[[v1]])
   // CHECK:   %[[v3:[^ ]*]] = irdl.parametric @testd::@parametric<%[[v2]]>
-  // CHECK:   irdl.results(%[[v3]])
+  // CHECK:   irdl.results(foo: %[[v3]])
   // CHECK: }
   irdl.operation @dynparams {
     %0 = irdl.is i32
     %1 = irdl.is i64
     %2 = irdl.any_of(%0, %1)
     %3 = irdl.parametric @testd::@parametric<%2>
-    irdl.results(%3)
+    irdl.results(foo: %3)
   }
 
   // CHECK: irdl.operation @constraint_vars {
   // CHECK:   %[[v0:[^ ]*]] = irdl.is i32
   // CHECK:   %[[v1:[^ ]*]] = irdl.is i64
   // CHECK:   %[[v2:[^ ]*]] = irdl.any_of(%[[v0]], %[[v1]])
-  // CHECK:   irdl.results(%[[v2]], %[[v2]])
+  // CHECK:   irdl.results(foo: %[[v2]], bar: %[[v2]])
   // CHECK: }
   irdl.operation @constraint_vars {
     %0 = irdl.is i32
     %1 = irdl.is i64
     %2 = irdl.any_of(%0, %1)
-    irdl.results(%2, %2)
+    irdl.results(foo: %2, bar: %2)
   }
 
   // CHECK: irdl.operation @attrs {
@@ -160,7 +160,7 @@ irdl.dialect @testd {
   // CHECK:   %[[r1:[^ ]*]] = irdl.region(%[[v0]], %[[v1]])
   // CHECK:   %[[r2:[^ ]*]] = irdl.region with size 3
   // CHECK:   %[[r3:[^ ]*]] = irdl.region()
-  // CHECK:   irdl.regions(%[[r0]], %[[r1]], %[[r2]], %[[r3]])
+  // CHECK:   irdl.regions(foo: %[[r0]], bar: %[[r1]], baz: %[[r2]], qux: %[[r3]])
   // CHECK: }
   irdl.operation @regions {
     %r0 = irdl.region
@@ -170,20 +170,20 @@ irdl.dialect @testd {
     %r2 = irdl.region with size 3
     %r3 = irdl.region()
 
-    irdl.regions(%r0, %r1, %r2, %r3)
+    irdl.regions(foo: %r0, bar: %r1, baz: %r2, qux: %r3)
   }
 
   // CHECK: irdl.operation @region_and_operand {
   // CHECK:   %[[v0:[^ ]*]] = irdl.any
   // CHECK:   %[[r0:[^ ]*]] = irdl.region(%[[v0]])
-  // CHECK:   irdl.operands(%[[v0]])
-  // CHECK:   irdl.regions(%[[r0]])
+  // CHECK:   irdl.operands(foo: %[[v0]])
+  // CHECK:   irdl.regions(bar: %[[r0]])
   // CHECK: }
   irdl.operation @region_and_operand {
     %v0 = irdl.any
     %r0 = irdl.region(%v0)
 
-    irdl.operands(%v0)
-    irdl.regions(%r0)
+    irdl.operands(foo: %v0)
+    irdl.regions(bar: %r0)
   }
 }
diff --git a/mlir/test/Dialect/IRDL/variadics-error.irdl.mlir b/mlir/test/Dialect/IRDL/variadics-error.irdl.mlir
index 67fa94ea8b7427..3e29dd837916b0 100644
--- a/mlir/test/Dialect/IRDL/variadics-error.irdl.mlir
+++ b/mlir/test/Dialect/IRDL/variadics-error.irdl.mlir
@@ -5,7 +5,7 @@ irdl.dialect @errors {
     %0 = irdl.is i32
 
     // expected-error at +1 {{'irdl.operands' op the number of operands and their variadicities must be the same, but got 2 and 1 respectively}}
-    "irdl.operands"(%0, %0) <{variadicity = #irdl<variadicity_array[single]>}> : (!irdl.attribute, !irdl.attribute) -> ()
+    "irdl.operands"(%0, %0) <{names = ["foo", "bar"], variadicity = #irdl<variadicity_array[single]>}> : (!irdl.attribute, !irdl.attribute) -> ()
   }
 }
 
@@ -16,7 +16,7 @@ irdl.dialect @errors {
     %0 = irdl.is i32
    
     // expected-error at +1 {{'irdl.operands' op the number of operands and their variadicities must be the same, but got 1 and 2 respectively}}
-    "irdl.operands"(%0) <{variadicity = #irdl<variadicity_array[single, single]>}> : (!irdl.attribute) -> ()
+    "irdl.operands"(%0) <{names = ["foo"], variadicity = #irdl<variadicity_array[single, single]>}> : (!irdl.attribute) -> ()
   }
 }
 
@@ -26,8 +26,8 @@ irdl.dialect @errors {
   irdl.operation @results {
     %0 = irdl.is i32
 
-    // expected-error at +1 {{'irdl.results' op the number of operands and their variadicities must be the same, but got 2 and 1 respectively}}
-    "irdl.results"(%0, %0) <{variadicity = #irdl<variadicity_array[single]>}> : (!irdl.attribute, !irdl.attribute) -> ()
+    // expected-error at +1 {{'irdl.results' op the number of results and their variadicities must be the same, but got 2 and 1 respectively}}
+    "irdl.results"(%0, %0) <{names = ["foo", "bar"], variadicity = #irdl<variadicity_array[single]>}> : (!irdl.attribute, !irdl.attribute) -> ()
   }
 }
 
@@ -37,7 +37,7 @@ irdl.dialect @errors {
   irdl.operation @results2 {
     %0 = irdl.is i32
    
-    // expected-error at +1 {{'irdl.results' op the number of operands and their variadicities must be the same, but got 1 and 2 respectively}}
-    "irdl.results"(%0) <{variadicity = #irdl<variadicity_array[single, single]>}> : (!irdl.attribute) -> ()
+    // expected-error at +1 {{'irdl.results' op the number of results and their variadicities must be the same, but got 1 and 2 respectively}}
+    "irdl.results"(%0) <{names = ["foo"], variadicity = #irdl<variadicity_array[single, single]>}> : (!irdl.attribute) -> ()
   }
 }
diff --git a/mlir/test/Dialect/IRDL/variadics.irdl.mlir b/mlir/test/Dialect/IRDL/variadics.irdl.mlir
index 64c5e1878f08eb..5118320f6d2e80 100644
--- a/mlir/test/Dialect/IRDL/variadics.irdl.mlir
+++ b/mlir/test/Dialect/IRDL/variadics.irdl.mlir
@@ -5,98 +5,98 @@ irdl.dialect @testvar {
 
   // CHECK-LABEL: irdl.operation @single_operand {
   // CHECK-NEXT:    %[[v0:[^ ]*]] = irdl.is i32
-  // CHECK-NEXT:    irdl.operands(%[[v0]])
+  // CHECK-NEXT:    irdl.operands(foo: %[[v0]])
   // CHECK-NEXT:  }
   irdl.operation @single_operand {
     %0 = irdl.is i32
-    irdl.operands(single %0)
+    irdl.operands(foo: single %0)
   }
 
   // CHECK-LABEL: irdl.operation @var_operand {
   // CHECK-NEXT:    %[[v0:[^ ]*]] = irdl.is i16 
   // CHECK-NEXT:    %[[v1:[^ ]*]] = irdl.is i32 
   // CHECK-NEXT:    %[[v2:[^ ]*]] = irdl.is i64 
-  // CHECK-NEXT:    irdl.operands(%[[v0]], variadic %[[v1]], %[[v2]])
+  // CHECK-NEXT:    irdl.operands(foo: %[[v0]], bar: variadic %[[v1]], baz: %[[v2]])
   // CHECK-NEXT:  }
   irdl.operation @var_operand {
     %0 = irdl.is i16
     %1 = irdl.is i32
     %2 = irdl.is i64
-    irdl.operands(%0, variadic %1, %2)
+    irdl.operands(foo: %0, bar: variadic %1, baz: %2)
   }
 
   // CHECK-LABEL: irdl.operation @opt_operand {
   // CHECK-NEXT:    %[[v0:[^ ]*]] = irdl.is i16 
   // CHECK-NEXT:    %[[v1:[^ ]*]] = irdl.is i32 
   // CHECK-NEXT:    %[[v2:[^ ]*]] = irdl.is i64 
-  // CHECK-NEXT:    irdl.operands(%[[v0]], optional %[[v1]], %[[v2]])
+  // CHECK-NEXT:    irdl.operands(foo: %[[v0]], bar: optional %[[v1]], baz: %[[v2]])
   // CHECK-NEXT:  }
   irdl.operation @opt_operand {
     %0 = irdl.is i16
     %1 = irdl.is i32
     %2 = irdl.is i64
-    irdl.operands(%0, optional %1, %2)
+    irdl.operands(foo: %0, bar: optional %1, baz: %2)
   }
 
   // CHECK-LABEL: irdl.operation @var_and_opt_operand {
   // CHECK-NEXT:    %[[v0:[^ ]*]] = irdl.is i16 
   // CHECK-NEXT:    %[[v1:[^ ]*]] = irdl.is i32 
   // CHECK-NEXT:    %[[v2:[^ ]*]] = irdl.is i64 
-  // CHECK-NEXT:    irdl.operands(variadic %[[v0]], optional %[[v1]], %[[v2]])
+  // CHECK-NEXT:    irdl.operands(foo: variadic %[[v0]], bar: optional %[[v1]], baz: %[[v2]])
   // CHECK-NEXT:  }
   irdl.operation @var_and_opt_operand {
     %0 = irdl.is i16
     %1 = irdl.is i32
     %2 = irdl.is i64
-    irdl.operands(variadic %0, optional %1, %2)
+    irdl.operands(foo: variadic %0, bar: optional %1, baz: %2)
   }
 
 
   // CHECK-LABEL: irdl.operation @single_result {
   // CHECK-NEXT:    %[[v0:[^ ]*]] = irdl.is i32
-  // CHECK-NEXT:    irdl.results(%[[v0]])
+  // CHECK-NEXT:    irdl.results(foo: %[[v0]])
   // CHECK-NEXT:  }
   irdl.operation @single_result {
     %0 = irdl.is i32
-    irdl.results(single %0)
+    irdl.results(foo: single %0)
   }
 
   // CHECK-LABEL: irdl.operation @var_result {
   // CHECK-NEXT:    %[[v0:[^ ]*]] = irdl.is i16 
   // CHECK-NEXT:    %[[v1:[^ ]*]] = irdl.is i32 
   // CHECK-NEXT:    %[[v2:[^ ]*]] = irdl.is i64 
-  // CHECK-NEXT:    irdl.results(%[[v0]], variadic %[[v1]], %[[v2]])
+  // CHECK-NEXT:    irdl.results(foo: %[[v0]], bar: variadic %[[v1]], baz: %[[v2]])
   // CHECK-NEXT:  }
   irdl.operation @var_result {
     %0 = irdl.is i16
     %1 = irdl.is i32
     %2 = irdl.is i64
-    irdl.results(%0, variadic %1, %2)
+    irdl.results(foo: %0, bar: variadic %1, baz: %2)
   }
 
   // CHECK-LABEL: irdl.operation @opt_result {
   // CHECK-NEXT:    %[[v0:[^ ]*]] = irdl.is i16 
   // CHECK-NEXT:    %[[v1:[^ ]*]] = irdl.is i32 
   // CHECK-NEXT:    %[[v2:[^ ]*]] = irdl.is i64 
-  // CHECK-NEXT:    irdl.results(%[[v0]], optional %[[v1]], %[[v2]])
+  // CHECK-NEXT:    irdl.results(foo: %[[v0]], bar: optional %[[v1]], baz: %[[v2]])
   // CHECK-NEXT:  }
   irdl.operation @opt_result {
     %0 = irdl.is i16
     %1 = irdl.is i32
     %2 = irdl.is i64
-    irdl.results(%0, optional %1, %2)
+    irdl.results(foo: %0, bar: optional %1, baz: %2)
   }
 
   // CHECK-LABEL: irdl.operation @var_and_opt_result {
   // CHECK-NEXT:    %[[v0:[^ ]*]] = irdl.is i16 
   // CHECK-NEXT:    %[[v1:[^ ]*]] = irdl.is i32 
   // CHECK-NEXT:    %[[v2:[^ ]*]] = irdl.is i64 
-  // CHECK-NEXT:    irdl.results(variadic %[[v0]], optional %[[v1]], %[[v2]])
+  // CHECK-NEXT:    irdl.results(foo: variadic %[[v0]], bar: optional %[[v1]], baz: %[[v2]])
   // CHECK-NEXT:  }
   irdl.operation @var_and_opt_result {
     %0 = irdl.is i16
     %1 = irdl.is i32
     %2 = irdl.is i64
-    irdl.results(variadic %0, optional %1, %2)
+    irdl.results(foo: variadic %0, bar: optional %1, baz: %2)
   }
 }
diff --git a/mlir/tools/tblgen-to-irdl/OpDefinitionsGen.cpp b/mlir/tools/tblgen-to-irdl/OpDefinitionsGen.cpp
index 4e354e535dd3af..e8aa670f112056 100644
--- a/mlir/tools/tblgen-to-irdl/OpDefinitionsGen.cpp
+++ b/mlir/tools/tblgen-to-irdl/OpDefinitionsGen.cpp
@@ -396,11 +396,14 @@ irdl::OperationOp createIRDLOperation(OpBuilder &builder,
 
   auto getValues = [&](tblgen::Operator::const_value_range namedCons) {
     SmallVector<Value> operands;
+    SmallVector<Attribute> names;
     SmallVector<irdl::VariadicityAttr> variadicity;
     for (const NamedTypeConstraint &namedCons : namedCons) {
       auto operand = createTypeConstraint(consBuilder, namedCons.constraint);
       operands.push_back(operand);
 
+      names.push_back(consBuilder.getAttr<StringAttr>(namedCons.name));
+
       irdl::VariadicityAttr var;
       if (namedCons.isOptional())
         var = consBuilder.getAttr<irdl::VariadicityAttr>(
@@ -414,11 +417,13 @@ irdl::OperationOp createIRDLOperation(OpBuilder &builder,
 
       variadicity.push_back(var);
     }
-    return std::make_tuple(operands, variadicity);
+    return std::make_tuple(operands, names, variadicity);
   };
 
-  auto [operands, operandVariadicity] = getValues(tblgenOp.getOperands());
-  auto [results, resultVariadicity] = getValues(tblgenOp.getResults());
+  auto [operands, operandNames, operandVariadicity] =
+      getValues(tblgenOp.getOperands());
+  auto [results, resultNames, resultVariadicity] =
+      getValues(tblgenOp.getResults());
 
   SmallVector<Value> attributes;
   SmallVector<Attribute> attrNames;
@@ -430,23 +435,28 @@ irdl::OperationOp createIRDLOperation(OpBuilder &builder,
   }
 
   SmallVector<Value> regions;
+  SmallVector<Attribute> regionNames;
   for (auto namedRegion : tblgenOp.getRegions()) {
     regions.push_back(
         createRegionConstraint(consBuilder, namedRegion.constraint));
+    regionNames.push_back(StringAttr::get(ctx, namedRegion.name));
   }
 
   // Create the operands and results operations.
   if (!operands.empty())
     consBuilder.create<irdl::OperandsOp>(UnknownLoc::get(ctx), operands,
+                                         ArrayAttr::get(ctx, operandNames),
                                          operandVariadicity);
   if (!results.empty())
     consBuilder.create<irdl::ResultsOp>(UnknownLoc::get(ctx), results,
+                                        ArrayAttr::get(ctx, resultNames),
                                         resultVariadicity);
   if (!attributes.empty())
     consBuilder.create<irdl::AttributesOp>(UnknownLoc::get(ctx), attributes,
                                            ArrayAttr::get(ctx, attrNames));
   if (!regions.empty())
-    consBuilder.create<irdl::RegionsOp>(UnknownLoc::get(ctx), regions);
+    consBuilder.create<irdl::RegionsOp>(UnknownLoc::get(ctx), regions,
+                                        ArrayAttr::get(ctx, regionNames));
 
   return op;
 }

>From 7fbcb5e7f32b5d932109336289dd7ee3831d638b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Th=C3=A9o=20Degioanni?=
 <theo.degioanni.llvm.deluge062 at simplelogin.fr>
Date: Sun, 19 Jan 2025 21:20:24 +0100
Subject: [PATCH 2/4] adjust remaining tests

---
 mlir/lib/Dialect/IRDL/IR/IRDL.cpp             |  4 +--
 mlir/test/CAPI/irdl.c                         |  4 +--
 mlir/test/Dialect/Transform/irdl.mlir         |  2 +-
 mlir/test/tblgen-to-irdl/CMathDialect.td      | 10 +++---
 mlir/test/tblgen-to-irdl/TestDialect.td       | 35 +++++++++++++++----
 .../tools/tblgen-to-irdl/OpDefinitionsGen.cpp | 31 ++++++++++++++--
 6 files changed, 67 insertions(+), 19 deletions(-)

diff --git a/mlir/lib/Dialect/IRDL/IR/IRDL.cpp b/mlir/lib/Dialect/IRDL/IR/IRDL.cpp
index dfa55f86635941..d1ba53fb797c04 100644
--- a/mlir/lib/Dialect/IRDL/IR/IRDL.cpp
+++ b/mlir/lib/Dialect/IRDL/IR/IRDL.cpp
@@ -84,10 +84,10 @@ LogicalResult DialectOp::verify() {
 LogicalResult OperationOp::verifyRegions() {
   // Stores pairs of value kinds and the list of names of values of this kind in
   // the operation.
-  SmallVector<std::tuple<StringRef, DenseSet<StringRef>>> valueNames;
+  SmallVector<std::tuple<StringRef, llvm::SmallDenseSet<StringRef>>> valueNames;
 
   auto insertNames = [&](StringRef kind, ArrayAttr names) {
-    DenseSet<StringRef> nameSet;
+    llvm::SmallDenseSet<StringRef> nameSet;
     nameSet.reserve(names.size());
     for (auto name : names)
       nameSet.insert(llvm::cast<StringAttr>(name).getValue());
diff --git a/mlir/test/CAPI/irdl.c b/mlir/test/CAPI/irdl.c
index b35345b664b14c..ad52ece6a41ce7 100644
--- a/mlir/test/CAPI/irdl.c
+++ b/mlir/test/CAPI/irdl.c
@@ -17,13 +17,13 @@ const char irdlDialect[] = "\
   irdl.dialect @foo {\
     irdl.operation @op {\
       %i32 = irdl.is i32\
-      irdl.results(%i32)\
+      irdl.results(baz: %i32)\
     }\
   }\
   irdl.dialect @bar {\
     irdl.operation @op {\
       %i32 = irdl.is i32\
-      irdl.operands(%i32)\
+      irdl.operands(baz: %i32)\
     }\
   }";
 
diff --git a/mlir/test/Dialect/Transform/irdl.mlir b/mlir/test/Dialect/Transform/irdl.mlir
index ae68d96c4314f6..6c8c0bf50191a9 100644
--- a/mlir/test/Dialect/Transform/irdl.mlir
+++ b/mlir/test/Dialect/Transform/irdl.mlir
@@ -9,7 +9,7 @@ module attributes {transform.with_named_sequence} {
           %0 = irdl.is i32
           %1 = irdl.is i64
           %2 = irdl.any_of(%0, %1)
-          irdl.results(%2)
+          irdl.results(foo: %2)
         }
       }
     }
diff --git a/mlir/test/tblgen-to-irdl/CMathDialect.td b/mlir/test/tblgen-to-irdl/CMathDialect.td
index abda7ca41e9db9..3ed700c4974103 100644
--- a/mlir/test/tblgen-to-irdl/CMathDialect.td
+++ b/mlir/test/tblgen-to-irdl/CMathDialect.td
@@ -27,7 +27,7 @@ def CMath_ComplexType : CMath_Type<"ComplexType", "complex"> {
 
 // CHECK:      irdl.operation @identity {
 // CHECK-NEXT:   %0 = irdl.base @cmath::@"!complex"
-// CHECK-NEXT:   irdl.results(%0)
+// CHECK-NEXT:   irdl.results(out: %0)
 // CHECK-NEXT: }
 def CMath_IdentityOp : CMath_Op<"identity"> {
   let results = (outs CMath_ComplexType:$out);
@@ -37,8 +37,8 @@ def CMath_IdentityOp : CMath_Op<"identity"> {
 // CHECK-NEXT:   %0 = irdl.base @cmath::@"!complex"
 // CHECK-NEXT:   %1 = irdl.base @cmath::@"!complex"
 // CHECK-NEXT:   %2 = irdl.base @cmath::@"!complex"
-// CHECK-NEXT:   irdl.operands(%0, %1)
-// CHECK-NEXT:   irdl.results(%2)
+// CHECK-NEXT:   irdl.operands(in1: %0, in2: %1)
+// CHECK-NEXT:   irdl.results(out: %2)
 // CHECK-NEXT: }
 def CMath_MulOp : CMath_Op<"mul"> {
   let arguments = (ins CMath_ComplexType:$in1, CMath_ComplexType:$in2);
@@ -48,8 +48,8 @@ def CMath_MulOp : CMath_Op<"mul"> {
 // CHECK:      irdl.operation @norm {
 // CHECK-NEXT:   %0 = irdl.any
 // CHECK-NEXT:   %1 = irdl.base @cmath::@"!complex"
-// CHECK-NEXT:   irdl.operands(%0)
-// CHECK-NEXT:   irdl.results(%1)
+// CHECK-NEXT:   irdl.operands(in: %0)
+// CHECK-NEXT:   irdl.results(out: %1)
 // CHECK-NEXT: }
 def CMath_NormOp : CMath_Op<"norm"> {
   let arguments = (ins AnyType:$in);
diff --git a/mlir/test/tblgen-to-irdl/TestDialect.td b/mlir/test/tblgen-to-irdl/TestDialect.td
index 7f4815d865b60b..913b9b1b759e21 100644
--- a/mlir/test/tblgen-to-irdl/TestDialect.td
+++ b/mlir/test/tblgen-to-irdl/TestDialect.td
@@ -38,7 +38,7 @@ def Test_AndOp : Test_Op<"and"> {
 // CHECK-NEXT:    %[[v0:[^ ]*]] = irdl.base @test::@"!singleton_a"
 // CHECK-NEXT:    %[[v1:[^ ]*]] = irdl.any
 // CHECK-NEXT:    %[[v2:[^ ]*]] = irdl.all_of(%[[v0]], %[[v1]])
-// CHECK-NEXT:    irdl.operands(%[[v2]])
+// CHECK-NEXT:    irdl.operands(in: %[[v2]])
 // CHECK-NEXT:  }
 
 
@@ -48,7 +48,7 @@ def Test_AnyOp : Test_Op<"any"> {
 }
 // CHECK-LABEL: irdl.operation @any {
 // CHECK-NEXT:    %[[v0:[^ ]*]] = irdl.any
-// CHECK-NEXT:    irdl.operands(%[[v0]])
+// CHECK-NEXT:    irdl.operands(in: %[[v0]])
 // CHECK-NEXT:  }
 
 // Check attributes are converted correctly.
@@ -77,7 +77,7 @@ def Test_ConfinedOp : Test_Op<"confined"> {
 // CHECK-NEXT:    %[[v5:[^ ]*]] = irdl.c_pred "(::llvm::cast<::mlir::VectorType>($_self).getRank() > 0)"
 // CHECK-NEXT:    %[[v6:[^ ]*]] = irdl.all_of(%[[v4]], %[[v5]])
 // CHECK-NEXT:    %[[v7:[^ ]*]] = irdl.all_of(%[[v3]], %[[v6]])
-// CHECK-NEXT:    irdl.operands(%[[v2]], %[[v7]])
+// CHECK-NEXT:    irdl.operands(tensor: %[[v2]], vector: %[[v7]])
 // CHECK-NEXT:  }
 
 // Check generic integer types are converted correctly.
@@ -91,7 +91,28 @@ def Test_Integers : Test_Op<"integers"> {
 // CHECK-NEXT:    %[[v2:[^ ]*]] = irdl.is ui8
 // CHECK-NEXT:    %[[v3:[^ ]*]] = irdl.any_of(%[[v0]], %[[v1]], %[[v2]])
 // CHECK-NEXT:    %[[v4:[^ ]*]] = irdl.base "!builtin.integer"
-// CHECK-NEXT:    irdl.operands(%[[v3]], %[[v4]])
+// CHECK-NEXT:    irdl.operands(any_int: %[[v3]], any_integer: %[[v4]])
+// CHECK-NEXT:  }
+
+// Check that IRDL names are properly generated when needed.
+def Test_NamesOp : Test_Op<"names"> {
+  let arguments = (ins I32:$a,
+                       I32:$_hello,
+                       I32:$unnamed0,
+                       I32);
+  let regions = (region AnyRegion:$unnamed1);
+  let results = (outs I32:$unnamed2);
+}
+// CHECK-LABEL: irdl.operation @names {
+// CHECK-NEXT:    %[[v0:[^ ]*]] = irdl.is i32
+// CHECK-NEXT:    %[[v1:[^ ]*]] = irdl.is i32
+// CHECK-NEXT:    %[[v2:[^ ]*]] = irdl.is i32
+// CHECK-NEXT:    %[[v3:[^ ]*]] = irdl.is i32
+// CHECK-NEXT:    %[[v4:[^ ]*]] = irdl.is i32
+// CHECK-NEXT:    %[[reg:[^ ]*]] = irdl.region
+// CHECK-NEXT:    irdl.operands(a: %[[v0]], _hello: %[[v1]], unnamed0: %[[v2]], unnamed3: %[[v3]])
+// CHECK-NEXT:    irdl.results(unnamed2: %[[v4]])
+// CHECK-NEXT:    irdl.regions(unnamed1: %[[reg]])
 // CHECK-NEXT:  }
 
 // Check that AnyTypeOf is converted correctly.
@@ -103,7 +124,7 @@ def Test_OrOp : Test_Op<"or"> {
 // CHECK-NEXT:    %[[v1:[^ ]*]] = irdl.base @test::@"!singleton_b"
 // CHECK-NEXT:    %[[v2:[^ ]*]] = irdl.base @test::@"!singleton_c"
 // CHECK-NEXT:    %[[v3:[^ ]*]] = irdl.any_of(%[[v0]], %[[v1]], %[[v2]])
-// CHECK-NEXT:    irdl.operands(%[[v3]])
+// CHECK-NEXT:    irdl.operands(in: %[[v3]])
 // CHECK-NEXT:  }
 
 // Check regions are converted correctly.
@@ -114,7 +135,7 @@ def Test_RegionsOp : Test_Op<"regions"> {
 // CHECK-LABEL: irdl.operation @regions {
 // CHECK-NEXT:    %[[v0:[^ ]*]] = irdl.region
 // CHECK-NEXT:    %[[v1:[^ ]*]] = irdl.region with size 1
-// CHECK-NEXT:    irdl.regions(%[[v0]], %[[v1]])
+// CHECK-NEXT:    irdl.regions(any_region: %[[v0]], single_block_region: %[[v1]])
 // CHECK-NEXT:  }
 
 // Check that various types are converted correctly.
@@ -148,5 +169,5 @@ def Test_VariadicityOp : Test_Op<"variadicity"> {
 // CHECK-NEXT:    %[[v0:[^ ]*]] = irdl.base @test::@"!singleton_a"
 // CHECK-NEXT:    %[[v1:[^ ]*]] = irdl.base @test::@"!singleton_b"
 // CHECK-NEXT:    %[[v2:[^ ]*]] = irdl.base @test::@"!singleton_c"
-// CHECK-NEXT:    irdl.operands(variadic %[[v0]], optional %[[v1]], %[[v2]])
+// CHECK-NEXT:    irdl.operands(variadic: variadic %[[v0]], optional: optional %[[v1]], required: %[[v2]])
 // CHECK-NEXT:  }
diff --git a/mlir/tools/tblgen-to-irdl/OpDefinitionsGen.cpp b/mlir/tools/tblgen-to-irdl/OpDefinitionsGen.cpp
index e8aa670f112056..c9f6dd35de44e9 100644
--- a/mlir/tools/tblgen-to-irdl/OpDefinitionsGen.cpp
+++ b/mlir/tools/tblgen-to-irdl/OpDefinitionsGen.cpp
@@ -23,6 +23,7 @@
 #include "mlir/TableGen/GenNameParser.h"
 #include "mlir/TableGen/Interfaces.h"
 #include "mlir/TableGen/Operator.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/InitLLVM.h"
 #include "llvm/Support/raw_ostream.h"
@@ -394,15 +395,41 @@ irdl::OperationOp createIRDLOperation(OpBuilder &builder,
   Block &opBlock = op.getBody().emplaceBlock();
   OpBuilder consBuilder = OpBuilder::atBlockBegin(&opBlock);
 
+  SmallDenseSet<StringRef> usedNames;
+  for (auto &namedCons : tblgenOp.getOperands())
+    usedNames.insert(namedCons.name);
+  for (auto &namedCons : tblgenOp.getResults())
+    usedNames.insert(namedCons.name);
+  for (auto &namedReg : tblgenOp.getRegions())
+    usedNames.insert(namedReg.name);
+
+  size_t generateCounter = 0;
+  auto generateName = [&](StringRef prefix) -> StringAttr {
+    SmallString<16> candidate;
+    do {
+      candidate.clear();
+      raw_svector_ostream candidateStream(candidate);
+      candidateStream << prefix << generateCounter;
+      generateCounter++;
+    } while (usedNames.contains(candidate));
+    return StringAttr::get(ctx, candidate);
+  };
+  auto normalizeName = [&](StringRef name) -> StringAttr {
+    if (name == "")
+      return generateName("unnamed");
+    return StringAttr::get(ctx, name);
+  };
+
   auto getValues = [&](tblgen::Operator::const_value_range namedCons) {
     SmallVector<Value> operands;
     SmallVector<Attribute> names;
     SmallVector<irdl::VariadicityAttr> variadicity;
+
     for (const NamedTypeConstraint &namedCons : namedCons) {
       auto operand = createTypeConstraint(consBuilder, namedCons.constraint);
       operands.push_back(operand);
 
-      names.push_back(consBuilder.getAttr<StringAttr>(namedCons.name));
+      names.push_back(normalizeName(namedCons.name));
 
       irdl::VariadicityAttr var;
       if (namedCons.isOptional())
@@ -439,7 +466,7 @@ irdl::OperationOp createIRDLOperation(OpBuilder &builder,
   for (auto namedRegion : tblgenOp.getRegions()) {
     regions.push_back(
         createRegionConstraint(consBuilder, namedRegion.constraint));
-    regionNames.push_back(StringAttr::get(ctx, namedRegion.name));
+    regionNames.push_back(normalizeName(namedRegion.name));
   }
 
   // Create the operands and results operations.

>From 6d3909e8eff1333308e7ad6157bc09bc79b464c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Th=C3=A9o=20Degioanni?=
 <theo.degioanni.llvm.deluge062 at simplelogin.fr>
Date: Sun, 19 Jan 2025 21:25:16 +0100
Subject: [PATCH 3/4] remove accidental change to attributes

---
 mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td b/mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td
index 54d25099a68e2f..f3bc3497500e76 100644
--- a/mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td
+++ b/mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td
@@ -304,7 +304,7 @@ def IRDL_AttributesOp : IRDL_Op<"attributes", [HasParent<"OperationOp">]> {
 
   let description = [{
     `irdl.attributes` defines the attributes of the `irdl.operation` parent
-    operation definition. Each attribute is named after an identifier.
+    operation definition.
 
     In the following example, `irdl.attributes` defines the attributes of the
     `attr_op` operation:

>From fce2ca0ee75ec69248eca3df5992dad0a295e34d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Th=C3=A9o=20Degioanni?=
 <theo.degioanni.llvm.deluge062 at simplelogin.fr>
Date: Sun, 19 Jan 2025 21:33:13 +0100
Subject: [PATCH 4/4] oops, silly bug

---
 mlir/lib/Dialect/IRDL/IR/IRDL.cpp        |  2 +-
 mlir/test/Dialect/IRDL/invalid.irdl.mlir | 13 +++++++++++++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/mlir/lib/Dialect/IRDL/IR/IRDL.cpp b/mlir/lib/Dialect/IRDL/IR/IRDL.cpp
index d1ba53fb797c04..48391afbbb3b5f 100644
--- a/mlir/lib/Dialect/IRDL/IR/IRDL.cpp
+++ b/mlir/lib/Dialect/IRDL/IR/IRDL.cpp
@@ -107,7 +107,7 @@ LogicalResult OperationOp::verifyRegions() {
   // Verify that no two operand, result or region share the same name.
   for (size_t i : llvm::seq(valueNames.size())) {
     for (size_t j : llvm::seq(i + 1, valueNames.size())) {
-      auto &[lhs, lhsSet] = valueNames[i];
+      auto [lhs, lhsSet] = valueNames[i];
       auto &[rhs, rhsSet] = valueNames[j];
       llvm::set_intersect(lhsSet, rhsSet);
       if (!lhsSet.empty())
diff --git a/mlir/test/Dialect/IRDL/invalid.irdl.mlir b/mlir/test/Dialect/IRDL/invalid.irdl.mlir
index 0f91d49d243f7c..090c0228653d7c 100644
--- a/mlir/test/Dialect/IRDL/invalid.irdl.mlir
+++ b/mlir/test/Dialect/IRDL/invalid.irdl.mlir
@@ -117,6 +117,19 @@ irdl.dialect @testd {
 
 // -----
 
+irdl.dialect @testd {
+  // expected-error at +1 {{contains a value named 'baz' for both its regions and results}}
+  irdl.operation @op {
+    %0 = irdl.any
+    %1 = irdl.region
+    irdl.regions(baz: %1)
+    irdl.operands(qux: %0)
+    irdl.results(baz: %0)
+  }
+}
+
+// -----
+
 irdl.dialect @testd {
   irdl.type @type {
     // expected-error at +1 {{symbol '@foo' not found}}



More information about the Mlir-commits mailing list