diff --git a/mlir/lib/Dialect/Arith/IR/InferIntRangeInterfaceImpls.cpp b/mlir/lib/Dialect/Arith/IR/InferIntRangeInterfaceImpls.cpp --- a/mlir/lib/Dialect/Arith/IR/InferIntRangeInterfaceImpls.cpp +++ b/mlir/lib/Dialect/Arith/IR/InferIntRangeInterfaceImpls.cpp @@ -469,9 +469,9 @@ static ConstantIntRanges extUIRange(const ConstantIntRanges &range, Type destType) { unsigned destWidth = ConstantIntRanges::getStorageBitwidth(destType); - APInt smin = range.umin().zext(destWidth); - APInt smax = range.umax().zext(destWidth); - return ConstantIntRanges::fromSigned(smin, smax); + APInt umin = range.umin().zext(destWidth); + APInt umax = range.umax().zext(destWidth); + return ConstantIntRanges::fromUnsigned(umin, umax); } void arith::ExtUIOp::inferResultRanges(ArrayRef argRanges, diff --git a/mlir/test/Dialect/Arith/int-range-interface.mlir b/mlir/test/Dialect/Arith/int-range-interface.mlir --- a/mlir/test/Dialect/Arith/int-range-interface.mlir +++ b/mlir/test/Dialect/Arith/int-range-interface.mlir @@ -712,3 +712,21 @@ %5 = arith.andi %3, %4 : i1 func.return %5 : i1 } + +/// Catch a bug that crept in during an earlier refactoring that made unsigned +/// extension use the signed ranges + +// CHECK-LABEL: func.func @extui_uses_unsigned +// CHECK: %[[true:.*]] = arith.constant true +// CHECK: return %[[true]] +func.func @extui_uses_unsigned(%arg0 : i32) -> i1 { + %ci32_smin = arith.constant 0x80000000 : i32 + %ci32_smin_64 = arith.constant 0x80000000 : i64 + %c0_i64 = arith.constant 0 : i64 + %0 = arith.minui %arg0, %ci32_smin : i32 + %1 = arith.extui %0 : i32 to i64 + %2 = arith.cmpi sge, %1, %c0_i64 : i64 + %3 = arith.cmpi ule, %1, %ci32_smin_64 : i64 + %4 = arith.andi %2, %3 : i1 + func.return %4 : i1 +}