[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