@@ -201,6 +201,96 @@ 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
+ // 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
+
204
294
} // namespace
205
295
206
296
// ===----------------------------------------------------------------------===//
@@ -222,7 +312,11 @@ void mlir::populateArithToEmitCPatterns(TypeConverter &typeConverter,
222
312
IntegerOpConversion<arith::MulIOp, emitc::MulOp>,
223
313
IntegerOpConversion<arith::SubIOp, emitc::SubOp>,
224
314
CmpIOpConversion,
225
- SelectOpConversion
315
+ SelectOpConversion,
316
+ ItoFCastOpConversion<arith::SIToFPOp>,
317
+ ItoFCastOpConversion<arith::UIToFPOp>,
318
+ FtoICastOpConversion<arith::FPToSIOp>,
319
+ FtoICastOpConversion<arith::FPToUIOp>
226
320
>(typeConverter, ctx);
227
321
// clang-format on
228
322
}
0 commit comments