[OM] Add ClassOp region verifier

Add a region verifier to OM dialect's Class Op.  This verifies that the
terminator returns the right number of fields with the correct types that
match the declared type of the Class Op.

Fixes #7736.

Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
This commit is contained in:
Schuyler Eldridge 2024-10-28 15:49:27 -04:00
parent b76a3629d2
commit e08011253e
No known key found for this signature in database
GPG Key ID: 50C5E9936AAD536D
3 changed files with 48 additions and 0 deletions

View File

@ -143,6 +143,8 @@ def ClassOp : OMClassLike<"class", [
// assertion error
mlir::Location getFieldLocByIndex(size_t i);
}];
let hasRegionVerifier = 1;
}
def ClassFieldsOp : OMOp<"class.fields", [Terminator, ReturnLike, Pure,

View File

@ -306,6 +306,35 @@ void circt::om::ClassOp::print(OpAsmPrinter &printer) {
LogicalResult circt::om::ClassOp::verify() { return verifyClassLike(*this); }
LogicalResult circt::om::ClassOp::verifyRegions() {
auto fieldsOp = cast<ClassFieldsOp>(this->getBodyBlock()->getTerminator());
// The number of results matches the number of terminator operands.
if (fieldsOp.getNumOperands() != this->getFieldNames().size()) {
auto diag = this->emitOpError()
<< "returns '" << this->getFieldNames().size()
<< "' fields, but its terminator returned '"
<< fieldsOp.getNumOperands() << "' fields";
return diag.attachNote(fieldsOp.getLoc()) << "see terminator:";
}
// The type of each result matches the corresponding terminator operand type.
auto types = this->getFieldTypes();
for (auto [fieldName, terminatorOperandType] :
llvm::zip(this->getFieldNames(), fieldsOp.getOperandTypes())) {
if (terminatorOperandType ==
cast<TypeAttr>(types.get(cast<StringAttr>(fieldName))).getValue())
continue;
auto diag = this->emitOpError()
<< "returns different field types than its terminator";
return diag.attachNote(fieldsOp.getLoc()) << "see terminator:";
}
return success();
}
void circt::om::ClassOp::getAsmBlockArgumentNames(
Region &region, OpAsmSetValueNameFn setNameFn) {
getClassLikeAsmBlockArgumentNames(*this, region, setNameFn);

View File

@ -161,3 +161,20 @@ om.class @UnknownClass(%arg: !om.class.type<@Unknwon>) {
om.object.field %arg, [@unknown]: (!om.class.type<@Unknwon>) -> i1
om.class.fields
}
// -----
// expected-error @+1 {{returns '0' fields, but its terminator returned '1' fields}}
om.class @A(%arg: i1) {
// expected-note @+1 {{see terminator:}}
om.class.fields %arg : i1
}
// -----
// expected-error @+1 {{returns different field types than its terminator}}
om.class @A(%arg: i1) -> (a: i2) {
// expected-note @+1 {{see terminator:}}
om.class.fields %arg : i1
}