@@ -544,6 +544,10 @@ mlir::intrange::inferXor(ArrayRef<ConstantIntRanges> argRanges) {
544544ConstantIntRanges
545545mlir::intrange::inferShl (ArrayRef<ConstantIntRanges> argRanges) {
546546 const ConstantIntRanges &lhs = argRanges[0 ], &rhs = argRanges[1 ];
547+ const APInt &lhsSMin = lhs.smin (), &lhsSMax = lhs.smax (),
548+ &lhsUMax = lhs.umax (), &rhsUMin = rhs.umin (),
549+ &rhsUMax = rhs.umax ();
550+
547551 ConstArithFn shl = [](const APInt &l,
548552 const APInt &r) -> std::optional<APInt> {
549553 return r.uge (r.getBitWidth ()) ? std::optional<APInt>() : l.shl (r);
@@ -554,17 +558,16 @@ mlir::intrange::inferShl(ArrayRef<ConstantIntRanges> argRanges) {
554558 // change. In the unsigned case, it also leads to problems because the largest
555559 // LHS shifted by the largest RHS does not necessarily result in the largest
556560 // result anymore.
557- bool signbitSafe =
558- (lhs.smin ().getNumSignBits () > rhs.umax ().getZExtValue ()) &&
559- (lhs.smax ().getNumSignBits () > rhs.umax ().getZExtValue ());
560- if (!signbitSafe)
561- return ConstantIntRanges::maxRange (lhs.umax ().getBitWidth ());
561+ assert (rhsUMax.isNonNegative () && " Unexpected negative shift count" );
562+ if (rhsUMax.uge (lhsSMin.getNumSignBits ()) ||
563+ rhsUMax.uge (lhsSMax.getNumSignBits ()))
564+ return ConstantIntRanges::maxRange (lhsUMax.getBitWidth ());
562565
563566 ConstantIntRanges urange =
564- minMaxBy (shl, {lhs.umin (), lhs. umax () }, {rhs. umin (), rhs. umax () },
567+ minMaxBy (shl, {lhs.umin (), lhsUMax }, {rhsUMin, rhsUMax },
565568 /* isSigned=*/ false );
566569 ConstantIntRanges srange =
567- minMaxBy (shl, {lhs. smin (), lhs. smax () }, {rhs. umin (), rhs. umax () },
570+ minMaxBy (shl, {lhsSMin, lhsSMax }, {rhsUMin, rhsUMax },
568571 /* isSigned=*/ true );
569572 return urange.intersection (srange);
570573}
0 commit comments