mlir-tblgen has enough information to automatically generate the verify()
function for some attributes and types. (The canonical example might be checking
whether or not an integer value is one of the specified enum values for enum
attributes.)
Previously, the genVerifyDecl field was used to instruct mlir-tblgen to
generate a declaration for the verify() function, and users would be required
to provide the implementation. This diff adds support for a verifyInvariants()
function that will
- verify any individual parameters with custom verification code, and
- call the custom verify() function (if directed via genVerifyDecl=1)
This is accomplished by:
- Adding a verifier field to the AttrOrTypeParameter base class
- Modifying tblgen to generate a verifier function composed of parameter and custom verification
- Modifying the get() and getChecked() implementations in StorageUserBase to call verifyInvariants()
- Adding custom verification for integer and bit enum attributes
- Adding tests for integer and bit enums to verify that getChecked() will return a null attribute for invalid enum values
The existing genVerifyDecl behavior is maintained, and attributes/types will
only behave differently if a non-empty parameter verifier fields are present.
This functionality is expected to be used by a subsequent diff that adds Python
bindings for enums, and will also be used for fastmath support in the
Arithmetic dialect.
Example verifyInvariants() implementation for an enum attribute in the linalg dialect:
::mlir::LogicalResult TypeFnAttr::verifyInvariants( ::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError, ::mlir::linalg::TypeFn value) { // Verify parameter 'value': if (failed( [&emitError](::mlir::linalg::TypeFn value) -> ::mlir::LogicalResult { return symbolizeTypeFn(static_cast<uint32_t>(value)).hasValue() ? ::mlir::success() : (emitError() << "invalid enum value"); }(value))) return ::mlir::failure(); // If genVerifyDecl were equal to 1, the line below would look like this: // return verify(emitError, value); // Instead, in this case we just return success(); return ::mlir::success(); }
This could just link to the AttrParameter, TypeParameter, and AttrOrTypeParameter section above, which should likely also get a little blurb about the verifier field (which could just be the next paragraph + example you have here..