Пример #1
0
ConstantRange
ConstantRange::udiv(const ConstantRange &RHS) const {
  if (isEmptySet() || RHS.isEmptySet() || RHS.getUnsignedMax() == 0)
    return ConstantRange(getBitWidth(), /*isFullSet=*/false);
  if (RHS.isFullSet())
    return ConstantRange(getBitWidth(), /*isFullSet=*/true);

  APInt Lower = getUnsignedMin().udiv(RHS.getUnsignedMax());

  APInt RHS_umin = RHS.getUnsignedMin();
  if (RHS_umin == 0) {
    // We want the lowest value in RHS excluding zero. Usually that would be 1
    // except for a range in the form of [X, 1) in which case it would be X.
    if (RHS.getUpper() == 1)
      RHS_umin = RHS.getLower();
    else
      RHS_umin = APInt(getBitWidth(), 1);
  }

  APInt Upper = getUnsignedMax().udiv(RHS_umin) + 1;

  // If the LHS is Full and the RHS is a wrapped interval containing 1 then
  // this could occur.
  if (Lower == Upper)
    return ConstantRange(getBitWidth(), /*isFullSet=*/true);

  return ConstantRange(Lower, Upper);
}
Пример #2
0
ConstantRange
ConstantRange::ashr(const ConstantRange &Other) const {
  if (isEmptySet() || Other.isEmptySet())
    return ConstantRange(getBitWidth(), /*isFullSet=*/false);

  // May straddle zero, so handle both positive and negative cases.
  // 'PosMax' is the upper bound of the result of the ashr
  // operation, when Upper of the LHS of ashr is a non-negative.
  // number. Since ashr of a non-negative number will result in a
  // smaller number, the Upper value of LHS is shifted right with
  // the minimum value of 'Other' instead of the maximum value.
  APInt PosMax = getSignedMax().ashr(Other.getUnsignedMin()) + 1;

  // 'PosMin' is the lower bound of the result of the ashr
  // operation, when Lower of the LHS is a non-negative number.
  // Since ashr of a non-negative number will result in a smaller
  // number, the Lower value of LHS is shifted right with the
  // maximum value of 'Other'.
  APInt PosMin = getSignedMin().ashr(Other.getUnsignedMax());

  // 'NegMax' is the upper bound of the result of the ashr
  // operation, when Upper of the LHS of ashr is a negative number.
  // Since 'ashr' of a negative number will result in a bigger
  // number, the Upper value of LHS is shifted right with the
  // maximum value of 'Other'.
  APInt NegMax = getSignedMax().ashr(Other.getUnsignedMax()) + 1;

  // 'NegMin' is the lower bound of the result of the ashr
  // operation, when Lower of the LHS of ashr is a negative number.
  // Since 'ashr' of a negative number will result in a bigger
  // number, the Lower value of LHS is shifted right with the
  // minimum value of 'Other'.
  APInt NegMin = getSignedMin().ashr(Other.getUnsignedMin());

  APInt max, min;
  if (getSignedMin().isNonNegative()) {
    // Upper and Lower of LHS are non-negative.
    min = PosMin;
    max = PosMax;
  } else if (getSignedMax().isNegative()) {
    // Upper and Lower of LHS are negative.
    min = NegMin;
    max = NegMax;
  } else {
    // Upper is non-negative and Lower is negative.
    min = NegMin;
    max = PosMax;
  }
  if (min == max)
    return ConstantRange(getBitWidth(), /*isFullSet=*/true);

  return ConstantRange(std::move(min), std::move(max));
}
Пример #3
0
ConstantRange
ConstantRange::shl(const ConstantRange &Other) const {
  if (isEmptySet() || Other.isEmptySet())
    return ConstantRange(getBitWidth(), /*isFullSet=*/false);

  APInt min = getUnsignedMin().shl(Other.getUnsignedMin());
  APInt max = getUnsignedMax().shl(Other.getUnsignedMax());

  // there's no overflow!
  APInt Zeros(getBitWidth(), getUnsignedMax().countLeadingZeros());
  if (Zeros.ugt(Other.getUnsignedMax()))
    return ConstantRange(min, max + 1);

  // FIXME: implement the other tricky cases
  return ConstantRange(getBitWidth(), /*isFullSet=*/true);
}
Пример #4
0
ConstantRange
ConstantRange::shl(const ConstantRange &Amount) const {
  if (isEmptySet())
    return *this;

  APInt min = getUnsignedMin() << Amount.getUnsignedMin();
  APInt max = getUnsignedMax() << Amount.getUnsignedMax();

  // there's no overflow!
  APInt Zeros(getBitWidth(), getUnsignedMax().countLeadingZeros());
  if (Zeros.uge(Amount.getUnsignedMax()))
    return ConstantRange(min, max);

  // FIXME: implement the other tricky cases
  return ConstantRange(getBitWidth());
}
Пример #5
0
ConstantRange ConstantRange::makeICmpRegion(unsigned Pred,
                                            const ConstantRange &CR) {
  uint32_t W = CR.getBitWidth();
  switch (Pred) {
    default: assert(!"Invalid ICmp predicate to makeICmpRegion()");
    case ICmpInst::ICMP_EQ:
      return CR;
    case ICmpInst::ICMP_NE:
      if (CR.isSingleElement())
        return ConstantRange(CR.getUpper(), CR.getLower());
      return ConstantRange(W);
    case ICmpInst::ICMP_ULT:
      return ConstantRange(APInt::getMinValue(W), CR.getUnsignedMax());
    case ICmpInst::ICMP_SLT:
      return ConstantRange(APInt::getSignedMinValue(W), CR.getSignedMax());
    case ICmpInst::ICMP_ULE: {
      APInt UMax(CR.getUnsignedMax());
      if (UMax.isMaxValue())
        return ConstantRange(W);
      return ConstantRange(APInt::getMinValue(W), UMax + 1);
    }
    case ICmpInst::ICMP_SLE: {
      APInt SMax(CR.getSignedMax());
      if (SMax.isMaxSignedValue() || (SMax+1).isMaxSignedValue())
        return ConstantRange(W);
      return ConstantRange(APInt::getSignedMinValue(W), SMax + 1);
    }
    case ICmpInst::ICMP_UGT:
      return ConstantRange(CR.getUnsignedMin() + 1, APInt::getNullValue(W));
    case ICmpInst::ICMP_SGT:
      return ConstantRange(CR.getSignedMin() + 1,
                           APInt::getSignedMinValue(W));
    case ICmpInst::ICMP_UGE: {
      APInt UMin(CR.getUnsignedMin());
      if (UMin.isMinValue())
        return ConstantRange(W);
      return ConstantRange(UMin, APInt::getNullValue(W));
    }
    case ICmpInst::ICMP_SGE: {
      APInt SMin(CR.getSignedMin());
      if (SMin.isMinSignedValue())
        return ConstantRange(W);
      return ConstantRange(SMin, APInt::getSignedMinValue(W));
    }
  }
}
Пример #6
0
ConstantRange
ConstantRange::makeGuaranteedNoWrapRegion(Instruction::BinaryOps BinOp,
                                          const ConstantRange &Other,
                                          unsigned NoWrapKind) {
  typedef OverflowingBinaryOperator OBO;

  // Computes the intersection of CR0 and CR1.  It is different from
  // intersectWith in that the ConstantRange returned will only contain elements
  // in both CR0 and CR1 (i.e. SubsetIntersect(X, Y) is a *subset*, proper or
  // not, of both X and Y).
  auto SubsetIntersect =
      [](const ConstantRange &CR0, const ConstantRange &CR1) {
    return CR0.inverse().unionWith(CR1.inverse()).inverse();
  };

  assert(BinOp >= Instruction::BinaryOpsBegin &&
         BinOp < Instruction::BinaryOpsEnd && "Binary operators only!");

  assert((NoWrapKind == OBO::NoSignedWrap ||
          NoWrapKind == OBO::NoUnsignedWrap ||
          NoWrapKind == (OBO::NoUnsignedWrap | OBO::NoSignedWrap)) &&
         "NoWrapKind invalid!");

  unsigned BitWidth = Other.getBitWidth();
  if (BinOp != Instruction::Add)
    // Conservative answer: empty set
    return ConstantRange(BitWidth, false);

  if (auto *C = Other.getSingleElement())
    if (C->isMinValue())
      // Full set: nothing signed / unsigned wraps when added to 0.
      return ConstantRange(BitWidth);

  ConstantRange Result(BitWidth);

  if (NoWrapKind & OBO::NoUnsignedWrap)
    Result =
        SubsetIntersect(Result, ConstantRange(APInt::getNullValue(BitWidth),
                                              -Other.getUnsignedMax()));

  if (NoWrapKind & OBO::NoSignedWrap) {
    APInt SignedMin = Other.getSignedMin();
    APInt SignedMax = Other.getSignedMax();

    if (SignedMax.isStrictlyPositive())
      Result = SubsetIntersect(
          Result,
          ConstantRange(APInt::getSignedMinValue(BitWidth),
                        APInt::getSignedMinValue(BitWidth) - SignedMax));

    if (SignedMin.isNegative())
      Result = SubsetIntersect(
          Result, ConstantRange(APInt::getSignedMinValue(BitWidth) - SignedMin,
                                APInt::getSignedMinValue(BitWidth)));
  }

  return Result;
}
Пример #7
0
ConstantRange
ConstantRange::lshr(const ConstantRange &Amount) const {
  if (isEmptySet())
    return *this;
  
  APInt min = getUnsignedMax().lshr(Amount.getUnsignedMin());
  APInt max = getUnsignedMin().lshr(Amount.getUnsignedMax());
  return ConstantRange(min, max);
}
Пример #8
0
ConstantRange
ConstantRange::lshr(const ConstantRange &Other) const {
  if (isEmptySet() || Other.isEmptySet())
    return ConstantRange(getBitWidth(), /*isFullSet=*/false);
  
  APInt max = getUnsignedMax().lshr(Other.getUnsignedMin());
  APInt min = getUnsignedMin().lshr(Other.getUnsignedMax());
  if (min == max + 1)
    return ConstantRange(getBitWidth(), /*isFullSet=*/true);

  return ConstantRange(min, max + 1);
}
Пример #9
0
ConstantRange
ConstantRange::binaryAnd(const ConstantRange &Other) const {
  if (isEmptySet() || Other.isEmptySet())
    return ConstantRange(getBitWidth(), /*isFullSet=*/false);

  // TODO: replace this with something less conservative

  APInt umin = APIntOps::umin(Other.getUnsignedMax(), getUnsignedMax());
  if (umin.isAllOnesValue())
    return ConstantRange(getBitWidth(), /*isFullSet=*/true);
  return ConstantRange(APInt::getNullValue(getBitWidth()), umin + 1);
}
Пример #10
0
ConstantRange
ConstantRange::umin(const ConstantRange &Other) const {
  // X umin Y is: range(umin(X_umin, Y_umin),
  //                    umin(X_umax, Y_umax))
  if (isEmptySet() || Other.isEmptySet())
    return ConstantRange(getBitWidth(), /*isFullSet=*/false);
  APInt NewL = APIntOps::umin(getUnsignedMin(), Other.getUnsignedMin());
  APInt NewU = APIntOps::umin(getUnsignedMax(), Other.getUnsignedMax()) + 1;
  if (NewU == NewL)
    return ConstantRange(getBitWidth(), /*isFullSet=*/true);
  return ConstantRange(NewL, NewU);
}
Пример #11
0
ConstantRange
ConstantRange::multiply(const ConstantRange &Other) const {
  // TODO: If either operand is a single element and the multiply is known to
  // be non-wrapping, round the result min and max value to the appropriate
  // multiple of that element. If wrapping is possible, at least adjust the
  // range according to the greatest power-of-two factor of the single element.

  if (isEmptySet() || Other.isEmptySet())
    return ConstantRange(getBitWidth(), /*isFullSet=*/false);

  // Multiplication is signedness-independent. However different ranges can be
  // obtained depending on how the input ranges are treated. These different
  // ranges are all conservatively correct, but one might be better than the
  // other. We calculate two ranges; one treating the inputs as unsigned
  // and the other signed, then return the smallest of these ranges.

  // Unsigned range first.
  APInt this_min = getUnsignedMin().zext(getBitWidth() * 2);
  APInt this_max = getUnsignedMax().zext(getBitWidth() * 2);
  APInt Other_min = Other.getUnsignedMin().zext(getBitWidth() * 2);
  APInt Other_max = Other.getUnsignedMax().zext(getBitWidth() * 2);

  ConstantRange Result_zext = ConstantRange(this_min * Other_min,
                                            this_max * Other_max + 1);
  ConstantRange UR = Result_zext.truncate(getBitWidth());

  // If the unsigned range doesn't wrap, and isn't negative then it's a range
  // from one positive number to another which is as good as we can generate.
  // In this case, skip the extra work of generating signed ranges which aren't
  // going to be better than this range.
  if (!UR.isWrappedSet() &&
      (UR.getUpper().isNonNegative() || UR.getUpper().isMinSignedValue()))
    return UR;

  // Now the signed range. Because we could be dealing with negative numbers
  // here, the lower bound is the smallest of the cartesian product of the
  // lower and upper ranges; for example:
  //   [-1,4) * [-2,3) = min(-1*-2, -1*2, 3*-2, 3*2) = -6.
  // Similarly for the upper bound, swapping min for max.

  this_min = getSignedMin().sext(getBitWidth() * 2);
  this_max = getSignedMax().sext(getBitWidth() * 2);
  Other_min = Other.getSignedMin().sext(getBitWidth() * 2);
  Other_max = Other.getSignedMax().sext(getBitWidth() * 2);
  
  auto L = {this_min * Other_min, this_min * Other_max,
            this_max * Other_min, this_max * Other_max};
  auto Compare = [](const APInt &A, const APInt &B) { return A.slt(B); };
  ConstantRange Result_sext(std::min(L, Compare), std::max(L, Compare) + 1);
  ConstantRange SR = Result_sext.truncate(getBitWidth());

  return UR.isSizeStrictlySmallerThan(SR) ? UR : SR;
}
Пример #12
0
ConstantRange
ConstantRange::multiply(const ConstantRange &Other) const {
  if (isEmptySet() || Other.isEmptySet())
    return ConstantRange(getBitWidth(), /*isFullSet=*/false);
  if (isFullSet() || Other.isFullSet())
    return ConstantRange(getBitWidth(), /*isFullSet=*/true);

  APInt this_min = getUnsignedMin().zext(getBitWidth() * 2);
  APInt this_max = getUnsignedMax().zext(getBitWidth() * 2);
  APInt Other_min = Other.getUnsignedMin().zext(getBitWidth() * 2);
  APInt Other_max = Other.getUnsignedMax().zext(getBitWidth() * 2);

  ConstantRange Result_zext = ConstantRange(this_min * Other_min,
                                            this_max * Other_max + 1);
  return Result_zext.truncate(getBitWidth());
}
Пример #13
0
ConstantRange
ConstantRange::multiply(const ConstantRange &Other) const {
  // TODO: If either operand is a single element and the multiply is known to
  // be non-wrapping, round the result min and max value to the appropriate
  // multiple of that element. If wrapping is possible, at least adjust the
  // range according to the greatest power-of-two factor of the single element.

  if (isEmptySet() || Other.isEmptySet())
    return ConstantRange(getBitWidth(), /*isFullSet=*/false);

  APInt this_min = getUnsignedMin().zext(getBitWidth() * 2);
  APInt this_max = getUnsignedMax().zext(getBitWidth() * 2);
  APInt Other_min = Other.getUnsignedMin().zext(getBitWidth() * 2);
  APInt Other_max = Other.getUnsignedMax().zext(getBitWidth() * 2);

  ConstantRange Result_zext = ConstantRange(this_min * Other_min,
                                            this_max * Other_max + 1);
  return Result_zext.truncate(getBitWidth());
}
Пример #14
0
ConstantRange
ConstantRange::shl(const ConstantRange &Other) const {
  if (isEmptySet() || Other.isEmptySet())
    return ConstantRange(getBitWidth(), /*isFullSet=*/false);

  APInt max = getUnsignedMax();
  APInt Other_umax = Other.getUnsignedMax();

  // there's overflow!
  if (Other_umax.uge(max.countLeadingZeros()))
    return ConstantRange(getBitWidth(), /*isFullSet=*/true);

  // FIXME: implement the other tricky cases

  APInt min = getUnsignedMin();
  min <<= Other.getUnsignedMin();
  max <<= Other_umax;

  return ConstantRange(std::move(min), std::move(max) + 1);
}
Пример #15
0
MyConstantRange binaryAnd(const ConstantRange &Other) const {
  if (isEmptySet() || Other.isEmptySet())
    return MyConstantRange(getBitWidth(), /*isFullSet=*/false);

  if (!isWrappedSet() && !Other.isWrappedSet() && !isFullSet() && !Other.isFullSet()) {
    unsigned width1 = ((getUpper() - 1) ^ getLower()).logBase2() + 1;
    unsigned width2 = ((Other.getUpper() - 1) ^ Other.getLower()).logBase2() + 1;
    APInt res1 = getLower().lshr(width1) << width1;
    APInt res2 = Other.getLower().lshr(width2) << width2;
    APInt res_high1 = getLower();
    APInt res_high2 = Other.getLower();
    res_high1.setLowBits(width1);
    res_high2.setLowBits(width2);
    if ((res1 & res2).isNullValue() && (res_high1 & res_high2).isAllOnesValue()) {
        return MyConstantRange(getBitWidth(), /*isFullSet=*/true);
    }
    return MyConstantRange(res1 & res2, (res_high1 & res_high2) + 1);
  }

  APInt umin = APIntOps::umin(Other.getUnsignedMax(), getUnsignedMax());
  if (umin.isAllOnesValue())
    return MyConstantRange(getBitWidth(), /*isFullSet=*/true);
  return MyConstantRange(APInt::getNullValue(getBitWidth()), std::move(umin) + 1);
}
Пример #16
0
ConstantRange ConstantRange::makeAllowedICmpRegion(CmpInst::Predicate Pred,
                                                   const ConstantRange &CR) {
  if (CR.isEmptySet())
    return CR;

  uint32_t W = CR.getBitWidth();
  switch (Pred) {
  default:
    llvm_unreachable("Invalid ICmp predicate to makeAllowedICmpRegion()");
    case CmpInst::ICMP_EQ:
      return CR;
    case CmpInst::ICMP_NE:
      if (CR.isSingleElement())
        return ConstantRange(CR.getUpper(), CR.getLower());
      return ConstantRange(W);
    case CmpInst::ICMP_ULT: {
      APInt UMax(CR.getUnsignedMax());
      if (UMax.isMinValue())
        return ConstantRange(W, /* empty */ false);
      return ConstantRange(APInt::getMinValue(W), UMax);
    }
    case CmpInst::ICMP_SLT: {
      APInt SMax(CR.getSignedMax());
      if (SMax.isMinSignedValue())
        return ConstantRange(W, /* empty */ false);
      return ConstantRange(APInt::getSignedMinValue(W), SMax);
    }
    case CmpInst::ICMP_ULE: {
      APInt UMax(CR.getUnsignedMax());
      if (UMax.isMaxValue())
        return ConstantRange(W);
      return ConstantRange(APInt::getMinValue(W), UMax + 1);
    }
    case CmpInst::ICMP_SLE: {
      APInt SMax(CR.getSignedMax());
      if (SMax.isMaxSignedValue())
        return ConstantRange(W);
      return ConstantRange(APInt::getSignedMinValue(W), SMax + 1);
    }
    case CmpInst::ICMP_UGT: {
      APInt UMin(CR.getUnsignedMin());
      if (UMin.isMaxValue())
        return ConstantRange(W, /* empty */ false);
      return ConstantRange(UMin + 1, APInt::getNullValue(W));
    }
    case CmpInst::ICMP_SGT: {
      APInt SMin(CR.getSignedMin());
      if (SMin.isMaxSignedValue())
        return ConstantRange(W, /* empty */ false);
      return ConstantRange(SMin + 1, APInt::getSignedMinValue(W));
    }
    case CmpInst::ICMP_UGE: {
      APInt UMin(CR.getUnsignedMin());
      if (UMin.isMinValue())
        return ConstantRange(W);
      return ConstantRange(UMin, APInt::getNullValue(W));
    }
    case CmpInst::ICMP_SGE: {
      APInt SMin(CR.getSignedMin());
      if (SMin.isMinSignedValue())
        return ConstantRange(W);
      return ConstantRange(SMin, APInt::getSignedMinValue(W));
    }
  }
}