25#include "llvm/Config/llvm-config.h"
55 "ConstantRange with unequal bit widths");
57 "Lower == Upper, but they aren't min or max value!");
90 if (std::optional<unsigned> DifferentBit =
115 if (
UMax.isMinValue())
121 if (
SMax.isMinSignedValue())
131 if (
UMin.isMaxValue())
137 if (
SMin.isMaxSignedValue())
192 "Only for relational integer predicates!");
198 return FlippedSignednessPred;
217 RHS = *OnlyMissingElt;
251 if (
const APInt *R =
Other.getSingleElement())
279 unsigned BitWidth = V.getBitWidth();
281 return ConstantRange::getFull(V.getBitWidth());
293 unsigned BitWidth = V.getBitWidth();
295 return ConstantRange::getFull(
BitWidth);
304 if (V.isNegative()) {
317 unsigned NoWrapKind) {
322 assert((NoWrapKind == OBO::NoSignedWrap ||
323 NoWrapKind == OBO::NoUnsignedWrap) &&
324 "NoWrapKind invalid!");
326 bool Unsigned = NoWrapKind == OBO::NoUnsignedWrap;
333 case Instruction::Add: {
340 SMin.isNegative() ? SignedMinVal -
SMin : SignedMinVal,
341 SMax.isStrictlyPositive() ? SignedMinVal -
SMax : SignedMinVal);
344 case Instruction::Sub: {
351 SMax.isStrictlyPositive() ? SignedMinVal +
SMax : SignedMinVal,
352 SMin.isNegative() ? SignedMinVal +
SMin : SignedMinVal);
355 case Instruction::Mul:
366 case Instruction::Shl: {
391 unsigned NoWrapKind) {
399 unsigned BitWidth = Mask.getBitWidth();
423 return Lower.
ugt(Upper) && !Upper.
isZero();
427 return Lower.
ugt(Upper);
435 return Lower.
sgt(Upper);
443 if (
Other.isFullSet())
445 return (Upper - Lower).ult(
Other.Upper -
Other.Lower);
455 return (Upper - Lower).ugt(MaxSize);
512 return Lower.
ule(V) && V.ult(Upper);
513 return Lower.
ule(V) || V.ult(Upper);
521 if (
Other.isUpperWrapped())
524 return Lower.
ule(
Other.getLower()) &&
Other.getUpper().ule(Upper);
527 if (!
Other.isUpperWrapped())
528 return Other.getUpper().ule(Upper) ||
531 return Other.getUpper().ule(Upper) && Lower.
ule(
Other.getLower());
584 "ConstantRange types don't agree!");
594 if (Lower.
ult(CR.Lower)) {
597 if (Upper.
ule(CR.Lower))
602 if (Upper.
ult(CR.Upper))
611 if (Upper.
ult(CR.Upper))
616 if (Lower.
ult(CR.Upper))
625 if (CR.Lower.
ult(Upper)) {
628 if (CR.Upper.
ult(Upper))
633 if (CR.Upper.
ule(Lower))
640 if (CR.Lower.
ult(Lower)) {
643 if (CR.Upper.
ule(Lower))
656 if (CR.Upper.
ult(Upper)) {
659 if (CR.Lower.
ult(Upper))
664 if (CR.Lower.
ult(Lower))
671 if (CR.Upper.
ule(Lower)) {
674 if (CR.Lower.
ult(Lower))
690 "ConstantRange types don't agree!");
704 if (CR.Upper.
ult(Lower) || Upper.
ult(CR.Lower))
708 APInt L = CR.Lower.
ult(Lower) ? CR.Lower : Lower;
709 APInt U = (CR.Upper - 1).ugt(Upper - 1) ? CR.Upper : Upper;
711 if (L.isZero() && U.isZero())
720 if (CR.Upper.
ule(Upper) || CR.Lower.
uge(Lower))
725 if (CR.Lower.
ule(Upper) && Lower.
ule(CR.Upper))
733 if (Upper.
ult(CR.Lower) && CR.Upper.
ult(Lower))
739 if (Upper.
ult(CR.Lower) && Lower.
ule(CR.Upper))
745 "ConstantRange::unionWith missed a case with one range wrapped");
751 if (CR.Lower.
ule(Upper) || Lower.
ule(CR.Upper))
754 APInt L = CR.Lower.
ult(Lower) ? CR.Lower : Lower;
755 APInt U = CR.Upper.
ugt(Upper) ? CR.Upper : Upper;
760std::optional<ConstantRange>
769std::optional<ConstantRange>
783 case Instruction::Trunc:
785 case Instruction::SExt:
787 case Instruction::ZExt:
789 case Instruction::BitCast:
791 case Instruction::FPToUI:
792 case Instruction::FPToSI:
796 return getFull(ResultBitWidth);
797 case Instruction::UIToFP: {
802 if (ResultBitWidth > BW) {
803 Min = Min.
zext(ResultBitWidth);
804 Max = Max.zext(ResultBitWidth);
806 return getNonEmpty(std::move(Min), std::move(Max) + 1);
808 case Instruction::SIToFP: {
813 if (ResultBitWidth > BW) {
819 case Instruction::FPTrunc:
820 case Instruction::FPExt:
821 case Instruction::IntToPtr:
822 case Instruction::PtrToInt:
823 case Instruction::AddrSpaceCast:
825 return getFull(ResultBitWidth);
833 assert(SrcTySize < DstTySize &&
"Not a value extension");
836 APInt LowerExt(DstTySize, 0);
838 LowerExt = Lower.
zext(DstTySize);
850 assert(SrcTySize < DstTySize &&
"Not a value extension");
867 return getEmpty(DstTySize);
869 return getFull(DstTySize);
871 APInt LowerDiv(Lower), UpperDiv(Upper);
881 return getFull(DstTySize);
888 if (LowerDiv == UpperDiv)
893 if (LowerDiv.getActiveBits() > DstTySize) {
901 if (UpperDivWidth <= DstTySize)
906 if (UpperDivWidth == DstTySize + 1) {
909 if (UpperDiv.
ult(LowerDiv))
914 return getFull(DstTySize);
919 if (SrcTySize > DstTySize)
921 if (SrcTySize < DstTySize)
928 if (SrcTySize > DstTySize)
930 if (SrcTySize < DstTySize)
940 case Instruction::Add:
942 case Instruction::Sub:
944 case Instruction::Mul:
946 case Instruction::UDiv:
948 case Instruction::SDiv:
950 case Instruction::URem:
952 case Instruction::SRem:
954 case Instruction::Shl:
956 case Instruction::LShr:
958 case Instruction::AShr:
960 case Instruction::And:
962 case Instruction::Or:
964 case Instruction::Xor:
968 case Instruction::FAdd:
970 case Instruction::FSub:
972 case Instruction::FMul:
982 unsigned NoWrapKind)
const {
986 case Instruction::Add:
988 case Instruction::Sub:
990 case Instruction::Mul:
992 case Instruction::Shl:
1002 switch (IntrinsicID) {
1003 case Intrinsic::uadd_sat:
1004 case Intrinsic::usub_sat:
1005 case Intrinsic::sadd_sat:
1006 case Intrinsic::ssub_sat:
1007 case Intrinsic::umin:
1008 case Intrinsic::umax:
1009 case Intrinsic::smin:
1010 case Intrinsic::smax:
1011 case Intrinsic::abs:
1012 case Intrinsic::ctlz:
1013 case Intrinsic::cttz:
1014 case Intrinsic::ctpop:
1023 switch (IntrinsicID) {
1024 case Intrinsic::uadd_sat:
1025 return Ops[0].uadd_sat(Ops[1]);
1026 case Intrinsic::usub_sat:
1027 return Ops[0].usub_sat(Ops[1]);
1028 case Intrinsic::sadd_sat:
1029 return Ops[0].sadd_sat(Ops[1]);
1030 case Intrinsic::ssub_sat:
1031 return Ops[0].ssub_sat(Ops[1]);
1032 case Intrinsic::umin:
1033 return Ops[0].umin(Ops[1]);
1034 case Intrinsic::umax:
1035 return Ops[0].umax(Ops[1]);
1036 case Intrinsic::smin:
1037 return Ops[0].smin(Ops[1]);
1038 case Intrinsic::smax:
1039 return Ops[0].smax(Ops[1]);
1040 case Intrinsic::abs: {
1041 const APInt *IntMinIsPoison = Ops[1].getSingleElement();
1042 assert(IntMinIsPoison &&
"Must be known (immarg)");
1046 case Intrinsic::ctlz: {
1047 const APInt *ZeroIsPoison = Ops[1].getSingleElement();
1048 assert(ZeroIsPoison &&
"Must be known (immarg)");
1052 case Intrinsic::cttz: {
1053 const APInt *ZeroIsPoison = Ops[1].getSingleElement();
1054 assert(ZeroIsPoison &&
"Must be known (immarg)");
1058 case Intrinsic::ctpop:
1059 return Ops[0].ctpop();
1075 if (NewLower == NewUpper)
1079 if (
X.isSizeStrictlySmallerThan(*
this) ||
1080 X.isSizeStrictlySmallerThan(
Other))
1087 unsigned NoWrapKind,
1104 if (NoWrapKind & OBO::NoSignedWrap)
1107 if (NoWrapKind & OBO::NoUnsignedWrap)
1122 if (NewLower == NewUpper)
1126 if (
X.isSizeStrictlySmallerThan(*
this) ||
1127 X.isSizeStrictlySmallerThan(
Other))
1134 unsigned NoWrapKind,
1151 if (NoWrapKind & OBO::NoSignedWrap)
1154 if (NoWrapKind & OBO::NoUnsignedWrap) {
1200 this_max * Other_max + 1);
1222 auto L = {this_min * Other_min, this_min * Other_max,
1223 this_max * Other_min, this_max * Other_max};
1224 auto Compare = [](
const APInt &
A,
const APInt &
B) {
return A.slt(
B); };
1225 ConstantRange Result_sext(std::min(L, Compare), std::max(L, Compare) + 1);
1233 unsigned NoWrapKind,
1251 !Result.isAllNonNegative()) {
1253 Result = Result.intersectWith(
1271 bool O1, O2, O3, O4;
1272 auto Muls = {Min.
smul_ov(OtherMin, O1), Min.
smul_ov(OtherMax, O2),
1273 Max.smul_ov(OtherMin, O3), Max.smul_ov(OtherMax, O4)};
1274 if (O1 || O2 || O3 || O4)
1277 auto Compare = [](
const APInt &
A,
const APInt &
B) {
return A.slt(
B); };
1278 return getNonEmpty(std::min(Muls, Compare), std::max(Muls, Compare) + 1);
1344 APInt RHS_umin =
RHS.getUnsignedMin();
1348 if (
RHS.getUpper() == 1)
1349 RHS_umin =
RHS.getLower();
1378 (PosL.Upper - 1).
sdiv(PosR.Lower) + 1);
1393 if (
RHS.Lower.isAllOnes())
1395 AdjNegRUpper =
RHS.Upper;
1398 AdjNegRUpper = NegR.Upper - 1;
1406 if (NegL.Upper != SignedMin + 1) {
1408 if (Upper == SignedMin + 1)
1410 AdjNegLLower = Lower;
1413 AdjNegLLower = NegL.Lower + 1;
1417 AdjNegLLower.
sdiv(NegR.Upper - 1) + 1));
1428 NegRes =
ConstantRange((PosL.Upper - 1).sdiv(NegR.Upper - 1),
1429 PosL.Lower.
sdiv(NegR.Lower) + 1);
1435 (NegL.Upper - 1).
sdiv(PosR.Upper - 1) + 1));
1450 if (
const APInt *RHSInt =
RHS.getSingleElement()) {
1452 if (RHSInt->isZero())
1456 return {LHSInt->urem(*RHSInt)};
1472 if (
const APInt *RHSInt =
RHS.getSingleElement()) {
1474 if (RHSInt->isZero())
1478 return {LHSInt->srem(*RHSInt)};
1496 if (MaxLHS.ult(MinAbsRHS))
1505 if (MaxLHS.isNegative()) {
1506 if (MinLHS.
ugt(-MinAbsRHS))
1557 if (
Other.isSingleElement() &&
Other.getSingleElement()->isAllOnes())
1560 return Other.binaryNot();
1573 if ((~LHSKnown.
Zero).isSubsetOf(RHSKnown.
One))
1575 else if ((~RHSKnown.
Zero).isSubsetOf(LHSKnown.
One))
1592 unsigned EqualLeadingBits = (Min ^ Max).
countl_zero();
1593 if (
RHS->ule(EqualLeadingBits))
1604 Max <<=
Other.getUnsignedMin();
1610 if (OtherMax.
ugt(Max.countl_zero()))
1615 Min <<=
Other.getUnsignedMin();
1625 APInt LHSMin =
LHS.getUnsignedMin();
1626 unsigned RHSMin =
RHS.getUnsignedMin().getLimitedValue(
BitWidth);
1629 return ConstantRange::getEmpty(
BitWidth);
1630 APInt LHSMax =
LHS.getUnsignedMax();
1631 unsigned RHSMax =
RHS.getUnsignedMax().getLimitedValue(
BitWidth);
1632 APInt MaxShl = MinShl;
1634 if (RHSMin <= MaxShAmt)
1635 MaxShl = LHSMax << std::min(RHSMax, MaxShAmt);
1636 RHSMin = std::max(RHSMin, MaxShAmt + 1);
1638 if (RHSMin <= RHSMax)
1645 const APInt &LHSMax,
1652 return ConstantRange::getEmpty(
BitWidth);
1653 APInt MaxShl = MinShl;
1655 if (RHSMin <= MaxShAmt)
1656 MaxShl = LHSMax << std::min(RHSMax, MaxShAmt);
1657 RHSMin = std::max(RHSMin, MaxShAmt + 1);
1659 if (RHSMin <= RHSMax)
1666 const APInt &LHSMax,
1667 unsigned RHSMin,
unsigned RHSMax) {
1672 return ConstantRange::getEmpty(
BitWidth);
1673 APInt MinShl = MaxShl;
1675 if (RHSMin <= MaxShAmt)
1676 MinShl = LHSMin.
shl(std::min(RHSMax, MaxShAmt));
1677 RHSMin = std::max(RHSMin, MaxShAmt + 1);
1679 if (RHSMin <= RHSMax)
1687 unsigned RHSMin =
RHS.getUnsignedMin().getLimitedValue(
BitWidth);
1688 unsigned RHSMax =
RHS.getUnsignedMax().getLimitedValue(
BitWidth);
1703 unsigned NoWrapKind,
1708 switch (NoWrapKind) {
1791 return getNonEmpty(std::move(NewL), std::move(NewU));
1800 return getNonEmpty(std::move(NewL), std::move(NewU));
1809 return getNonEmpty(std::move(NewL), std::move(NewU));
1818 return getNonEmpty(std::move(NewL), std::move(NewU));
1827 return getNonEmpty(std::move(NewL), std::move(NewU));
1846 Max.smul_sat(OtherMin), Max.smul_sat(OtherMax)};
1847 auto Compare = [](
const APInt &
A,
const APInt &
B) {
return A.slt(
B); };
1848 return getNonEmpty(std::min(L, Compare), std::max(L, Compare) + 1);
1857 return getNonEmpty(std::move(NewL), std::move(NewU));
1865 APInt ShAmtMin =
Other.getUnsignedMin(), ShAmtMax =
Other.getUnsignedMax();
1867 APInt NewU = Max.sshl_sat(Max.isNegative() ? ShAmtMin : ShAmtMax) + 1;
1868 return getNonEmpty(std::move(NewL), std::move(NewU));
1901 if (IntMinIsPoison &&
SMin.isMinSignedValue()) {
1903 if (
SMax.isMinSignedValue())
1909 if (
SMin.isNonNegative())
1913 if (
SMax.isNegative())
1926 if (ZeroIsPoison &&
contains(Zero)) {
1962 "Unexpected wrapped set.");
1972 unsigned LCPLength = (
Lower ^ (
Upper - 1)).countl_zero();
1978 std::max(
BitWidth - LCPLength - 1,
Lower.countr_zero()) + 1));
1987 if (ZeroIsPoison &&
contains(Zero)) {
2003 }
else if (Upper == 1) {
2030 "Unexpected wrapped set.");
2039 unsigned LCPPopCount =
Lower.getHiBits(LCPLength).popcount();
2043 LCPPopCount + (
Lower.countr_zero() <
BitWidth - LCPLength ? 1 : 0);
2048 unsigned MaxBits = LCPPopCount + (
BitWidth - LCPLength) -
2049 (Max.countr_one() <
BitWidth - LCPLength ? 1 : 0);
2079 APInt OtherMin =
Other.getUnsignedMin(), OtherMax =
Other.getUnsignedMax();
2082 if (Min.
ugt(~OtherMin))
2084 if (Max.ugt(~OtherMax))
2095 APInt OtherMin =
Other.getSignedMin(), OtherMax =
Other.getSignedMax();
2103 Min.
sgt(SignedMax - OtherMin))
2105 if (Max.isNegative() && OtherMax.isNegative() &&
2106 Max.slt(SignedMin - OtherMax))
2109 if (Max.isNonNegative() && OtherMax.isNonNegative() &&
2110 Max.sgt(SignedMax - OtherMax))
2113 Min.
slt(SignedMin - OtherMin))
2125 APInt OtherMin =
Other.getUnsignedMin(), OtherMax =
Other.getUnsignedMax();
2128 if (Max.ult(OtherMin))
2130 if (Min.
ult(OtherMax))
2141 APInt OtherMin =
Other.getSignedMin(), OtherMax =
Other.getSignedMax();
2149 Min.
sgt(SignedMax + OtherMax))
2152 Max.slt(SignedMin + OtherMin))
2155 if (Max.isNonNegative() && OtherMin.
isNegative() &&
2156 Max.sgt(SignedMax + OtherMin))
2158 if (Min.
isNegative() && OtherMax.isNonNegative() &&
2159 Min.
slt(SignedMin + OtherMax))
2171 APInt OtherMin =
Other.getUnsignedMin(), OtherMax =
Other.getUnsignedMax();
2174 (void) Min.
umul_ov(OtherMin, Overflow);
2178 (void) Max.umul_ov(OtherMax, Overflow);
2191 OS <<
"[" << Lower <<
"," << Upper <<
")";
2194#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2201 const unsigned NumRanges = Ranges.getNumOperands() / 2;
2202 assert(NumRanges >= 1 &&
"Must have at least one range!");
2203 assert(Ranges.getNumOperands() % 2 == 0 &&
"Must be a sequence of pairs");
2205 auto *FirstLow = mdconst::extract<ConstantInt>(Ranges.getOperand(0));
2206 auto *FirstHigh = mdconst::extract<ConstantInt>(Ranges.getOperand(1));
2208 ConstantRange CR(FirstLow->getValue(), FirstHigh->getValue());
2210 for (
unsigned i = 1; i < NumRanges; ++i) {
2211 auto *
Low = mdconst::extract<ConstantInt>(Ranges.getOperand(2 * i + 0));
2212 auto *
High = mdconst::extract<ConstantInt>(Ranges.getOperand(2 * i + 1));
This file implements a class to represent arbitrary precision integral constant values and operations...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
static ConstantRange computeShlNUW(const ConstantRange &LHS, const ConstantRange &RHS)
static ConstantRange getUnsignedPopCountRange(const APInt &Lower, const APInt &Upper)
static ConstantRange computeShlNSW(const ConstantRange &LHS, const ConstantRange &RHS)
static ConstantRange makeExactMulNUWRegion(const APInt &V)
Exact mul nuw region for single element RHS.
static ConstantRange computeShlNSWWithNNegLHS(const APInt &LHSMin, const APInt &LHSMax, unsigned RHSMin, unsigned RHSMax)
static ConstantRange makeExactMulNSWRegion(const APInt &V)
Exact mul nsw region for single element RHS.
static ConstantRange getPreferredRange(const ConstantRange &CR1, const ConstantRange &CR2, ConstantRange::PreferredRangeType Type)
static ConstantRange getUnsignedCountTrailingZerosRange(const APInt &Lower, const APInt &Upper)
static ConstantRange computeShlNSWWithNegLHS(const APInt &LHSMin, const APInt &LHSMax, unsigned RHSMin, unsigned RHSMax)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Class for arbitrary precision integers.
APInt umul_ov(const APInt &RHS, bool &Overflow) const
APInt usub_sat(const APInt &RHS) const
APInt udiv(const APInt &RHS) const
Unsigned division operation.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
APInt zext(unsigned width) const
Zero extend to a new width.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
bool isMinSignedValue() const
Determine if this is the smallest signed value.
unsigned getActiveBits() const
Compute the number of active bits in the value.
APInt trunc(unsigned width) const
Truncate to new width.
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
APInt sshl_ov(const APInt &Amt, bool &Overflow) const
APInt smul_sat(const APInt &RHS) const
unsigned countLeadingOnes() const
APInt sadd_sat(const APInt &RHS) const
bool sgt(const APInt &RHS) const
Signed greater than comparison.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
bool isMinValue() const
Determine if this is the smallest unsigned value.
static APInt getMinValue(unsigned numBits)
Gets minimum unsigned value of APInt for a specific bit width.
bool isNegative() const
Determine sign of this APInt.
APInt sdiv(const APInt &RHS) const
Signed division function for APInt.
bool sle(const APInt &RHS) const
Signed less or equal comparison.
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
APInt sshl_sat(const APInt &RHS) const
APInt ushl_sat(const APInt &RHS) const
APInt ushl_ov(const APInt &Amt, bool &Overflow) const
unsigned countLeadingZeros() const
bool isStrictlyPositive() const
Determine if this APInt Value is positive.
unsigned countl_one() const
Count the number of leading one bits.
void clearLowBits(unsigned loBits)
Set bottom loBits bits to 0.
APInt uadd_sat(const APInt &RHS) const
APInt ashr(unsigned ShiftAmt) const
Arithmetic right-shift function.
void setAllBits()
Set every bit to 1.
bool getBoolValue() const
Convert APInt to a boolean value.
APInt smul_ov(const APInt &RHS, bool &Overflow) const
bool isNonNegative() const
Determine if this APInt Value is non-negative (>= 0)
bool ule(const APInt &RHS) const
Unsigned less or equal comparison.
APInt sext(unsigned width) const
Sign extend to a new width.
APInt shl(unsigned shiftAmt) const
Left-shift function.
APInt umul_sat(const APInt &RHS) const
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
bool slt(const APInt &RHS) const
Signed less than comparison.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
bool sge(const APInt &RHS) const
Signed greater or equal comparison.
static APInt getBitsSetFrom(unsigned numBits, unsigned loBit)
Constructs an APInt value that has a contiguous range of bits set.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
unsigned countr_one() const
Count the number of trailing one bits.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
void clearSignBit()
Set the sign bit to 0.
APInt ssub_sat(const APInt &RHS) const
bool isMaxValue() const
Determine if this is the largest unsigned value.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ ICMP_ULT
unsigned less than
@ ICMP_SGE
signed greater or equal
@ ICMP_ULE
unsigned less or equal
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
bool isIntPredicate() const
bool isRelational() const
Return true if the predicate is relational (not EQ or NE).
This class represents a range of values.
ConstantRange multiply(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a multiplication of a value in thi...
ConstantRange add(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an addition of a value in this ran...
bool isUpperSignWrapped() const
Return true if the (exclusive) upper bound wraps around the signed domain.
unsigned getActiveBits() const
Compute the maximal number of active bits needed to represent every value in this range.
ConstantRange zextOrTrunc(uint32_t BitWidth) const
Make this range have the bit width given by BitWidth.
PreferredRangeType
If represented precisely, the result of some range operations may consist of multiple disjoint ranges...
std::optional< ConstantRange > exactUnionWith(const ConstantRange &CR) const
Union the two ranges and return the result if it can be represented exactly, otherwise return std::nu...
bool getEquivalentICmp(CmpInst::Predicate &Pred, APInt &RHS) const
Set up Pred and RHS such that ConstantRange::makeExactICmpRegion(Pred, RHS) == *this.
ConstantRange umul_sat(const ConstantRange &Other) const
Perform an unsigned saturating multiplication of two constant ranges.
static CmpInst::Predicate getEquivalentPredWithFlippedSignedness(CmpInst::Predicate Pred, const ConstantRange &CR1, const ConstantRange &CR2)
If the comparison between constant ranges this and Other is insensitive to the signedness of the comp...
ConstantRange subtract(const APInt &CI) const
Subtract the specified constant from the endpoints of this constant range.
const APInt * getSingleElement() const
If this set contains a single element, return it, otherwise return null.
ConstantRange binaryXor(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a binary-xor of a value in this ra...
const APInt * getSingleMissingElement() const
If this set contains all but a single element, return it, otherwise return null.
static ConstantRange fromKnownBits(const KnownBits &Known, bool IsSigned)
Initialize a range based on a known bits constraint.
const APInt & getLower() const
Return the lower value for this range.
OverflowResult unsignedSubMayOverflow(const ConstantRange &Other) const
Return whether unsigned sub of the two ranges always/never overflows.
bool isAllNegative() const
Return true if all values in this range are negative.
ConstantRange truncate(uint32_t BitWidth) const
Return a new range in the specified integer type, which must be strictly smaller than the current typ...
OverflowResult unsignedAddMayOverflow(const ConstantRange &Other) const
Return whether unsigned add of the two ranges always/never overflows.
ConstantRange urem(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an unsigned remainder operation of...
ConstantRange sshl_sat(const ConstantRange &Other) const
Perform a signed saturating left shift of this constant range by a value in Other.
ConstantRange smul_fast(const ConstantRange &Other) const
Return range of possible values for a signed multiplication of this and Other.
ConstantRange lshr(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a logical right shift of a value i...
KnownBits toKnownBits() const
Return known bits for values in this range.
ConstantRange castOp(Instruction::CastOps CastOp, uint32_t BitWidth) const
Return a new range representing the possible values resulting from an application of the specified ca...
ConstantRange umin(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an unsigned minimum of a value in ...
APInt getUnsignedMin() const
Return the smallest unsigned value contained in the ConstantRange.
ConstantRange difference(const ConstantRange &CR) const
Subtract the specified range from this range (aka relative complement of the sets).
bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
ConstantRange srem(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a signed remainder operation of a ...
bool icmp(CmpInst::Predicate Pred, const ConstantRange &Other) const
Does the predicate Pred hold between ranges this and Other? NOTE: false does not mean that inverse pr...
ConstantRange sadd_sat(const ConstantRange &Other) const
Perform a signed saturating addition of two constant ranges.
ConstantRange ushl_sat(const ConstantRange &Other) const
Perform an unsigned saturating left shift of this constant range by a value in Other.
static ConstantRange intrinsic(Intrinsic::ID IntrinsicID, ArrayRef< ConstantRange > Ops)
Compute range of intrinsic result for the given operand ranges.
void dump() const
Allow printing from a debugger easily.
bool isEmptySet() const
Return true if this set contains no members.
ConstantRange smul_sat(const ConstantRange &Other) const
Perform a signed saturating multiplication of two constant ranges.
bool isAllPositive() const
Return true if all values in this range are positive.
ConstantRange shl(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a left shift of a value in this ra...
ConstantRange zeroExtend(uint32_t BitWidth) const
Return a new range in the specified integer type, which must be strictly larger than the current type...
bool isSignWrappedSet() const
Return true if this set wraps around the signed domain.
bool isSizeLargerThan(uint64_t MaxSize) const
Compare set size of this range with Value.
APInt getSignedMin() const
Return the smallest signed value contained in the ConstantRange.
ConstantRange abs(bool IntMinIsPoison=false) const
Calculate absolute value range.
static bool isIntrinsicSupported(Intrinsic::ID IntrinsicID)
Returns true if ConstantRange calculations are supported for intrinsic with IntrinsicID.
static ConstantRange makeSatisfyingICmpRegion(CmpInst::Predicate Pred, const ConstantRange &Other)
Produce the largest range such that all values in the returned range satisfy the given predicate with...
bool isWrappedSet() const
Return true if this set wraps around the unsigned domain.
ConstantRange usub_sat(const ConstantRange &Other) const
Perform an unsigned saturating subtraction of two constant ranges.
ConstantRange uadd_sat(const ConstantRange &Other) const
Perform an unsigned saturating addition of two constant ranges.
ConstantRange overflowingBinaryOp(Instruction::BinaryOps BinOp, const ConstantRange &Other, unsigned NoWrapKind) const
Return a new range representing the possible values resulting from an application of the specified ov...
void print(raw_ostream &OS) const
Print out the bounds to a stream.
ConstantRange(uint32_t BitWidth, bool isFullSet)
Initialize a full or empty set for the specified bit width.
OverflowResult unsignedMulMayOverflow(const ConstantRange &Other) const
Return whether unsigned mul of the two ranges always/never overflows.
ConstantRange subWithNoWrap(const ConstantRange &Other, unsigned NoWrapKind, PreferredRangeType RangeType=Smallest) const
Return a new range representing the possible values resulting from an subtraction with wrap type NoWr...
bool isSingleElement() const
Return true if this set contains exactly one member.
ConstantRange ssub_sat(const ConstantRange &Other) const
Perform a signed saturating subtraction of two constant ranges.
bool isAllNonNegative() const
Return true if all values in this range are non-negative.
ConstantRange umax(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an unsigned maximum of a value in ...
ConstantRange signExtend(uint32_t BitWidth) const
Return a new range in the specified integer type, which must be strictly larger than the current type...
static ConstantRange makeAllowedICmpRegion(CmpInst::Predicate Pred, const ConstantRange &Other)
Produce the smallest range such that all values that may satisfy the given predicate with any value c...
ConstantRange sdiv(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a signed division of a value in th...
const APInt & getUpper() const
Return the upper value for this range.
bool isUpperWrapped() const
Return true if the exclusive upper bound wraps around the unsigned domain.
ConstantRange shlWithNoWrap(const ConstantRange &Other, unsigned NoWrapKind, PreferredRangeType RangeType=Smallest) const
Return a new range representing the possible values resulting from a left shift with wrap type NoWrap...
ConstantRange unionWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the union of this range with another range.
static ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, const APInt &Other)
Produce the exact range such that all values in the returned range satisfy the given predicate with a...
ConstantRange inverse() const
Return a new range that is the logical not of the current set.
std::optional< ConstantRange > exactIntersectWith(const ConstantRange &CR) const
Intersect the two ranges and return the result if it can be represented exactly, otherwise return std...
ConstantRange ashr(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a arithmetic right shift of a valu...
ConstantRange binaryAnd(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a binary-and of a value in this ra...
bool contains(const APInt &Val) const
Return true if the specified value is in the set.
static bool areInsensitiveToSignednessOfInvertedICmpPredicate(const ConstantRange &CR1, const ConstantRange &CR2)
Return true iff CR1 ult CR2 is equivalent to CR1 sge CR2.
OverflowResult signedAddMayOverflow(const ConstantRange &Other) const
Return whether signed add of the two ranges always/never overflows.
APInt getUnsignedMax() const
Return the largest unsigned value contained in the ConstantRange.
ConstantRange addWithNoWrap(const ConstantRange &Other, unsigned NoWrapKind, PreferredRangeType RangeType=Smallest) const
Return a new range representing the possible values resulting from an addition with wrap type NoWrapK...
ConstantRange intersectWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the intersection of this range with another range.
APInt getSignedMax() const
Return the largest signed value contained in the ConstantRange.
OverflowResult
Represents whether an operation on the given constant range is known to always or never overflow.
@ NeverOverflows
Never overflows.
@ AlwaysOverflowsHigh
Always overflows in the direction of signed/unsigned max value.
@ AlwaysOverflowsLow
Always overflows in the direction of signed/unsigned min value.
@ MayOverflow
May or may not overflow.
static ConstantRange makeMaskNotEqualRange(const APInt &Mask, const APInt &C)
Initialize a range containing all values X that satisfy (X & Mask) != C.
static bool areInsensitiveToSignednessOfICmpPredicate(const ConstantRange &CR1, const ConstantRange &CR2)
Return true iff CR1 ult CR2 is equivalent to CR1 slt CR2.
ConstantRange cttz(bool ZeroIsPoison=false) const
Calculate cttz range.
static ConstantRange getNonEmpty(APInt Lower, APInt Upper)
Create non-empty constant range with the given bounds.
ConstantRange ctpop() const
Calculate ctpop range.
static ConstantRange makeGuaranteedNoWrapRegion(Instruction::BinaryOps BinOp, const ConstantRange &Other, unsigned NoWrapKind)
Produce the largest range containing all X such that "X BinOp Y" is guaranteed not to wrap (overflow)...
ConstantRange smin(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a signed minimum of a value in thi...
ConstantRange udiv(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an unsigned division of a value in...
unsigned getMinSignedBits() const
Compute the maximal number of bits needed to represent every value in this signed range.
uint32_t getBitWidth() const
Get the bit width of this ConstantRange.
ConstantRange binaryNot() const
Return a new range representing the possible values resulting from a binary-xor of a value in this ra...
ConstantRange smax(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a signed maximum of a value in thi...
ConstantRange binaryOp(Instruction::BinaryOps BinOp, const ConstantRange &Other) const
Return a new range representing the possible values resulting from an application of the specified bi...
ConstantRange binaryOr(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a binary-or of a value in this ran...
OverflowResult signedSubMayOverflow(const ConstantRange &Other) const
Return whether signed sub of the two ranges always/never overflows.
ConstantRange ctlz(bool ZeroIsPoison=false) const
Calculate ctlz range.
ConstantRange sub(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a subtraction of a value in this r...
ConstantRange sextOrTrunc(uint32_t BitWidth) const
Make this range have the bit width given by BitWidth.
static ConstantRange makeExactNoWrapRegion(Instruction::BinaryOps BinOp, const APInt &Other, unsigned NoWrapKind)
Produce the range that contains X if and only if "X BinOp Other" does not wrap.
bool isSizeStrictlySmallerThan(const ConstantRange &CR) const
Compare set size of this range with the range CR.
ConstantRange multiplyWithNoWrap(const ConstantRange &Other, unsigned NoWrapKind, PreferredRangeType RangeType=Smallest) const
Return a new range representing the possible values resulting from a multiplication with wrap type No...
Predicate getFlippedSignednessPredicate() const
For example, SLT->ULT, ULT->SLT, SLE->ULE, ULE->SLE, EQ->EQ.
Utility class for integer operators which may exhibit overflow - Add, Sub, Mul, and Shl.
The instances of the Type class are immutable: once they are created, they are never changed.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
std::optional< unsigned > GetMostSignificantDifferentBit(const APInt &A, const APInt &B)
Compare two values, and if they are different, return the position of the most significant bit that i...
APInt RoundingUDiv(const APInt &A, const APInt &B, APInt::Rounding RM)
Return A unsign-divided by B, rounded by the given rounding mode.
APInt RoundingSDiv(const APInt &A, const APInt &B, APInt::Rounding RM)
Return A sign-divided by B, rounded by the given rounding mode.
const APInt & smin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be signed.
const APInt & smax(const APInt &A, const APInt &B)
Determine the larger of two APInts considered to be signed.
const APInt & umin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be unsigned.
const APInt & umax(const APInt &A, const APInt &B)
Determine the larger of two APInts considered to be unsigned.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)
Parse out a conservative ConstantRange from !range metadata.
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
@ UMin
Unsigned integer min implemented in terms of select(cmp()).
@ SMax
Signed integer max implemented in terms of select(cmp()).
@ SMin
Signed integer min implemented in terms of select(cmp()).
@ UMax
Unsigned integer max implemented in terms of select(cmp()).
constexpr unsigned BitWidth
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Implement std::hash so that hash_code can be used in STL containers.
static KnownBits makeConstant(const APInt &C)
Create known bits from a known constant.
bool isNonNegative() const
Returns true if this value is known to be non-negative.
bool isUnknown() const
Returns true if we don't know any bits.
bool hasConflict() const
Returns true if there is conflicting information.
unsigned getBitWidth() const
Get the bit width of this value.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
APInt getMinValue() const
Return the minimal unsigned value possible given these KnownBits.
bool isNegative() const
Returns true if this value is known to be negative.