[llvm] [ConstantRange] Improve `shlWithNoWrap` (PR #101800)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 3 11:03:12 PDT 2024
================
@@ -1624,12 +1624,43 @@ 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) {
+ bool Overflow;
+ APInt LHSMin = getUnsignedMin();
+ APInt MinShl = LHSMin.ushl_ov(Other.getUnsignedMin(), Overflow);
+ if (Overflow)
+ return getEmpty();
+ APInt LHSMax = getUnsignedMax();
+ APInt MaxShl = LHSMax << Other.getUnsignedMax().getLimitedValue(
+ LHSMax.countLeadingZeros());
+ if (LHSMin.countLeadingZeros() != LHSMax.countLeadingZeros())
+ MaxShl = APIntOps::umax(
+ MaxShl, APInt::getHighBitsSet(
----------------
dtcxzyw wrote:
Consider the following case:
```
%x = [3, 5)
%y = Full
%shl = shl nuw i8 %x, %y
```
We have
```
4 << ctlz(4) = 128
3 << ctlz(3) = 192
```
https://github.com/llvm/llvm-project/pull/101800
More information about the llvm-commits
mailing list