[Mlir-commits] [mlir] 6c51938 - [MLIR] Guard optional operand resolution in generated op parsers (#180796)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Tue Feb 10 23:25:08 PST 2026


Author: Henrich Lauko
Date: 2026-02-11T08:25:03+01:00
New Revision: 6c51938067fa0e1b14b27e22d4b32d02bd5eb2a3

URL: https://github.com/llvm/llvm-project/commit/6c51938067fa0e1b14b27e22d4b32d02bd5eb2a3
DIFF: https://github.com/llvm/llvm-project/commit/6c51938067fa0e1b14b27e22d4b32d02bd5eb2a3.diff

LOG: [MLIR] Guard optional operand resolution in generated op parsers (#180796)

Skip resolveOperands for optional operands when they are absent to
avoid out-of-bounds access on the empty types vector.

Added: 
    

Modified: 
    mlir/test/lib/Dialect/Test/TestOpsSyntax.td
    mlir/test/mlir-tblgen/op-format.mlir
    mlir/tools/mlir-tblgen/OpFormatGen.cpp

Removed: 
    


################################################################################
diff  --git a/mlir/test/lib/Dialect/Test/TestOpsSyntax.td b/mlir/test/lib/Dialect/Test/TestOpsSyntax.td
index 73de8295380a6..6b10ec6173a50 100644
--- a/mlir/test/lib/Dialect/Test/TestOpsSyntax.td
+++ b/mlir/test/lib/Dialect/Test/TestOpsSyntax.td
@@ -667,6 +667,17 @@ def FormatTypesMatchContextOp : TEST_Op<"format_types_match_context", [
   let assemblyFormat = "attr-dict $value `:` type($value)";
 }
 
+def FormatTypesMatchOptionalOp : TEST_Op<"format_types_match_optional", [
+    OptionalTypesMatchWith<"optional type matches result", 
+                           "result", "optional", "$_self">
+  ]> {
+  let arguments = (ins Optional<AnyType>:$optional);
+  let results = (outs Optional<AnyType>:$result);
+  let assemblyFormat = [{
+    (`(` $optional^ `:` type($result) `)`)? attr-dict
+  }];
+}
+
 //===----------------------------------------------------------------------===//
 // InferTypeOpInterface type inference in assembly format
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/test/mlir-tblgen/op-format.mlir b/mlir/test/mlir-tblgen/op-format.mlir
index ac0931f18f042..7ff9091d5500d 100644
--- a/mlir/test/mlir-tblgen/op-format.mlir
+++ b/mlir/test/mlir-tblgen/op-format.mlir
@@ -488,6 +488,12 @@ test.format_infer_variadic_type_from_non_variadic %i64, %i64 : i64
 // CHECK: test.format_types_match_context %[[I64]] : i64
 %ignored_res6 = test.format_types_match_context %i64 : i64
 
+// CHECK: test.format_types_match_optional(%[[I64]] : i64)
+%ignored_res7 = test.format_types_match_optional(%i64 : i64)
+
+// CHECK: test.format_types_match_optional
+test.format_types_match_optional
+
 //===----------------------------------------------------------------------===//
 // InferTypeOpInterface type inference
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/tools/mlir-tblgen/OpFormatGen.cpp b/mlir/tools/mlir-tblgen/OpFormatGen.cpp
index ccf21d16005af..b834c6f8d3aaf 100644
--- a/mlir/tools/mlir-tblgen/OpFormatGen.cpp
+++ b/mlir/tools/mlir-tblgen/OpFormatGen.cpp
@@ -1848,6 +1848,10 @@ void OperationFormat::genParserOperandTypeResolution(
   // separately.
   for (unsigned i = 0, e = op.getNumOperands(); i != e; ++i) {
     NamedTypeConstraint &operand = op.getOperand(i);
+    // Optional operands may not be present; guard resolution to avoid
+    // out-of-bounds access on the (potentially empty) types vector.
+    if (operand.isOptional())
+      body << "  if (!" << operand.name << "Operands.empty()) {\n";
     body << "  if (parser.resolveOperands(" << operand.name << "Operands, ";
 
     // Resolve the type of this operand.
@@ -1856,6 +1860,8 @@ void OperationFormat::genParserOperandTypeResolution(
 
     body << ", " << operand.name
          << "OperandsLoc, result.operands))\n    return ::mlir::failure();\n";
+    if (operand.isOptional())
+      body << "  }\n";
   }
 }
 


        


More information about the Mlir-commits mailing list