[llvm] [ConstantRange] Improve `shlWithNoWrap` (PR #101800)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 3 03:46:17 PDT 2024
================
@@ -1624,12 +1624,33 @@ ConstantRange ConstantRange::shlWithNoWrap(const ConstantRange &Other,
return getEmpty();
ConstantRange Result = shl(Other);
+ if (!NoWrapKind)
+ return Result;
- if (NoWrapKind & OverflowingBinaryOperator::NoSignedWrap)
- Result = Result.intersectWith(sshl_sat(Other), RangeType);
+ KnownBits Known = toKnownBits();
+
+ if (NoWrapKind & OverflowingBinaryOperator::NoSignedWrap) {
+ ConstantRange ShAmtRange = Other;
+ if (isAllNonNegative())
+ ShAmtRange = ShAmtRange.intersectWith(
+ ConstantRange(APInt::getZero(getBitWidth()),
+ APInt(getBitWidth(), Known.countMaxLeadingZeros())),
+ Unsigned);
+ else if (isAllNegative())
+ ShAmtRange = ShAmtRange.intersectWith(
+ ConstantRange(APInt::getZero(getBitWidth()),
+ APInt(getBitWidth(), Known.countMaxLeadingOnes())),
+ Unsigned);
+ Result = Result.intersectWith(sshl_sat(ShAmtRange), RangeType);
+ }
- if (NoWrapKind & OverflowingBinaryOperator::NoUnsignedWrap)
- Result = Result.intersectWith(ushl_sat(Other), RangeType);
+ if (NoWrapKind & OverflowingBinaryOperator::NoUnsignedWrap) {
+ ConstantRange ShAmtRange =
+ getNonEmpty(APInt::getZero(getBitWidth()),
+ APInt(getBitWidth(), Known.countMaxLeadingZeros() + 1));
+ Result = Result.intersectWith(
+ ushl_sat(Other.intersectWith(ShAmtRange, Unsigned)), RangeType);
----------------
nikic wrote:
I feel like there has to be a better way to do this, that doesn't require multiple intersections and calling both shl and ushl_sat.
I think the logic here could be something like this: The lower bound here should be LHS min shifted by RHS min, or empty on overflow. The upper bound can either be LHS max shifted as far as it can go. Or it can be 0111... below the LHS max as far as it can go.
https://github.com/llvm/llvm-project/pull/101800
More information about the llvm-commits
mailing list