[MLIR] Add FieldParser implementation for Optional<> integer types.
authorNick Kreeger <nick.kreeger@gmail.com>
Sat, 19 Nov 2022 03:22:27 +0000 (21:22 -0600)
committerNick Kreeger <nick.kreeger@gmail.com>
Sat, 19 Nov 2022 03:22:27 +0000 (21:22 -0600)
This patch introduces a templated FieldParser to handle optional signed and unsigned integer types - NFC. Additionally, I've added an extra test to ensure that both signed and unsigned integers are properly tested in the templated integer types for FieldParser as well.

mlir/include/mlir/IR/DialectImplementation.h
mlir/test/lib/Dialect/Test/TestAttrDefs.td
mlir/test/lib/Dialect/Test/TestAttributes.cpp
mlir/test/mlir-tblgen/attr-or-type-format-roundtrip.mlir
mlir/test/mlir-tblgen/attr-or-type-format.mlir

index 02d14e6..ab5d6dc 100644 (file)
@@ -105,6 +105,23 @@ struct FieldParser<std::string> {
   }
 };
 
+/// Parse an Optional integer.
+template <typename IntT>
+struct FieldParser<
+    llvm::Optional<IntT>,
+    std::enable_if_t<std::is_integral<IntT>::value, Optional<IntT>>> {
+  static FailureOr<Optional<IntT>> parse(AsmParser &parser) {
+    IntT value;
+    OptionalParseResult result = parser.parseOptionalInteger(value);
+    if (result.has_value()) {
+      if (succeeded(*result))
+        return {Optional<IntT>(value)};
+      return failure();
+    }
+    return {llvm::None};
+  }
+};
+
 /// Parse any container that supports back insertion as a list.
 template <typename ContainerT>
 struct FieldParser<
index 145d021..a573c7d 100644 (file)
@@ -176,6 +176,8 @@ def TestParamFour : ArrayRefParameter<"int", ""> {
   let printer = "::printIntArray($_printer, $_self)";
 }
 
+def TestParamUnsigned : AttrParameter<"uint64_t", ""> {}
+
 def TestAttrWithFormat : Test_Attr<"TestAttrWithFormat"> {
   let parameters = (
     ins
@@ -183,6 +185,7 @@ def TestAttrWithFormat : Test_Attr<"TestAttrWithFormat"> {
     TestParamTwo:$two,
     "::mlir::IntegerAttr":$three,
     TestParamFour:$four,
+    TestParamUnsigned:$five,
     // Array of another attribute.
     ArrayRefParameter<
       "AttrWithTypeBuilderAttr", // The parameter C++ type.
@@ -192,12 +195,24 @@ def TestAttrWithFormat : Test_Attr<"TestAttrWithFormat"> {
 
   let mnemonic = "attr_with_format";
   let assemblyFormat = [{
-    `<` $one `:` struct($two, $four) `:` $three `,`
+    `<` $one `:` struct($two, $four) `:` $three `:` $five `,`
     `[` `` $arrayOfAttrWithTypeBuilderAttr `]` `>`
   }];
   let genVerifyDecl = 1;
 }
 
+def TestAttrWithOptionalSigned : Test_Attr<"TestAttrWithOptionalSigned"> {
+  let parameters = (ins OptionalParameter<"mlir::Optional<int64_t>">:$value);
+  let assemblyFormat = "`<` $value `>`";
+  let mnemonic = "attr_with_optional_signed";
+}
+
+def TestAttrWithOptionalUnsigned : Test_Attr<"TestAttrWithOptionalUnsigned"> {
+  let parameters = (ins OptionalParameter<"mlir::Optional<uint64_t>">:$value);
+  let assemblyFormat = "`<` $value `>`";
+  let mnemonic = "attr_with_optional_unsigned";
+}
+
 def TestAttrUgly : Test_Attr<"TestAttrUgly"> {
   let parameters = (ins "::mlir::Attribute":$attr);
 
index 4c7639b..c8ccd58 100644 (file)
@@ -101,7 +101,7 @@ TestI64ElementsAttr::verify(function_ref<InFlightDiagnostic()> emitError,
 LogicalResult
 TestAttrWithFormatAttr::verify(function_ref<InFlightDiagnostic()> emitError,
                                int64_t one, std::string two, IntegerAttr three,
-                               ArrayRef<int> four,
+                               ArrayRef<int> four, uint64_t five,
                                ArrayRef<AttrWithTypeBuilderAttr> arrayOfAttrs) {
   if (four.size() != static_cast<unsigned>(one))
     return emitError() << "expected 'one' to equal 'four.size()'";
index 22cf365..3fec4ea 100644 (file)
@@ -5,10 +5,10 @@
 // CHECK: !test.type_with_format<2147, three = "hi", two = "hi">
 func.func private @test_roundtrip_parameter_parsers(!test.type_with_format<111, three = #test<attr_ugly begin 5 : index end>, two = "foo">) -> !test.type_with_format<2147, two = "hi", three = "hi">
 attributes {
-  // CHECK: #test.attr_with_format<3 : two = "hello", four = [1, 2, 3] : 42 : i64, [ 10 : i16]
-  attr0 = #test.attr_with_format<3 : two = "hello", four = [1, 2, 3] : 42 : i64, [10 : i16]>,
-  // CHECK: #test.attr_with_format<5 : two = "a_string", four = [4, 5, 6, 7, 8] : 8 : i8, [ 10 : i16]>,
-  attr1 = #test.attr_with_format<5 : two = "a_string", four = [4, 5, 6, 7, 8] : 8 : i8, [10 : i16]>,
+  // CHECK: #test.attr_with_format<3 : two = "hello", four = [1, 2, 3] : 42 : i64 : 0, [ 10 : i16]
+  attr0 = #test.attr_with_format<3 : two = "hello", four = [1, 2, 3] : 42 : i64 : 0, [10 : i16]>,
+  // CHECK: #test.attr_with_format<5 : two = "a_string", four = [4, 5, 6, 7, 8] : 8 : i8 : 255, [ 10 : i16]>,
+  attr1 = #test.attr_with_format<5 : two = "a_string", four = [4, 5, 6, 7, 8] : 8 : i8 : 255, [10 : i16]>,
   // CHECK: #test<attr_ugly begin 5 : index end>
   attr2 = #test<attr_ugly begin 5 : index end>,
   // CHECK: #test.attr_params<42, 24>
@@ -22,7 +22,11 @@ attributes {
   // CHECK: #test.custom_anchor<5>
   attr7 = #test.custom_anchor<5>,
   // CHECK: #test.custom_anchor<5, true>
-  attr8 = #test.custom_anchor<5, true>
+  attr8 = #test.custom_anchor<5, true>,
+  // CHECK: #test.attr_with_optional_signed<-12>
+  attr9 = #test.attr_with_optional_signed<-12>,
+  // CHECK: #test.attr_with_optional_unsigned<22>
+  attr_10 = #test.attr_with_optional_unsigned<22>
 }
 
 // CHECK-LABEL: @test_roundtrip_default_parsers_struct
index eb7d967..ead7e83 100644 (file)
@@ -123,7 +123,7 @@ func.func private @test_type_syntax_error() -> !test.type_with_format<42, two =
 
 func.func private @test_verifier_fails() -> () attributes {
   // expected-error@+1 {{expected 'one' to equal 'four.size()'}}
-  attr = #test.attr_with_format<42 : two = "hello", four = [1, 2, 3] : 42 : i64, [10 : i16]>
+  attr = #test.attr_with_format<42 : two = "hello", four = [1, 2, 3] : 42 : i64 : 0, [10 : i16]>
 }
 
 // -----