[Mlir-commits] [mlir] [mlir][arith] wide integer emulation support for fpto*i ops (PR #132375)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed Mar 26 08:26:58 PDT 2025
================
@@ -974,6 +974,126 @@ struct ConvertUIToFP final : OpConversionPattern<arith::UIToFPOp> {
}
};
+//===----------------------------------------------------------------------===//
+// ConvertFPToSI
+//===----------------------------------------------------------------------===//
+
+struct ConvertFPToSI final : OpConversionPattern<arith::FPToSIOp> {
+ using OpConversionPattern::OpConversionPattern;
+
+ LogicalResult
+ matchAndRewrite(arith::FPToSIOp op, OpAdaptor adaptor,
+ ConversionPatternRewriter &rewriter) const override {
+ Location loc = op.getLoc();
+ // Get the input float type.
+ Value inFp = adaptor.getIn();
+ Type fpTy = inFp.getType();
+
+ Type intTy = op.getType();
+ unsigned oldBitWidth = getElementTypeOrSelf(intTy).getIntOrFloatBitWidth();
+
+ auto newTy = getTypeConverter()->convertType<VectorType>(intTy);
+ if (!newTy)
+ return rewriter.notifyMatchFailure(
+ loc, llvm::formatv("unsupported type: {0}", intTy));
+
+ // Work on the absolute value and then convert the result to signed integer.
+ // Defer absolute value to fptoui. If minSInt < fp < maxSInt, i.e.
+ // if the fp is representable in signed i2N, emits the correct result.
+ // Else, the result is UB.
+
+ TypedAttr zeroAttr = rewriter.getZeroAttr(fpTy);
+ Value zeroCst = rewriter.create<arith::ConstantOp>(loc, zeroAttr);
+
+ Value oneCst = createScalarOrSplatConstant(rewriter, loc, intTy, 1);
+ Value allOnesCst = createScalarOrSplatConstant(
+ rewriter, loc, intTy, APInt::getAllOnes(oldBitWidth));
+
+ // Get the absolute value.
+ Value isNeg = rewriter.create<arith::CmpFOp>(loc, arith::CmpFPredicate::OLT,
+ inFp, zeroCst);
+ Value negInFp = rewriter.create<arith::NegFOp>(loc, inFp);
+
+ Value absVal = rewriter.create<arith::SelectOp>(loc, isNeg, negInFp, inFp);
+
+ // Defer the absolute value to fptoui.
+ Value res = rewriter.create<arith::FPToUIOp>(loc, intTy, absVal);
+
+ // Negate the value if < 0 .
+ Value bitwiseNeg = rewriter.create<arith::XOrIOp>(loc, res, allOnesCst);
+ Value neg = rewriter.create<arith::AddIOp>(loc, bitwiseNeg, oneCst);
+
+ rewriter.replaceOpWithNewOp<arith::SelectOp>(op, isNeg, neg, res);
+ return success();
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// ConvertFPToUI
+//===----------------------------------------------------------------------===//
+
+struct ConvertFPToUI final : OpConversionPattern<arith::FPToUIOp> {
+ using OpConversionPattern::OpConversionPattern;
+
+ LogicalResult
+ matchAndRewrite(arith::FPToUIOp op, OpAdaptor adaptor,
+ ConversionPatternRewriter &rewriter) const override {
+ Location loc = op.getLoc();
+ // Get the input float type.
+ Value inFp = adaptor.getIn();
+ Type fpTy = inFp.getType();
+
+ Type intTy = op.getType();
+ auto newTy = getTypeConverter()->convertType<VectorType>(intTy);
+ if (!newTy)
+ return rewriter.notifyMatchFailure(
+ loc, llvm::formatv("unsupported type: {0}", intTy));
+ unsigned newBitWidth = newTy.getElementTypeBitWidth();
+ // double cannot hold powBitwidth when bitwidth > 1023.
+ if (newBitWidth > 512)
+ return rewriter.notifyMatchFailure(
+ loc, llvm::formatv("unsupported integer emulation: i{0}->i{1}",
+ intTy.getIntOrFloatBitWidth(), newBitWidth));
+ Type newHalfType = IntegerType::get(inFp.getContext(), newBitWidth);
+ if (auto vecType = dyn_cast<VectorType>(fpTy))
+ newHalfType = VectorType::get(vecType.getShape(), newHalfType);
+
+ // The resulting integer has the upper part and the lower part.
+ // This would be interpreted as 2^N * high + low, where N is the bitwidth.
+ // Therefore, to calculate the higher part, we emit resHigh =
+ // fptoui(fp/2^N). For the lower part, we emit fptoui(fp - resHigh * 2^N).
+ // The special cases of overflows including +-inf, NaNs and negative numbers
+ // are UB.
+
+ double powBitwidth =
----------------
egebeysel wrote:
Did that, thanks for the direction :)
https://github.com/llvm/llvm-project/pull/132375
More information about the Mlir-commits
mailing list