Skip to content

Commit 0733f38

Browse files
authored
[mlir][int-range] Limit xor int range inference to i1 (#116968)
Fixes #82168 `intrange::inferXor` was incorrectly handling ranges for widths > i1 (see example in code). Limit it to i1 for now. For bigger widths it will return maxRange.
1 parent 81c2024 commit 0733f38

File tree

2 files changed

+42
-2
lines changed

2 files changed

+42
-2
lines changed

mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,20 @@ mlir::intrange::inferOr(ArrayRef<ConstantIntRanges> argRanges) {
558558

559559
ConstantIntRanges
560560
mlir::intrange::inferXor(ArrayRef<ConstantIntRanges> argRanges) {
561+
// TODO: The code below doesn't work for bitwidths > i1.
562+
// For input ranges lhs=[2060639849, 2060639850], rhs=[2060639849, 2060639849]
563+
// widenBitwiseBounds will produce:
564+
// lhs:
565+
// 2060639848 01111010110100101101111001101000
566+
// 2060639851 01111010110100101101111001101011
567+
// rhs:
568+
// 2060639849 01111010110100101101111001101001
569+
// 2060639849 01111010110100101101111001101001
570+
// None of those combinations xor to 0, while intermediate values does.
571+
unsigned width = argRanges[0].umin().getBitWidth();
572+
if (width > 1)
573+
return ConstantIntRanges::maxRange(width);
574+
561575
auto [lhsZeros, lhsOnes] = widenBitwiseBounds(argRanges[0]);
562576
auto [rhsZeros, rhsOnes] = widenBitwiseBounds(argRanges[1]);
563577
auto xori = [](const APInt &a, const APInt &b) -> std::optional<APInt> {

mlir/test/Dialect/Arith/int-range-interface.mlir

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -454,9 +454,35 @@ func.func @ori(%arg0 : i128, %arg1 : i128) -> i1 {
454454
func.return %2 : i1
455455
}
456456

457+
// CHECK-LABEL: func @xori_issue_82168
458+
// arith.cmpi was erroneously folded to %false, see Issue #82168.
459+
// CHECK: %[[R:.*]] = arith.cmpi eq, %{{.*}}, %{{.*}} : i64
460+
// CHECK: return %[[R]]
461+
func.func @xori_issue_82168() -> i1 {
462+
%c0_i64 = arith.constant 0 : i64
463+
%c2060639849_i64 = arith.constant 2060639849 : i64
464+
%2 = test.with_bounds { umin = 2060639849 : i64, umax = 2060639850 : i64, smin = 2060639849 : i64, smax = 2060639850 : i64 } : i64
465+
%3 = arith.xori %2, %c2060639849_i64 : i64
466+
%4 = arith.cmpi eq, %3, %c0_i64 : i64
467+
func.return %4 : i1
468+
}
469+
470+
// CHECK-LABEL: func @xori_i1
471+
// CHECK-DAG: %[[true:.*]] = arith.constant true
472+
// CHECK-DAG: %[[false:.*]] = arith.constant false
473+
// CHECK: return %[[true]], %[[false]]
474+
func.func @xori_i1() -> (i1, i1) {
475+
%true = arith.constant true
476+
%1 = test.with_bounds { umin = 0 : i1, umax = 0 : i1, smin = 0 : i1, smax = 0 : i1 } : i1
477+
%2 = test.with_bounds { umin = 1 : i1, umax = 1 : i1, smin = 1 : i1, smax = 1 : i1 } : i1
478+
%3 = arith.xori %1, %true : i1
479+
%4 = arith.xori %2, %true : i1
480+
func.return %3, %4 : i1, i1
481+
}
482+
457483
// CHECK-LABEL: func @xori
458-
// CHECK: %[[false:.*]] = arith.constant false
459-
// CHECK: return %[[false]]
484+
// TODO: xor folding is temporarily disabled
485+
// CHECK-NOT: arith.constant false
460486
func.func @xori(%arg0 : i64, %arg1 : i64) -> i1 {
461487
%c0 = arith.constant 0 : i64
462488
%c7 = arith.constant 7 : i64

0 commit comments

Comments
 (0)