// Process the remapping for each of the original arguments.
for (unsigned i = 0, e = origBlock->getNumArguments(); i != e; ++i) {
- // FIXME: We should run the below checks even if a type converter wasn't
- // provided, but a lot of existing lowering rely on the block argument
- // being blindly replaced. We should rework argument materialization to be
- // more robust for temporary source materializations, update existing
- // patterns, and remove these checks.
- if (!blockInfo.converter && blockInfo.argInfo[i])
- continue;
-
// If the type of this argument changed and the argument is still live, we
// need to materialize a conversion.
BlockArgument origArg = origBlock->getArgument(i);
}) : () -> ()
return
}
+
+// -----
+
+// Make sure argument type changes aren't implicitly forwarded.
+func @test_signature_conversion_no_converter() {
+ "test.signature_conversion_no_converter"() ({
+ // expected-error@below {{failed to materialize conversion for block argument #0 that remained live after conversion}}
+ ^bb0(%arg0: f32):
+ // expected-note@below {{see existing live user here}}
+ "test.type_consumer"(%arg0) : (f32) -> ()
+ "test.return"(%arg0) : (f32) -> ()
+ }) : () -> ()
+ return
+}
}
};
+/// Call signature conversion without providing a type converter to handle
+/// materializations.
+struct TestTestSignatureConversionNoConverter
+ : public OpConversionPattern<TestSignatureConversionNoConverterOp> {
+ TestTestSignatureConversionNoConverter(TypeConverter &converter,
+ MLIRContext *context)
+ : OpConversionPattern<TestSignatureConversionNoConverterOp>(context),
+ converter(converter) {}
+
+ LogicalResult
+ matchAndRewrite(TestSignatureConversionNoConverterOp op, OpAdaptor adaptor,
+ ConversionPatternRewriter &rewriter) const final {
+ Region ®ion = op->getRegion(0);
+ Block *entry = ®ion.front();
+
+ // Convert the original entry arguments.
+ TypeConverter::SignatureConversion result(entry->getNumArguments());
+ if (failed(
+ converter.convertSignatureArgs(entry->getArgumentTypes(), result)))
+ return failure();
+ rewriter.updateRootInPlace(
+ op, [&] { rewriter.applySignatureConversion(®ion, result); });
+ return success();
+ }
+
+ TypeConverter &converter;
+};
+
/// Just forward the operands to the root op. This is essentially a no-op
/// pattern that is used to trigger target materialization.
struct TestTypeConsumerForward
// Allow casts from F64 to F32.
return (*op.operand_type_begin()).isF64() && op.getType().isF32();
});
+ target.addDynamicallyLegalOp<TestSignatureConversionNoConverterOp>(
+ [&](TestSignatureConversionNoConverterOp op) {
+ return converter.isLegal(op.getRegion().front().getArgumentTypes());
+ });
// Initialize the set of rewrite patterns.
RewritePatternSet patterns(&getContext());
patterns.add<TestTypeConsumerForward, TestTypeConversionProducer,
- TestSignatureConversionUndo>(converter, &getContext());
+ TestSignatureConversionUndo,
+ TestTestSignatureConversionNoConverter>(converter,
+ &getContext());
patterns.add<TestTypeConversionAnotherProducer>(&getContext());
mlir::populateFuncOpTypeConversionPattern(patterns, converter);