summaryrefslogtreecommitdiff
path: root/mlir
diff options
context:
space:
mode:
authorMatthias Springer <me@m-sp.org>2025-11-20 17:51:44 +0800
committerGitHub <noreply@github.com>2025-11-20 17:51:44 +0800
commit54f69caf1f3e92ee147bac7e508ba65aff5ed1d5 (patch)
treede4c9d58ed8271e11fb08e2432749c58cb5edca4 /mlir
parent131cf7d5b2aa29b8018ac6422515ad2f522008c9 (diff)
[mlir][Pass] Fix crash when applying a pass to an optional interface (#168499)
Interfaces can be optional: whether an op implements an interface or not can depend on the state of the operation. ``` // An optional code block for adding additional "classof" logic. This can // be used to better enable "optional" interfaces, where an entity only // implements the interface if some dynamic characteristic holds. // `$_attr`/`$_op`/`$_type` may be used to refer to an instance of the // interface instance being checked. code extraClassOf = ""; ``` The current `Pass::canScheduleOn(RegisteredOperationName)` is insufficient. This commit adds an additional overload to inspect `Operation *`. This commit fixes a crash when scheduling an `InterfacePass` for an optional interface on an operation that does not actually implement the interface.
Diffstat (limited to 'mlir')
-rw-r--r--mlir/include/mlir/Pass/Pass.h8
-rw-r--r--mlir/lib/Pass/Pass.cpp6
-rw-r--r--mlir/test/Dialect/Transform/test-pass-application.mlir2
-rw-r--r--mlir/test/Pass/invalid-unsupported-operation.mlir10
-rw-r--r--mlir/test/Pass/pipeline-invalid.mlir2
5 files changed, 23 insertions, 5 deletions
diff --git a/mlir/include/mlir/Pass/Pass.h b/mlir/include/mlir/Pass/Pass.h
index 16893c6db87b..448a68824349 100644
--- a/mlir/include/mlir/Pass/Pass.h
+++ b/mlir/include/mlir/Pass/Pass.h
@@ -193,6 +193,13 @@ protected:
/// This is useful for generic operation passes to add restrictions on the
/// operations they operate on.
virtual bool canScheduleOn(RegisteredOperationName opName) const = 0;
+ virtual bool canScheduleOn(Operation *op) const {
+ std::optional<RegisteredOperationName> registeredInfo =
+ op->getName().getRegisteredInfo();
+ if (!registeredInfo)
+ return false;
+ return canScheduleOn(*registeredInfo);
+ }
/// Schedule an arbitrary pass pipeline on the provided operation.
/// This can be invoke any time in a pass to dynamic schedule more passes.
@@ -436,6 +443,7 @@ protected:
/// Indicate if the current pass can be scheduled on the given operation type.
/// For an InterfacePass, this checks if the operation implements the given
/// interface.
+ bool canScheduleOn(Operation *op) const final { return isa<InterfaceT>(op); }
bool canScheduleOn(RegisteredOperationName opName) const final {
return opName.hasInterface<InterfaceT>();
}
diff --git a/mlir/lib/Pass/Pass.cpp b/mlir/lib/Pass/Pass.cpp
index 521c7c6be17b..75f882606e0a 100644
--- a/mlir/lib/Pass/Pass.cpp
+++ b/mlir/lib/Pass/Pass.cpp
@@ -559,9 +559,9 @@ LogicalResult OpToOpPassAdaptor::run(Pass *pass, Operation *op,
return op->emitOpError() << "trying to schedule a pass on an operation not "
"marked as 'IsolatedFromAbove'";
}
- if (!pass->canScheduleOn(*op->getName().getRegisteredInfo())) {
- return op->emitOpError()
- << "trying to schedule a pass on an unsupported operation";
+ if (!pass->canScheduleOn(op)) {
+ return op->emitOpError() << "trying to schedule pass '" << pass->getName()
+ << "' on an unsupported operation";
}
// Initialize the pass state with a callback for the pass to dynamically
diff --git a/mlir/test/Dialect/Transform/test-pass-application.mlir b/mlir/test/Dialect/Transform/test-pass-application.mlir
index ce8f69c58701..4806daf7ce73 100644
--- a/mlir/test/Dialect/Transform/test-pass-application.mlir
+++ b/mlir/test/Dialect/Transform/test-pass-application.mlir
@@ -386,7 +386,7 @@ module attributes {transform.with_named_sequence} {
// -----
module attributes {transform.with_named_sequence} {
- // expected-error @below {{trying to schedule a pass on an unsupported operation}}
+ // expected-error @below {{trying to schedule pass 'DuplicateFunctionEliminationPass' on an unsupported operation}}
// expected-note @below {{target op}}
func.func @invalid_target_op_type() {
return
diff --git a/mlir/test/Pass/invalid-unsupported-operation.mlir b/mlir/test/Pass/invalid-unsupported-operation.mlir
new file mode 100644
index 000000000000..0ff49448c1da
--- /dev/null
+++ b/mlir/test/Pass/invalid-unsupported-operation.mlir
@@ -0,0 +1,10 @@
+// RUN: mlir-opt %s -test-print-liveness -split-input-file -verify-diagnostics
+
+// Unnamed modules do not implement SymbolOpInterface.
+// expected-error @+1 {{trying to schedule pass '(anonymous namespace)::TestLivenessPass' on an unsupported operation}}
+module {}
+
+// -----
+
+// Named modules implement SymbolOpInterface.
+module @named_module {}
diff --git a/mlir/test/Pass/pipeline-invalid.mlir b/mlir/test/Pass/pipeline-invalid.mlir
index 948a13384bc7..4116e127a24a 100644
--- a/mlir/test/Pass/pipeline-invalid.mlir
+++ b/mlir/test/Pass/pipeline-invalid.mlir
@@ -15,5 +15,5 @@ arith.constant 0
// -----
-// expected-error@below {{trying to schedule a pass on an unsupported operation}}
+// expected-error@below {{trying to schedule pass '(anonymous namespace)::TestFunctionPass' on an unsupported operation}}
module {}