25#include "llvm/Config/llvm-config.h"
51 : Lower(
std::
move(V)), Upper(Lower + 1) {}
55 assert(Lower.getBitWidth() == Upper.getBitWidth() &&
56 "ConstantRange with unequal bit widths");
57 assert((Lower != Upper || (Lower.isMaxValue() || Lower.isMinValue())) &&
58 "Lower == Upper, but they aren't min or max value!");
63 if (
Known.hasConflict())
64 return getEmpty(
Known.getBitWidth());
65 if (
Known.isUnknown())
66 return getFull(
Known.getBitWidth());
70 if (!IsSigned ||
Known.isNegative() ||
Known.isNonNegative())
91 if (std::optional<unsigned> DifferentBit =
93 Known.Zero.clearLowBits(*DifferentBit + 1);
94 Known.One.clearLowBits(*DifferentBit + 1);
127 if (
UMax.isMinValue())
133 if (
SMax.isMinSignedValue())
143 if (
UMin.isMaxValue())
149 if (
SMin.isMaxSignedValue())
163 if (!Pred.hasSameSign())
165 return Result.intersectWith(
212 "Only for relational integer predicates!");
218 return FlippedSignednessPred;
237 RHS = *OnlyMissingElt;
271 if (
const APInt *R =
Other.getSingleElement())
299 unsigned BitWidth = V.getBitWidth();
301 return ConstantRange::getFull(V.getBitWidth());
313 unsigned BitWidth = V.getBitWidth();
315 return ConstantRange::getFull(
BitWidth);
324 if (V.isNegative()) {
337 unsigned NoWrapKind) {
342 assert((NoWrapKind == OBO::NoSignedWrap ||
343 NoWrapKind == OBO::NoUnsignedWrap) &&
344 "NoWrapKind invalid!");
346 bool Unsigned = NoWrapKind == OBO::NoUnsignedWrap;
353 case Instruction::Add: {
360 SMin.isNegative() ? SignedMinVal -
SMin : SignedMinVal,
361 SMax.isStrictlyPositive() ? SignedMinVal -
SMax : SignedMinVal);
364 case Instruction::Sub: {
371 SMax.isStrictlyPositive() ? SignedMinVal +
SMax : SignedMinVal,
372 SMin.isNegative() ? SignedMinVal +
SMin : SignedMinVal);
375 case Instruction::Mul:
386 case Instruction::Shl: {
411 unsigned NoWrapKind) {
415 (NoWrapKind == OBO::NoSignedWrap || NoWrapKind == OBO::NoUnsignedWrap) &&
416 "NoWrapKind invalid!");
418 bool Unsigned = NoWrapKind == OBO::NoUnsignedWrap;
421 case Instruction::Add: {
429 case Instruction::Sub: {
437 case Instruction::Mul:
441 case Instruction::Shl:
458 unsigned BitWidth = Mask.getBitWidth();
474 return Lower == Upper && Lower.isMaxValue();
478 return Lower == Upper && Lower.isMinValue();
482 return Lower.ugt(Upper) && !Upper.isZero();
486 return Lower.ugt(Upper);
490 return Lower.sgt(Upper) && !Upper.isMinSignedValue();
494 return Lower.sgt(Upper);
502 if (
Other.isFullSet())
504 return (Upper - Lower).ult(
Other.Upper -
Other.Lower);
514 return (Upper - Lower).ugt(MaxSize);
571 return Lower.ule(V) && V.ult(Upper);
572 return Lower.ule(V) || V.ult(Upper);
580 if (
Other.isUpperWrapped())
583 return Lower.ule(
Other.getLower()) &&
Other.getUpper().ule(Upper);
586 if (!
Other.isUpperWrapped())
587 return Other.getUpper().ule(Upper) ||
588 Lower.ule(
Other.getLower());
590 return Other.getUpper().ule(Upper) && Lower.ule(
Other.getLower());
643 "ConstantRange types don't agree!");
653 if (Lower.ult(CR.Lower)) {
656 if (Upper.ule(CR.Lower))
661 if (Upper.ult(CR.Upper))
670 if (Upper.ult(CR.Upper))
675 if (Lower.ult(CR.Upper))
684 if (CR.Lower.
ult(Upper)) {
687 if (CR.Upper.
ult(Upper))
692 if (CR.Upper.
ule(Lower))
699 if (CR.Lower.
ult(Lower)) {
702 if (CR.Upper.
ule(Lower))
715 if (CR.Upper.
ult(Upper)) {
718 if (CR.Lower.
ult(Upper))
723 if (CR.Lower.
ult(Lower))
730 if (CR.Upper.
ule(Lower)) {
733 if (CR.Lower.
ult(Lower))
749 "ConstantRange types don't agree!");
763 if (CR.Upper.
ult(Lower) || Upper.ult(CR.Lower))
767 APInt L = CR.Lower.
ult(Lower) ? CR.Lower : Lower;
768 APInt U = (CR.Upper - 1).ugt(Upper - 1) ? CR.Upper : Upper;
770 if (L.isZero() && U.isZero())
779 if (CR.Upper.
ule(Upper) || CR.Lower.
uge(Lower))
784 if (CR.Lower.
ule(Upper) && Lower.ule(CR.Upper))
792 if (Upper.ult(CR.Lower) && CR.Upper.
ult(Lower))
798 if (Upper.ult(CR.Lower) && Lower.ule(CR.Upper))
804 "ConstantRange::unionWith missed a case with one range wrapped");
810 if (CR.Lower.
ule(Upper) || Lower.ule(CR.Upper))
813 APInt L = CR.Lower.
ult(Lower) ? CR.Lower : Lower;
814 APInt U = CR.Upper.
ugt(Upper) ? CR.Upper : Upper;
819std::optional<ConstantRange>
828std::optional<ConstantRange>
842 case Instruction::Trunc:
844 case Instruction::SExt:
846 case Instruction::ZExt:
848 case Instruction::BitCast:
850 case Instruction::FPToUI:
851 case Instruction::FPToSI:
855 return getFull(ResultBitWidth);
856 case Instruction::UIToFP: {
861 if (ResultBitWidth > BW) {
862 Min = Min.
zext(ResultBitWidth);
863 Max = Max.zext(ResultBitWidth);
865 return getNonEmpty(std::move(Min), std::move(Max) + 1);
867 case Instruction::SIToFP: {
872 if (ResultBitWidth > BW) {
878 case Instruction::FPTrunc:
879 case Instruction::FPExt:
880 case Instruction::IntToPtr:
881 case Instruction::PtrToAddr:
882 case Instruction::PtrToInt:
883 case Instruction::AddrSpaceCast:
885 return getFull(ResultBitWidth);
893 if (DstTySize == SrcTySize)
895 assert(SrcTySize < DstTySize &&
"Not a value extension");
898 APInt LowerExt(DstTySize, 0);
900 LowerExt = Lower.
zext(DstTySize);
905 return ConstantRange(Lower.zext(DstTySize), Upper.zext(DstTySize));
912 if (DstTySize == SrcTySize)
914 assert(SrcTySize < DstTySize &&
"Not a value extension");
917 if (Upper.isMinSignedValue())
918 return ConstantRange(Lower.sext(DstTySize), Upper.zext(DstTySize));
925 return ConstantRange(Lower.sext(DstTySize), Upper.sext(DstTySize));
929 unsigned NoWrapKind)
const {
934 return getEmpty(DstTySize);
936 return getFull(DstTySize);
938 APInt LowerDiv(Lower), UpperDiv(Upper);
947 if (Upper.getActiveBits() > DstTySize)
948 return getFull(DstTySize);
957 if (Upper.countr_one() == DstTySize)
958 return getFull(DstTySize);
964 if (LowerDiv == UpperDiv)
970 if (LowerDiv.getActiveBits() > DstTySize) {
982 if (UpperDivWidth <= DstTySize)
984 UpperDiv.
trunc(DstTySize)).unionWith(Union);
991 if (UpperDivWidth == DstTySize + 1) {
994 if (UpperDiv.
ult(LowerDiv))
996 UpperDiv.
trunc(DstTySize)).unionWith(Union);
999 return getFull(DstTySize);
1004 if (SrcTySize > DstTySize)
1006 if (SrcTySize < DstTySize)
1013 if (SrcTySize > DstTySize)
1015 if (SrcTySize < DstTySize)
1025 case Instruction::Add:
1027 case Instruction::Sub:
1029 case Instruction::Mul:
1031 case Instruction::UDiv:
1033 case Instruction::SDiv:
1035 case Instruction::URem:
1037 case Instruction::SRem:
1039 case Instruction::Shl:
1041 case Instruction::LShr:
1043 case Instruction::AShr:
1045 case Instruction::And:
1047 case Instruction::Or:
1049 case Instruction::Xor:
1053 case Instruction::FAdd:
1055 case Instruction::FSub:
1057 case Instruction::FMul:
1067 unsigned NoWrapKind)
const {
1071 case Instruction::Add:
1073 case Instruction::Sub:
1075 case Instruction::Mul:
1077 case Instruction::Shl:
1098 switch (IntrinsicID) {
1099 case Intrinsic::uadd_sat:
1100 case Intrinsic::usub_sat:
1101 case Intrinsic::sadd_sat:
1102 case Intrinsic::ssub_sat:
1103 case Intrinsic::umin:
1104 case Intrinsic::umax:
1105 case Intrinsic::smin:
1106 case Intrinsic::smax:
1107 case Intrinsic::abs:
1108 case Intrinsic::ctlz:
1109 case Intrinsic::cttz:
1110 case Intrinsic::ctpop:
1119 switch (IntrinsicID) {
1120 case Intrinsic::uadd_sat:
1121 return Ops[0].uadd_sat(
Ops[1]);
1122 case Intrinsic::usub_sat:
1123 return Ops[0].usub_sat(
Ops[1]);
1124 case Intrinsic::sadd_sat:
1125 return Ops[0].sadd_sat(
Ops[1]);
1126 case Intrinsic::ssub_sat:
1127 return Ops[0].ssub_sat(
Ops[1]);
1128 case Intrinsic::umin:
1129 return Ops[0].umin(
Ops[1]);
1130 case Intrinsic::umax:
1131 return Ops[0].umax(
Ops[1]);
1132 case Intrinsic::smin:
1133 return Ops[0].smin(
Ops[1]);
1134 case Intrinsic::smax:
1135 return Ops[0].smax(
Ops[1]);
1136 case Intrinsic::abs: {
1137 const APInt *IntMinIsPoison =
Ops[1].getSingleElement();
1138 assert(IntMinIsPoison &&
"Must be known (immarg)");
1142 case Intrinsic::ctlz: {
1143 const APInt *ZeroIsPoison =
Ops[1].getSingleElement();
1144 assert(ZeroIsPoison &&
"Must be known (immarg)");
1148 case Intrinsic::cttz: {
1149 const APInt *ZeroIsPoison =
Ops[1].getSingleElement();
1150 assert(ZeroIsPoison &&
"Must be known (immarg)");
1154 case Intrinsic::ctpop:
1155 return Ops[0].ctpop();
1171 if (NewLower == NewUpper)
1175 if (
X.isSizeStrictlySmallerThan(*
this) ||
1176 X.isSizeStrictlySmallerThan(
Other))
1183 unsigned NoWrapKind,
1200 if (NoWrapKind & OBO::NoSignedWrap)
1203 if (NoWrapKind & OBO::NoUnsignedWrap)
1218 if (NewLower == NewUpper)
1222 if (
X.isSizeStrictlySmallerThan(*
this) ||
1223 X.isSizeStrictlySmallerThan(
Other))
1230 unsigned NoWrapKind,
1247 if (NoWrapKind & OBO::NoSignedWrap)
1250 if (NoWrapKind & OBO::NoUnsignedWrap) {
1260 unsigned NoWrapKind)
const {
1303 APInt Other_min =
Other.getUnsignedMin().zext(BW * 2);
1304 APInt Other_max =
Other.getUnsignedMax().zext(BW * 2);
1307 ConstantRange(this_min * Other_min, this_max * Other_max + 1);
1329 APInt Other_min =
Other.getSignedMin().sext(BW * 2);
1330 APInt Other_max =
Other.getSignedMax().sext(BW * 2);
1332 auto L = {this_min * Other_min, this_min * Other_max,
1333 this_max * Other_min, this_max * Other_max};
1334 auto Compare = [](
const APInt &
A,
const APInt &
B) {
return A.slt(
B); };
1335 ConstantRange Result_sext(std::min(L, Compare), std::max(L, Compare) + 1);
1347 !Result.isAllNonNegative()) {
1349 Result = Result.intersectWith(
1368 Max.smul_ov(OtherMin,
O3), Max.smul_ov(OtherMax, O4)};
1369 if (
O1 ||
O2 ||
O3 || O4)
1372 auto Compare = [](
const APInt &
A,
const APInt &
B) {
return A.slt(
B); };
1373 return getNonEmpty(std::min(Muls, Compare), std::max(Muls, Compare) + 1);
1434 if (
isEmptySet() || RHS.isEmptySet() || RHS.getUnsignedMax().isZero())
1439 APInt RHS_umin = RHS.getUnsignedMin();
1443 if (RHS.getUpper() == 1)
1444 RHS_umin = RHS.getLower();
1450 return getNonEmpty(std::move(Lower), std::move(Upper));
1461 auto [PosR, NegR] = RHS.splitPosNeg();
1464 if (!PosL.isEmptySet() && !PosR.isEmptySet())
1467 (PosL.Upper - 1).sdiv(PosR.Lower) + 1);
1469 if (!NegL.isEmptySet() && !NegR.isEmptySet()) {
1477 if (NegL.Lower.isMinSignedValue() && NegR.Upper.isZero()) {
1480 if (!NegR.Lower.isAllOnes()) {
1482 if (RHS.Lower.isAllOnes())
1484 AdjNegRUpper = RHS.Upper;
1487 AdjNegRUpper = NegR.Upper - 1;
1495 if (NegL.Upper != SignedMin + 1) {
1497 if (Upper == SignedMin + 1)
1499 AdjNegLLower = Lower;
1502 AdjNegLLower = NegL.Lower + 1;
1506 AdjNegLLower.
sdiv(NegR.Upper - 1) + 1));
1515 if (!PosL.isEmptySet() && !NegR.isEmptySet())
1517 NegRes =
ConstantRange((PosL.Upper - 1).sdiv(NegR.Upper - 1),
1518 PosL.Lower.sdiv(NegR.Lower) + 1);
1520 if (!NegL.isEmptySet() && !PosR.isEmptySet())
1524 (NegL.Upper - 1).sdiv(PosR.Upper - 1) + 1));
1530 if (
contains(Zero) && (!PosR.isEmptySet() || !NegR.isEmptySet()))
1536 if (
isEmptySet() || RHS.isEmptySet() || RHS.getUnsignedMax().isZero())
1539 if (
const APInt *RHSInt = RHS.getSingleElement()) {
1541 if (RHSInt->isZero())
1545 return {LHSInt->urem(*RHSInt)};
1561 if (
const APInt *RHSInt = RHS.getSingleElement()) {
1563 if (RHSInt->isZero())
1567 return {LHSInt->srem(*RHSInt)};
1585 if (MaxLHS.ult(MinAbsRHS))
1594 if (MaxLHS.isNegative()) {
1595 if (MinLHS.
ugt(-MinAbsRHS))
1641 if ((
LHS.isFullSet() ||
RHS.isFullSet()) ||
1642 (
LHS.isWrappedSet() ||
RHS.isWrappedSet()))
1645 auto LLo =
LHS.getLower();
1646 auto LHi =
LHS.getUpper() - 1;
1647 auto RLo =
RHS.getLower();
1648 auto RHi =
RHS.getUpper() - 1;
1651 auto Mask = ~((LLo ^ LHi) | (RLo ^ RHi) | (LLo ^ RLo));
1652 unsigned LeadingOnes = Mask.countLeadingOnes();
1653 Mask.clearLowBits(
BitWidth - LeadingOnes);
1657 unsigned LeadingOnes = ((BLo & BHi) | Mask).countLeadingOnes();
1658 unsigned StartBit =
BitWidth - LeadingOnes;
1659 ALo.clearLowBits(StartBit);
1663 auto LowerBoundByLHS = estimateBound(LLo, RLo, RHi);
1664 auto LowerBoundByRHS = estimateBound(RLo, LLo, LHi);
1682 bool IsDisjoint)
const {
1720 if (
Other.isSingleElement() &&
Other.getSingleElement()->isAllOnes())
1723 return Other.binaryNot();
1736 if ((~LHSKnown.
Zero).isSubsetOf(RHSKnown.
One))
1738 else if ((~RHSKnown.
Zero).isSubsetOf(LHSKnown.
One))
1750 if (
const APInt *RHS =
Other.getSingleElement()) {
1755 unsigned EqualLeadingBits = (Min ^ Max).
countl_zero();
1756 if (RHS->ule(EqualLeadingBits))
1757 return getNonEmpty(Min << *RHS, (Max << *RHS) + 1);
1767 Max <<=
Other.getUnsignedMin();
1773 if (OtherMax.
ugt(Max.countl_zero()))
1778 Min <<=
Other.getUnsignedMin();
1788 APInt LHSMin =
LHS.getUnsignedMin();
1789 unsigned RHSMin =
RHS.getUnsignedMin().getLimitedValue(
BitWidth);
1792 return ConstantRange::getEmpty(
BitWidth);
1793 APInt LHSMax =
LHS.getUnsignedMax();
1794 unsigned RHSMax =
RHS.getUnsignedMax().getLimitedValue(
BitWidth);
1795 APInt MaxShl = MinShl;
1797 if (RHSMin <= MaxShAmt)
1798 MaxShl = LHSMax << std::min(RHSMax, MaxShAmt);
1799 RHSMin = std::max(RHSMin, MaxShAmt + 1);
1801 if (RHSMin <= RHSMax)
1808 const APInt &LHSMax,
1815 return ConstantRange::getEmpty(
BitWidth);
1816 APInt MaxShl = MinShl;
1818 if (RHSMin <= MaxShAmt)
1819 MaxShl = LHSMax << std::min(RHSMax, MaxShAmt);
1820 RHSMin = std::max(RHSMin, MaxShAmt + 1);
1822 if (RHSMin <= RHSMax)
1829 const APInt &LHSMax,
1830 unsigned RHSMin,
unsigned RHSMax) {
1835 return ConstantRange::getEmpty(
BitWidth);
1836 APInt MinShl = MaxShl;
1838 if (RHSMin <= MaxShAmt)
1839 MinShl = LHSMin.
shl(std::min(RHSMax, MaxShAmt));
1840 RHSMin = std::max(RHSMin, MaxShAmt + 1);
1842 if (RHSMin <= RHSMax)
1850 unsigned RHSMin =
RHS.getUnsignedMin().getLimitedValue(
BitWidth);
1851 unsigned RHSMax =
RHS.getUnsignedMax().getLimitedValue(
BitWidth);
1866 unsigned NoWrapKind,
1871 switch (NoWrapKind) {
1934 min = std::move(PosMin);
1935 max = std::move(PosMax);
1938 min = std::move(NegMin);
1939 max = std::move(NegMax);
1942 min = std::move(NegMin);
1943 max = std::move(PosMax);
1954 return getNonEmpty(std::move(NewL), std::move(NewU));
1963 return getNonEmpty(std::move(NewL), std::move(NewU));
1972 return getNonEmpty(std::move(NewL), std::move(NewU));
1981 return getNonEmpty(std::move(NewL), std::move(NewU));
1990 return getNonEmpty(std::move(NewL), std::move(NewU));
2009 Max.smul_sat(OtherMin), Max.smul_sat(OtherMax)};
2010 auto Compare = [](
const APInt &
A,
const APInt &
B) {
return A.slt(
B); };
2011 return getNonEmpty(std::min(L, Compare), std::max(L, Compare) + 1);
2020 return getNonEmpty(std::move(NewL), std::move(NewU));
2028 APInt ShAmtMin =
Other.getUnsignedMin(), ShAmtMax =
Other.getUnsignedMax();
2030 APInt NewU = Max.sshl_sat(Max.isNegative() ? ShAmtMin : ShAmtMax) + 1;
2031 return getNonEmpty(std::move(NewL), std::move(NewU));
2049 if (Upper.isStrictlyPositive() || !Lower.isStrictlyPositive())
2064 if (IntMinIsPoison &&
SMin.isMinSignedValue()) {
2066 if (
SMax.isMinSignedValue())
2072 if (
SMin.isNonNegative())
2076 if (
SMax.isNegative())
2089 if (ZeroIsPoison &&
contains(Zero)) {
2125 "Unexpected wrapped set.");
2141 std::max(
BitWidth - LCPLength - 1,
Lower.countr_zero()) + 1));
2150 if (ZeroIsPoison &&
contains(Zero)) {
2157 if (Lower.isZero()) {
2166 }
else if (Upper == 1) {
2193 "Unexpected wrapped set.");
2202 unsigned LCPPopCount =
Lower.getHiBits(LCPLength).popcount();
2206 LCPPopCount + (
Lower.countr_zero() <
BitWidth - LCPLength ? 1 : 0);
2211 unsigned MaxBits = LCPPopCount + (
BitWidth - LCPLength) -
2212 (Max.countr_one() <
BitWidth - LCPLength ? 1 : 0);
2252 APInt OtherMin =
Other.getUnsignedMin(), OtherMax =
Other.getUnsignedMax();
2255 if (Min.
ugt(~OtherMin))
2257 if (Max.ugt(~OtherMax))
2268 APInt OtherMin =
Other.getSignedMin(), OtherMax =
Other.getSignedMax();
2276 Min.
sgt(SignedMax - OtherMin))
2278 if (Max.isNegative() && OtherMax.isNegative() &&
2279 Max.slt(SignedMin - OtherMax))
2282 if (Max.isNonNegative() && OtherMax.isNonNegative() &&
2283 Max.sgt(SignedMax - OtherMax))
2286 Min.
slt(SignedMin - OtherMin))
2298 APInt OtherMin =
Other.getUnsignedMin(), OtherMax =
Other.getUnsignedMax();
2301 if (Max.ult(OtherMin))
2303 if (Min.
ult(OtherMax))
2314 APInt OtherMin =
Other.getSignedMin(), OtherMax =
Other.getSignedMax();
2322 Min.
sgt(SignedMax + OtherMax))
2325 Max.slt(SignedMin + OtherMin))
2328 if (Max.isNonNegative() && OtherMin.
isNegative() &&
2329 Max.sgt(SignedMax + OtherMin))
2331 if (Min.
isNegative() && OtherMax.isNonNegative() &&
2332 Min.
slt(SignedMin + OtherMax))
2344 APInt OtherMin =
Other.getUnsignedMin(), OtherMax =
Other.getUnsignedMax();
2347 (void) Min.
umul_ov(OtherMin, Overflow);
2351 (void) Max.umul_ov(OtherMax, Overflow);
2364 OS <<
"[" << Lower <<
"," << Upper <<
")";
2367#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2374 const unsigned NumRanges = Ranges.getNumOperands() / 2;
2375 assert(NumRanges >= 1 &&
"Must have at least one range!");
2376 assert(Ranges.getNumOperands() % 2 == 0 &&
"Must be a sequence of pairs");
2381 ConstantRange CR(FirstLow->getValue(), FirstHigh->getValue());
2383 for (
unsigned i = 1; i < NumRanges; ++i) {
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
static APInt estimateBitMaskedAndLowerBound(const ConstantRange &LHS, const ConstantRange &RHS)
Estimate the 'bit-masked AND' operation's lower bound.
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...
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
Class for arbitrary precision integers.
LLVM_ABI APInt umul_ov(const APInt &RHS, bool &Overflow) const
LLVM_ABI APInt usub_sat(const APInt &RHS) const
LLVM_ABI 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.
LLVM_ABI 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.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
LLVM_ABI APInt sshl_ov(const APInt &Amt, bool &Overflow) const
LLVM_ABI APInt smul_sat(const APInt &RHS) const
unsigned countLeadingOnes() const
LLVM_ABI APInt sadd_sat(const APInt &RHS) const
bool sgt(const APInt &RHS) const
Signed greater than comparison.
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.
static APInt getMinValue(unsigned numBits)
Gets minimum unsigned value of APInt for a specific bit width.
bool isNegative() const
Determine sign of this APInt.
LLVM_ABI 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.
LLVM_ABI APInt sshl_sat(const APInt &RHS) const
LLVM_ABI APInt ushl_sat(const APInt &RHS) const
LLVM_ABI APInt ushl_ov(const APInt &Amt, bool &Overflow) const
unsigned countLeadingZeros() const
unsigned countl_one() const
Count the number of leading one bits.
LLVM_ABI 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.
LLVM_ABI 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.
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
APInt shl(unsigned shiftAmt) const
Left-shift function.
LLVM_ABI 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.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
LLVM_ABI APInt ssub_sat(const APInt &RHS) const
Represent a constant reference to an array (0 or more elements consecutively in memory),...
BinaryOps getOpcode() const
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
static bool isRelational(Predicate P)
Return true if the predicate is relational (not EQ or NE).
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
static bool isIntPredicate(Predicate P)
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
This class represents a range of values.
LLVM_ABI ConstantRange add(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an addition of a value in this ran...
LLVM_ABI bool isUpperSignWrapped() const
Return true if the (exclusive) upper bound wraps around the signed domain.
LLVM_ABI unsigned getActiveBits() const
Compute the maximal number of active bits needed to represent every value in this range.
LLVM_ABI 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...
LLVM_ABI 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...
LLVM_ABI bool getEquivalentICmp(CmpInst::Predicate &Pred, APInt &RHS) const
Set up Pred and RHS such that ConstantRange::makeExactICmpRegion(Pred, RHS) == *this.
LLVM_ABI ConstantRange umul_sat(const ConstantRange &Other) const
Perform an unsigned saturating multiplication of two constant ranges.
static LLVM_ABI 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...
LLVM_ABI 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.
LLVM_ABI 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 LLVM_ABI 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.
LLVM_ABI OverflowResult unsignedSubMayOverflow(const ConstantRange &Other) const
Return whether unsigned sub of the two ranges always/never overflows.
LLVM_ABI bool isAllNegative() const
Return true if all values in this range are negative.
LLVM_ABI OverflowResult unsignedAddMayOverflow(const ConstantRange &Other) const
Return whether unsigned add of the two ranges always/never overflows.
LLVM_ABI ConstantRange sqrtFloor() const
Calculate sqrtFloor range. See APInt::sqrtFloor().
LLVM_ABI ConstantRange urem(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an unsigned remainder operation of...
LLVM_ABI ConstantRange sshl_sat(const ConstantRange &Other) const
Perform a signed saturating left shift of this constant range by a value in Other.
LLVM_ABI ConstantRange smul_fast(const ConstantRange &Other) const
Return range of possible values for a signed multiplication of this and Other.
LLVM_ABI ConstantRange lshr(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a logical right shift of a value i...
LLVM_ABI KnownBits toKnownBits() const
Return known bits for values in this range.
LLVM_ABI 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...
LLVM_ABI ConstantRange umin(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an unsigned minimum of a value in ...
LLVM_ABI APInt getUnsignedMin() const
Return the smallest unsigned value contained in the ConstantRange.
LLVM_ABI ConstantRange difference(const ConstantRange &CR) const
Subtract the specified range from this range (aka relative complement of the sets).
LLVM_ABI bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
LLVM_ABI ConstantRange srem(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a signed remainder operation of a ...
LLVM_ABI bool icmp(CmpInst::Predicate Pred, const ConstantRange &Other) const
Does the predicate Pred hold between ranges this and Other?
LLVM_ABI ConstantRange sadd_sat(const ConstantRange &Other) const
Perform a signed saturating addition of two constant ranges.
LLVM_ABI ConstantRange ushl_sat(const ConstantRange &Other) const
Perform an unsigned saturating left shift of this constant range by a value in Other.
static LLVM_ABI ConstantRange intrinsic(Intrinsic::ID IntrinsicID, ArrayRef< ConstantRange > Ops)
Compute range of intrinsic result for the given operand ranges.
LLVM_ABI ConstantRange binaryOr(const ConstantRange &Other, bool IsDisjoint=false) const
Return a new range representing the possible values resulting from a binary-or of a value in this ran...
LLVM_ABI void dump() const
Allow printing from a debugger easily.
LLVM_ABI bool isEmptySet() const
Return true if this set contains no members.
LLVM_ABI ConstantRange smul_sat(const ConstantRange &Other) const
Perform a signed saturating multiplication of two constant ranges.
LLVM_ABI bool isAllPositive() const
Return true if all values in this range are positive.
LLVM_ABI 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...
LLVM_ABI ConstantRange zeroExtend(uint32_t BitWidth) const
Return a new range in the specified integer type, which must be strictly larger than the current type...
LLVM_ABI bool isSignWrappedSet() const
Return true if this set wraps around the signed domain.
LLVM_ABI bool isSizeLargerThan(uint64_t MaxSize) const
Compare set size of this range with Value.
LLVM_ABI APInt getSignedMin() const
Return the smallest signed value contained in the ConstantRange.
LLVM_ABI ConstantRange abs(bool IntMinIsPoison=false) const
Calculate absolute value range.
static LLVM_ABI bool isIntrinsicSupported(Intrinsic::ID IntrinsicID)
Returns true if ConstantRange calculations are supported for intrinsic with IntrinsicID.
static LLVM_ABI 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...
LLVM_ABI bool isWrappedSet() const
Return true if this set wraps around the unsigned domain.
LLVM_ABI ConstantRange usub_sat(const ConstantRange &Other) const
Perform an unsigned saturating subtraction of two constant ranges.
LLVM_ABI ConstantRange uadd_sat(const ConstantRange &Other) const
Perform an unsigned saturating addition of two constant ranges.
LLVM_ABI 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...
LLVM_ABI void print(raw_ostream &OS) const
Print out the bounds to a stream.
LLVM_ABI ConstantRange(uint32_t BitWidth, bool isFullSet)
Initialize a full or empty set for the specified bit width.
LLVM_ABI OverflowResult unsignedMulMayOverflow(const ConstantRange &Other) const
Return whether unsigned mul of the two ranges always/never overflows.
LLVM_ABI std::pair< ConstantRange, ConstantRange > splitPosNeg() const
Split the ConstantRange into positive and negative components, ignoring zero values.
LLVM_ABI 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.
LLVM_ABI ConstantRange truncate(uint32_t BitWidth, unsigned NoWrapKind=0) const
Return a new range in the specified integer type, which must be strictly smaller than the current typ...
LLVM_ABI ConstantRange ssub_sat(const ConstantRange &Other) const
Perform a signed saturating subtraction of two constant ranges.
LLVM_ABI bool isAllNonNegative() const
Return true if all values in this range are non-negative.
LLVM_ABI ConstantRange umax(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an unsigned maximum of a value in ...
LLVM_ABI 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 LLVM_ABI 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...
LLVM_ABI 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.
LLVM_ABI bool isUpperWrapped() const
Return true if the exclusive upper bound wraps around the unsigned domain.
LLVM_ABI ConstantRange multiply(const ConstantRange &Other, unsigned NoWrapKind=0) const
Return a new range representing the possible values resulting from a multiplication of a value in thi...
LLVM_ABI 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...
LLVM_ABI ConstantRange unionWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the union of this range with another range.
static LLVM_ABI 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...
LLVM_ABI ConstantRange inverse() const
Return a new range that is the logical not of the current set.
LLVM_ABI 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...
LLVM_ABI ConstantRange ashr(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a arithmetic right shift of a valu...
LLVM_ABI 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...
LLVM_ABI bool contains(const APInt &Val) const
Return true if the specified value is in the set.
static LLVM_ABI bool areInsensitiveToSignednessOfInvertedICmpPredicate(const ConstantRange &CR1, const ConstantRange &CR2)
Return true iff CR1 ult CR2 is equivalent to CR1 sge CR2.
LLVM_ABI OverflowResult signedAddMayOverflow(const ConstantRange &Other) const
Return whether signed add of the two ranges always/never overflows.
LLVM_ABI APInt getUnsignedMax() const
Return the largest unsigned value contained in the ConstantRange.
LLVM_ABI 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...
LLVM_ABI ConstantRange intersectWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the intersection of this range with another range.
LLVM_ABI 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 LLVM_ABI ConstantRange makeMaskNotEqualRange(const APInt &Mask, const APInt &C)
Initialize a range containing all values X that satisfy (X & Mask) / != C.
static LLVM_ABI bool areInsensitiveToSignednessOfICmpPredicate(const ConstantRange &CR1, const ConstantRange &CR2)
Return true iff CR1 ult CR2 is equivalent to CR1 slt CR2.
LLVM_ABI 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.
LLVM_ABI ConstantRange ctpop() const
Calculate ctpop range.
static LLVM_ABI 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)...
LLVM_ABI ConstantRange smin(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a signed minimum of a value in thi...
LLVM_ABI ConstantRange udiv(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an unsigned division of a value in...
LLVM_ABI 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.
LLVM_ABI ConstantRange binaryNot() const
Return a new range representing the possible values resulting from a binary-xor of a value in this ra...
LLVM_ABI ConstantRange smax(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a signed maximum of a value in thi...
LLVM_ABI 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...
LLVM_ABI OverflowResult signedSubMayOverflow(const ConstantRange &Other) const
Return whether signed sub of the two ranges always/never overflows.
LLVM_ABI ConstantRange ctlz(bool ZeroIsPoison=false) const
Calculate ctlz range.
LLVM_ABI ConstantRange sub(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a subtraction of a value in this r...
LLVM_ABI ConstantRange sextOrTrunc(uint32_t BitWidth) const
Make this range have the bit width given by BitWidth.
static LLVM_ABI 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.
LLVM_ABI bool isSizeStrictlySmallerThan(const ConstantRange &CR) const
Compare set size of this range with the range CR.
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.
LLVM_ABI 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...
LLVM_ABI APInt RoundingUDiv(const APInt &A, const APInt &B, APInt::Rounding RM)
Return A unsign-divided by B, rounded by the given rounding mode.
LLVM_ABI 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.
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
@ Known
Known to have no common set bits.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
constexpr NextUseDistance min(NextUseDistance A, NextUseDistance B)
@ O1
Optimize quickly without destroying debuggability.
@ O3
Optimize for fast execution as much as possible.
@ O2
Optimize for fast execution as much as possible without triggering significant incremental compile ti...
LLVM_ABI 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.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr NextUseDistance max(NextUseDistance A, NextUseDistance B)
@ 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.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
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.