diff --git a/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp b/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp --- a/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp +++ b/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp @@ -300,6 +300,11 @@ transform::TransformState &state) { SmallVector fusedOps; ArrayRef producerOps = state.getPayloadOps(getProducerOp()); + // If nothing to fuse, propagate success. + if (producerOps.empty()) { + results.set(getResult().cast(), SmallVector{}); + return DiagnosedSilenceableFailure::success(); + } for (Operation *producerOp : producerOps) { if (producerOp->getNumResults() != 1) { Diagnostic diag(producerOp->getLoc(), DiagnosticSeverity::Note); @@ -310,7 +315,8 @@ ArrayRef containingOps = state.getPayloadOps(getContainingOp()); if (containingOps.size() != 1) return DiagnosedSilenceableFailure( - this->emitOpError("requires exactly one containing_op handle")); + this->emitOpError("requires exactly one containing_op handle (got ") + << containingOps.size() << ")"); Operation *containingOp = containingOps.front(); // Helper function to find the next producer that should be fused. Take any diff --git a/mlir/test/Dialect/Linalg/transform-op-fuse-into-containing.mlir b/mlir/test/Dialect/Linalg/transform-op-fuse-into-containing.mlir --- a/mlir/test/Dialect/Linalg/transform-op-fuse-into-containing.mlir +++ b/mlir/test/Dialect/Linalg/transform-op-fuse-into-containing.mlir @@ -36,6 +36,11 @@ func.return %2 : tensor } + // Check no failure when nothing happens. + func.func @dummy1() { return } + func.func @dummy2() { return } + func.func @dummy3() { return } + transform.with_pdl_patterns { ^bb0(%arg0: !pdl.operation): transform.sequence %arg0 {