@@ -824,21 +824,35 @@ mlir::transform::TransformEachOpTrait<OpTy>::apply(
824
824
decltype (&OpTy::applyToOne)>::template arg_t <0 >;
825
825
ArrayRef<Operation *> targets =
826
826
state.getPayloadOps (this ->getOperation ()->getOperand (0 ));
827
+ // Handle the corner case where no target is specified.
828
+ // This is typically the case when the matcher fails to apply and we need to
829
+ // propagate gracefully.
830
+ // In this case, we fill all results with an empty vector.
831
+ if (targets.empty ()) {
832
+ SmallVector<Operation *> emptyResult;
833
+ for (auto r : this ->getOperation ()->getResults ())
834
+ transformResults.set (r.template cast <OpResult>(), emptyResult);
835
+ return DiagnosedSilenceableFailure::success ();
836
+ }
837
+
827
838
SmallVector<SmallVector<Operation *>, 1 > results;
828
839
// In the multi-result case, collect the number of results each transform
829
840
// produced.
830
841
DiagnosedSilenceableFailure result = detail::applyTransformToEach (
831
842
targets, results, [&](TransformOpType specificOp) {
832
843
return static_cast <OpTy *>(this )->applyToOne (specificOp, state);
833
844
});
845
+ // Propagate the failure (definite or silencable) if any.
834
846
if (!result.succeeded ())
835
847
return result;
836
- if (results.empty ())
848
+
849
+ // Legitimately no results, bail early.
850
+ if (results.empty () && OpTy::template hasTrait<OpTrait::ZeroResults>())
837
851
return DiagnosedSilenceableFailure::success ();
838
852
839
853
// Ensure all applications return the same number of results.
840
854
// Variadic cases are much trickier to handle in a generic fashion.
841
- int64_t nRes = results[0 ].size ();
855
+ int64_t nRes = results. empty () ? 0 : results [0 ].size ();
842
856
if (llvm::any_of (results, [&](const auto &r) {
843
857
return static_cast <int64_t >(r.size ()) != nRes;
844
858
})) {
@@ -849,6 +863,8 @@ mlir::transform::TransformEachOpTrait<OpTy>::apply(
849
863
" generic `apply` instead of the specialized `applyToOne`" ;
850
864
}
851
865
// Ensure the number of results agrees with what the transform op expects.
866
+ // Unless we see empty results, in which case we just want to propagate the
867
+ // emptiness.
852
868
if (this ->getOperation ()->getNumResults () != nRes) {
853
869
InFlightDiagnostic diag = static_cast <OpTy *>(this )->emitError ()
854
870
<< " unexpected number of results (got " << nRes
@@ -857,10 +873,6 @@ mlir::transform::TransformEachOpTrait<OpTy>::apply(
857
873
return DiagnosedSilenceableFailure::definiteFailure ();
858
874
}
859
875
860
- // If no results, bail early.
861
- if (OpTy::template hasTrait<OpTrait::ZeroResults>())
862
- return DiagnosedSilenceableFailure::success ();
863
-
864
876
// Perform transposition of M applications producing N results each into N
865
877
// results for each of the M applications.
866
878
SmallVector<SmallVector<Operation *, 1 >> transposedResults =
0 commit comments