Skip to content

Commit db3765b

Browse files
committed
Merge pull request #160 from Xilinx/corentin.fix_itofp
[FXML-4281] Fix signedness behavior of unsigned integer <-> floating-point conversions
1 parent 133a8ba commit db3765b

File tree

3 files changed

+35
-7
lines changed

3 files changed

+35
-7
lines changed

mlir/lib/Conversion/ArithToEmitC/ArithToEmitC.cpp

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,22 @@ class FtoICastOpConversion : public OpConversionPattern<CastOp> {
162162
return rewriter.notifyMatchFailure(castOp,
163163
"unsupported cast destination type");
164164

165-
rewriter.replaceOpWithNewOp<emitc::CastOp>(castOp, dstType,
166-
adaptor.getOperands());
165+
// Convert to unsigned if it's the "ui" variant
166+
// Signless is interpreted as signed, so no need to cast for "si"
167+
Type actualResultType = dstType;
168+
if (isa<arith::FPToUIOp>(castOp)) {
169+
actualResultType =
170+
rewriter.getIntegerType(operandType.getIntOrFloatBitWidth(),
171+
/*isSigned=*/false);
172+
}
173+
174+
Value result = rewriter.create<emitc::CastOp>(
175+
castOp.getLoc(), actualResultType, adaptor.getOperands());
176+
177+
if (isa<arith::FPToUIOp>(castOp)) {
178+
result = rewriter.create<emitc::CastOp>(castOp.getLoc(), dstType, result);
179+
}
180+
rewriter.replaceOp(castOp, result);
167181

168182
return success();
169183
}
@@ -179,7 +193,7 @@ class ItoFCastOpConversion : public OpConversionPattern<CastOp> {
179193
LogicalResult
180194
matchAndRewrite(CastOp castOp, typename CastOp::Adaptor adaptor,
181195
ConversionPatternRewriter &rewriter) const override {
182-
196+
// Vectors in particular are not supported
183197
Type operandType = adaptor.getIn().getType();
184198
if (!emitc::isSupportedIntegerType(operandType))
185199
return rewriter.notifyMatchFailure(castOp,
@@ -193,8 +207,20 @@ class ItoFCastOpConversion : public OpConversionPattern<CastOp> {
193207
return rewriter.notifyMatchFailure(castOp,
194208
"unsupported cast destination type");
195209

196-
rewriter.replaceOpWithNewOp<emitc::CastOp>(castOp, dstType,
197-
adaptor.getOperands());
210+
// Convert to unsigned if it's the "ui" variant
211+
// Signless is interpreted as signed, so no need to cast for "si"
212+
Type actualOperandType = operandType;
213+
if (isa<arith::UIToFPOp>(castOp)) {
214+
actualOperandType =
215+
rewriter.getIntegerType(operandType.getIntOrFloatBitWidth(),
216+
/*isSigned=*/false);
217+
}
218+
Value fpCastOperand = adaptor.getIn();
219+
if (actualOperandType != operandType) {
220+
fpCastOperand = rewriter.template create<emitc::CastOp>(
221+
castOp.getLoc(), actualOperandType, fpCastOperand);
222+
}
223+
rewriter.replaceOpWithNewOp<emitc::CastOp>(castOp, dstType, fpCastOperand);
198224

199225
return success();
200226
}

mlir/test/Conversion/ArithToEmitC/arith-to-emitc-cast-truncate.mlir

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ func.func @arith_float_to_int_cast_ops(%arg0: f32, %arg1: f64) {
1313
// CHECK: emitc.cast %arg1 : f64 to i16
1414
%3 = arith.fptosi %arg1 : f64 to i16
1515

16-
// CHECK: emitc.cast %arg0 : f32 to i32
16+
// CHECK: %[[CAST0:.*]] = emitc.cast %arg0 : f32 to ui32
17+
// CHECK: emitc.cast %[[CAST0]] : ui32 to i32
1718
%4 = arith.fptoui %arg0 : f32 to i32
1819

1920
return

mlir/test/Conversion/ArithToEmitC/arith-to-emitc.mlir

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ func.func @arith_int_to_float_cast_ops(%arg0: i8, %arg1: i64) {
103103
// CHECK: emitc.cast %arg1 : i64 to f32
104104
%1 = arith.sitofp %arg1 : i64 to f32
105105

106-
// CHECK: emitc.cast %arg0 : i8 to f32
106+
// CHECK: %[[CAST_UNS:.*]] = emitc.cast %arg0 : i8 to ui8
107+
// CHECK: emitc.cast %[[CAST_UNS]] : ui8 to f32
107108
%2 = arith.uitofp %arg0 : i8 to f32
108109

109110
return

0 commit comments

Comments
 (0)