@@ -23,21 +23,34 @@ struct CallOpSignatureConversion : public OpConversionPattern<CallOp> {
2323 LogicalResult
2424 matchAndRewrite (CallOp callOp, OpAdaptor adaptor,
2525 ConversionPatternRewriter &rewriter) const override {
26- // Convert the original function results.
26+ // Convert the original function results. Keep track of how many result
27+ // types an original result type is converted into.
28+ SmallVector<size_t > numResultsReplacments;
2729 SmallVector<Type, 1 > convertedResults;
28- if ( failed (typeConverter-> convertTypes (callOp. getResultTypes (),
29- convertedResults )))
30- return failure ();
31-
32- // If this isn't a one-to-one type mapping, we don't know how to aggregate
33- // the results.
34- if (callOp-> getNumResults () ! = convertedResults.size ())
35- return failure ();
30+ size_t numFlattenedResults = 0 ;
31+ for ( auto [idx, type] : llvm::enumerate (callOp. getResultTypes ( ))) {
32+ if ( failed (typeConverter-> convertTypes (type, convertedResults)))
33+ return failure ();
34+ numResultsReplacments. push_back (convertedResults. size () -
35+ numFlattenedResults);
36+ numFlattenedResults = convertedResults.size ();
37+ }
3638
3739 // Substitute with the new result types from the corresponding FuncType
3840 // conversion.
39- rewriter.replaceOpWithNewOp <CallOp>(
40- callOp, callOp.getCallee (), convertedResults, adaptor.getOperands ());
41+ auto newCallOp =
42+ rewriter.create <CallOp>(callOp.getLoc (), callOp.getCallee (),
43+ convertedResults, adaptor.getOperands ());
44+ SmallVector<ValueRange> replacements;
45+ size_t offset = 0 ;
46+ for (int i = 0 , e = callOp->getNumResults (); i < e; ++i) {
47+ replacements.push_back (
48+ newCallOp->getResults ().slice (offset, numResultsReplacments[i]));
49+ offset += numResultsReplacments[i];
50+ }
51+ assert (offset == convertedResults.size () &&
52+ " expected that all converted results are used" );
53+ rewriter.replaceOpWithMultiple (callOp, replacements);
4154 return success ();
4255 }
4356};
0 commit comments