diff options
| author | Matthias Springer <me@m-sp.org> | 2025-11-20 17:51:44 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-11-20 17:51:44 +0800 |
| commit | 54f69caf1f3e92ee147bac7e508ba65aff5ed1d5 (patch) | |
| tree | de4c9d58ed8271e11fb08e2432749c58cb5edca4 /mlir | |
| parent | 131cf7d5b2aa29b8018ac6422515ad2f522008c9 (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.h | 8 | ||||
| -rw-r--r-- | mlir/lib/Pass/Pass.cpp | 6 | ||||
| -rw-r--r-- | mlir/test/Dialect/Transform/test-pass-application.mlir | 2 | ||||
| -rw-r--r-- | mlir/test/Pass/invalid-unsupported-operation.mlir | 10 | ||||
| -rw-r--r-- | mlir/test/Pass/pipeline-invalid.mlir | 2 |
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 {} |
