[Mlir-commits] [mlir] [MLIR][Math] Fix math.ceil expansion to avoid undefined behavior on Inf/NaN (PR #170028)
Benoit Jacob
llvmlistbot at llvm.org
Thu Feb 5 11:53:03 PST 2026
================
@@ -232,6 +232,37 @@ static LogicalResult convertCeilOp(math::CeilOp op, PatternRewriter &rewriter) {
ImplicitLocOpBuilder b(op->getLoc(), rewriter);
Value operand = op.getOperand();
Type opType = operand.getType();
+
+ auto operandETy = getElementTypeOrSelf(opType);
+ unsigned bitWidth = operandETy.getIntOrFloatBitWidth();
+ unsigned mantissaWidth =
+ llvm::cast<FloatType>(operandETy).getFPMantissaWidth() - 1;
+ unsigned exponentWidth = bitWidth - mantissaWidth - 1;
+
+ Type iTy = rewriter.getIntegerType(bitWidth);
+ if (auto shapedTy = dyn_cast<ShapedType>(opType))
+ iTy = shapedTy.clone(iTy);
+
+ Value cMantissaWidth = createIntConst(op->getLoc(), iTy, mantissaWidth, b);
+ Value cBias =
+ createIntConst(op->getLoc(), iTy, (1ull << (exponentWidth - 1)) - 1, b);
+ Value cExpMask =
+ createIntConst(op->getLoc(), iTy, (1ull << exponentWidth) - 1, b);
+
+ // Any floating-point value with an unbiased exponent ≥ `mantissaWidth`
+ // falls into one of these categories:
+ // - a large finite value (|x| ≥ 2^mantissaWidth), where all representable
+ // numbers are already integral, or
+ // - a special value (NaN or ±Inf), which also satisfies this exponent
+ // condition.
+ // For all such cases, `ceilf(x)` is defined to return `x` directly.
----------------
bjacob wrote:
There is one corner case to consider: for "FNUZ" types, those that have fltNanEncoding::NegativeZero i.e. where NaN is encoded as negative zero. In that case, the exponent is not large, so `isSpecialValOrLargeVal ` is false, but we still need to avoid creating poison in the fptosi.
https://github.com/llvm/llvm-project/pull/170028
More information about the Mlir-commits
mailing list