diff --git a/mlir/test/lib/Dialect/Test/TestOps.td b/mlir/test/lib/Dialect/Test/TestOps.td --- a/mlir/test/lib/Dialect/Test/TestOps.td +++ b/mlir/test/lib/Dialect/Test/TestOps.td @@ -1214,9 +1214,15 @@ let assemblyFormat = "$attr attr-dict"; } +// Test that we elide optional attributes that are within the syntax. +def FormatOptAttrOp : TEST_Op<"format_opt_attr_op"> { + let arguments = (ins OptionalAttr:$opt_attr); + let assemblyFormat = "(`(`$opt_attr^`)`)? attr-dict"; +} + // Test that we elide attributes that are within the syntax. def FormatAttrDictWithKeywordOp : TEST_Op<"format_attr_dict_w_keyword"> { - let arguments = (ins I64Attr:$attr); + let arguments = (ins I64Attr:$attr, OptionalAttr:$opt_attr); let assemblyFormat = "attr-dict-with-keyword"; } diff --git a/mlir/test/mlir-tblgen/op-format.mlir b/mlir/test/mlir-tblgen/op-format.mlir --- a/mlir/test/mlir-tblgen/op-format.mlir +++ b/mlir/test/mlir-tblgen/op-format.mlir @@ -12,9 +12,16 @@ // CHECK-NOT: {attr test.format_attr_op 10 +// CHECK: test.format_opt_attr_op(10) +// CHECK-NOT: {opt_attr +test.format_opt_attr_op(10) + // CHECK: test.format_attr_dict_w_keyword attributes {attr = 10 : i64} test.format_attr_dict_w_keyword attributes {attr = 10 : i64} +// CHECK: test.format_attr_dict_w_keyword attributes {attr = 10 : i64, opt_attr = 10 : i64} +test.format_attr_dict_w_keyword attributes {attr = 10 : i64, opt_attr = 10 : i64} + // CHECK: test.format_buildable_type_op %[[I64]] %ignored = test.format_buildable_type_op %i64 diff --git a/mlir/tools/mlir-tblgen/OpFormatGen.cpp b/mlir/tools/mlir-tblgen/OpFormatGen.cpp --- a/mlir/tools/mlir-tblgen/OpFormatGen.cpp +++ b/mlir/tools/mlir-tblgen/OpFormatGen.cpp @@ -886,9 +886,17 @@ OpMethodBody &body, bool withKeyword) { // Collect all of the attributes used in the format, these will be elided. SmallVector usedAttributes; - for (auto &it : fmt.elements) + for (auto &it : fmt.elements) { if (auto *attr = dyn_cast(it.get())) usedAttributes.push_back(attr->getVar()); + // Collect the optional attributes. + if (auto *opt = dyn_cast(it.get())) { + for (auto &elem : opt->getElements()) { + if (auto *attr = dyn_cast(&elem)) + usedAttributes.push_back(attr->getVar()); + } + } + } body << " p.printOptionalAttrDict" << (withKeyword ? "WithKeyword" : "") << "(getAttrs(), /*elidedAttrs=*/{";