[PATCH] D71011: [ConstantRange] Add `shlWithNoWrap()` method

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 10 11:42:06 PST 2019


nikic added a comment.

Variant with nuw+nsw support:

  if (NoWrapKind & OBO::NoUnsignedWrap) {
    APInt Min = getUnsignedMin(), Max = getUnsignedMax();
    unsigned MinLeadingZeros = Max.countLeadingZeros();
    unsigned MaxLeadingZeros = Min.countLeadingZeros();
  
    // If additionally the nsw flag is set, we can treat this the same way as
    // nuw, but with one less bit available.
    unsigned EffectiveBitWidth = BitWidth;
    if (NoWrapKind & OBO::NoSignedWrap) {
      --EffectiveBitWidth;
      if (MinLeadingZeros != 0) --MinLeadingZeros;
      if (MaxLeadingZeros != 0) --MaxLeadingZeros;
    }
  
    unsigned ShAmtMax = ShAmt.getUnsignedMax().getLimitedValue();
    unsigned ShAmtMin = ShAmt.getUnsignedMin().getLimitedValue();
    if (ShAmtMin > MaxLeadingZeros)
      // All possible shifts will overflow.
      return getEmpty();
  
    APInt ResMin = Min.shl(ShAmtMin);
    // We'll pick the larger of two possible upper bounds, initialize to zero.
    APInt ResMax = APInt::getNullValue(BitWidth);
    // Shift the maximum as far as possible without overflowing.
    if (ShAmtMin <= MinLeadingZeros)
      ResMax = Max.shl(std::min(ShAmtMax, MinLeadingZeros));
    // Pick the largest number with all low bits sets that is both in the LHS
    // range and can be shifted without overflowing.
    if (MinLeadingZeros != MaxLeadingZeros && ShAmtMax >= MinLeadingZeros + 1) {
      unsigned Shift = std::max(ShAmtMin, MinLeadingZeros + 1);
      ResMax = APIntOps::umax(ResMax,
          APInt::getLowBitsSet(BitWidth, EffectiveBitWidth - Shift).shl(Shift));
    }
    return getNonEmpty(ResMin, ResMax + 1);
  }

The nsw case is ... uh ... left as an exercise for the reader.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D71011/new/

https://reviews.llvm.org/D71011





More information about the llvm-commits mailing list