Skip to content

Commit f6ae8e6

Browse files
authored
[mlir][irdl] Fix missing verifier in irdl.parametric (#92700)
The parametric op was not checking the symbol it points to is a type or attribute. This PR also fixes a small bug where an invalid IRDL file would not end processing in mlir-opt. I also improved the error messages for the already handled irdl.base invalid symbols.
1 parent 6733a50 commit f6ae8e6

File tree

4 files changed

+43
-10
lines changed

4 files changed

+43
-10
lines changed

mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,8 @@ def IRDL_BaseOp : IRDL_ConstraintOp<"base",
503503
}
504504

505505
def IRDL_ParametricOp : IRDL_ConstraintOp<"parametric",
506-
[ParentOneOf<["TypeOp", "AttributeOp", "OperationOp"]>, Pure]> {
506+
[ParentOneOf<["TypeOp", "AttributeOp", "OperationOp"]>,
507+
DeclareOpInterfaceMethods<SymbolUserOpInterface>, Pure]> {
507508
let summary = "Constraints an attribute/type base and its parameters";
508509
let description = [{
509510
`irdl.parametric` defines a constraint that accepts only a single type

mlir/lib/Dialect/IRDL/IR/IRDL.cpp

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,22 +132,37 @@ LogicalResult BaseOp::verify() {
132132
return success();
133133
}
134134

135+
static LogicalResult
136+
checkSymbolIsTypeOrAttribute(SymbolTableCollection &symbolTable,
137+
Operation *source, SymbolRefAttr symbol) {
138+
Operation *targetOp = symbolTable.lookupNearestSymbolFrom(source, symbol);
139+
if (!targetOp)
140+
return source->emitOpError() << "symbol '" << symbol << "' not found";
141+
142+
if (!isa<TypeOp, AttributeOp>(targetOp))
143+
return source->emitOpError() << "symbol '" << symbol
144+
<< "' does not refer to a type or attribute "
145+
"definition (refers to '"
146+
<< targetOp->getName() << "')";
147+
148+
return success();
149+
}
150+
135151
LogicalResult BaseOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
136152
std::optional<SymbolRefAttr> baseRef = getBaseRef();
137153
if (!baseRef)
138154
return success();
139155

140-
TypeOp typeOp = symbolTable.lookupNearestSymbolFrom<TypeOp>(*this, *baseRef);
141-
if (typeOp)
142-
return success();
156+
return checkSymbolIsTypeOrAttribute(symbolTable, *this, *baseRef);
157+
}
143158

144-
AttributeOp attrOp =
145-
symbolTable.lookupNearestSymbolFrom<AttributeOp>(*this, *baseRef);
146-
if (attrOp)
159+
LogicalResult
160+
ParametricOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
161+
std::optional<SymbolRefAttr> baseRef = getBaseType();
162+
if (!baseRef)
147163
return success();
148164

149-
return emitOpError() << "'" << *baseRef
150-
<< "' does not refer to a type or attribute definition";
165+
return checkSymbolIsTypeOrAttribute(symbolTable, *this, *baseRef);
151166
}
152167

153168
/// Parse a value with its variadicity first. By default, the variadicity is

mlir/lib/Tools/mlir-opt/MlirOptMain.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,8 @@ LogicalResult loadIRDLDialects(StringRef irdlFile, MLIRContext &ctx) {
266266

267267
// Parse the input file.
268268
OwningOpRef<ModuleOp> module(parseSourceFile<ModuleOp>(sourceMgr, &ctx));
269+
if (!module)
270+
return failure();
269271

270272
// Load IRDL dialects.
271273
return irdl::loadDialects(module.get());

mlir/test/Dialect/IRDL/invalid.irdl.mlir

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ func.func private @foo()
66

77
irdl.dialect @testd {
88
irdl.type @type {
9-
// expected-error@+1 {{'@foo' does not refer to a type or attribute definition}}
9+
// expected-error@+1 {{symbol '@foo' not found}}
1010
%0 = irdl.base @foo
1111
irdl.parameters(%0)
1212
}
@@ -41,3 +41,18 @@ irdl.dialect @testd {
4141
irdl.parameters(%0)
4242
}
4343
}
44+
45+
// -----
46+
47+
irdl.dialect @invalid_parametric {
48+
irdl.operation @foo {
49+
// expected-error@+1 {{symbol '@not_a_type_or_attr' does not refer to a type or attribute definition}}
50+
%param = irdl.parametric @not_a_type_or_attr<>
51+
irdl.results(%param)
52+
}
53+
54+
irdl.operation @not_a_type_or_attr {
55+
%param = irdl.is i1
56+
irdl.results(%param)
57+
}
58+
}

0 commit comments

Comments
 (0)