[Mlir-commits] [mlir] [MLIR] Fix miscompilation when use --math-expand-ops (PR #218242)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Sun Aug 23 06:50:56 PDT 2026
https://github.com/tht2005 created https://github.com/llvm/llvm-project/pull/218242
Fix the bug in convertCeilOp that loses the sign
of zero when expanding math.ceil
>From eaace66fc1254ce3b4b1de9f3edd4b8459930249 Mon Sep 17 00:00:00 2001
From: Nguyen Dinh Dang Duong <dangduong31205 at gmail.com>
Date: Sun, 23 Aug 2026 16:45:01 +0700
Subject: [PATCH] [MLIR] Fix miscompilation when use --math-expand-ops
Fix the bug in convertCeilOp that loses the sign
of zero when expanding math.ceil
---
.../lib/Dialect/Math/Transforms/ExpandOps.cpp | 10 +++---
mlir/test/Dialect/Math/expand-math.mlir | 15 ++++----
.../mlir-runner/test-expand-math-approx.mlir | 36 +++++++++++++++++++
3 files changed, 46 insertions(+), 15 deletions(-)
diff --git a/mlir/lib/Dialect/Math/Transforms/ExpandOps.cpp b/mlir/lib/Dialect/Math/Transforms/ExpandOps.cpp
index 41816abf07339..98511a065e87a 100644
--- a/mlir/lib/Dialect/Math/Transforms/ExpandOps.cpp
+++ b/mlir/lib/Dialect/Math/Transforms/ExpandOps.cpp
@@ -338,16 +338,14 @@ static LogicalResult convertCeilOp(math::CeilOp op, PatternRewriter &rewriter) {
Value fpFixedConvert = createTruncatedFPValue(operand, b);
// Creating constants for later use.
- Value zero = createFloatConst(op->getLoc(), opType, 0.00, rewriter, operand);
Value one = createFloatConst(op->getLoc(), opType, 1.00, rewriter, operand);
Value gtCheck = arith::CmpFOp::create(b, arith::CmpFPredicate::OGT, operand,
fpFixedConvert);
- Value incrValue =
- arith::SelectOp::create(b, op->getLoc(), gtCheck, one, zero);
-
- Value add = arith::AddFOp::create(b, opType, fpFixedConvert, incrValue);
- Value ret = arith::SelectOp::create(b, isSpecialValOrLargeVal, operand, add);
+ Value add = arith::AddFOp::create(b, opType, fpFixedConvert, one);
+ Value rounded = arith::SelectOp::create(b, gtCheck, add, fpFixedConvert);
+ Value ret =
+ arith::SelectOp::create(b, isSpecialValOrLargeVal, operand, rounded);
rewriter.replaceOp(op, ret);
return success();
}
diff --git a/mlir/test/Dialect/Math/expand-math.mlir b/mlir/test/Dialect/Math/expand-math.mlir
index 84b0bb0aa314a..5839909aa3956 100644
--- a/mlir/test/Dialect/Math/expand-math.mlir
+++ b/mlir/test/Dialect/Math/expand-math.mlir
@@ -154,7 +154,6 @@ func.func @fmaf_func(%a: f64, %b: f64, %c: f64) -> f64 {
// CHECK-LABEL: func @ceilf_func
// CHECK-SAME: ([[ARG0:%.+]]: f64) -> f64
func.func @ceilf_func(%a: f64) -> f64 {
- // CHECK-DAG: [[C_0:%.+]] = arith.constant 0.000
// CHECK-DAG: [[C_1:%.+]] = arith.constant 1.000
// CHECK-DAG: [[C_4841369599423283200:%.*]] = arith.constant 4841369599423283200
// CHECK-DAG: [[C_9223372036854775807:%.*]] = arith.constant 9223372036854775807
@@ -165,9 +164,9 @@ func.func @ceilf_func(%a: f64) -> f64 {
// CHECK-NEXT: [[CVTF:%.+]] = arith.sitofp [[CVTI]]
// CHECK-NEXT: [[COPYSIGN:%.+]] = math.copysign [[CVTF]], [[ARG0]]
// CHECK-NEXT: [[COMP:%.+]] = arith.cmpf ogt, [[ARG0]], [[COPYSIGN]]
- // CHECK-NEXT: [[INCR:%.+]] = arith.select [[COMP]], [[C_1]], [[C_0]]
- // CHECK-NEXT: [[ADDF:%.+]] = arith.addf [[COPYSIGN]], [[INCR]]
- // CHECK-NEXT: [[RESULT:%.*]] = arith.select [[IS_SPECIAL_VAL]], [[ARG0]], [[ADDF]]
+ // CHECK-NEXT: [[ADDF:%.+]] = arith.addf [[COPYSIGN]], [[C_1]]
+ // CHECK-NEXT: [[ROUNDED:%.+]] = arith.select [[COMP]], [[ADDF]], [[COPYSIGN]]
+ // CHECK-NEXT: [[RESULT:%.*]] = arith.select [[IS_SPECIAL_VAL]], [[ARG0]], [[ROUNDED]]
// CHECK-NEXT: return [[RESULT]]
// CHECK-FILTER: math.ceil
%ret = math.ceil %a : f64
@@ -179,7 +178,6 @@ func.func @ceilf_func(%a: f64) -> f64 {
// CHECK-LABEL: func @ceilf_fnuz_func
// CHECK-SAME: ([[ARG0:%.+]]: f8E5M2FNUZ) -> f8E5M2FNUZ
func.func @ceilf_fnuz_func(%a: f8E5M2FNUZ) -> f8E5M2FNUZ {
- // CHECK-DAG: [[C_0:%.+]] = arith.constant 0.000
// CHECK-DAG: [[C_1:%.+]] = arith.constant 1.000
// CHECK-DAG: [[C_NEG_128:%.*]] = arith.constant -128
// CHECK-DAG: [[C_72:%.*]] = arith.constant 72
@@ -193,9 +191,9 @@ func.func @ceilf_fnuz_func(%a: f8E5M2FNUZ) -> f8E5M2FNUZ {
// CHECK-NEXT: [[CVTF:%.+]] = arith.sitofp [[CVTI]]
// CHECK-NEXT: [[COPYSIGN:%.+]] = math.copysign [[CVTF]], [[ARG0]]
// CHECK-NEXT: [[COMP:%.+]] = arith.cmpf ogt, [[ARG0]], [[COPYSIGN]]
- // CHECK-NEXT: [[INCR:%.+]] = arith.select [[COMP]], [[C_1]], [[C_0]]
- // CHECK-NEXT: [[ADDF:%.+]] = arith.addf [[COPYSIGN]], [[INCR]]
- // CHECK-NEXT: [[RESULT:%.*]] = arith.select [[IS_SPECIAL_VAL]], [[ARG0]], [[ADDF]]
+ // CHECK-NEXT: [[ADDF:%.+]] = arith.addf [[COPYSIGN]], [[C_1]]
+ // CHECK-NEXT: [[ROUNDED:%.+]] = arith.select [[COMP]], [[ADDF]], [[COPYSIGN]]
+ // CHECK-NEXT: [[RESULT:%.*]] = arith.select [[IS_SPECIAL_VAL]], [[ARG0]], [[ROUNDED]]
// CHECK-NEXT: return [[RESULT]]
// CHECK-FILTER: math.ceil
%ret = math.ceil %a : f8E5M2FNUZ
@@ -821,7 +819,6 @@ func.func @rsqrt_tns(%float: tensor<5x8xf32>) -> (tensor<5x8xf32>) {
// CHECK-LABEL: func.func @non_static_shape_ceil_op
// CHECK-SAME: (%[[ARG:.*]]: tensor<?xf32>)
// CHECK-SAME: -> tensor<?xf32>
-// CHECK-DAG: arith.constant 0.000000e+00 : f32
// CHECK-DAG: arith.constant 1.000000e+00 : f32
// CHECK-DAG: tensor.dim %[[ARG]]
// CHECK: tensor.splat %{{.*}}[%{{.*}}] : tensor<?xf32>
diff --git a/mlir/test/mlir-runner/test-expand-math-approx.mlir b/mlir/test/mlir-runner/test-expand-math-approx.mlir
index 06b3171a2349e..949e5658ce58f 100644
--- a/mlir/test/mlir-runner/test-expand-math-approx.mlir
+++ b/mlir/test/mlir-runner/test-expand-math-approx.mlir
@@ -886,6 +886,41 @@ func.func @rsqrt() {
return
}
+// -------------------------------------------------------------------------- //
+// Ceil.
+// -------------------------------------------------------------------------- //
+
+func.func @ceil_f32_bits(%arg : f32) {
+ %result = math.ceil %arg : f32
+ %bits = arith.bitcast %result : f32 to i32
+ vector.print %bits : i32
+ return
+}
+
+func.func @ceil_f64_bits(%arg : f64) {
+ %result = math.ceil %arg : f64
+ %bits = arith.bitcast %result : f64 to i64
+ vector.print %bits : i64
+ return
+}
+
+func.func @ceil() {
+ %neg_fraction_f32 = arith.constant -0.25 : f32
+ %neg_zero_f32 = arith.constant 0x80000000 : f32
+ %neg_fraction_f64 = arith.constant -0.25 : f64
+ %neg_zero_f64 = arith.constant 0x8000000000000000 : f64
+
+ // CHECK: -2147483648
+ call @ceil_f32_bits(%neg_fraction_f32) : (f32) -> ()
+ // CHECK-NEXT: -2147483648
+ call @ceil_f32_bits(%neg_zero_f32) : (f32) -> ()
+ // CHECK-NEXT: -9223372036854775808
+ call @ceil_f64_bits(%neg_fraction_f64) : (f64) -> ()
+ // CHECK-NEXT: -9223372036854775808
+ call @ceil_f64_bits(%neg_zero_f64) : (f64) -> ()
+ return
+}
+
func.func @main() {
call @exp2f() : () -> ()
call @roundf() : () -> ()
@@ -898,5 +933,6 @@ func.func @main() {
call @acosh() : () -> ()
call @atanh() : () -> ()
call @rsqrt() : () -> ()
+ call @ceil() : () -> ()
return
}
More information about the Mlir-commits
mailing list