@@ -201,6 +201,96 @@ class SelectOpConversion : public OpConversionPattern<arith::SelectOp> {
201201 }
202202};
203203
204+ // Floating-point to integer conversions.
205+ template <typename CastOp>
206+ class FtoICastOpConversion : public OpConversionPattern <CastOp> {
207+ public:
208+ FtoICastOpConversion (const TypeConverter &typeConverter, MLIRContext *context)
209+ : OpConversionPattern<CastOp>(typeConverter, context) {}
210+
211+ LogicalResult
212+ matchAndRewrite (CastOp castOp, typename CastOp::Adaptor adaptor,
213+ ConversionPatternRewriter &rewriter) const override {
214+
215+ Type operandType = adaptor.getIn ().getType ();
216+ if (!emitc::isSupportedFloatType (operandType))
217+ return rewriter.notifyMatchFailure (castOp,
218+ " unsupported cast source type" );
219+
220+ Type dstType = this ->getTypeConverter ()->convertType (castOp.getType ());
221+ if (!dstType)
222+ return rewriter.notifyMatchFailure (castOp, " type conversion failed" );
223+
224+ // Float-to-i1 casts are not supported: any value with 0 < value < 1 must be
225+ // truncated to 0, whereas a boolean conversion would return true.
226+ if (!emitc::isSupportedIntegerType (dstType) || dstType.isInteger (1 ))
227+ return rewriter.notifyMatchFailure (castOp,
228+ " unsupported cast destination type" );
229+
230+ // Convert to unsigned if it's the "ui" variant
231+ // Signless is interpreted as signed, so no need to cast for "si"
232+ Type actualResultType = dstType;
233+ if (isa<arith::FPToUIOp>(castOp)) {
234+ actualResultType =
235+ rewriter.getIntegerType (operandType.getIntOrFloatBitWidth (),
236+ /* isSigned=*/ false );
237+ }
238+
239+ Value result = rewriter.create <emitc::CastOp>(
240+ castOp.getLoc (), actualResultType, adaptor.getOperands ());
241+
242+ if (isa<arith::FPToUIOp>(castOp)) {
243+ result = rewriter.create <emitc::CastOp>(castOp.getLoc (), dstType, result);
244+ }
245+ rewriter.replaceOp (castOp, result);
246+
247+ return success ();
248+ }
249+ };
250+
251+ // Integer to floating-point conversions.
252+ template <typename CastOp>
253+ class ItoFCastOpConversion : public OpConversionPattern <CastOp> {
254+ public:
255+ ItoFCastOpConversion (const TypeConverter &typeConverter, MLIRContext *context)
256+ : OpConversionPattern<CastOp>(typeConverter, context) {}
257+
258+ LogicalResult
259+ matchAndRewrite (CastOp castOp, typename CastOp::Adaptor adaptor,
260+ ConversionPatternRewriter &rewriter) const override {
261+ // Vectors in particular are not supported
262+ Type operandType = adaptor.getIn ().getType ();
263+ if (!emitc::isSupportedIntegerType (operandType))
264+ return rewriter.notifyMatchFailure (castOp,
265+ " unsupported cast source type" );
266+
267+ Type dstType = this ->getTypeConverter ()->convertType (castOp.getType ());
268+ if (!dstType)
269+ return rewriter.notifyMatchFailure (castOp, " type conversion failed" );
270+
271+ if (!emitc::isSupportedFloatType (dstType))
272+ return rewriter.notifyMatchFailure (castOp,
273+ " unsupported cast destination type" );
274+
275+ // Convert to unsigned if it's the "ui" variant
276+ // Signless is interpreted as signed, so no need to cast for "si"
277+ Type actualOperandType = operandType;
278+ if (isa<arith::UIToFPOp>(castOp)) {
279+ actualOperandType =
280+ rewriter.getIntegerType (operandType.getIntOrFloatBitWidth (),
281+ /* isSigned=*/ false );
282+ }
283+ Value fpCastOperand = adaptor.getIn ();
284+ if (actualOperandType != operandType) {
285+ fpCastOperand = rewriter.template create <emitc::CastOp>(
286+ castOp.getLoc (), actualOperandType, fpCastOperand);
287+ }
288+ rewriter.replaceOpWithNewOp <emitc::CastOp>(castOp, dstType, fpCastOperand);
289+
290+ return success ();
291+ }
292+ };
293+
204294} // namespace
205295
206296// ===----------------------------------------------------------------------===//
@@ -222,7 +312,11 @@ void mlir::populateArithToEmitCPatterns(TypeConverter &typeConverter,
222312 IntegerOpConversion<arith::MulIOp, emitc::MulOp>,
223313 IntegerOpConversion<arith::SubIOp, emitc::SubOp>,
224314 CmpIOpConversion,
225- SelectOpConversion
315+ SelectOpConversion,
316+ ItoFCastOpConversion<arith::SIToFPOp>,
317+ ItoFCastOpConversion<arith::UIToFPOp>,
318+ FtoICastOpConversion<arith::FPToSIOp>,
319+ FtoICastOpConversion<arith::FPToUIOp>
226320 >(typeConverter, ctx);
227321 // clang-format on
228322}
0 commit comments