[Mlir-commits] [mlir] [MLIR][Math] Fix math.ceil expansion to avoid undefined behavior on Inf/NaN (PR #170028)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Mon Feb 9 21:49:26 PST 2026


================
@@ -232,6 +232,50 @@ static LogicalResult convertCeilOp(math::CeilOp op, PatternRewriter &rewriter) {
   ImplicitLocOpBuilder b(op->getLoc(), rewriter);
   Value operand = op.getOperand();
   Type opType = operand.getType();
+  Type operandETy = getElementTypeOrSelf(opType);
+  FloatType floatTy = llvm::dyn_cast<FloatType>(operandETy);
+  const llvm::fltSemantics &semantics = floatTy.getFloatSemantics();
+
+  unsigned bitWidth = floatTy.getWidth();
+  unsigned mantissaWidth = floatTy.getFPMantissaWidth() - 1;
+  const int bias = (&semantics == &APFloat::Float8E8M0FNU())
+                       ? -semantics.minExponent
+                       : -(semantics.minExponent - 1);
+  bool hasNegativeZeroNaNEncoding =
+      (semantics.nanEncoding == llvm::fltNanEncoding::NegativeZero);
+
+  Type iTy = rewriter.getIntegerType(bitWidth);
+  if (auto shapedTy = dyn_cast<ShapedType>(opType))
+    iTy = shapedTy.clone(iTy);
+
+  // For IEEE-like floating-point formats 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.
+  Value operandBitcast = arith::BitcastOp::create(b, iTy, operand);
+  Value cMask =
+      createIntConst(op->getLoc(), iTy, (1ull << (bitWidth - 1)) - 1, b);
----------------
hankluo6 wrote:

Yes, I didn't notice that before. Fixed by explicitly casting to int64_t.

https://github.com/llvm/llvm-project/pull/170028


More information about the Mlir-commits mailing list