[Mlir-commits] [mlir] [mlir][IntRangeInference] Fix `arith.ceildivsi` range inference when it includes `INT_MIN` (PR #121062)
Ivan Butygin
llvmlistbot at llvm.org
Tue Dec 24 08:52:19 PST 2024
https://github.com/Hardcode84 created https://github.com/llvm/llvm-project/pull/121062
There is a special case in `arith.ceildivsi` range inference for handling `lhs.smin()==INT_MIN`, but when `lhs` is not a single value, it can cause it to skip entire negative range. Add `lhs.smin() + 1` check to handle it.
>From 3f4d662a6c7d5b9d7779205bda81b1c4ee443449 Mon Sep 17 00:00:00 2001
From: Ivan Butygin <ivan.butygin at gmail.com>
Date: Tue, 24 Dec 2024 17:48:45 +0100
Subject: [PATCH] [mlir][IntRangeInference] Fix `arith.ceildivsi` range
inference when it includes INT_MIN
There is a special case in `arith.ceildivsi` range inference for handling `lhs.smin()==INT_MIN`, but when
`lhs` is not a single value, it can cause it to skip entire negative range. Add `lhs.smin() + 1` check to handle it.
---
mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp | 10 +++++++++-
mlir/test/Dialect/Arith/int-range-interface.mlir | 12 ++++++++++++
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp b/mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp
index 7a73a94201f1d6..1eab4139488bdd 100644
--- a/mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp
+++ b/mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp
@@ -386,7 +386,15 @@ mlir::intrange::inferCeilDivS(ArrayRef<ConstantIntRanges> argRanges) {
}
return result;
};
- return inferDivSRange(lhs, rhs, ceilDivSIFix);
+ ConstantIntRanges result = inferDivSRange(lhs, rhs, ceilDivSIFix);
+ if (lhs.smin().isMinSignedValue() && lhs.smax().sgt(lhs.smin())) {
+ // If lhs range includes INT_MIN and lhs is not a single value, we can
+ // suddenly wrap to positive val, skipping entire negative range, add
+ // [INT_MIN + 1, smax()] range to the result to handle this.
+ auto newLhs = ConstantIntRanges::fromSigned(lhs.smin() + 1, lhs.smax());
+ result = result.rangeUnion(inferDivSRange(newLhs, rhs, ceilDivSIFix));
+ }
+ return result;
}
ConstantIntRanges
diff --git a/mlir/test/Dialect/Arith/int-range-interface.mlir b/mlir/test/Dialect/Arith/int-range-interface.mlir
index 48a3eb20eb7fb0..090af3e79f4a10 100644
--- a/mlir/test/Dialect/Arith/int-range-interface.mlir
+++ b/mlir/test/Dialect/Arith/int-range-interface.mlir
@@ -249,6 +249,18 @@ func.func @ceil_divsi(%arg0 : index) -> i1 {
func.return %10 : i1
}
+// There was a bug, which was causing this expr errorneously fold to constant
+// CHECK-LABEL: func @ceil_divsi_full_range
+// CHECK-SAME: (%[[arg:.*]]: index)
+// CHECK: %[[c64:.*]] = arith.constant 64 : index
+// CHECK: %[[ret:.*]] = arith.ceildivsi %[[arg]], %[[c64]] : index
+// CHECK: return %[[ret]]
+func.func @ceil_divsi_full_range(%6: index) -> index {
+ %c64 = arith.constant 64 : index
+ %55 = arith.ceildivsi %6, %c64 : index
+ return %55 : index
+}
+
// CHECK-LABEL: func @ceil_divsi_intmin_bug_115293
// CHECK: %[[ret:.*]] = arith.constant true
// CHECK: return %[[ret]]
More information about the Mlir-commits
mailing list