@@ -201,6 +201,94 @@ class SelectOpConversion : public OpConversionPattern<arith::SelectOp> {
201
201
}
202
202
};
203
203
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
+ if (!emitc::isSupportedIntegerType (dstType))
225
+ return rewriter.notifyMatchFailure (castOp,
226
+ " unsupported cast destination type" );
227
+
228
+ // Convert to unsigned if it's the "ui" variant
229
+ // Signless is interpreted as signed, so no need to cast for "si"
230
+ Type actualResultType = dstType;
231
+ if (isa<arith::FPToUIOp>(castOp)) {
232
+ actualResultType =
233
+ rewriter.getIntegerType (operandType.getIntOrFloatBitWidth (),
234
+ /* isSigned=*/ false );
235
+ }
236
+
237
+ Value result = rewriter.create <emitc::CastOp>(
238
+ castOp.getLoc (), actualResultType, adaptor.getOperands ());
239
+
240
+ if (isa<arith::FPToUIOp>(castOp)) {
241
+ result = rewriter.create <emitc::CastOp>(castOp.getLoc (), dstType, result);
242
+ }
243
+ rewriter.replaceOp (castOp, result);
244
+
245
+ return success ();
246
+ }
247
+ };
248
+
249
+ // Integer to floating-point conversions.
250
+ template <typename CastOp>
251
+ class ItoFCastOpConversion : public OpConversionPattern <CastOp> {
252
+ public:
253
+ ItoFCastOpConversion (const TypeConverter &typeConverter, MLIRContext *context)
254
+ : OpConversionPattern<CastOp>(typeConverter, context) {}
255
+
256
+ LogicalResult
257
+ matchAndRewrite (CastOp castOp, typename CastOp::Adaptor adaptor,
258
+ ConversionPatternRewriter &rewriter) const override {
259
+ // Vectors in particular are not supported
260
+ Type operandType = adaptor.getIn ().getType ();
261
+ if (!emitc::isSupportedIntegerType (operandType))
262
+ return rewriter.notifyMatchFailure (castOp,
263
+ " unsupported cast source type" );
264
+
265
+ Type dstType = this ->getTypeConverter ()->convertType (castOp.getType ());
266
+ if (!dstType)
267
+ return rewriter.notifyMatchFailure (castOp, " type conversion failed" );
268
+
269
+ if (!emitc::isSupportedFloatType (dstType))
270
+ return rewriter.notifyMatchFailure (castOp,
271
+ " unsupported cast destination type" );
272
+
273
+ // Convert to unsigned if it's the "ui" variant
274
+ // Signless is interpreted as signed, so no need to cast for "si"
275
+ Type actualOperandType = operandType;
276
+ if (isa<arith::UIToFPOp>(castOp)) {
277
+ actualOperandType =
278
+ rewriter.getIntegerType (operandType.getIntOrFloatBitWidth (),
279
+ /* isSigned=*/ false );
280
+ }
281
+ Value fpCastOperand = adaptor.getIn ();
282
+ if (actualOperandType != operandType) {
283
+ fpCastOperand = rewriter.template create <emitc::CastOp>(
284
+ castOp.getLoc (), actualOperandType, fpCastOperand);
285
+ }
286
+ rewriter.replaceOpWithNewOp <emitc::CastOp>(castOp, dstType, fpCastOperand);
287
+
288
+ return success ();
289
+ }
290
+ };
291
+
204
292
} // namespace
205
293
206
294
// ===----------------------------------------------------------------------===//
@@ -222,7 +310,11 @@ void mlir::populateArithToEmitCPatterns(TypeConverter &typeConverter,
222
310
IntegerOpConversion<arith::MulIOp, emitc::MulOp>,
223
311
IntegerOpConversion<arith::SubIOp, emitc::SubOp>,
224
312
CmpIOpConversion,
225
- SelectOpConversion
313
+ SelectOpConversion,
314
+ ItoFCastOpConversion<arith::SIToFPOp>,
315
+ ItoFCastOpConversion<arith::UIToFPOp>,
316
+ FtoICastOpConversion<arith::FPToSIOp>,
317
+ FtoICastOpConversion<arith::FPToUIOp>
226
318
>(typeConverter, ctx);
227
319
// clang-format on
228
320
}
0 commit comments