Skip to content

Commit

Permalink
[mlir][IntRangeInference] Fix arith.ceildivsi range inference when …
Browse files Browse the repository at this point in the history
…it includes `INT_MIN` (#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.
  • Loading branch information
Hardcode84 authored Dec 27, 2024
1 parent 5ad4213 commit 9ab16d4
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 1 deletion.
10 changes: 9 additions & 1 deletion mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 12 additions & 0 deletions mlir/test/Dialect/Arith/int-range-interface.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -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]]
Expand Down

0 comments on commit 9ab16d4

Please # to comment.