[Mlir-commits] [mlir] [mlir][IntRange] Avoid division by zero for empty divisor ranges in divs (PR #234159)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed Oct 21 04:21:11 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-arith
Author: Sajid Zubair (Sajid-Zubair)
<details>
<summary>Changes</summary>
inferSub can produce an empty range (smin > smax) when both nsw and nuw saturate, e.g. for `arith.subi 0, 1 overflow<nsw, nuw>`, whose result is poison. inferDivSRange only checked rhsMax.isNegative() to rule out a zero divisor, so it then evaluated sdiv with rhsMin == 0 and asserted in APInt::udiv. Treat an empty divisor range as unknown and return the max range instead.
Fixes #<!-- -->231845
---
Full diff: https://github.com/llvm/llvm-project/pull/234159.diff
2 Files Affected:
- (modified) mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp (+4-1)
- (modified) mlir/test/Dialect/Arith/int-range-opts-crash.mlir (+12)
``````````diff
diff --git a/mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp b/mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp
index c9f49fda726e7..24fb166ce91c1 100644
--- a/mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp
+++ b/mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp
@@ -342,7 +342,10 @@ static ConstantIntRanges inferDivSRange(const ConstantIntRanges &lhs,
DivisionFixupFn fixup) {
const APInt &lhsMin = lhs.smin(), &lhsMax = lhs.smax(), &rhsMin = rhs.smin(),
&rhsMax = rhs.smax();
- bool canDivide = rhsMin.isStrictlyPositive() || rhsMax.isNegative();
+ // An empty (min > max) divisor range can arise from poison, e.g. a
+ // saturated `nsw`/`nuw` subtraction. Don't trust its bounds.
+ bool canDivide = rhsMin.sle(rhsMax) &&
+ (rhsMin.isStrictlyPositive() || rhsMax.isNegative());
if (canDivide) {
auto sdiv = [&fixup](const APInt &a,
diff --git a/mlir/test/Dialect/Arith/int-range-opts-crash.mlir b/mlir/test/Dialect/Arith/int-range-opts-crash.mlir
index fa763c163160d..77b173311f6ac 100644
--- a/mlir/test/Dialect/Arith/int-range-opts-crash.mlir
+++ b/mlir/test/Dialect/Arith/int-range-opts-crash.mlir
@@ -11,3 +11,15 @@ func.func @repro_crash() -> !test.i32 {
// CHECK: return %[[RES]] : !test.i32
return %0 : !test.i32
}
+
+// The divisor is poison (0 - 1 with nuw), giving an empty range.
+// This used to divide by zero in inferDivSRange.
+// CHECK-LABEL: func.func @divs_by_poison_sub
+// CHECK: index.divs
+func.func @divs_by_poison_sub() -> index {
+ %z = arith.constant 0 : index
+ %o = arith.constant 1 : index
+ %bad = arith.subi %z, %o overflow<nsw, nuw> : index
+ %q = index.divs %o, %bad
+ return %q : index
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/234159
More information about the Mlir-commits
mailing list