コード例 #1
0
ファイル: ConstantRange.cpp プロジェクト: crabtw/llvm
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));
}
コード例 #2
0
ファイル: ConstantRange.cpp プロジェクト: delcypher/llvm
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);
}
コード例 #3
0
ファイル: SimplifyIndVar.cpp プロジェクト: filcab/llvm
/// Annotate the Shr in (X << IVOperand) >> C as exact using the
/// information from the IV's range. Returns true if anything changed, false
/// otherwise.
bool SimplifyIndvar::strengthenRightShift(BinaryOperator *BO,
                                          Value *IVOperand) {
  using namespace llvm::PatternMatch;

  if (BO->getOpcode() == Instruction::Shl) {
    bool Changed = false;
    ConstantRange IVRange = SE->getUnsignedRange(SE->getSCEV(IVOperand));
    for (auto *U : BO->users()) {
      const APInt *C;
      if (match(U,
                m_AShr(m_Shl(m_Value(), m_Specific(IVOperand)), m_APInt(C))) ||
          match(U,
                m_LShr(m_Shl(m_Value(), m_Specific(IVOperand)), m_APInt(C)))) {
        BinaryOperator *Shr = cast<BinaryOperator>(U);
        if (!Shr->isExact() && IVRange.getUnsignedMin().uge(*C)) {
          Shr->setIsExact(true);
          Changed = true;
        }
      }
    }
    return Changed;
  }

  return false;
}
コード例 #4
0
ファイル: ConstantRange.cpp プロジェクト: aaasz/SHP
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));
    }
  }
}
コード例 #5
0
ファイル: ConstantRange.cpp プロジェクト: aaasz/SHP
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);
}
コード例 #6
0
ファイル: ConstantRange.cpp プロジェクト: delcypher/llvm
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);
}
コード例 #7
0
ファイル: ConstantRange.cpp プロジェクト: delcypher/llvm
ConstantRange
ConstantRange::binaryOr(const ConstantRange &Other) const {
  if (isEmptySet() || Other.isEmptySet())
    return ConstantRange(getBitWidth(), /*isFullSet=*/false);

  // TODO: replace this with something less conservative

  APInt umax = APIntOps::umax(getUnsignedMin(), Other.getUnsignedMin());
  if (umax.isMinValue())
    return ConstantRange(getBitWidth(), /*isFullSet=*/true);
  return ConstantRange(umax, APInt::getNullValue(getBitWidth()));
}
コード例 #8
0
ファイル: ConstantRange.cpp プロジェクト: delcypher/llvm
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);
}
コード例 #9
0
ファイル: ConstantRange.cpp プロジェクト: crabtw/llvm
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;
}
コード例 #10
0
ファイル: ConstantRange.cpp プロジェクト: delcypher/llvm
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);
}
コード例 #11
0
ファイル: ConstantRange.cpp プロジェクト: aaasz/SHP
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());
}
コード例 #12
0
ファイル: ConstantRange.cpp プロジェクト: aaasz/SHP
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.cpp プロジェクト: crabtw/llvm
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
ファイル: ConstantRange.cpp プロジェクト: delcypher/llvm
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));
    }
  }
}