1de6cce22SEugene Zelenko //===- ConstantRange.cpp - ConstantRange implementation -------------------===//
28cd041efSChandler Carruth //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
68cd041efSChandler Carruth //
78cd041efSChandler Carruth //===----------------------------------------------------------------------===//
88cd041efSChandler Carruth //
98cd041efSChandler Carruth // Represent a range of possible values that may occur when the program is run
108cd041efSChandler Carruth // for an integral value.  This keeps track of a lower and upper bound for the
118cd041efSChandler Carruth // constant, which MAY wrap around the end of the numeric range.  To do this, it
128cd041efSChandler Carruth // keeps track of a [lower, upper) bound, which specifies an interval just like
138cd041efSChandler Carruth // STL iterators.  When used with boolean values, the following are important
148cd041efSChandler Carruth // ranges (other integral ranges use min/max values for special range values):
158cd041efSChandler Carruth //
168cd041efSChandler Carruth //  [F, F) = {}     = Empty set
178cd041efSChandler Carruth //  [T, F) = {T}
188cd041efSChandler Carruth //  [F, T) = {F}
198cd041efSChandler Carruth //  [T, T) = {F, T} = Full set
208cd041efSChandler Carruth //
218cd041efSChandler Carruth //===----------------------------------------------------------------------===//
228cd041efSChandler Carruth 
23de6cce22SEugene Zelenko #include "llvm/ADT/APInt.h"
24432a3883SNico Weber #include "llvm/Config/llvm-config.h"
258cd041efSChandler Carruth #include "llvm/IR/ConstantRange.h"
26de6cce22SEugene Zelenko #include "llvm/IR/Constants.h"
276bda14b3SChandler Carruth #include "llvm/IR/InstrTypes.h"
286bda14b3SChandler Carruth #include "llvm/IR/Instruction.h"
29897bdca4SNikita Popov #include "llvm/IR/Intrinsics.h"
30de6cce22SEugene Zelenko #include "llvm/IR/Metadata.h"
316bda14b3SChandler Carruth #include "llvm/IR/Operator.h"
32de6cce22SEugene Zelenko #include "llvm/Support/Compiler.h"
338cd041efSChandler Carruth #include "llvm/Support/Debug.h"
34de6cce22SEugene Zelenko #include "llvm/Support/ErrorHandling.h"
35ef2d9799SNikita Popov #include "llvm/Support/KnownBits.h"
368cd041efSChandler Carruth #include "llvm/Support/raw_ostream.h"
37de6cce22SEugene Zelenko #include <algorithm>
38de6cce22SEugene Zelenko #include <cassert>
39de6cce22SEugene Zelenko #include <cstdint>
40de6cce22SEugene Zelenko 
418cd041efSChandler Carruth using namespace llvm;
428cd041efSChandler Carruth 
ConstantRange(uint32_t BitWidth,bool Full)43ee4f22dcSCraig Topper ConstantRange::ConstantRange(uint32_t BitWidth, bool Full)
44ee4f22dcSCraig Topper     : Lower(Full ? APInt::getMaxValue(BitWidth) : APInt::getMinValue(BitWidth)),
45ee4f22dcSCraig Topper       Upper(Lower) {}
468cd041efSChandler Carruth 
ConstantRange(APInt V)4737df0180SCraig Topper ConstantRange::ConstantRange(APInt V)
488cd041efSChandler Carruth     : Lower(std::move(V)), Upper(Lower + 1) {}
498cd041efSChandler Carruth 
ConstantRange(APInt L,APInt U)5037df0180SCraig Topper ConstantRange::ConstantRange(APInt L, APInt U)
518cd041efSChandler Carruth     : Lower(std::move(L)), Upper(std::move(U)) {
528cd041efSChandler Carruth   assert(Lower.getBitWidth() == Upper.getBitWidth() &&
538cd041efSChandler Carruth          "ConstantRange with unequal bit widths");
548cd041efSChandler Carruth   assert((Lower != Upper || (Lower.isMaxValue() || Lower.isMinValue())) &&
558cd041efSChandler Carruth          "Lower == Upper, but they aren't min or max value!");
568cd041efSChandler Carruth }
578cd041efSChandler Carruth 
fromKnownBits(const KnownBits & Known,bool IsSigned)58ef2d9799SNikita Popov ConstantRange ConstantRange::fromKnownBits(const KnownBits &Known,
59ef2d9799SNikita Popov                                            bool IsSigned) {
605e7b62deSNikita Popov   assert(!Known.hasConflict() && "Expected valid KnownBits");
615e7b62deSNikita Popov 
62ef2d9799SNikita Popov   if (Known.isUnknown())
63977934f0SNikita Popov     return getFull(Known.getBitWidth());
64ef2d9799SNikita Popov 
65ef2d9799SNikita Popov   // For unsigned ranges, or signed ranges with known sign bit, create a simple
66ef2d9799SNikita Popov   // range between the smallest and largest possible value.
67ef2d9799SNikita Popov   if (!IsSigned || Known.isNegative() || Known.isNonNegative())
689a20c79dSRoman Lebedev     return ConstantRange(Known.getMinValue(), Known.getMaxValue() + 1);
69ef2d9799SNikita Popov 
70ef2d9799SNikita Popov   // If we don't know the sign bit, pick the lower bound as a negative number
71ef2d9799SNikita Popov   // and the upper bound as a non-negative one.
729a20c79dSRoman Lebedev   APInt Lower = Known.getMinValue(), Upper = Known.getMaxValue();
73ef2d9799SNikita Popov   Lower.setSignBit();
74ef2d9799SNikita Popov   Upper.clearSignBit();
75ef2d9799SNikita Popov   return ConstantRange(Lower, Upper + 1);
76ef2d9799SNikita Popov }
77ef2d9799SNikita Popov 
toKnownBits() const788ab819adSNikita Popov KnownBits ConstantRange::toKnownBits() const {
798ab819adSNikita Popov   // TODO: We could return conflicting known bits here, but consumers are
808ab819adSNikita Popov   // likely not prepared for that.
818ab819adSNikita Popov   if (isEmptySet())
828ab819adSNikita Popov     return KnownBits(getBitWidth());
838ab819adSNikita Popov 
848ab819adSNikita Popov   // We can only retain the top bits that are the same between min and max.
858ab819adSNikita Popov   APInt Min = getUnsignedMin();
868ab819adSNikita Popov   APInt Max = getUnsignedMax();
878ab819adSNikita Popov   KnownBits Known = KnownBits::makeConstant(Min);
888ab819adSNikita Popov   if (Optional<unsigned> DifferentBit =
898ab819adSNikita Popov           APIntOps::GetMostSignificantDifferentBit(Min, Max)) {
908ab819adSNikita Popov     Known.Zero.clearLowBits(*DifferentBit + 1);
918ab819adSNikita Popov     Known.One.clearLowBits(*DifferentBit + 1);
928ab819adSNikita Popov   }
938ab819adSNikita Popov   return Known;
948ab819adSNikita Popov }
958ab819adSNikita Popov 
makeAllowedICmpRegion(CmpInst::Predicate Pred,const ConstantRange & CR)967182d36fSSanjoy Das ConstantRange ConstantRange::makeAllowedICmpRegion(CmpInst::Predicate Pred,
978cd041efSChandler Carruth                                                    const ConstantRange &CR) {
988cd041efSChandler Carruth   if (CR.isEmptySet())
998cd041efSChandler Carruth     return CR;
1008cd041efSChandler Carruth 
1018cd041efSChandler Carruth   uint32_t W = CR.getBitWidth();
1028cd041efSChandler Carruth   switch (Pred) {
1037182d36fSSanjoy Das   default:
1047182d36fSSanjoy Das     llvm_unreachable("Invalid ICmp predicate to makeAllowedICmpRegion()");
1058cd041efSChandler Carruth   case CmpInst::ICMP_EQ:
1068cd041efSChandler Carruth     return CR;
1078cd041efSChandler Carruth   case CmpInst::ICMP_NE:
1088cd041efSChandler Carruth     if (CR.isSingleElement())
1098cd041efSChandler Carruth       return ConstantRange(CR.getUpper(), CR.getLower());
110977934f0SNikita Popov     return getFull(W);
1118cd041efSChandler Carruth   case CmpInst::ICMP_ULT: {
1128cd041efSChandler Carruth     APInt UMax(CR.getUnsignedMax());
1138cd041efSChandler Carruth     if (UMax.isMinValue())
114977934f0SNikita Popov       return getEmpty(W);
115b792025bSCraig Topper     return ConstantRange(APInt::getMinValue(W), std::move(UMax));
1168cd041efSChandler Carruth   }
1178cd041efSChandler Carruth   case CmpInst::ICMP_SLT: {
1188cd041efSChandler Carruth     APInt SMax(CR.getSignedMax());
1198cd041efSChandler Carruth     if (SMax.isMinSignedValue())
120977934f0SNikita Popov       return getEmpty(W);
121b792025bSCraig Topper     return ConstantRange(APInt::getSignedMinValue(W), std::move(SMax));
1228cd041efSChandler Carruth   }
123dbc3fbafSNikita Popov   case CmpInst::ICMP_ULE:
124dbc3fbafSNikita Popov     return getNonEmpty(APInt::getMinValue(W), CR.getUnsignedMax() + 1);
125dbc3fbafSNikita Popov   case CmpInst::ICMP_SLE:
126dbc3fbafSNikita Popov     return getNonEmpty(APInt::getSignedMinValue(W), CR.getSignedMax() + 1);
1278cd041efSChandler Carruth   case CmpInst::ICMP_UGT: {
1288cd041efSChandler Carruth     APInt UMin(CR.getUnsignedMin());
1298cd041efSChandler Carruth     if (UMin.isMaxValue())
130977934f0SNikita Popov       return getEmpty(W);
131735f4671SChris Lattner     return ConstantRange(std::move(UMin) + 1, APInt::getZero(W));
1328cd041efSChandler Carruth   }
1338cd041efSChandler Carruth   case CmpInst::ICMP_SGT: {
1348cd041efSChandler Carruth     APInt SMin(CR.getSignedMin());
1358cd041efSChandler Carruth     if (SMin.isMaxSignedValue())
136977934f0SNikita Popov       return getEmpty(W);
137b792025bSCraig Topper     return ConstantRange(std::move(SMin) + 1, APInt::getSignedMinValue(W));
1388cd041efSChandler Carruth   }
139dbc3fbafSNikita Popov   case CmpInst::ICMP_UGE:
140735f4671SChris Lattner     return getNonEmpty(CR.getUnsignedMin(), APInt::getZero(W));
141dbc3fbafSNikita Popov   case CmpInst::ICMP_SGE:
142dbc3fbafSNikita Popov     return getNonEmpty(CR.getSignedMin(), APInt::getSignedMinValue(W));
1438cd041efSChandler Carruth   }
1448cd041efSChandler Carruth }
1458cd041efSChandler Carruth 
makeSatisfyingICmpRegion(CmpInst::Predicate Pred,const ConstantRange & CR)1467182d36fSSanjoy Das ConstantRange ConstantRange::makeSatisfyingICmpRegion(CmpInst::Predicate Pred,
1477182d36fSSanjoy Das                                                       const ConstantRange &CR) {
1487182d36fSSanjoy Das   // Follows from De-Morgan's laws:
1497182d36fSSanjoy Das   //
1507182d36fSSanjoy Das   // ~(~A union ~B) == A intersect B.
1517182d36fSSanjoy Das   //
1527182d36fSSanjoy Das   return makeAllowedICmpRegion(CmpInst::getInversePredicate(Pred), CR)
1537182d36fSSanjoy Das       .inverse();
1547182d36fSSanjoy Das }
1557182d36fSSanjoy Das 
makeExactICmpRegion(CmpInst::Predicate Pred,const APInt & C)156569eaec5SBalaram Makam ConstantRange ConstantRange::makeExactICmpRegion(CmpInst::Predicate Pred,
157569eaec5SBalaram Makam                                                  const APInt &C) {
158569eaec5SBalaram Makam   // Computes the exact range that is equal to both the constant ranges returned
159569eaec5SBalaram Makam   // by makeAllowedICmpRegion and makeSatisfyingICmpRegion. This is always true
160569eaec5SBalaram Makam   // when RHS is a singleton such as an APInt and so the assert is valid.
161569eaec5SBalaram Makam   // However for non-singleton RHS, for example ult [2,5) makeAllowedICmpRegion
162569eaec5SBalaram Makam   // returns [0,4) but makeSatisfyICmpRegion returns [0,2).
163569eaec5SBalaram Makam   //
164569eaec5SBalaram Makam   assert(makeAllowedICmpRegion(Pred, C) == makeSatisfyingICmpRegion(Pred, C));
165569eaec5SBalaram Makam   return makeAllowedICmpRegion(Pred, C);
166569eaec5SBalaram Makam }
167569eaec5SBalaram Makam 
areInsensitiveToSignednessOfICmpPredicate(const ConstantRange & CR1,const ConstantRange & CR2)16803a4f1f3SRoman Lebedev bool ConstantRange::areInsensitiveToSignednessOfICmpPredicate(
16903a4f1f3SRoman Lebedev     const ConstantRange &CR1, const ConstantRange &CR2) {
17003a4f1f3SRoman Lebedev   if (CR1.isEmptySet() || CR2.isEmptySet())
17103a4f1f3SRoman Lebedev     return true;
17203a4f1f3SRoman Lebedev 
17303a4f1f3SRoman Lebedev   return (CR1.isAllNonNegative() && CR2.isAllNonNegative()) ||
17403a4f1f3SRoman Lebedev          (CR1.isAllNegative() && CR2.isAllNegative());
17503a4f1f3SRoman Lebedev }
17603a4f1f3SRoman Lebedev 
areInsensitiveToSignednessOfInvertedICmpPredicate(const ConstantRange & CR1,const ConstantRange & CR2)17703a4f1f3SRoman Lebedev bool ConstantRange::areInsensitiveToSignednessOfInvertedICmpPredicate(
17803a4f1f3SRoman Lebedev     const ConstantRange &CR1, const ConstantRange &CR2) {
17903a4f1f3SRoman Lebedev   if (CR1.isEmptySet() || CR2.isEmptySet())
18003a4f1f3SRoman Lebedev     return true;
18103a4f1f3SRoman Lebedev 
18203a4f1f3SRoman Lebedev   return (CR1.isAllNonNegative() && CR2.isAllNegative()) ||
18303a4f1f3SRoman Lebedev          (CR1.isAllNegative() && CR2.isAllNonNegative());
18403a4f1f3SRoman Lebedev }
18503a4f1f3SRoman Lebedev 
getEquivalentPredWithFlippedSignedness(CmpInst::Predicate Pred,const ConstantRange & CR1,const ConstantRange & CR2)18603a4f1f3SRoman Lebedev CmpInst::Predicate ConstantRange::getEquivalentPredWithFlippedSignedness(
18703a4f1f3SRoman Lebedev     CmpInst::Predicate Pred, const ConstantRange &CR1,
18803a4f1f3SRoman Lebedev     const ConstantRange &CR2) {
18903a4f1f3SRoman Lebedev   assert(CmpInst::isIntPredicate(Pred) && CmpInst::isRelational(Pred) &&
19003a4f1f3SRoman Lebedev          "Only for relational integer predicates!");
19103a4f1f3SRoman Lebedev 
19203a4f1f3SRoman Lebedev   CmpInst::Predicate FlippedSignednessPred =
19303a4f1f3SRoman Lebedev       CmpInst::getFlippedSignednessPredicate(Pred);
19403a4f1f3SRoman Lebedev 
19503a4f1f3SRoman Lebedev   if (areInsensitiveToSignednessOfICmpPredicate(CR1, CR2))
19603a4f1f3SRoman Lebedev     return FlippedSignednessPred;
19703a4f1f3SRoman Lebedev 
19803a4f1f3SRoman Lebedev   if (areInsensitiveToSignednessOfInvertedICmpPredicate(CR1, CR2))
19903a4f1f3SRoman Lebedev     return CmpInst::getInversePredicate(FlippedSignednessPred);
20003a4f1f3SRoman Lebedev 
20103a4f1f3SRoman Lebedev   return CmpInst::Predicate::BAD_ICMP_PREDICATE;
20203a4f1f3SRoman Lebedev }
20303a4f1f3SRoman Lebedev 
getEquivalentICmp(CmpInst::Predicate & Pred,APInt & RHS,APInt & Offset) const2049f0194beSNikita Popov void ConstantRange::getEquivalentICmp(CmpInst::Predicate &Pred,
2059f0194beSNikita Popov                                       APInt &RHS, APInt &Offset) const {
2069f0194beSNikita Popov   Offset = APInt(getBitWidth(), 0);
207590614c1SSanjoy Das   if (isFullSet() || isEmptySet()) {
208590614c1SSanjoy Das     Pred = isEmptySet() ? CmpInst::ICMP_ULT : CmpInst::ICMP_UGE;
209590614c1SSanjoy Das     RHS = APInt(getBitWidth(), 0);
210c7d3291bSSanjoy Das   } else if (auto *OnlyElt = getSingleElement()) {
211c7d3291bSSanjoy Das     Pred = CmpInst::ICMP_EQ;
212c7d3291bSSanjoy Das     RHS = *OnlyElt;
213c7d3291bSSanjoy Das   } else if (auto *OnlyMissingElt = getSingleMissingElement()) {
214c7d3291bSSanjoy Das     Pred = CmpInst::ICMP_NE;
215c7d3291bSSanjoy Das     RHS = *OnlyMissingElt;
216590614c1SSanjoy Das   } else if (getLower().isMinSignedValue() || getLower().isMinValue()) {
217590614c1SSanjoy Das     Pred =
218590614c1SSanjoy Das         getLower().isMinSignedValue() ? CmpInst::ICMP_SLT : CmpInst::ICMP_ULT;
219590614c1SSanjoy Das     RHS = getUpper();
220590614c1SSanjoy Das   } else if (getUpper().isMinSignedValue() || getUpper().isMinValue()) {
221590614c1SSanjoy Das     Pred =
222590614c1SSanjoy Das         getUpper().isMinSignedValue() ? CmpInst::ICMP_SGE : CmpInst::ICMP_UGE;
223590614c1SSanjoy Das     RHS = getLower();
2249f0194beSNikita Popov   } else {
2259f0194beSNikita Popov     Pred = CmpInst::ICMP_ULT;
2269f0194beSNikita Popov     RHS = getUpper() - getLower();
2279f0194beSNikita Popov     Offset = -getLower();
228590614c1SSanjoy Das   }
229590614c1SSanjoy Das 
2309f0194beSNikita Popov   assert(ConstantRange::makeExactICmpRegion(Pred, RHS) == add(Offset) &&
231590614c1SSanjoy Das          "Bad result!");
2329f0194beSNikita Popov }
233590614c1SSanjoy Das 
getEquivalentICmp(CmpInst::Predicate & Pred,APInt & RHS) const2349f0194beSNikita Popov bool ConstantRange::getEquivalentICmp(CmpInst::Predicate &Pred,
2359f0194beSNikita Popov                                       APInt &RHS) const {
2369f0194beSNikita Popov   APInt Offset;
2379f0194beSNikita Popov   getEquivalentICmp(Pred, RHS, Offset);
2389f0194beSNikita Popov   return Offset.isZero();
239590614c1SSanjoy Das }
240590614c1SSanjoy Das 
icmp(CmpInst::Predicate Pred,const ConstantRange & Other) const241e8c7f43eSRoman Lebedev bool ConstantRange::icmp(CmpInst::Predicate Pred,
242e8c7f43eSRoman Lebedev                          const ConstantRange &Other) const {
243e8c7f43eSRoman Lebedev   return makeSatisfyingICmpRegion(Pred, Other).contains(*this);
244e8c7f43eSRoman Lebedev }
245e8c7f43eSRoman Lebedev 
246f610110fSNikita Popov /// Exact mul nuw region for single element RHS.
makeExactMulNUWRegion(const APInt & V)247f610110fSNikita Popov static ConstantRange makeExactMulNUWRegion(const APInt &V) {
248f610110fSNikita Popov   unsigned BitWidth = V.getBitWidth();
249f610110fSNikita Popov   if (V == 0)
250f610110fSNikita Popov     return ConstantRange::getFull(V.getBitWidth());
251f610110fSNikita Popov 
252f610110fSNikita Popov   return ConstantRange::getNonEmpty(
253f610110fSNikita Popov       APIntOps::RoundingUDiv(APInt::getMinValue(BitWidth), V,
254f610110fSNikita Popov                              APInt::Rounding::UP),
255f610110fSNikita Popov       APIntOps::RoundingUDiv(APInt::getMaxValue(BitWidth), V,
256f610110fSNikita Popov                              APInt::Rounding::DOWN) + 1);
257f610110fSNikita Popov }
258f610110fSNikita Popov 
259f610110fSNikita Popov /// Exact mul nsw region for single element RHS.
makeExactMulNSWRegion(const APInt & V)260f610110fSNikita Popov static ConstantRange makeExactMulNSWRegion(const APInt &V) {
261f610110fSNikita Popov   // Handle special case for 0, -1 and 1. See the last for reason why we
262f610110fSNikita Popov   // specialize -1 and 1.
263f610110fSNikita Popov   unsigned BitWidth = V.getBitWidth();
264a9bceb2bSJay Foad   if (V == 0 || V.isOne())
265f610110fSNikita Popov     return ConstantRange::getFull(BitWidth);
266f610110fSNikita Popov 
267f610110fSNikita Popov   APInt MinValue = APInt::getSignedMinValue(BitWidth);
268f610110fSNikita Popov   APInt MaxValue = APInt::getSignedMaxValue(BitWidth);
269f610110fSNikita Popov   // e.g. Returning [-127, 127], represented as [-127, -128).
270a9bceb2bSJay Foad   if (V.isAllOnes())
271f610110fSNikita Popov     return ConstantRange(-MaxValue, MinValue);
272f610110fSNikita Popov 
273f610110fSNikita Popov   APInt Lower, Upper;
274f610110fSNikita Popov   if (V.isNegative()) {
275f610110fSNikita Popov     Lower = APIntOps::RoundingSDiv(MaxValue, V, APInt::Rounding::UP);
276f610110fSNikita Popov     Upper = APIntOps::RoundingSDiv(MinValue, V, APInt::Rounding::DOWN);
277f610110fSNikita Popov   } else {
278f610110fSNikita Popov     Lower = APIntOps::RoundingSDiv(MinValue, V, APInt::Rounding::UP);
279f610110fSNikita Popov     Upper = APIntOps::RoundingSDiv(MaxValue, V, APInt::Rounding::DOWN);
280f610110fSNikita Popov   }
281f610110fSNikita Popov   // ConstantRange ctor take a half inclusive interval [Lower, Upper + 1).
282f610110fSNikita Popov   // Upper + 1 is guaranteed not to overflow, because |divisor| > 1. 0, -1,
283f610110fSNikita Popov   // and 1 are already handled as special cases.
284f610110fSNikita Popov   return ConstantRange(Lower, Upper + 1);
285f610110fSNikita Popov }
286f610110fSNikita Popov 
2875079f626SSanjoy Das ConstantRange
makeGuaranteedNoWrapRegion(Instruction::BinaryOps BinOp,const ConstantRange & Other,unsigned NoWrapKind)2885aacc7a5SNikita Popov ConstantRange::makeGuaranteedNoWrapRegion(Instruction::BinaryOps BinOp,
289f3867e64SSanjoy Das                                           const ConstantRange &Other,
290f3867e64SSanjoy Das                                           unsigned NoWrapKind) {
291de6cce22SEugene Zelenko   using OBO = OverflowingBinaryOperator;
2926ed05305SSanjoy Das 
293e0a6eb1fSSimon Pilgrim   assert(Instruction::isBinaryOp(BinOp) && "Binary operators only!");
2946ed05305SSanjoy Das 
2956ed05305SSanjoy Das   assert((NoWrapKind == OBO::NoSignedWrap ||
296a96480ebSNikita Popov           NoWrapKind == OBO::NoUnsignedWrap) &&
2976ed05305SSanjoy Das          "NoWrapKind invalid!");
2986ed05305SSanjoy Das 
299f610110fSNikita Popov   bool Unsigned = NoWrapKind == OBO::NoUnsignedWrap;
300f3867e64SSanjoy Das   unsigned BitWidth = Other.getBitWidth();
301c32b0fc2SJoel Galenson 
302c32b0fc2SJoel Galenson   switch (BinOp) {
303c32b0fc2SJoel Galenson   default:
3048b1fa076SNikita Popov     llvm_unreachable("Unsupported binary op");
3056ed05305SSanjoy Das 
306f610110fSNikita Popov   case Instruction::Add: {
307f610110fSNikita Popov     if (Unsigned)
308735f4671SChris Lattner       return getNonEmpty(APInt::getZero(BitWidth), -Other.getUnsignedMax());
309a96480ebSNikita Popov 
310f610110fSNikita Popov     APInt SignedMinVal = APInt::getSignedMinValue(BitWidth);
311f610110fSNikita Popov     APInt SMin = Other.getSignedMin(), SMax = Other.getSignedMax();
312f610110fSNikita Popov     return getNonEmpty(
313f610110fSNikita Popov         SMin.isNegative() ? SignedMinVal - SMin : SignedMinVal,
314f610110fSNikita Popov         SMax.isStrictlyPositive() ? SignedMinVal - SMax : SignedMinVal);
3156ed05305SSanjoy Das   }
316c32b0fc2SJoel Galenson 
317f610110fSNikita Popov   case Instruction::Sub: {
318b32823cbSTim Shen     if (Unsigned)
319f610110fSNikita Popov       return getNonEmpty(Other.getUnsignedMax(), APInt::getMinValue(BitWidth));
320b32823cbSTim Shen 
321f610110fSNikita Popov     APInt SignedMinVal = APInt::getSignedMinValue(BitWidth);
322f610110fSNikita Popov     APInt SMin = Other.getSignedMin(), SMax = Other.getSignedMax();
323f610110fSNikita Popov     return getNonEmpty(
324f610110fSNikita Popov         SMax.isStrictlyPositive() ? SignedMinVal + SMax : SignedMinVal,
325f610110fSNikita Popov         SMin.isNegative() ? SignedMinVal + SMin : SignedMinVal);
326b32823cbSTim Shen   }
327f610110fSNikita Popov 
328f610110fSNikita Popov   case Instruction::Mul:
329f610110fSNikita Popov     if (Unsigned)
330f610110fSNikita Popov       return makeExactMulNUWRegion(Other.getUnsignedMax());
331f610110fSNikita Popov 
332f610110fSNikita Popov     return makeExactMulNSWRegion(Other.getSignedMin())
333f610110fSNikita Popov         .intersectWith(makeExactMulNSWRegion(Other.getSignedMax()));
3344b622326SRoman Lebedev 
3354b622326SRoman Lebedev   case Instruction::Shl: {
3364b622326SRoman Lebedev     // For given range of shift amounts, if we ignore all illegal shift amounts
3374b622326SRoman Lebedev     // (that always produce poison), what shift amount range is left?
3384b622326SRoman Lebedev     ConstantRange ShAmt = Other.intersectWith(
3394b622326SRoman Lebedev         ConstantRange(APInt(BitWidth, 0), APInt(BitWidth, (BitWidth - 1) + 1)));
3404b622326SRoman Lebedev     if (ShAmt.isEmptySet()) {
3414b622326SRoman Lebedev       // If the entire range of shift amounts is already poison-producing,
3424b622326SRoman Lebedev       // then we can freely add more poison-producing flags ontop of that.
3434b622326SRoman Lebedev       return getFull(BitWidth);
3444b622326SRoman Lebedev     }
3454b622326SRoman Lebedev     // There are some legal shift amounts, we can compute conservatively-correct
3464b622326SRoman Lebedev     // range of no-wrap inputs. Note that by now we have clamped the ShAmtUMax
3474b622326SRoman Lebedev     // to be at most bitwidth-1, which results in most conservative range.
3484b622326SRoman Lebedev     APInt ShAmtUMax = ShAmt.getUnsignedMax();
3494b622326SRoman Lebedev     if (Unsigned)
350735f4671SChris Lattner       return getNonEmpty(APInt::getZero(BitWidth),
3514b622326SRoman Lebedev                          APInt::getMaxValue(BitWidth).lshr(ShAmtUMax) + 1);
3524b622326SRoman Lebedev     return getNonEmpty(APInt::getSignedMinValue(BitWidth).ashr(ShAmtUMax),
3534b622326SRoman Lebedev                        APInt::getSignedMaxValue(BitWidth).ashr(ShAmtUMax) + 1);
3544b622326SRoman Lebedev   }
355c32b0fc2SJoel Galenson   }
3566ed05305SSanjoy Das }
3576ed05305SSanjoy Das 
makeExactNoWrapRegion(Instruction::BinaryOps BinOp,const APInt & Other,unsigned NoWrapKind)3587a94795bSNikita Popov ConstantRange ConstantRange::makeExactNoWrapRegion(Instruction::BinaryOps BinOp,
3597a94795bSNikita Popov                                                    const APInt &Other,
3607a94795bSNikita Popov                                                    unsigned NoWrapKind) {
3617a94795bSNikita Popov   // makeGuaranteedNoWrapRegion() is exact for single-element ranges, as
3627a94795bSNikita Popov   // "for all" and "for any" coincide in this case.
3637a94795bSNikita Popov   return makeGuaranteedNoWrapRegion(BinOp, ConstantRange(Other), NoWrapKind);
3647a94795bSNikita Popov }
3657a94795bSNikita Popov 
isFullSet() const3668cd041efSChandler Carruth bool ConstantRange::isFullSet() const {
3678cd041efSChandler Carruth   return Lower == Upper && Lower.isMaxValue();
3688cd041efSChandler Carruth }
3698cd041efSChandler Carruth 
isEmptySet() const3708cd041efSChandler Carruth bool ConstantRange::isEmptySet() const {
3718cd041efSChandler Carruth   return Lower == Upper && Lower.isMinValue();
3728cd041efSChandler Carruth }
3738cd041efSChandler Carruth 
isWrappedSet() const3747b4e9a1cSNikita Popov bool ConstantRange::isWrappedSet() const {
375735f4671SChris Lattner   return Lower.ugt(Upper) && !Upper.isZero();
3767b4e9a1cSNikita Popov }
3777b4e9a1cSNikita Popov 
isUpperWrapped() const3786d855ea0SNikita Popov bool ConstantRange::isUpperWrapped() const {
3798cd041efSChandler Carruth   return Lower.ugt(Upper);
3808cd041efSChandler Carruth }
3818cd041efSChandler Carruth 
isSignWrappedSet() const3828cd041efSChandler Carruth bool ConstantRange::isSignWrappedSet() const {
383e6eef49fSNikita Popov   return Lower.sgt(Upper) && !Upper.isMinSignedValue();
3848cd041efSChandler Carruth }
3858cd041efSChandler Carruth 
isUpperSignWrapped() const3867b4e9a1cSNikita Popov bool ConstantRange::isUpperSignWrapped() const {
3877b4e9a1cSNikita Popov   return Lower.sgt(Upper);
3887b4e9a1cSNikita Popov }
3897b4e9a1cSNikita Popov 
390c69955c6SMichael Zolotukhin bool
isSizeStrictlySmallerThan(const ConstantRange & Other) const391d29549e9SCraig Topper ConstantRange::isSizeStrictlySmallerThan(const ConstantRange &Other) const {
392c69955c6SMichael Zolotukhin   assert(getBitWidth() == Other.getBitWidth());
393c69955c6SMichael Zolotukhin   if (isFullSet())
394c69955c6SMichael Zolotukhin     return false;
395c69955c6SMichael Zolotukhin   if (Other.isFullSet())
396c69955c6SMichael Zolotukhin     return true;
397c69955c6SMichael Zolotukhin   return (Upper - Lower).ult(Other.Upper - Other.Lower);
398c69955c6SMichael Zolotukhin }
399c69955c6SMichael Zolotukhin 
4007e3e7afcSCraig Topper bool
isSizeLargerThan(uint64_t MaxSize) const4017e3e7afcSCraig Topper ConstantRange::isSizeLargerThan(uint64_t MaxSize) const {
4027e3e7afcSCraig Topper   // If this a full set, we need special handling to avoid needing an extra bit
4037e3e7afcSCraig Topper   // to represent the size.
4047e3e7afcSCraig Topper   if (isFullSet())
405cf71a5eaSNikita Popov     return MaxSize == 0 || APInt::getMaxValue(getBitWidth()).ugt(MaxSize - 1);
4067e3e7afcSCraig Topper 
4077e3e7afcSCraig Topper   return (Upper - Lower).ugt(MaxSize);
4087e3e7afcSCraig Topper }
4097e3e7afcSCraig Topper 
isAllNegative() const410bad648a2SNikita Popov bool ConstantRange::isAllNegative() const {
411bad648a2SNikita Popov   // Empty set is all negative, full set is not.
412bad648a2SNikita Popov   if (isEmptySet())
413bad648a2SNikita Popov     return true;
414bad648a2SNikita Popov   if (isFullSet())
415bad648a2SNikita Popov     return false;
416bad648a2SNikita Popov 
417bad648a2SNikita Popov   return !isUpperSignWrapped() && !Upper.isStrictlyPositive();
418bad648a2SNikita Popov }
419bad648a2SNikita Popov 
isAllNonNegative() const420bad648a2SNikita Popov bool ConstantRange::isAllNonNegative() const {
421bad648a2SNikita Popov   // Empty and full set are automatically treated correctly.
422bad648a2SNikita Popov   return !isSignWrappedSet() && Lower.isNonNegative();
423bad648a2SNikita Popov }
424bad648a2SNikita Popov 
getUnsignedMax() const4258cd041efSChandler Carruth APInt ConstantRange::getUnsignedMax() const {
4266d855ea0SNikita Popov   if (isFullSet() || isUpperWrapped())
4278cd041efSChandler Carruth     return APInt::getMaxValue(getBitWidth());
4288cd041efSChandler Carruth   return getUpper() - 1;
4298cd041efSChandler Carruth }
4308cd041efSChandler Carruth 
getUnsignedMin() const4318cd041efSChandler Carruth APInt ConstantRange::getUnsignedMin() const {
4327b4e9a1cSNikita Popov   if (isFullSet() || isWrappedSet())
4338cd041efSChandler Carruth     return APInt::getMinValue(getBitWidth());
4348cd041efSChandler Carruth   return getLower();
4358cd041efSChandler Carruth }
4368cd041efSChandler Carruth 
getSignedMax() const4378cd041efSChandler Carruth APInt ConstantRange::getSignedMax() const {
4387b4e9a1cSNikita Popov   if (isFullSet() || isUpperSignWrapped())
43988c64f32SCraig Topper     return APInt::getSignedMaxValue(getBitWidth());
4408cd041efSChandler Carruth   return getUpper() - 1;
4418cd041efSChandler Carruth }
4428cd041efSChandler Carruth 
getSignedMin() const4438cd041efSChandler Carruth APInt ConstantRange::getSignedMin() const {
4447b4e9a1cSNikita Popov   if (isFullSet() || isSignWrappedSet())
44588c64f32SCraig Topper     return APInt::getSignedMinValue(getBitWidth());
4468cd041efSChandler Carruth   return getLower();
4478cd041efSChandler Carruth }
4488cd041efSChandler Carruth 
contains(const APInt & V) const4498cd041efSChandler Carruth bool ConstantRange::contains(const APInt &V) const {
4508cd041efSChandler Carruth   if (Lower == Upper)
4518cd041efSChandler Carruth     return isFullSet();
4528cd041efSChandler Carruth 
4536d855ea0SNikita Popov   if (!isUpperWrapped())
4548cd041efSChandler Carruth     return Lower.ule(V) && V.ult(Upper);
4558cd041efSChandler Carruth   return Lower.ule(V) || V.ult(Upper);
4568cd041efSChandler Carruth }
4578cd041efSChandler Carruth 
contains(const ConstantRange & Other) const4588cd041efSChandler Carruth bool ConstantRange::contains(const ConstantRange &Other) const {
4598cd041efSChandler Carruth   if (isFullSet() || Other.isEmptySet()) return true;
4608cd041efSChandler Carruth   if (isEmptySet() || Other.isFullSet()) return false;
4618cd041efSChandler Carruth 
4626d855ea0SNikita Popov   if (!isUpperWrapped()) {
4636d855ea0SNikita Popov     if (Other.isUpperWrapped())
4648cd041efSChandler Carruth       return false;
4658cd041efSChandler Carruth 
4668cd041efSChandler Carruth     return Lower.ule(Other.getLower()) && Other.getUpper().ule(Upper);
4678cd041efSChandler Carruth   }
4688cd041efSChandler Carruth 
4696d855ea0SNikita Popov   if (!Other.isUpperWrapped())
4708cd041efSChandler Carruth     return Other.getUpper().ule(Upper) ||
4718cd041efSChandler Carruth            Lower.ule(Other.getLower());
4728cd041efSChandler Carruth 
4738cd041efSChandler Carruth   return Other.getUpper().ule(Upper) && Lower.ule(Other.getLower());
4748cd041efSChandler Carruth }
4758cd041efSChandler Carruth 
getActiveBits() const4762ed9c4c7SRoman Lebedev unsigned ConstantRange::getActiveBits() const {
4772ed9c4c7SRoman Lebedev   if (isEmptySet())
4782ed9c4c7SRoman Lebedev     return 0;
4792ed9c4c7SRoman Lebedev 
4802ed9c4c7SRoman Lebedev   return getUnsignedMax().getActiveBits();
4812ed9c4c7SRoman Lebedev }
4822ed9c4c7SRoman Lebedev 
getMinSignedBits() const4837465da20SRoman Lebedev unsigned ConstantRange::getMinSignedBits() const {
4847465da20SRoman Lebedev   if (isEmptySet())
4857465da20SRoman Lebedev     return 0;
4867465da20SRoman Lebedev 
4877465da20SRoman Lebedev   return std::max(getSignedMin().getMinSignedBits(),
4887465da20SRoman Lebedev                   getSignedMax().getMinSignedBits());
4897465da20SRoman Lebedev }
4907465da20SRoman Lebedev 
subtract(const APInt & Val) const4918cd041efSChandler Carruth ConstantRange ConstantRange::subtract(const APInt &Val) const {
4928cd041efSChandler Carruth   assert(Val.getBitWidth() == getBitWidth() && "Wrong bit width");
4938cd041efSChandler Carruth   // If the set is empty or full, don't modify the endpoints.
4948cd041efSChandler Carruth   if (Lower == Upper)
4958cd041efSChandler Carruth     return *this;
4968cd041efSChandler Carruth   return ConstantRange(Lower - Val, Upper - Val);
4978cd041efSChandler Carruth }
4988cd041efSChandler Carruth 
difference(const ConstantRange & CR) const4998cd041efSChandler Carruth ConstantRange ConstantRange::difference(const ConstantRange &CR) const {
5008cd041efSChandler Carruth   return intersectWith(CR.inverse());
5018cd041efSChandler Carruth }
5028cd041efSChandler Carruth 
getPreferredRange(const ConstantRange & CR1,const ConstantRange & CR2,ConstantRange::PreferredRangeType Type)5034246106aSNikita Popov static ConstantRange getPreferredRange(
5044246106aSNikita Popov     const ConstantRange &CR1, const ConstantRange &CR2,
5054246106aSNikita Popov     ConstantRange::PreferredRangeType Type) {
5064246106aSNikita Popov   if (Type == ConstantRange::Unsigned) {
5074246106aSNikita Popov     if (!CR1.isWrappedSet() && CR2.isWrappedSet())
5084246106aSNikita Popov       return CR1;
5094246106aSNikita Popov     if (CR1.isWrappedSet() && !CR2.isWrappedSet())
5104246106aSNikita Popov       return CR2;
5114246106aSNikita Popov   } else if (Type == ConstantRange::Signed) {
5124246106aSNikita Popov     if (!CR1.isSignWrappedSet() && CR2.isSignWrappedSet())
5134246106aSNikita Popov       return CR1;
5144246106aSNikita Popov     if (CR1.isSignWrappedSet() && !CR2.isSignWrappedSet())
5154246106aSNikita Popov       return CR2;
5164246106aSNikita Popov   }
5174246106aSNikita Popov 
5184246106aSNikita Popov   if (CR1.isSizeStrictlySmallerThan(CR2))
5194246106aSNikita Popov     return CR1;
5204246106aSNikita Popov   return CR2;
5214246106aSNikita Popov }
5224246106aSNikita Popov 
intersectWith(const ConstantRange & CR,PreferredRangeType Type) const5234246106aSNikita Popov ConstantRange ConstantRange::intersectWith(const ConstantRange &CR,
5244246106aSNikita Popov                                            PreferredRangeType Type) const {
5258cd041efSChandler Carruth   assert(getBitWidth() == CR.getBitWidth() &&
5268cd041efSChandler Carruth          "ConstantRange types don't agree!");
5278cd041efSChandler Carruth 
5288cd041efSChandler Carruth   // Handle common cases.
5298cd041efSChandler Carruth   if (   isEmptySet() || CR.isFullSet()) return *this;
5308cd041efSChandler Carruth   if (CR.isEmptySet() ||    isFullSet()) return CR;
5318cd041efSChandler Carruth 
5326d855ea0SNikita Popov   if (!isUpperWrapped() && CR.isUpperWrapped())
5334246106aSNikita Popov     return CR.intersectWith(*this, Type);
5348cd041efSChandler Carruth 
5356d855ea0SNikita Popov   if (!isUpperWrapped() && !CR.isUpperWrapped()) {
5368cd041efSChandler Carruth     if (Lower.ult(CR.Lower)) {
5374246106aSNikita Popov       // L---U       : this
5384246106aSNikita Popov       //       L---U : CR
5398cd041efSChandler Carruth       if (Upper.ule(CR.Lower))
540977934f0SNikita Popov         return getEmpty();
5418cd041efSChandler Carruth 
5424246106aSNikita Popov       // L---U       : this
5434246106aSNikita Popov       //   L---U     : CR
5448cd041efSChandler Carruth       if (Upper.ult(CR.Upper))
5458cd041efSChandler Carruth         return ConstantRange(CR.Lower, Upper);
5468cd041efSChandler Carruth 
5474246106aSNikita Popov       // L-------U   : this
5484246106aSNikita Popov       //   L---U     : CR
5498cd041efSChandler Carruth       return CR;
5508cd041efSChandler Carruth     }
5514246106aSNikita Popov     //   L---U     : this
5524246106aSNikita Popov     // L-------U   : CR
5538cd041efSChandler Carruth     if (Upper.ult(CR.Upper))
5548cd041efSChandler Carruth       return *this;
5558cd041efSChandler Carruth 
5564246106aSNikita Popov     //   L-----U   : this
5574246106aSNikita Popov     // L-----U     : CR
5588cd041efSChandler Carruth     if (Lower.ult(CR.Upper))
5598cd041efSChandler Carruth       return ConstantRange(Lower, CR.Upper);
5608cd041efSChandler Carruth 
5614246106aSNikita Popov     //       L---U : this
5624246106aSNikita Popov     // L---U       : CR
563977934f0SNikita Popov     return getEmpty();
5648cd041efSChandler Carruth   }
5658cd041efSChandler Carruth 
5666d855ea0SNikita Popov   if (isUpperWrapped() && !CR.isUpperWrapped()) {
5678cd041efSChandler Carruth     if (CR.Lower.ult(Upper)) {
5684246106aSNikita Popov       // ------U   L--- : this
5694246106aSNikita Popov       //  L--U          : CR
5708cd041efSChandler Carruth       if (CR.Upper.ult(Upper))
5718cd041efSChandler Carruth         return CR;
5728cd041efSChandler Carruth 
5734246106aSNikita Popov       // ------U   L--- : this
5744246106aSNikita Popov       //  L------U      : CR
5758cd041efSChandler Carruth       if (CR.Upper.ule(Lower))
5768cd041efSChandler Carruth         return ConstantRange(CR.Lower, Upper);
5778cd041efSChandler Carruth 
5784246106aSNikita Popov       // ------U   L--- : this
5794246106aSNikita Popov       //  L----------U  : CR
5804246106aSNikita Popov       return getPreferredRange(*this, CR, Type);
5818cd041efSChandler Carruth     }
5828cd041efSChandler Carruth     if (CR.Lower.ult(Lower)) {
5834246106aSNikita Popov       // --U      L---- : this
5844246106aSNikita Popov       //     L--U       : CR
5858cd041efSChandler Carruth       if (CR.Upper.ule(Lower))
586977934f0SNikita Popov         return getEmpty();
5878cd041efSChandler Carruth 
5884246106aSNikita Popov       // --U      L---- : this
5894246106aSNikita Popov       //     L------U   : CR
5908cd041efSChandler Carruth       return ConstantRange(Lower, CR.Upper);
5918cd041efSChandler Carruth     }
5924246106aSNikita Popov 
5934246106aSNikita Popov     // --U  L------ : this
5944246106aSNikita Popov     //        L--U  : CR
5958cd041efSChandler Carruth     return CR;
5968cd041efSChandler Carruth   }
5978cd041efSChandler Carruth 
5988cd041efSChandler Carruth   if (CR.Upper.ult(Upper)) {
5994246106aSNikita Popov     // ------U L-- : this
6004246106aSNikita Popov     // --U L------ : CR
6014246106aSNikita Popov     if (CR.Lower.ult(Upper))
6024246106aSNikita Popov       return getPreferredRange(*this, CR, Type);
6038cd041efSChandler Carruth 
6044246106aSNikita Popov     // ----U   L-- : this
6054246106aSNikita Popov     // --U   L---- : CR
6068cd041efSChandler Carruth     if (CR.Lower.ult(Lower))
6078cd041efSChandler Carruth       return ConstantRange(Lower, CR.Upper);
6088cd041efSChandler Carruth 
6094246106aSNikita Popov     // ----U L---- : this
6104246106aSNikita Popov     // --U     L-- : CR
6118cd041efSChandler Carruth     return CR;
6128cd041efSChandler Carruth   }
6138cd041efSChandler Carruth   if (CR.Upper.ule(Lower)) {
6144246106aSNikita Popov     // --U     L-- : this
6154246106aSNikita Popov     // ----U L---- : CR
6168cd041efSChandler Carruth     if (CR.Lower.ult(Lower))
6178cd041efSChandler Carruth       return *this;
6188cd041efSChandler Carruth 
6194246106aSNikita Popov     // --U   L---- : this
6204246106aSNikita Popov     // ----U   L-- : CR
6218cd041efSChandler Carruth     return ConstantRange(CR.Lower, Upper);
6228cd041efSChandler Carruth   }
6234246106aSNikita Popov 
6244246106aSNikita Popov   // --U L------ : this
6254246106aSNikita Popov   // ------U L-- : CR
6264246106aSNikita Popov   return getPreferredRange(*this, CR, Type);
6278cd041efSChandler Carruth }
6288cd041efSChandler Carruth 
unionWith(const ConstantRange & CR,PreferredRangeType Type) const629f38b46ffSNikita Popov ConstantRange ConstantRange::unionWith(const ConstantRange &CR,
630f38b46ffSNikita Popov                                        PreferredRangeType Type) const {
6318cd041efSChandler Carruth   assert(getBitWidth() == CR.getBitWidth() &&
6328cd041efSChandler Carruth          "ConstantRange types don't agree!");
6338cd041efSChandler Carruth 
6348cd041efSChandler Carruth   if (   isFullSet() || CR.isEmptySet()) return *this;
6358cd041efSChandler Carruth   if (CR.isFullSet() ||    isEmptySet()) return CR;
6368cd041efSChandler Carruth 
637f38b46ffSNikita Popov   if (!isUpperWrapped() && CR.isUpperWrapped())
638f38b46ffSNikita Popov     return CR.unionWith(*this, Type);
6398cd041efSChandler Carruth 
6406d855ea0SNikita Popov   if (!isUpperWrapped() && !CR.isUpperWrapped()) {
641f38b46ffSNikita Popov     //        L---U  and  L---U        : this
642f38b46ffSNikita Popov     //  L---U                   L---U  : CR
643f38b46ffSNikita Popov     // result in one of
644f38b46ffSNikita Popov     //  L---------U
645f38b46ffSNikita Popov     // -----U L-----
646f38b46ffSNikita Popov     if (CR.Upper.ult(Lower) || Upper.ult(CR.Lower))
647f38b46ffSNikita Popov       return getPreferredRange(
648f38b46ffSNikita Popov           ConstantRange(Lower, CR.Upper), ConstantRange(CR.Lower, Upper), Type);
6498cd041efSChandler Carruth 
6508fb5a14cSCraig Topper     APInt L = CR.Lower.ult(Lower) ? CR.Lower : Lower;
6518fb5a14cSCraig Topper     APInt U = (CR.Upper - 1).ugt(Upper - 1) ? CR.Upper : Upper;
6528cd041efSChandler Carruth 
653735f4671SChris Lattner     if (L.isZero() && U.isZero())
654977934f0SNikita Popov       return getFull();
6558cd041efSChandler Carruth 
656b792025bSCraig Topper     return ConstantRange(std::move(L), std::move(U));
6578cd041efSChandler Carruth   }
6588cd041efSChandler Carruth 
6596d855ea0SNikita Popov   if (!CR.isUpperWrapped()) {
6608cd041efSChandler Carruth     // ------U   L-----  and  ------U   L----- : this
6618cd041efSChandler Carruth     //   L--U                            L--U  : CR
6628cd041efSChandler Carruth     if (CR.Upper.ule(Upper) || CR.Lower.uge(Lower))
6638cd041efSChandler Carruth       return *this;
6648cd041efSChandler Carruth 
6658cd041efSChandler Carruth     // ------U   L----- : this
6668cd041efSChandler Carruth     //    L---------U   : CR
6678cd041efSChandler Carruth     if (CR.Lower.ule(Upper) && Lower.ule(CR.Upper))
668977934f0SNikita Popov       return getFull();
6698cd041efSChandler Carruth 
6708cd041efSChandler Carruth     // ----U       L---- : this
6718cd041efSChandler Carruth     //       L---U       : CR
672f38b46ffSNikita Popov     // results in one of
673f38b46ffSNikita Popov     // ----------U L----
674f38b46ffSNikita Popov     // ----U L----------
675f38b46ffSNikita Popov     if (Upper.ult(CR.Lower) && CR.Upper.ult(Lower))
676f38b46ffSNikita Popov       return getPreferredRange(
677f38b46ffSNikita Popov           ConstantRange(Lower, CR.Upper), ConstantRange(CR.Lower, Upper), Type);
6788cd041efSChandler Carruth 
6798cd041efSChandler Carruth     // ----U     L----- : this
6808cd041efSChandler Carruth     //        L----U    : CR
681f38b46ffSNikita Popov     if (Upper.ult(CR.Lower) && Lower.ule(CR.Upper))
6828cd041efSChandler Carruth       return ConstantRange(CR.Lower, Upper);
6838cd041efSChandler Carruth 
6848cd041efSChandler Carruth     // ------U    L---- : this
6858cd041efSChandler Carruth     //    L-----U       : CR
686f38b46ffSNikita Popov     assert(CR.Lower.ule(Upper) && CR.Upper.ult(Lower) &&
6878cd041efSChandler Carruth            "ConstantRange::unionWith missed a case with one range wrapped");
6888cd041efSChandler Carruth     return ConstantRange(Lower, CR.Upper);
6898cd041efSChandler Carruth   }
6908cd041efSChandler Carruth 
6918cd041efSChandler Carruth   // ------U    L----  and  ------U    L---- : this
6928cd041efSChandler Carruth   // -U  L-----------  and  ------------U  L : CR
6938cd041efSChandler Carruth   if (CR.Lower.ule(Upper) || Lower.ule(CR.Upper))
694977934f0SNikita Popov     return getFull();
6958cd041efSChandler Carruth 
6968fb5a14cSCraig Topper   APInt L = CR.Lower.ult(Lower) ? CR.Lower : Lower;
6978fb5a14cSCraig Topper   APInt U = CR.Upper.ugt(Upper) ? CR.Upper : Upper;
6988cd041efSChandler Carruth 
699b792025bSCraig Topper   return ConstantRange(std::move(L), std::move(U));
7008cd041efSChandler Carruth }
7018cd041efSChandler Carruth 
7022060895cSNikita Popov Optional<ConstantRange>
exactIntersectWith(const ConstantRange & CR) const7032060895cSNikita Popov ConstantRange::exactIntersectWith(const ConstantRange &CR) const {
7042060895cSNikita Popov   // TODO: This can be implemented more efficiently.
7052060895cSNikita Popov   ConstantRange Result = intersectWith(CR);
7062060895cSNikita Popov   if (Result == inverse().unionWith(CR.inverse()).inverse())
7072060895cSNikita Popov     return Result;
7082060895cSNikita Popov   return None;
7092060895cSNikita Popov }
7102060895cSNikita Popov 
7112060895cSNikita Popov Optional<ConstantRange>
exactUnionWith(const ConstantRange & CR) const7122060895cSNikita Popov ConstantRange::exactUnionWith(const ConstantRange &CR) const {
7132060895cSNikita Popov   // TODO: This can be implemented more efficiently.
7142060895cSNikita Popov   ConstantRange Result = unionWith(CR);
7152060895cSNikita Popov   if (Result == inverse().intersectWith(CR.inverse()).inverse())
7162060895cSNikita Popov     return Result;
7172060895cSNikita Popov   return None;
7182060895cSNikita Popov }
7192060895cSNikita Popov 
castOp(Instruction::CastOps CastOp,uint32_t ResultBitWidth) const7204d00af1bSPhilip Reames ConstantRange ConstantRange::castOp(Instruction::CastOps CastOp,
7214d00af1bSPhilip Reames                                     uint32_t ResultBitWidth) const {
7224d00af1bSPhilip Reames   switch (CastOp) {
7234d00af1bSPhilip Reames   default:
7244d00af1bSPhilip Reames     llvm_unreachable("unsupported cast type");
7254d00af1bSPhilip Reames   case Instruction::Trunc:
7264d00af1bSPhilip Reames     return truncate(ResultBitWidth);
7274d00af1bSPhilip Reames   case Instruction::SExt:
7284d00af1bSPhilip Reames     return signExtend(ResultBitWidth);
7294d00af1bSPhilip Reames   case Instruction::ZExt:
7304d00af1bSPhilip Reames     return zeroExtend(ResultBitWidth);
7314d00af1bSPhilip Reames   case Instruction::BitCast:
7324d00af1bSPhilip Reames     return *this;
7334d00af1bSPhilip Reames   case Instruction::FPToUI:
7344d00af1bSPhilip Reames   case Instruction::FPToSI:
7354d00af1bSPhilip Reames     if (getBitWidth() == ResultBitWidth)
7364d00af1bSPhilip Reames       return *this;
7374d00af1bSPhilip Reames     else
738b35c585aSFlorian Hahn       return getFull(ResultBitWidth);
7394d00af1bSPhilip Reames   case Instruction::UIToFP: {
7404d00af1bSPhilip Reames     // TODO: use input range if available
7414d00af1bSPhilip Reames     auto BW = getBitWidth();
7426bec3e93SJay Foad     APInt Min = APInt::getMinValue(BW);
7436bec3e93SJay Foad     APInt Max = APInt::getMaxValue(BW);
7446bec3e93SJay Foad     if (ResultBitWidth > BW) {
7456bec3e93SJay Foad       Min = Min.zext(ResultBitWidth);
7466bec3e93SJay Foad       Max = Max.zext(ResultBitWidth);
7476bec3e93SJay Foad     }
748b792025bSCraig Topper     return ConstantRange(std::move(Min), std::move(Max));
7494d00af1bSPhilip Reames   }
7504d00af1bSPhilip Reames   case Instruction::SIToFP: {
7514d00af1bSPhilip Reames     // TODO: use input range if available
7524d00af1bSPhilip Reames     auto BW = getBitWidth();
7536bec3e93SJay Foad     APInt SMin = APInt::getSignedMinValue(BW);
7546bec3e93SJay Foad     APInt SMax = APInt::getSignedMaxValue(BW);
7556bec3e93SJay Foad     if (ResultBitWidth > BW) {
7566bec3e93SJay Foad       SMin = SMin.sext(ResultBitWidth);
7576bec3e93SJay Foad       SMax = SMax.sext(ResultBitWidth);
7586bec3e93SJay Foad     }
759b792025bSCraig Topper     return ConstantRange(std::move(SMin), std::move(SMax));
7604d00af1bSPhilip Reames   }
7614d00af1bSPhilip Reames   case Instruction::FPTrunc:
7624d00af1bSPhilip Reames   case Instruction::FPExt:
7634d00af1bSPhilip Reames   case Instruction::IntToPtr:
7644d00af1bSPhilip Reames   case Instruction::PtrToInt:
7654d00af1bSPhilip Reames   case Instruction::AddrSpaceCast:
766977934f0SNikita Popov     // Conservatively return getFull set.
767b35c585aSFlorian Hahn     return getFull(ResultBitWidth);
7684d00af1bSPhilip Reames   };
7694d00af1bSPhilip Reames }
7704d00af1bSPhilip Reames 
zeroExtend(uint32_t DstTySize) const7718cd041efSChandler Carruth ConstantRange ConstantRange::zeroExtend(uint32_t DstTySize) const {
772977934f0SNikita Popov   if (isEmptySet()) return getEmpty(DstTySize);
7738cd041efSChandler Carruth 
7748cd041efSChandler Carruth   unsigned SrcTySize = getBitWidth();
7758cd041efSChandler Carruth   assert(SrcTySize < DstTySize && "Not a value extension");
7766d855ea0SNikita Popov   if (isFullSet() || isUpperWrapped()) {
7778cd041efSChandler Carruth     // Change into [0, 1 << src bit width)
7788cd041efSChandler Carruth     APInt LowerExt(DstTySize, 0);
7798cd041efSChandler Carruth     if (!Upper) // special case: [X, 0) -- not really wrapping around
7808cd041efSChandler Carruth       LowerExt = Lower.zext(DstTySize);
781b792025bSCraig Topper     return ConstantRange(std::move(LowerExt),
782b792025bSCraig Topper                          APInt::getOneBitSet(DstTySize, SrcTySize));
7838cd041efSChandler Carruth   }
7848cd041efSChandler Carruth 
7858cd041efSChandler Carruth   return ConstantRange(Lower.zext(DstTySize), Upper.zext(DstTySize));
7868cd041efSChandler Carruth }
7878cd041efSChandler Carruth 
signExtend(uint32_t DstTySize) const7888cd041efSChandler Carruth ConstantRange ConstantRange::signExtend(uint32_t DstTySize) const {
789977934f0SNikita Popov   if (isEmptySet()) return getEmpty(DstTySize);
7908cd041efSChandler Carruth 
7918cd041efSChandler Carruth   unsigned SrcTySize = getBitWidth();
7928cd041efSChandler Carruth   assert(SrcTySize < DstTySize && "Not a value extension");
7938cd041efSChandler Carruth 
7948cd041efSChandler Carruth   // special case: [X, INT_MIN) -- not really wrapping around
7958cd041efSChandler Carruth   if (Upper.isMinSignedValue())
7968cd041efSChandler Carruth     return ConstantRange(Lower.sext(DstTySize), Upper.zext(DstTySize));
7978cd041efSChandler Carruth 
7988cd041efSChandler Carruth   if (isFullSet() || isSignWrappedSet()) {
7998cd041efSChandler Carruth     return ConstantRange(APInt::getHighBitsSet(DstTySize,DstTySize-SrcTySize+1),
8008cd041efSChandler Carruth                          APInt::getLowBitsSet(DstTySize, SrcTySize-1) + 1);
8018cd041efSChandler Carruth   }
8028cd041efSChandler Carruth 
8038cd041efSChandler Carruth   return ConstantRange(Lower.sext(DstTySize), Upper.sext(DstTySize));
8048cd041efSChandler Carruth }
8058cd041efSChandler Carruth 
truncate(uint32_t DstTySize) const8068cd041efSChandler Carruth ConstantRange ConstantRange::truncate(uint32_t DstTySize) const {
8078cd041efSChandler Carruth   assert(getBitWidth() > DstTySize && "Not a value truncation");
8088cd041efSChandler Carruth   if (isEmptySet())
809977934f0SNikita Popov     return getEmpty(DstTySize);
8108cd041efSChandler Carruth   if (isFullSet())
811977934f0SNikita Popov     return getFull(DstTySize);
8128cd041efSChandler Carruth 
8138cd041efSChandler Carruth   APInt LowerDiv(Lower), UpperDiv(Upper);
8148cd041efSChandler Carruth   ConstantRange Union(DstTySize, /*isFullSet=*/false);
8158cd041efSChandler Carruth 
8168cd041efSChandler Carruth   // Analyze wrapped sets in their two parts: [0, Upper) \/ [Lower, MaxValue]
8178cd041efSChandler Carruth   // We use the non-wrapped set code to analyze the [Lower, MaxValue) part, and
8188cd041efSChandler Carruth   // then we do the union with [MaxValue, Upper)
8196d855ea0SNikita Popov   if (isUpperWrapped()) {
820f6e138d7SCraig Topper     // If Upper is greater than or equal to MaxValue(DstTy), it covers the whole
821f6e138d7SCraig Topper     // truncated range.
822f6e138d7SCraig Topper     if (Upper.getActiveBits() > DstTySize ||
823f6e138d7SCraig Topper         Upper.countTrailingOnes() == DstTySize)
824977934f0SNikita Popov       return getFull(DstTySize);
8258cd041efSChandler Carruth 
8268cd041efSChandler Carruth     Union = ConstantRange(APInt::getMaxValue(DstTySize),Upper.trunc(DstTySize));
82786616530SCraig Topper     UpperDiv.setAllBits();
8288cd041efSChandler Carruth 
8298cd041efSChandler Carruth     // Union covers the MaxValue case, so return if the remaining range is just
830f6e138d7SCraig Topper     // MaxValue(DstTy).
8318cd041efSChandler Carruth     if (LowerDiv == UpperDiv)
8328cd041efSChandler Carruth       return Union;
8338cd041efSChandler Carruth   }
8348cd041efSChandler Carruth 
8358cd041efSChandler Carruth   // Chop off the most significant bits that are past the destination bitwidth.
836f6e138d7SCraig Topper   if (LowerDiv.getActiveBits() > DstTySize) {
837f6e138d7SCraig Topper     // Mask to just the signficant bits and subtract from LowerDiv/UpperDiv.
838f6e138d7SCraig Topper     APInt Adjust = LowerDiv & APInt::getBitsSetFrom(getBitWidth(), DstTySize);
839f6e138d7SCraig Topper     LowerDiv -= Adjust;
840f6e138d7SCraig Topper     UpperDiv -= Adjust;
8418cd041efSChandler Carruth   }
8428cd041efSChandler Carruth 
843f6e138d7SCraig Topper   unsigned UpperDivWidth = UpperDiv.getActiveBits();
844f6e138d7SCraig Topper   if (UpperDivWidth <= DstTySize)
8458cd041efSChandler Carruth     return ConstantRange(LowerDiv.trunc(DstTySize),
8468cd041efSChandler Carruth                          UpperDiv.trunc(DstTySize)).unionWith(Union);
8478cd041efSChandler Carruth 
848bfad0155SNick Lewycky   // The truncated value wraps around. Check if we can do better than fullset.
849f6e138d7SCraig Topper   if (UpperDivWidth == DstTySize + 1) {
850f6e138d7SCraig Topper     // Clear the MSB so that UpperDiv wraps around.
851f6e138d7SCraig Topper     UpperDiv.clearBit(DstTySize);
852685327ddSCraig Topper     if (UpperDiv.ult(LowerDiv))
8538cd041efSChandler Carruth       return ConstantRange(LowerDiv.trunc(DstTySize),
854685327ddSCraig Topper                            UpperDiv.trunc(DstTySize)).unionWith(Union);
855f6e138d7SCraig Topper   }
8568cd041efSChandler Carruth 
857977934f0SNikita Popov   return getFull(DstTySize);
8588cd041efSChandler Carruth }
8598cd041efSChandler Carruth 
zextOrTrunc(uint32_t DstTySize) const8608cd041efSChandler Carruth ConstantRange ConstantRange::zextOrTrunc(uint32_t DstTySize) const {
8618cd041efSChandler Carruth   unsigned SrcTySize = getBitWidth();
8628cd041efSChandler Carruth   if (SrcTySize > DstTySize)
8638cd041efSChandler Carruth     return truncate(DstTySize);
8648cd041efSChandler Carruth   if (SrcTySize < DstTySize)
8658cd041efSChandler Carruth     return zeroExtend(DstTySize);
8668cd041efSChandler Carruth   return *this;
8678cd041efSChandler Carruth }
8688cd041efSChandler Carruth 
sextOrTrunc(uint32_t DstTySize) const8698cd041efSChandler Carruth ConstantRange ConstantRange::sextOrTrunc(uint32_t DstTySize) const {
8708cd041efSChandler Carruth   unsigned SrcTySize = getBitWidth();
8718cd041efSChandler Carruth   if (SrcTySize > DstTySize)
8728cd041efSChandler Carruth     return truncate(DstTySize);
8738cd041efSChandler Carruth   if (SrcTySize < DstTySize)
8748cd041efSChandler Carruth     return signExtend(DstTySize);
8758cd041efSChandler Carruth   return *this;
8768cd041efSChandler Carruth }
8778cd041efSChandler Carruth 
binaryOp(Instruction::BinaryOps BinOp,const ConstantRange & Other) const8784d00af1bSPhilip Reames ConstantRange ConstantRange::binaryOp(Instruction::BinaryOps BinOp,
8794d00af1bSPhilip Reames                                       const ConstantRange &Other) const {
880e0a6eb1fSSimon Pilgrim   assert(Instruction::isBinaryOp(BinOp) && "Binary operators only!");
8814d00af1bSPhilip Reames 
8824d00af1bSPhilip Reames   switch (BinOp) {
8834d00af1bSPhilip Reames   case Instruction::Add:
8844d00af1bSPhilip Reames     return add(Other);
8854d00af1bSPhilip Reames   case Instruction::Sub:
8864d00af1bSPhilip Reames     return sub(Other);
8874d00af1bSPhilip Reames   case Instruction::Mul:
8884d00af1bSPhilip Reames     return multiply(Other);
8894d00af1bSPhilip Reames   case Instruction::UDiv:
8904d00af1bSPhilip Reames     return udiv(Other);
891c061b99cSNikita Popov   case Instruction::SDiv:
892c061b99cSNikita Popov     return sdiv(Other);
893f945429fSNikita Popov   case Instruction::URem:
894f945429fSNikita Popov     return urem(Other);
895d5a403fbSNikita Popov   case Instruction::SRem:
896d5a403fbSNikita Popov     return srem(Other);
8974d00af1bSPhilip Reames   case Instruction::Shl:
8984d00af1bSPhilip Reames     return shl(Other);
8994d00af1bSPhilip Reames   case Instruction::LShr:
9004d00af1bSPhilip Reames     return lshr(Other);
901d792171eSMax Kazantsev   case Instruction::AShr:
902d792171eSMax Kazantsev     return ashr(Other);
9034d00af1bSPhilip Reames   case Instruction::And:
9044d00af1bSPhilip Reames     return binaryAnd(Other);
9054d00af1bSPhilip Reames   case Instruction::Or:
9064d00af1bSPhilip Reames     return binaryOr(Other);
9077caba339SFlorian Hahn   case Instruction::Xor:
9087caba339SFlorian Hahn     return binaryXor(Other);
9094d00af1bSPhilip Reames   // Note: floating point operations applied to abstract ranges are just
9104d00af1bSPhilip Reames   // ideal integer operations with a lossy representation
9114d00af1bSPhilip Reames   case Instruction::FAdd:
9124d00af1bSPhilip Reames     return add(Other);
9134d00af1bSPhilip Reames   case Instruction::FSub:
9144d00af1bSPhilip Reames     return sub(Other);
9154d00af1bSPhilip Reames   case Instruction::FMul:
9164d00af1bSPhilip Reames     return multiply(Other);
9174d00af1bSPhilip Reames   default:
918977934f0SNikita Popov     // Conservatively return getFull set.
919977934f0SNikita Popov     return getFull();
9204d00af1bSPhilip Reames   }
9214d00af1bSPhilip Reames }
9224d00af1bSPhilip Reames 
overflowingBinaryOp(Instruction::BinaryOps BinOp,const ConstantRange & Other,unsigned NoWrapKind) const9231f665046SRoman Lebedev ConstantRange ConstantRange::overflowingBinaryOp(Instruction::BinaryOps BinOp,
9241f665046SRoman Lebedev                                                  const ConstantRange &Other,
9251f665046SRoman Lebedev                                                  unsigned NoWrapKind) const {
9261f665046SRoman Lebedev   assert(Instruction::isBinaryOp(BinOp) && "Binary operators only!");
9271f665046SRoman Lebedev 
9281f665046SRoman Lebedev   switch (BinOp) {
9291f665046SRoman Lebedev   case Instruction::Add:
9301f665046SRoman Lebedev     return addWithNoWrap(Other, NoWrapKind);
93169ce2ae9SRoman Lebedev   case Instruction::Sub:
93269ce2ae9SRoman Lebedev     return subWithNoWrap(Other, NoWrapKind);
9331f665046SRoman Lebedev   default:
9341f665046SRoman Lebedev     // Don't know about this Overflowing Binary Operation.
9351f665046SRoman Lebedev     // Conservatively fallback to plain binop handling.
9361f665046SRoman Lebedev     return binaryOp(BinOp, Other);
9371f665046SRoman Lebedev   }
9381f665046SRoman Lebedev }
9391f665046SRoman Lebedev 
isIntrinsicSupported(Intrinsic::ID IntrinsicID)940897bdca4SNikita Popov bool ConstantRange::isIntrinsicSupported(Intrinsic::ID IntrinsicID) {
941897bdca4SNikita Popov   switch (IntrinsicID) {
942897bdca4SNikita Popov   case Intrinsic::uadd_sat:
943897bdca4SNikita Popov   case Intrinsic::usub_sat:
944897bdca4SNikita Popov   case Intrinsic::sadd_sat:
945897bdca4SNikita Popov   case Intrinsic::ssub_sat:
946d8a98a9cSNikita Popov   case Intrinsic::umin:
947d8a98a9cSNikita Popov   case Intrinsic::umax:
948d8a98a9cSNikita Popov   case Intrinsic::smin:
949d8a98a9cSNikita Popov   case Intrinsic::smax:
950d8a98a9cSNikita Popov   case Intrinsic::abs:
951897bdca4SNikita Popov     return true;
952897bdca4SNikita Popov   default:
953897bdca4SNikita Popov     return false;
954897bdca4SNikita Popov   }
955897bdca4SNikita Popov }
956897bdca4SNikita Popov 
intrinsic(Intrinsic::ID IntrinsicID,ArrayRef<ConstantRange> Ops)957897bdca4SNikita Popov ConstantRange ConstantRange::intrinsic(Intrinsic::ID IntrinsicID,
958897bdca4SNikita Popov                                        ArrayRef<ConstantRange> Ops) {
959897bdca4SNikita Popov   switch (IntrinsicID) {
960897bdca4SNikita Popov   case Intrinsic::uadd_sat:
961897bdca4SNikita Popov     return Ops[0].uadd_sat(Ops[1]);
962897bdca4SNikita Popov   case Intrinsic::usub_sat:
963897bdca4SNikita Popov     return Ops[0].usub_sat(Ops[1]);
964897bdca4SNikita Popov   case Intrinsic::sadd_sat:
965897bdca4SNikita Popov     return Ops[0].sadd_sat(Ops[1]);
966897bdca4SNikita Popov   case Intrinsic::ssub_sat:
967897bdca4SNikita Popov     return Ops[0].ssub_sat(Ops[1]);
968d8a98a9cSNikita Popov   case Intrinsic::umin:
969d8a98a9cSNikita Popov     return Ops[0].umin(Ops[1]);
970d8a98a9cSNikita Popov   case Intrinsic::umax:
971d8a98a9cSNikita Popov     return Ops[0].umax(Ops[1]);
972d8a98a9cSNikita Popov   case Intrinsic::smin:
973d8a98a9cSNikita Popov     return Ops[0].smin(Ops[1]);
974d8a98a9cSNikita Popov   case Intrinsic::smax:
975d8a98a9cSNikita Popov     return Ops[0].smax(Ops[1]);
9769ebeac67SNikita Popov   case Intrinsic::abs: {
9779ebeac67SNikita Popov     const APInt *IntMinIsPoison = Ops[1].getSingleElement();
9789ebeac67SNikita Popov     assert(IntMinIsPoison && "Must be known (immarg)");
9799ebeac67SNikita Popov     assert(IntMinIsPoison->getBitWidth() == 1 && "Must be boolean");
9809ebeac67SNikita Popov     return Ops[0].abs(IntMinIsPoison->getBoolValue());
9819ebeac67SNikita Popov   }
982897bdca4SNikita Popov   default:
983897bdca4SNikita Popov     assert(!isIntrinsicSupported(IntrinsicID) && "Shouldn't be supported");
984897bdca4SNikita Popov     llvm_unreachable("Unsupported intrinsic");
985897bdca4SNikita Popov   }
986897bdca4SNikita Popov }
987897bdca4SNikita Popov 
9888cd041efSChandler Carruth ConstantRange
add(const ConstantRange & Other) const9898cd041efSChandler Carruth ConstantRange::add(const ConstantRange &Other) const {
9908cd041efSChandler Carruth   if (isEmptySet() || Other.isEmptySet())
991977934f0SNikita Popov     return getEmpty();
9928cd041efSChandler Carruth   if (isFullSet() || Other.isFullSet())
993977934f0SNikita Popov     return getFull();
9948cd041efSChandler Carruth 
9958cd041efSChandler Carruth   APInt NewLower = getLower() + Other.getLower();
9968cd041efSChandler Carruth   APInt NewUpper = getUpper() + Other.getUpper() - 1;
9978cd041efSChandler Carruth   if (NewLower == NewUpper)
998977934f0SNikita Popov     return getFull();
9998cd041efSChandler Carruth 
1000b792025bSCraig Topper   ConstantRange X = ConstantRange(std::move(NewLower), std::move(NewUpper));
1001d29549e9SCraig Topper   if (X.isSizeStrictlySmallerThan(*this) ||
1002d29549e9SCraig Topper       X.isSizeStrictlySmallerThan(Other))
10038cd041efSChandler Carruth     // We've wrapped, therefore, full set.
1004977934f0SNikita Popov     return getFull();
10058cd041efSChandler Carruth   return X;
10068cd041efSChandler Carruth }
10078cd041efSChandler Carruth 
addWithNoWrap(const ConstantRange & Other,unsigned NoWrapKind,PreferredRangeType RangeType) const1008bfec0456SChen Zheng ConstantRange ConstantRange::addWithNoWrap(const ConstantRange &Other,
1009bfec0456SChen Zheng                                            unsigned NoWrapKind,
1010bfec0456SChen Zheng                                            PreferredRangeType RangeType) const {
1011bfec0456SChen Zheng   // Calculate the range for "X + Y" which is guaranteed not to wrap(overflow).
1012bfec0456SChen Zheng   // (X is from this, and Y is from Other)
1013bfec0456SChen Zheng   if (isEmptySet() || Other.isEmptySet())
1014bfec0456SChen Zheng     return getEmpty();
1015bfec0456SChen Zheng   if (isFullSet() && Other.isFullSet())
1016bfec0456SChen Zheng     return getFull();
1017bfec0456SChen Zheng 
1018bfec0456SChen Zheng   using OBO = OverflowingBinaryOperator;
1019bfec0456SChen Zheng   ConstantRange Result = add(Other);
1020bfec0456SChen Zheng 
1021365d729eSRoman Lebedev   // If an overflow happens for every value pair in these two constant ranges,
1022365d729eSRoman Lebedev   // we must return Empty set. In this case, we get that for free, because we
1023365d729eSRoman Lebedev   // get lucky that intersection of add() with uadd_sat()/sadd_sat() results
1024365d729eSRoman Lebedev   // in an empty set.
1025bfec0456SChen Zheng 
1026bfec0456SChen Zheng   if (NoWrapKind & OBO::NoSignedWrap)
1027365d729eSRoman Lebedev     Result = Result.intersectWith(sadd_sat(Other), RangeType);
1028365d729eSRoman Lebedev 
1029bfec0456SChen Zheng   if (NoWrapKind & OBO::NoUnsignedWrap)
1030365d729eSRoman Lebedev     Result = Result.intersectWith(uadd_sat(Other), RangeType);
1031365d729eSRoman Lebedev 
1032bfec0456SChen Zheng   return Result;
1033bfec0456SChen Zheng }
1034bfec0456SChen Zheng 
10358cd041efSChandler Carruth ConstantRange
sub(const ConstantRange & Other) const10368cd041efSChandler Carruth ConstantRange::sub(const ConstantRange &Other) const {
10378cd041efSChandler Carruth   if (isEmptySet() || Other.isEmptySet())
1038977934f0SNikita Popov     return getEmpty();
10398cd041efSChandler Carruth   if (isFullSet() || Other.isFullSet())
1040977934f0SNikita Popov     return getFull();
10418cd041efSChandler Carruth 
10428cd041efSChandler Carruth   APInt NewLower = getLower() - Other.getUpper() + 1;
10438cd041efSChandler Carruth   APInt NewUpper = getUpper() - Other.getLower();
10448cd041efSChandler Carruth   if (NewLower == NewUpper)
1045977934f0SNikita Popov     return getFull();
10468cd041efSChandler Carruth 
1047b792025bSCraig Topper   ConstantRange X = ConstantRange(std::move(NewLower), std::move(NewUpper));
1048d29549e9SCraig Topper   if (X.isSizeStrictlySmallerThan(*this) ||
1049d29549e9SCraig Topper       X.isSizeStrictlySmallerThan(Other))
10508cd041efSChandler Carruth     // We've wrapped, therefore, full set.
1051977934f0SNikita Popov     return getFull();
10528cd041efSChandler Carruth   return X;
10538cd041efSChandler Carruth }
10548cd041efSChandler Carruth 
subWithNoWrap(const ConstantRange & Other,unsigned NoWrapKind,PreferredRangeType RangeType) const10557fbe5d4bSRoman Lebedev ConstantRange ConstantRange::subWithNoWrap(const ConstantRange &Other,
10567fbe5d4bSRoman Lebedev                                            unsigned NoWrapKind,
10577fbe5d4bSRoman Lebedev                                            PreferredRangeType RangeType) const {
10587fbe5d4bSRoman Lebedev   // Calculate the range for "X - Y" which is guaranteed not to wrap(overflow).
10597fbe5d4bSRoman Lebedev   // (X is from this, and Y is from Other)
10607fbe5d4bSRoman Lebedev   if (isEmptySet() || Other.isEmptySet())
10617fbe5d4bSRoman Lebedev     return getEmpty();
10627fbe5d4bSRoman Lebedev   if (isFullSet() && Other.isFullSet())
10637fbe5d4bSRoman Lebedev     return getFull();
10647fbe5d4bSRoman Lebedev 
10657fbe5d4bSRoman Lebedev   using OBO = OverflowingBinaryOperator;
10667fbe5d4bSRoman Lebedev   ConstantRange Result = sub(Other);
10677fbe5d4bSRoman Lebedev 
10687fbe5d4bSRoman Lebedev   // If an overflow happens for every value pair in these two constant ranges,
10697fbe5d4bSRoman Lebedev   // we must return Empty set. In signed case, we get that for free, because we
10707dddfa2aSRoman Lebedev   // get lucky that intersection of sub() with ssub_sat() results in an
10717fbe5d4bSRoman Lebedev   // empty set. But for unsigned we must perform the overflow check manually.
10727fbe5d4bSRoman Lebedev 
10737fbe5d4bSRoman Lebedev   if (NoWrapKind & OBO::NoSignedWrap)
10747fbe5d4bSRoman Lebedev     Result = Result.intersectWith(ssub_sat(Other), RangeType);
10757fbe5d4bSRoman Lebedev 
10767fbe5d4bSRoman Lebedev   if (NoWrapKind & OBO::NoUnsignedWrap) {
10777fbe5d4bSRoman Lebedev     if (getUnsignedMax().ult(Other.getUnsignedMin()))
10787fbe5d4bSRoman Lebedev       return getEmpty(); // Always overflows.
10797fbe5d4bSRoman Lebedev     Result = Result.intersectWith(usub_sat(Other), RangeType);
10807fbe5d4bSRoman Lebedev   }
10817fbe5d4bSRoman Lebedev 
10827fbe5d4bSRoman Lebedev   return Result;
10837fbe5d4bSRoman Lebedev }
10847fbe5d4bSRoman Lebedev 
10858cd041efSChandler Carruth ConstantRange
multiply(const ConstantRange & Other) const10868cd041efSChandler Carruth ConstantRange::multiply(const ConstantRange &Other) const {
10878cd041efSChandler Carruth   // TODO: If either operand is a single element and the multiply is known to
10888cd041efSChandler Carruth   // be non-wrapping, round the result min and max value to the appropriate
10898cd041efSChandler Carruth   // multiple of that element. If wrapping is possible, at least adjust the
10908cd041efSChandler Carruth   // range according to the greatest power-of-two factor of the single element.
10918cd041efSChandler Carruth 
10928cd041efSChandler Carruth   if (isEmptySet() || Other.isEmptySet())
1093977934f0SNikita Popov     return getEmpty();
10948cd041efSChandler Carruth 
1095dcc78ec3SJames Molloy   // Multiplication is signedness-independent. However different ranges can be
1096dcc78ec3SJames Molloy   // obtained depending on how the input ranges are treated. These different
1097dcc78ec3SJames Molloy   // ranges are all conservatively correct, but one might be better than the
1098dcc78ec3SJames Molloy   // other. We calculate two ranges; one treating the inputs as unsigned
1099dcc78ec3SJames Molloy   // and the other signed, then return the smallest of these ranges.
1100dcc78ec3SJames Molloy 
1101dcc78ec3SJames Molloy   // Unsigned range first.
11028cd041efSChandler Carruth   APInt this_min = getUnsignedMin().zext(getBitWidth() * 2);
11038cd041efSChandler Carruth   APInt this_max = getUnsignedMax().zext(getBitWidth() * 2);
11048cd041efSChandler Carruth   APInt Other_min = Other.getUnsignedMin().zext(getBitWidth() * 2);
11058cd041efSChandler Carruth   APInt Other_max = Other.getUnsignedMax().zext(getBitWidth() * 2);
11068cd041efSChandler Carruth 
11078cd041efSChandler Carruth   ConstantRange Result_zext = ConstantRange(this_min * Other_min,
11088cd041efSChandler Carruth                                             this_max * Other_max + 1);
1109dcc78ec3SJames Molloy   ConstantRange UR = Result_zext.truncate(getBitWidth());
1110dcc78ec3SJames Molloy 
111134a7a945SPete Cooper   // If the unsigned range doesn't wrap, and isn't negative then it's a range
111234a7a945SPete Cooper   // from one positive number to another which is as good as we can generate.
111334a7a945SPete Cooper   // In this case, skip the extra work of generating signed ranges which aren't
111434a7a945SPete Cooper   // going to be better than this range.
11156d855ea0SNikita Popov   if (!UR.isUpperWrapped() &&
1116c51d0536SCraig Topper       (UR.getUpper().isNonNegative() || UR.getUpper().isMinSignedValue()))
111734a7a945SPete Cooper     return UR;
111834a7a945SPete Cooper 
1119dcc78ec3SJames Molloy   // Now the signed range. Because we could be dealing with negative numbers
1120dcc78ec3SJames Molloy   // here, the lower bound is the smallest of the cartesian product of the
1121dcc78ec3SJames Molloy   // lower and upper ranges; for example:
1122dcc78ec3SJames Molloy   //   [-1,4) * [-2,3) = min(-1*-2, -1*2, 3*-2, 3*2) = -6.
1123dcc78ec3SJames Molloy   // Similarly for the upper bound, swapping min for max.
1124dcc78ec3SJames Molloy 
1125dcc78ec3SJames Molloy   this_min = getSignedMin().sext(getBitWidth() * 2);
1126dcc78ec3SJames Molloy   this_max = getSignedMax().sext(getBitWidth() * 2);
1127dcc78ec3SJames Molloy   Other_min = Other.getSignedMin().sext(getBitWidth() * 2);
1128dcc78ec3SJames Molloy   Other_max = Other.getSignedMax().sext(getBitWidth() * 2);
1129dcc78ec3SJames Molloy 
1130dcc78ec3SJames Molloy   auto L = {this_min * Other_min, this_min * Other_max,
1131dcc78ec3SJames Molloy             this_max * Other_min, this_max * Other_max};
1132dcc78ec3SJames Molloy   auto Compare = [](const APInt &A, const APInt &B) { return A.slt(B); };
1133dcc78ec3SJames Molloy   ConstantRange Result_sext(std::min(L, Compare), std::max(L, Compare) + 1);
1134dcc78ec3SJames Molloy   ConstantRange SR = Result_sext.truncate(getBitWidth());
1135dcc78ec3SJames Molloy 
1136d29549e9SCraig Topper   return UR.isSizeStrictlySmallerThan(SR) ? UR : SR;
11378cd041efSChandler Carruth }
11388cd041efSChandler Carruth 
smul_fast(const ConstantRange & Other) const1139274b2439SNikita Popov ConstantRange ConstantRange::smul_fast(const ConstantRange &Other) const {
1140274b2439SNikita Popov   if (isEmptySet() || Other.isEmptySet())
1141274b2439SNikita Popov     return getEmpty();
1142274b2439SNikita Popov 
1143274b2439SNikita Popov   APInt Min = getSignedMin();
1144274b2439SNikita Popov   APInt Max = getSignedMax();
1145274b2439SNikita Popov   APInt OtherMin = Other.getSignedMin();
1146274b2439SNikita Popov   APInt OtherMax = Other.getSignedMax();
1147274b2439SNikita Popov 
1148274b2439SNikita Popov   bool O1, O2, O3, O4;
1149274b2439SNikita Popov   auto Muls = {Min.smul_ov(OtherMin, O1), Min.smul_ov(OtherMax, O2),
1150274b2439SNikita Popov                Max.smul_ov(OtherMin, O3), Max.smul_ov(OtherMax, O4)};
1151274b2439SNikita Popov   if (O1 || O2 || O3 || O4)
1152274b2439SNikita Popov     return getFull();
1153274b2439SNikita Popov 
1154274b2439SNikita Popov   auto Compare = [](const APInt &A, const APInt &B) { return A.slt(B); };
1155274b2439SNikita Popov   return getNonEmpty(std::min(Muls, Compare), std::max(Muls, Compare) + 1);
1156274b2439SNikita Popov }
1157274b2439SNikita Popov 
11588cd041efSChandler Carruth ConstantRange
smax(const ConstantRange & Other) const11598cd041efSChandler Carruth ConstantRange::smax(const ConstantRange &Other) const {
11608cd041efSChandler Carruth   // X smax Y is: range(smax(X_smin, Y_smin),
11618cd041efSChandler Carruth   //                    smax(X_smax, Y_smax))
11628cd041efSChandler Carruth   if (isEmptySet() || Other.isEmptySet())
1163977934f0SNikita Popov     return getEmpty();
11648cd041efSChandler Carruth   APInt NewL = APIntOps::smax(getSignedMin(), Other.getSignedMin());
11658cd041efSChandler Carruth   APInt NewU = APIntOps::smax(getSignedMax(), Other.getSignedMax()) + 1;
1166a852234fSNikita Popov   ConstantRange Res = getNonEmpty(std::move(NewL), std::move(NewU));
1167a852234fSNikita Popov   if (isSignWrappedSet() || Other.isSignWrappedSet())
1168a852234fSNikita Popov     return Res.intersectWith(unionWith(Other, Signed), Signed);
1169a852234fSNikita Popov   return Res;
11708cd041efSChandler Carruth }
11718cd041efSChandler Carruth 
11728cd041efSChandler Carruth ConstantRange
umax(const ConstantRange & Other) const11738cd041efSChandler Carruth ConstantRange::umax(const ConstantRange &Other) const {
11748cd041efSChandler Carruth   // X umax Y is: range(umax(X_umin, Y_umin),
11758cd041efSChandler Carruth   //                    umax(X_umax, Y_umax))
11768cd041efSChandler Carruth   if (isEmptySet() || Other.isEmptySet())
1177977934f0SNikita Popov     return getEmpty();
11788cd041efSChandler Carruth   APInt NewL = APIntOps::umax(getUnsignedMin(), Other.getUnsignedMin());
11798cd041efSChandler Carruth   APInt NewU = APIntOps::umax(getUnsignedMax(), Other.getUnsignedMax()) + 1;
1180a852234fSNikita Popov   ConstantRange Res = getNonEmpty(std::move(NewL), std::move(NewU));
1181a852234fSNikita Popov   if (isWrappedSet() || Other.isWrappedSet())
1182a852234fSNikita Popov     return Res.intersectWith(unionWith(Other, Unsigned), Unsigned);
1183a852234fSNikita Popov   return Res;
11848cd041efSChandler Carruth }
11858cd041efSChandler Carruth 
11868cd041efSChandler Carruth ConstantRange
smin(const ConstantRange & Other) const1187ba31312fSPhilip Reames ConstantRange::smin(const ConstantRange &Other) const {
1188ba31312fSPhilip Reames   // X smin Y is: range(smin(X_smin, Y_smin),
1189ba31312fSPhilip Reames   //                    smin(X_smax, Y_smax))
1190ba31312fSPhilip Reames   if (isEmptySet() || Other.isEmptySet())
1191977934f0SNikita Popov     return getEmpty();
1192ba31312fSPhilip Reames   APInt NewL = APIntOps::smin(getSignedMin(), Other.getSignedMin());
1193ba31312fSPhilip Reames   APInt NewU = APIntOps::smin(getSignedMax(), Other.getSignedMax()) + 1;
1194a852234fSNikita Popov   ConstantRange Res = getNonEmpty(std::move(NewL), std::move(NewU));
1195a852234fSNikita Popov   if (isSignWrappedSet() || Other.isSignWrappedSet())
1196a852234fSNikita Popov     return Res.intersectWith(unionWith(Other, Signed), Signed);
1197a852234fSNikita Popov   return Res;
1198ba31312fSPhilip Reames }
1199ba31312fSPhilip Reames 
1200ba31312fSPhilip Reames ConstantRange
umin(const ConstantRange & Other) const1201ba31312fSPhilip Reames ConstantRange::umin(const ConstantRange &Other) const {
1202ba31312fSPhilip Reames   // X umin Y is: range(umin(X_umin, Y_umin),
1203ba31312fSPhilip Reames   //                    umin(X_umax, Y_umax))
1204ba31312fSPhilip Reames   if (isEmptySet() || Other.isEmptySet())
1205977934f0SNikita Popov     return getEmpty();
1206ba31312fSPhilip Reames   APInt NewL = APIntOps::umin(getUnsignedMin(), Other.getUnsignedMin());
1207ba31312fSPhilip Reames   APInt NewU = APIntOps::umin(getUnsignedMax(), Other.getUnsignedMax()) + 1;
1208a852234fSNikita Popov   ConstantRange Res = getNonEmpty(std::move(NewL), std::move(NewU));
1209a852234fSNikita Popov   if (isWrappedSet() || Other.isWrappedSet())
1210a852234fSNikita Popov     return Res.intersectWith(unionWith(Other, Unsigned), Unsigned);
1211a852234fSNikita Popov   return Res;
1212ba31312fSPhilip Reames }
1213ba31312fSPhilip Reames 
1214ba31312fSPhilip Reames ConstantRange
udiv(const ConstantRange & RHS) const12158cd041efSChandler Carruth ConstantRange::udiv(const ConstantRange &RHS) const {
1216735f4671SChris Lattner   if (isEmptySet() || RHS.isEmptySet() || RHS.getUnsignedMax().isZero())
1217977934f0SNikita Popov     return getEmpty();
12188cd041efSChandler Carruth 
12198cd041efSChandler Carruth   APInt Lower = getUnsignedMin().udiv(RHS.getUnsignedMax());
12208cd041efSChandler Carruth 
12218cd041efSChandler Carruth   APInt RHS_umin = RHS.getUnsignedMin();
1222735f4671SChris Lattner   if (RHS_umin.isZero()) {
12238cd041efSChandler Carruth     // We want the lowest value in RHS excluding zero. Usually that would be 1
12248cd041efSChandler Carruth     // except for a range in the form of [X, 1) in which case it would be X.
12258cd041efSChandler Carruth     if (RHS.getUpper() == 1)
12268cd041efSChandler Carruth       RHS_umin = RHS.getLower();
12278cd041efSChandler Carruth     else
122886616530SCraig Topper       RHS_umin = 1;
12298cd041efSChandler Carruth   }
12308cd041efSChandler Carruth 
12318cd041efSChandler Carruth   APInt Upper = getUnsignedMax().udiv(RHS_umin) + 1;
1232dbc3fbafSNikita Popov   return getNonEmpty(std::move(Lower), std::move(Upper));
12338cd041efSChandler Carruth }
12348cd041efSChandler Carruth 
sdiv(const ConstantRange & RHS) const1235c061b99cSNikita Popov ConstantRange ConstantRange::sdiv(const ConstantRange &RHS) const {
1236c061b99cSNikita Popov   // We split up the LHS and RHS into positive and negative components
1237c061b99cSNikita Popov   // and then also compute the positive and negative components of the result
1238c061b99cSNikita Popov   // separately by combining division results with the appropriate signs.
1239735f4671SChris Lattner   APInt Zero = APInt::getZero(getBitWidth());
1240c061b99cSNikita Popov   APInt SignedMin = APInt::getSignedMinValue(getBitWidth());
1241*ba1e04b9SNikita Popov   // There are no positive 1-bit values. The 1 would get interpreted as -1.
1242*ba1e04b9SNikita Popov   ConstantRange PosFilter =
1243*ba1e04b9SNikita Popov       getBitWidth() == 1 ? getEmpty()
1244*ba1e04b9SNikita Popov                          : ConstantRange(APInt(getBitWidth(), 1), SignedMin);
1245c061b99cSNikita Popov   ConstantRange NegFilter(SignedMin, Zero);
1246c061b99cSNikita Popov   ConstantRange PosL = intersectWith(PosFilter);
1247c061b99cSNikita Popov   ConstantRange NegL = intersectWith(NegFilter);
1248c061b99cSNikita Popov   ConstantRange PosR = RHS.intersectWith(PosFilter);
1249c061b99cSNikita Popov   ConstantRange NegR = RHS.intersectWith(NegFilter);
1250c061b99cSNikita Popov 
1251c061b99cSNikita Popov   ConstantRange PosRes = getEmpty();
1252c061b99cSNikita Popov   if (!PosL.isEmptySet() && !PosR.isEmptySet())
1253c061b99cSNikita Popov     // pos / pos = pos.
1254c061b99cSNikita Popov     PosRes = ConstantRange(PosL.Lower.sdiv(PosR.Upper - 1),
1255c061b99cSNikita Popov                            (PosL.Upper - 1).sdiv(PosR.Lower) + 1);
1256c061b99cSNikita Popov 
1257c061b99cSNikita Popov   if (!NegL.isEmptySet() && !NegR.isEmptySet()) {
1258c061b99cSNikita Popov     // neg / neg = pos.
1259c061b99cSNikita Popov     //
1260c061b99cSNikita Popov     // We need to deal with one tricky case here: SignedMin / -1 is UB on the
1261c061b99cSNikita Popov     // IR level, so we'll want to exclude this case when calculating bounds.
1262c061b99cSNikita Popov     // (For APInts the operation is well-defined and yields SignedMin.) We
1263c061b99cSNikita Popov     // handle this by dropping either SignedMin from the LHS or -1 from the RHS.
1264c061b99cSNikita Popov     APInt Lo = (NegL.Upper - 1).sdiv(NegR.Lower);
1265735f4671SChris Lattner     if (NegL.Lower.isMinSignedValue() && NegR.Upper.isZero()) {
1266c061b99cSNikita Popov       // Remove -1 from the LHS. Skip if it's the only element, as this would
1267c061b99cSNikita Popov       // leave us with an empty set.
1268a9bceb2bSJay Foad       if (!NegR.Lower.isAllOnes()) {
1269c061b99cSNikita Popov         APInt AdjNegRUpper;
1270a9bceb2bSJay Foad         if (RHS.Lower.isAllOnes())
1271c061b99cSNikita Popov           // Negative part of [-1, X] without -1 is [SignedMin, X].
1272c061b99cSNikita Popov           AdjNegRUpper = RHS.Upper;
1273c061b99cSNikita Popov         else
1274c061b99cSNikita Popov           // [X, -1] without -1 is [X, -2].
1275c061b99cSNikita Popov           AdjNegRUpper = NegR.Upper - 1;
1276c061b99cSNikita Popov 
1277c061b99cSNikita Popov         PosRes = PosRes.unionWith(
1278c061b99cSNikita Popov             ConstantRange(Lo, NegL.Lower.sdiv(AdjNegRUpper - 1) + 1));
1279c061b99cSNikita Popov       }
1280c061b99cSNikita Popov 
1281c061b99cSNikita Popov       // Remove SignedMin from the RHS. Skip if it's the only element, as this
1282c061b99cSNikita Popov       // would leave us with an empty set.
1283c061b99cSNikita Popov       if (NegL.Upper != SignedMin + 1) {
1284c061b99cSNikita Popov         APInt AdjNegLLower;
1285c061b99cSNikita Popov         if (Upper == SignedMin + 1)
1286c061b99cSNikita Popov           // Negative part of [X, SignedMin] without SignedMin is [X, -1].
1287c061b99cSNikita Popov           AdjNegLLower = Lower;
1288c061b99cSNikita Popov         else
1289c061b99cSNikita Popov           // [SignedMin, X] without SignedMin is [SignedMin + 1, X].
1290c061b99cSNikita Popov           AdjNegLLower = NegL.Lower + 1;
1291c061b99cSNikita Popov 
1292c061b99cSNikita Popov         PosRes = PosRes.unionWith(
1293c061b99cSNikita Popov             ConstantRange(std::move(Lo),
1294c061b99cSNikita Popov                           AdjNegLLower.sdiv(NegR.Upper - 1) + 1));
1295c061b99cSNikita Popov       }
1296c061b99cSNikita Popov     } else {
1297c061b99cSNikita Popov       PosRes = PosRes.unionWith(
1298c061b99cSNikita Popov           ConstantRange(std::move(Lo), NegL.Lower.sdiv(NegR.Upper - 1) + 1));
1299c061b99cSNikita Popov     }
1300c061b99cSNikita Popov   }
1301c061b99cSNikita Popov 
1302c061b99cSNikita Popov   ConstantRange NegRes = getEmpty();
1303c061b99cSNikita Popov   if (!PosL.isEmptySet() && !NegR.isEmptySet())
1304c061b99cSNikita Popov     // pos / neg = neg.
1305c061b99cSNikita Popov     NegRes = ConstantRange((PosL.Upper - 1).sdiv(NegR.Upper - 1),
1306c061b99cSNikita Popov                            PosL.Lower.sdiv(NegR.Lower) + 1);
1307c061b99cSNikita Popov 
1308c061b99cSNikita Popov   if (!NegL.isEmptySet() && !PosR.isEmptySet())
1309c061b99cSNikita Popov     // neg / pos = neg.
1310c061b99cSNikita Popov     NegRes = NegRes.unionWith(
1311c061b99cSNikita Popov         ConstantRange(NegL.Lower.sdiv(PosR.Lower),
1312c061b99cSNikita Popov                       (NegL.Upper - 1).sdiv(PosR.Upper - 1) + 1));
1313c061b99cSNikita Popov 
1314c061b99cSNikita Popov   // Prefer a non-wrapping signed range here.
1315c061b99cSNikita Popov   ConstantRange Res = NegRes.unionWith(PosRes, PreferredRangeType::Signed);
1316c061b99cSNikita Popov 
1317c061b99cSNikita Popov   // Preserve the zero that we dropped when splitting the LHS by sign.
1318c061b99cSNikita Popov   if (contains(Zero) && (!PosR.isEmptySet() || !NegR.isEmptySet()))
1319c061b99cSNikita Popov     Res = Res.unionWith(ConstantRange(Zero));
1320c061b99cSNikita Popov   return Res;
1321c061b99cSNikita Popov }
1322c061b99cSNikita Popov 
urem(const ConstantRange & RHS) const1323f945429fSNikita Popov ConstantRange ConstantRange::urem(const ConstantRange &RHS) const {
1324735f4671SChris Lattner   if (isEmptySet() || RHS.isEmptySet() || RHS.getUnsignedMax().isZero())
1325f945429fSNikita Popov     return getEmpty();
1326f945429fSNikita Popov 
1327611a02ccSFlorian Hahn   if (const APInt *RHSInt = RHS.getSingleElement()) {
1328611a02ccSFlorian Hahn     // UREM by null is UB.
1329735f4671SChris Lattner     if (RHSInt->isZero())
1330611a02ccSFlorian Hahn       return getEmpty();
1331611a02ccSFlorian Hahn     // Use APInt's implementation of UREM for single element ranges.
1332611a02ccSFlorian Hahn     if (const APInt *LHSInt = getSingleElement())
1333611a02ccSFlorian Hahn       return {LHSInt->urem(*RHSInt)};
1334611a02ccSFlorian Hahn   }
1335611a02ccSFlorian Hahn 
1336f945429fSNikita Popov   // L % R for L < R is L.
1337f945429fSNikita Popov   if (getUnsignedMax().ult(RHS.getUnsignedMin()))
1338f945429fSNikita Popov     return *this;
1339f945429fSNikita Popov 
1340f945429fSNikita Popov   // L % R is <= L and < R.
1341f945429fSNikita Popov   APInt Upper = APIntOps::umin(getUnsignedMax(), RHS.getUnsignedMax() - 1) + 1;
1342735f4671SChris Lattner   return getNonEmpty(APInt::getZero(getBitWidth()), std::move(Upper));
1343f945429fSNikita Popov }
1344f945429fSNikita Popov 
srem(const ConstantRange & RHS) const1345d5a403fbSNikita Popov ConstantRange ConstantRange::srem(const ConstantRange &RHS) const {
1346d5a403fbSNikita Popov   if (isEmptySet() || RHS.isEmptySet())
1347d5a403fbSNikita Popov     return getEmpty();
1348d5a403fbSNikita Popov 
1349611a02ccSFlorian Hahn   if (const APInt *RHSInt = RHS.getSingleElement()) {
1350611a02ccSFlorian Hahn     // SREM by null is UB.
1351735f4671SChris Lattner     if (RHSInt->isZero())
1352611a02ccSFlorian Hahn       return getEmpty();
1353611a02ccSFlorian Hahn     // Use APInt's implementation of SREM for single element ranges.
1354611a02ccSFlorian Hahn     if (const APInt *LHSInt = getSingleElement())
1355611a02ccSFlorian Hahn       return {LHSInt->srem(*RHSInt)};
1356611a02ccSFlorian Hahn   }
1357611a02ccSFlorian Hahn 
1358d5a403fbSNikita Popov   ConstantRange AbsRHS = RHS.abs();
1359d5a403fbSNikita Popov   APInt MinAbsRHS = AbsRHS.getUnsignedMin();
1360d5a403fbSNikita Popov   APInt MaxAbsRHS = AbsRHS.getUnsignedMax();
1361d5a403fbSNikita Popov 
1362d5a403fbSNikita Popov   // Modulus by zero is UB.
1363735f4671SChris Lattner   if (MaxAbsRHS.isZero())
1364d5a403fbSNikita Popov     return getEmpty();
1365d5a403fbSNikita Popov 
1366735f4671SChris Lattner   if (MinAbsRHS.isZero())
1367d5a403fbSNikita Popov     ++MinAbsRHS;
1368d5a403fbSNikita Popov 
1369d5a403fbSNikita Popov   APInt MinLHS = getSignedMin(), MaxLHS = getSignedMax();
1370d5a403fbSNikita Popov 
1371d5a403fbSNikita Popov   if (MinLHS.isNonNegative()) {
1372d5a403fbSNikita Popov     // L % R for L < R is L.
1373d5a403fbSNikita Popov     if (MaxLHS.ult(MinAbsRHS))
1374d5a403fbSNikita Popov       return *this;
1375d5a403fbSNikita Popov 
1376d5a403fbSNikita Popov     // L % R is <= L and < R.
1377d5a403fbSNikita Popov     APInt Upper = APIntOps::umin(MaxLHS, MaxAbsRHS - 1) + 1;
1378735f4671SChris Lattner     return ConstantRange(APInt::getZero(getBitWidth()), std::move(Upper));
1379d5a403fbSNikita Popov   }
1380d5a403fbSNikita Popov 
1381d5a403fbSNikita Popov   // Same basic logic as above, but the result is negative.
1382d5a403fbSNikita Popov   if (MaxLHS.isNegative()) {
1383d5a403fbSNikita Popov     if (MinLHS.ugt(-MinAbsRHS))
1384d5a403fbSNikita Popov       return *this;
1385d5a403fbSNikita Popov 
1386d5a403fbSNikita Popov     APInt Lower = APIntOps::umax(MinLHS, -MaxAbsRHS + 1);
1387d5a403fbSNikita Popov     return ConstantRange(std::move(Lower), APInt(getBitWidth(), 1));
1388d5a403fbSNikita Popov   }
1389d5a403fbSNikita Popov 
1390d5a403fbSNikita Popov   // LHS range crosses zero.
1391d5a403fbSNikita Popov   APInt Lower = APIntOps::umax(MinLHS, -MaxAbsRHS + 1);
1392d5a403fbSNikita Popov   APInt Upper = APIntOps::umin(MaxLHS, MaxAbsRHS - 1) + 1;
1393d5a403fbSNikita Popov   return ConstantRange(std::move(Lower), std::move(Upper));
1394d5a403fbSNikita Popov }
1395d5a403fbSNikita Popov 
binaryNot() const1396b38d897eSRoman Lebedev ConstantRange ConstantRange::binaryNot() const {
1397735f4671SChris Lattner   return ConstantRange(APInt::getAllOnes(getBitWidth())).sub(*this);
1398b38d897eSRoman Lebedev }
1399b38d897eSRoman Lebedev 
binaryAnd(const ConstantRange & Other) const14000f4d9f9bSAlexander Shaposhnikov ConstantRange ConstantRange::binaryAnd(const ConstantRange &Other) const {
14018cd041efSChandler Carruth   if (isEmptySet() || Other.isEmptySet())
1402977934f0SNikita Popov     return getEmpty();
14038cd041efSChandler Carruth 
14040f4d9f9bSAlexander Shaposhnikov   ConstantRange KnownBitsRange =
14050f4d9f9bSAlexander Shaposhnikov       fromKnownBits(toKnownBits() & Other.toKnownBits(), false);
14060f4d9f9bSAlexander Shaposhnikov   ConstantRange UMinUMaxRange =
14070f4d9f9bSAlexander Shaposhnikov       getNonEmpty(APInt::getZero(getBitWidth()),
14080f4d9f9bSAlexander Shaposhnikov                   APIntOps::umin(Other.getUnsignedMax(), getUnsignedMax()) + 1);
14090f4d9f9bSAlexander Shaposhnikov   return KnownBitsRange.intersectWith(UMinUMaxRange);
14108cd041efSChandler Carruth }
14118cd041efSChandler Carruth 
binaryOr(const ConstantRange & Other) const14120f4d9f9bSAlexander Shaposhnikov ConstantRange ConstantRange::binaryOr(const ConstantRange &Other) const {
14138cd041efSChandler Carruth   if (isEmptySet() || Other.isEmptySet())
1414977934f0SNikita Popov     return getEmpty();
14158cd041efSChandler Carruth 
14169398caf3SAlexander Shaposhnikov   ConstantRange KnownBitsRange =
14179398caf3SAlexander Shaposhnikov       fromKnownBits(toKnownBits() | Other.toKnownBits(), false);
14189398caf3SAlexander Shaposhnikov   // Upper wrapped range.
14199398caf3SAlexander Shaposhnikov   ConstantRange UMaxUMinRange =
14209398caf3SAlexander Shaposhnikov       getNonEmpty(APIntOps::umax(getUnsignedMin(), Other.getUnsignedMin()),
14219398caf3SAlexander Shaposhnikov                   APInt::getZero(getBitWidth()));
14229398caf3SAlexander Shaposhnikov   return KnownBitsRange.intersectWith(UMaxUMinRange);
14238cd041efSChandler Carruth }
14248cd041efSChandler Carruth 
binaryXor(const ConstantRange & Other) const14257caba339SFlorian Hahn ConstantRange ConstantRange::binaryXor(const ConstantRange &Other) const {
14267caba339SFlorian Hahn   if (isEmptySet() || Other.isEmptySet())
14277caba339SFlorian Hahn     return getEmpty();
14287caba339SFlorian Hahn 
14297caba339SFlorian Hahn   // Use APInt's implementation of XOR for single element ranges.
14307caba339SFlorian Hahn   if (isSingleElement() && Other.isSingleElement())
14317caba339SFlorian Hahn     return {*getSingleElement() ^ *Other.getSingleElement()};
14327caba339SFlorian Hahn 
1433b38d897eSRoman Lebedev   // Special-case binary complement, since we can give a precise answer.
1434a9bceb2bSJay Foad   if (Other.isSingleElement() && Other.getSingleElement()->isAllOnes())
1435b38d897eSRoman Lebedev     return binaryNot();
1436a9bceb2bSJay Foad   if (isSingleElement() && getSingleElement()->isAllOnes())
1437b38d897eSRoman Lebedev     return Other.binaryNot();
1438b38d897eSRoman Lebedev 
14392db4dc7eSNikita Popov   return fromKnownBits(toKnownBits() ^ Other.toKnownBits(), /*IsSigned*/false);
14407caba339SFlorian Hahn }
14417caba339SFlorian Hahn 
14428cd041efSChandler Carruth ConstantRange
shl(const ConstantRange & Other) const14438cd041efSChandler Carruth ConstantRange::shl(const ConstantRange &Other) const {
14448cd041efSChandler Carruth   if (isEmptySet() || Other.isEmptySet())
1445977934f0SNikita Popov     return getEmpty();
14468cd041efSChandler Carruth 
1447587493b4SNikita Popov   APInt Min = getUnsignedMin();
1448587493b4SNikita Popov   APInt Max = getUnsignedMax();
1449587493b4SNikita Popov   if (const APInt *RHS = Other.getSingleElement()) {
1450587493b4SNikita Popov     unsigned BW = getBitWidth();
1451587493b4SNikita Popov     if (RHS->uge(BW))
1452587493b4SNikita Popov       return getEmpty();
14538cd041efSChandler Carruth 
1454587493b4SNikita Popov     unsigned EqualLeadingBits = (Min ^ Max).countLeadingZeros();
1455587493b4SNikita Popov     if (RHS->ule(EqualLeadingBits))
1456587493b4SNikita Popov       return getNonEmpty(Min << *RHS, (Max << *RHS) + 1);
1457587493b4SNikita Popov 
1458587493b4SNikita Popov     return getNonEmpty(APInt::getZero(BW),
1459587493b4SNikita Popov                        APInt::getBitsSetFrom(BW, RHS->getZExtValue()) + 1);
1460587493b4SNikita Popov   }
1461587493b4SNikita Popov 
1462587493b4SNikita Popov   APInt OtherMax = Other.getUnsignedMax();
1463587493b4SNikita Popov 
1464587493b4SNikita Popov   // There's overflow!
1465587493b4SNikita Popov   if (OtherMax.ugt(Max.countLeadingZeros()))
1466977934f0SNikita Popov     return getFull();
14678cd041efSChandler Carruth 
14688cd041efSChandler Carruth   // FIXME: implement the other tricky cases
1469ef02803bSCraig Topper 
1470587493b4SNikita Popov   Min <<= Other.getUnsignedMin();
1471587493b4SNikita Popov   Max <<= OtherMax;
1472ef02803bSCraig Topper 
1473587493b4SNikita Popov   return ConstantRange::getNonEmpty(std::move(Min), std::move(Max) + 1);
14748cd041efSChandler Carruth }
14758cd041efSChandler Carruth 
14768cd041efSChandler Carruth ConstantRange
lshr(const ConstantRange & Other) const14778cd041efSChandler Carruth ConstantRange::lshr(const ConstantRange &Other) const {
14788cd041efSChandler Carruth   if (isEmptySet() || Other.isEmptySet())
1479977934f0SNikita Popov     return getEmpty();
14808cd041efSChandler Carruth 
148179b7666fSCraig Topper   APInt max = getUnsignedMax().lshr(Other.getUnsignedMin()) + 1;
14828cd041efSChandler Carruth   APInt min = getUnsignedMin().lshr(Other.getUnsignedMax());
1483dbc3fbafSNikita Popov   return getNonEmpty(std::move(min), std::move(max));
14848cd041efSChandler Carruth }
14858cd041efSChandler Carruth 
1486d792171eSMax Kazantsev ConstantRange
ashr(const ConstantRange & Other) const1487d792171eSMax Kazantsev ConstantRange::ashr(const ConstantRange &Other) const {
1488d792171eSMax Kazantsev   if (isEmptySet() || Other.isEmptySet())
1489977934f0SNikita Popov     return getEmpty();
1490d792171eSMax Kazantsev 
1491d792171eSMax Kazantsev   // May straddle zero, so handle both positive and negative cases.
1492d792171eSMax Kazantsev   // 'PosMax' is the upper bound of the result of the ashr
1493d792171eSMax Kazantsev   // operation, when Upper of the LHS of ashr is a non-negative.
1494d792171eSMax Kazantsev   // number. Since ashr of a non-negative number will result in a
1495d792171eSMax Kazantsev   // smaller number, the Upper value of LHS is shifted right with
1496d792171eSMax Kazantsev   // the minimum value of 'Other' instead of the maximum value.
1497d792171eSMax Kazantsev   APInt PosMax = getSignedMax().ashr(Other.getUnsignedMin()) + 1;
1498d792171eSMax Kazantsev 
1499d792171eSMax Kazantsev   // 'PosMin' is the lower bound of the result of the ashr
1500d792171eSMax Kazantsev   // operation, when Lower of the LHS is a non-negative number.
1501d792171eSMax Kazantsev   // Since ashr of a non-negative number will result in a smaller
1502d792171eSMax Kazantsev   // number, the Lower value of LHS is shifted right with the
1503d792171eSMax Kazantsev   // maximum value of 'Other'.
1504d792171eSMax Kazantsev   APInt PosMin = getSignedMin().ashr(Other.getUnsignedMax());
1505d792171eSMax Kazantsev 
1506d792171eSMax Kazantsev   // 'NegMax' is the upper bound of the result of the ashr
1507d792171eSMax Kazantsev   // operation, when Upper of the LHS of ashr is a negative number.
1508d792171eSMax Kazantsev   // Since 'ashr' of a negative number will result in a bigger
1509d792171eSMax Kazantsev   // number, the Upper value of LHS is shifted right with the
1510d792171eSMax Kazantsev   // maximum value of 'Other'.
1511d792171eSMax Kazantsev   APInt NegMax = getSignedMax().ashr(Other.getUnsignedMax()) + 1;
1512d792171eSMax Kazantsev 
1513d792171eSMax Kazantsev   // 'NegMin' is the lower bound of the result of the ashr
1514d792171eSMax Kazantsev   // operation, when Lower of the LHS of ashr is a negative number.
1515d792171eSMax Kazantsev   // Since 'ashr' of a negative number will result in a bigger
1516d792171eSMax Kazantsev   // number, the Lower value of LHS is shifted right with the
1517d792171eSMax Kazantsev   // minimum value of 'Other'.
1518d792171eSMax Kazantsev   APInt NegMin = getSignedMin().ashr(Other.getUnsignedMin());
1519d792171eSMax Kazantsev 
1520d792171eSMax Kazantsev   APInt max, min;
1521d792171eSMax Kazantsev   if (getSignedMin().isNonNegative()) {
1522d792171eSMax Kazantsev     // Upper and Lower of LHS are non-negative.
1523d792171eSMax Kazantsev     min = PosMin;
1524d792171eSMax Kazantsev     max = PosMax;
1525d792171eSMax Kazantsev   } else if (getSignedMax().isNegative()) {
1526d792171eSMax Kazantsev     // Upper and Lower of LHS are negative.
1527d792171eSMax Kazantsev     min = NegMin;
1528d792171eSMax Kazantsev     max = NegMax;
1529d792171eSMax Kazantsev   } else {
1530d792171eSMax Kazantsev     // Upper is non-negative and Lower is negative.
1531d792171eSMax Kazantsev     min = NegMin;
1532d792171eSMax Kazantsev     max = PosMax;
1533d792171eSMax Kazantsev   }
1534dbc3fbafSNikita Popov   return getNonEmpty(std::move(min), std::move(max));
1535d792171eSMax Kazantsev }
1536d792171eSMax Kazantsev 
uadd_sat(const ConstantRange & Other) const1537198ab601SNikita Popov ConstantRange ConstantRange::uadd_sat(const ConstantRange &Other) const {
1538198ab601SNikita Popov   if (isEmptySet() || Other.isEmptySet())
1539198ab601SNikita Popov     return getEmpty();
1540198ab601SNikita Popov 
1541198ab601SNikita Popov   APInt NewL = getUnsignedMin().uadd_sat(Other.getUnsignedMin());
1542198ab601SNikita Popov   APInt NewU = getUnsignedMax().uadd_sat(Other.getUnsignedMax()) + 1;
1543198ab601SNikita Popov   return getNonEmpty(std::move(NewL), std::move(NewU));
1544198ab601SNikita Popov }
1545198ab601SNikita Popov 
sadd_sat(const ConstantRange & Other) const1546198ab601SNikita Popov ConstantRange ConstantRange::sadd_sat(const ConstantRange &Other) const {
1547198ab601SNikita Popov   if (isEmptySet() || Other.isEmptySet())
1548198ab601SNikita Popov     return getEmpty();
1549198ab601SNikita Popov 
1550198ab601SNikita Popov   APInt NewL = getSignedMin().sadd_sat(Other.getSignedMin());
1551198ab601SNikita Popov   APInt NewU = getSignedMax().sadd_sat(Other.getSignedMax()) + 1;
1552198ab601SNikita Popov   return getNonEmpty(std::move(NewL), std::move(NewU));
1553198ab601SNikita Popov }
1554198ab601SNikita Popov 
usub_sat(const ConstantRange & Other) const1555198ab601SNikita Popov ConstantRange ConstantRange::usub_sat(const ConstantRange &Other) const {
1556198ab601SNikita Popov   if (isEmptySet() || Other.isEmptySet())
1557198ab601SNikita Popov     return getEmpty();
1558198ab601SNikita Popov 
1559198ab601SNikita Popov   APInt NewL = getUnsignedMin().usub_sat(Other.getUnsignedMax());
1560198ab601SNikita Popov   APInt NewU = getUnsignedMax().usub_sat(Other.getUnsignedMin()) + 1;
1561198ab601SNikita Popov   return getNonEmpty(std::move(NewL), std::move(NewU));
1562198ab601SNikita Popov }
1563198ab601SNikita Popov 
ssub_sat(const ConstantRange & Other) const1564198ab601SNikita Popov ConstantRange ConstantRange::ssub_sat(const ConstantRange &Other) const {
1565198ab601SNikita Popov   if (isEmptySet() || Other.isEmptySet())
1566198ab601SNikita Popov     return getEmpty();
1567198ab601SNikita Popov 
1568198ab601SNikita Popov   APInt NewL = getSignedMin().ssub_sat(Other.getSignedMax());
1569198ab601SNikita Popov   APInt NewU = getSignedMax().ssub_sat(Other.getSignedMin()) + 1;
1570198ab601SNikita Popov   return getNonEmpty(std::move(NewL), std::move(NewU));
1571198ab601SNikita Popov }
1572198ab601SNikita Popov 
umul_sat(const ConstantRange & Other) const15735a9fd76dSRoman Lebedev ConstantRange ConstantRange::umul_sat(const ConstantRange &Other) const {
15745a9fd76dSRoman Lebedev   if (isEmptySet() || Other.isEmptySet())
15755a9fd76dSRoman Lebedev     return getEmpty();
15765a9fd76dSRoman Lebedev 
15775a9fd76dSRoman Lebedev   APInt NewL = getUnsignedMin().umul_sat(Other.getUnsignedMin());
15785a9fd76dSRoman Lebedev   APInt NewU = getUnsignedMax().umul_sat(Other.getUnsignedMax()) + 1;
15795a9fd76dSRoman Lebedev   return getNonEmpty(std::move(NewL), std::move(NewU));
15805a9fd76dSRoman Lebedev }
15815a9fd76dSRoman Lebedev 
smul_sat(const ConstantRange & Other) const15825a9fd76dSRoman Lebedev ConstantRange ConstantRange::smul_sat(const ConstantRange &Other) const {
15835a9fd76dSRoman Lebedev   if (isEmptySet() || Other.isEmptySet())
15845a9fd76dSRoman Lebedev     return getEmpty();
15855a9fd76dSRoman Lebedev 
15865a9fd76dSRoman Lebedev   // Because we could be dealing with negative numbers here, the lower bound is
15875a9fd76dSRoman Lebedev   // the smallest of the cartesian product of the lower and upper ranges;
15885a9fd76dSRoman Lebedev   // for example:
15895a9fd76dSRoman Lebedev   //   [-1,4) * [-2,3) = min(-1*-2, -1*2, 3*-2, 3*2) = -6.
15905a9fd76dSRoman Lebedev   // Similarly for the upper bound, swapping min for max.
15915a9fd76dSRoman Lebedev 
1592ea7be260SNikita Popov   APInt Min = getSignedMin();
1593ea7be260SNikita Popov   APInt Max = getSignedMax();
1594ea7be260SNikita Popov   APInt OtherMin = Other.getSignedMin();
1595ea7be260SNikita Popov   APInt OtherMax = Other.getSignedMax();
15965a9fd76dSRoman Lebedev 
1597ea7be260SNikita Popov   auto L = {Min.smul_sat(OtherMin), Min.smul_sat(OtherMax),
1598ea7be260SNikita Popov             Max.smul_sat(OtherMin), Max.smul_sat(OtherMax)};
15995a9fd76dSRoman Lebedev   auto Compare = [](const APInt &A, const APInt &B) { return A.slt(B); };
1600ea7be260SNikita Popov   return getNonEmpty(std::min(L, Compare), std::max(L, Compare) + 1);
16015a9fd76dSRoman Lebedev }
16025a9fd76dSRoman Lebedev 
ushl_sat(const ConstantRange & Other) const1603e0ea842bSRoman Lebedev ConstantRange ConstantRange::ushl_sat(const ConstantRange &Other) const {
1604e0ea842bSRoman Lebedev   if (isEmptySet() || Other.isEmptySet())
1605e0ea842bSRoman Lebedev     return getEmpty();
1606e0ea842bSRoman Lebedev 
1607e0ea842bSRoman Lebedev   APInt NewL = getUnsignedMin().ushl_sat(Other.getUnsignedMin());
1608e0ea842bSRoman Lebedev   APInt NewU = getUnsignedMax().ushl_sat(Other.getUnsignedMax()) + 1;
1609e0ea842bSRoman Lebedev   return getNonEmpty(std::move(NewL), std::move(NewU));
1610e0ea842bSRoman Lebedev }
1611e0ea842bSRoman Lebedev 
sshl_sat(const ConstantRange & Other) const1612e0ea842bSRoman Lebedev ConstantRange ConstantRange::sshl_sat(const ConstantRange &Other) const {
1613e0ea842bSRoman Lebedev   if (isEmptySet() || Other.isEmptySet())
1614e0ea842bSRoman Lebedev     return getEmpty();
1615e0ea842bSRoman Lebedev 
1616e0ea842bSRoman Lebedev   APInt Min = getSignedMin(), Max = getSignedMax();
1617e0ea842bSRoman Lebedev   APInt ShAmtMin = Other.getUnsignedMin(), ShAmtMax = Other.getUnsignedMax();
161872a21ad6SRoman Lebedev   APInt NewL = Min.sshl_sat(Min.isNonNegative() ? ShAmtMin : ShAmtMax);
161972a21ad6SRoman Lebedev   APInt NewU = Max.sshl_sat(Max.isNegative() ? ShAmtMin : ShAmtMax) + 1;
1620e0ea842bSRoman Lebedev   return getNonEmpty(std::move(NewL), std::move(NewU));
1621e0ea842bSRoman Lebedev }
1622e0ea842bSRoman Lebedev 
inverse() const16238cd041efSChandler Carruth ConstantRange ConstantRange::inverse() const {
16248cd041efSChandler Carruth   if (isFullSet())
1625977934f0SNikita Popov     return getEmpty();
16268cd041efSChandler Carruth   if (isEmptySet())
1627977934f0SNikita Popov     return getFull();
16288cd041efSChandler Carruth   return ConstantRange(Upper, Lower);
16298cd041efSChandler Carruth }
16308cd041efSChandler Carruth 
abs(bool IntMinIsPoison) const163194f8120cSNikita Popov ConstantRange ConstantRange::abs(bool IntMinIsPoison) const {
1632c0fa4ec0SNikita Popov   if (isEmptySet())
1633c0fa4ec0SNikita Popov     return getEmpty();
1634c0fa4ec0SNikita Popov 
1635c0fa4ec0SNikita Popov   if (isSignWrappedSet()) {
1636c0fa4ec0SNikita Popov     APInt Lo;
1637c0fa4ec0SNikita Popov     // Check whether the range crosses zero.
1638c0fa4ec0SNikita Popov     if (Upper.isStrictlyPositive() || !Lower.isStrictlyPositive())
1639735f4671SChris Lattner       Lo = APInt::getZero(getBitWidth());
1640c0fa4ec0SNikita Popov     else
1641c0fa4ec0SNikita Popov       Lo = APIntOps::umin(Lower, -Upper + 1);
1642c0fa4ec0SNikita Popov 
164394f8120cSNikita Popov     // If SignedMin is not poison, then it is included in the result range.
164494f8120cSNikita Popov     if (IntMinIsPoison)
164594f8120cSNikita Popov       return ConstantRange(Lo, APInt::getSignedMinValue(getBitWidth()));
164694f8120cSNikita Popov     else
1647c0fa4ec0SNikita Popov       return ConstantRange(Lo, APInt::getSignedMinValue(getBitWidth()) + 1);
1648c0fa4ec0SNikita Popov   }
1649c0fa4ec0SNikita Popov 
1650c0fa4ec0SNikita Popov   APInt SMin = getSignedMin(), SMax = getSignedMax();
1651c0fa4ec0SNikita Popov 
165294f8120cSNikita Popov   // Skip SignedMin if it is poison.
165394f8120cSNikita Popov   if (IntMinIsPoison && SMin.isMinSignedValue()) {
165494f8120cSNikita Popov     // The range may become empty if it *only* contains SignedMin.
165594f8120cSNikita Popov     if (SMax.isMinSignedValue())
165694f8120cSNikita Popov       return getEmpty();
165794f8120cSNikita Popov     ++SMin;
165894f8120cSNikita Popov   }
165994f8120cSNikita Popov 
1660c0fa4ec0SNikita Popov   // All non-negative.
1661c0fa4ec0SNikita Popov   if (SMin.isNonNegative())
1662c0fa4ec0SNikita Popov     return *this;
1663c0fa4ec0SNikita Popov 
1664c0fa4ec0SNikita Popov   // All negative.
1665c0fa4ec0SNikita Popov   if (SMax.isNegative())
1666c0fa4ec0SNikita Popov     return ConstantRange(-SMax, -SMin + 1);
1667c0fa4ec0SNikita Popov 
1668c0fa4ec0SNikita Popov   // Range crosses zero.
1669735f4671SChris Lattner   return ConstantRange(APInt::getZero(getBitWidth()),
1670c0fa4ec0SNikita Popov                        APIntOps::umax(-SMin, SMax) + 1);
1671c0fa4ec0SNikita Popov }
1672c0fa4ec0SNikita Popov 
unsignedAddMayOverflow(const ConstantRange & Other) const1673e3d3e862SNikita Popov ConstantRange::OverflowResult ConstantRange::unsignedAddMayOverflow(
1674e3d3e862SNikita Popov     const ConstantRange &Other) const {
1675e3d3e862SNikita Popov   if (isEmptySet() || Other.isEmptySet())
1676e3d3e862SNikita Popov     return OverflowResult::MayOverflow;
1677e3d3e862SNikita Popov 
1678e3d3e862SNikita Popov   APInt Min = getUnsignedMin(), Max = getUnsignedMax();
1679e3d3e862SNikita Popov   APInt OtherMin = Other.getUnsignedMin(), OtherMax = Other.getUnsignedMax();
1680e3d3e862SNikita Popov 
1681332c1005SNikita Popov   // a u+ b overflows high iff a u> ~b.
1682e3d3e862SNikita Popov   if (Min.ugt(~OtherMin))
1683332c1005SNikita Popov     return OverflowResult::AlwaysOverflowsHigh;
1684e3d3e862SNikita Popov   if (Max.ugt(~OtherMax))
1685e3d3e862SNikita Popov     return OverflowResult::MayOverflow;
1686e3d3e862SNikita Popov   return OverflowResult::NeverOverflows;
1687e3d3e862SNikita Popov }
1688e3d3e862SNikita Popov 
signedAddMayOverflow(const ConstantRange & Other) const1689e3d3e862SNikita Popov ConstantRange::OverflowResult ConstantRange::signedAddMayOverflow(
1690e3d3e862SNikita Popov     const ConstantRange &Other) const {
1691e3d3e862SNikita Popov   if (isEmptySet() || Other.isEmptySet())
1692e3d3e862SNikita Popov     return OverflowResult::MayOverflow;
1693e3d3e862SNikita Popov 
1694e3d3e862SNikita Popov   APInt Min = getSignedMin(), Max = getSignedMax();
1695e3d3e862SNikita Popov   APInt OtherMin = Other.getSignedMin(), OtherMax = Other.getSignedMax();
1696e3d3e862SNikita Popov 
1697e3d3e862SNikita Popov   APInt SignedMin = APInt::getSignedMinValue(getBitWidth());
1698e3d3e862SNikita Popov   APInt SignedMax = APInt::getSignedMaxValue(getBitWidth());
1699e3d3e862SNikita Popov 
1700e3d3e862SNikita Popov   // a s+ b overflows high iff a s>=0 && b s>= 0 && a s> smax - b.
1701e3d3e862SNikita Popov   // a s+ b overflows low iff a s< 0 && b s< 0 && a s< smin - b.
1702e3d3e862SNikita Popov   if (Min.isNonNegative() && OtherMin.isNonNegative() &&
1703e3d3e862SNikita Popov       Min.sgt(SignedMax - OtherMin))
1704332c1005SNikita Popov     return OverflowResult::AlwaysOverflowsHigh;
1705e3d3e862SNikita Popov   if (Max.isNegative() && OtherMax.isNegative() &&
1706e3d3e862SNikita Popov       Max.slt(SignedMin - OtherMax))
1707332c1005SNikita Popov     return OverflowResult::AlwaysOverflowsLow;
1708e3d3e862SNikita Popov 
1709e3d3e862SNikita Popov   if (Max.isNonNegative() && OtherMax.isNonNegative() &&
1710e3d3e862SNikita Popov       Max.sgt(SignedMax - OtherMax))
1711e3d3e862SNikita Popov     return OverflowResult::MayOverflow;
1712e3d3e862SNikita Popov   if (Min.isNegative() && OtherMin.isNegative() &&
1713e3d3e862SNikita Popov       Min.slt(SignedMin - OtherMin))
1714e3d3e862SNikita Popov     return OverflowResult::MayOverflow;
1715e3d3e862SNikita Popov 
1716e3d3e862SNikita Popov   return OverflowResult::NeverOverflows;
1717e3d3e862SNikita Popov }
1718e3d3e862SNikita Popov 
unsignedSubMayOverflow(const ConstantRange & Other) const1719e3d3e862SNikita Popov ConstantRange::OverflowResult ConstantRange::unsignedSubMayOverflow(
1720e3d3e862SNikita Popov     const ConstantRange &Other) const {
1721e3d3e862SNikita Popov   if (isEmptySet() || Other.isEmptySet())
1722e3d3e862SNikita Popov     return OverflowResult::MayOverflow;
1723e3d3e862SNikita Popov 
1724e3d3e862SNikita Popov   APInt Min = getUnsignedMin(), Max = getUnsignedMax();
1725e3d3e862SNikita Popov   APInt OtherMin = Other.getUnsignedMin(), OtherMax = Other.getUnsignedMax();
1726e3d3e862SNikita Popov 
1727332c1005SNikita Popov   // a u- b overflows low iff a u< b.
1728e3d3e862SNikita Popov   if (Max.ult(OtherMin))
1729332c1005SNikita Popov     return OverflowResult::AlwaysOverflowsLow;
1730e3d3e862SNikita Popov   if (Min.ult(OtherMax))
1731e3d3e862SNikita Popov     return OverflowResult::MayOverflow;
1732e3d3e862SNikita Popov   return OverflowResult::NeverOverflows;
1733e3d3e862SNikita Popov }
1734e3d3e862SNikita Popov 
signedSubMayOverflow(const ConstantRange & Other) const1735e3d3e862SNikita Popov ConstantRange::OverflowResult ConstantRange::signedSubMayOverflow(
1736e3d3e862SNikita Popov     const ConstantRange &Other) const {
1737e3d3e862SNikita Popov   if (isEmptySet() || Other.isEmptySet())
1738e3d3e862SNikita Popov     return OverflowResult::MayOverflow;
1739e3d3e862SNikita Popov 
1740e3d3e862SNikita Popov   APInt Min = getSignedMin(), Max = getSignedMax();
1741e3d3e862SNikita Popov   APInt OtherMin = Other.getSignedMin(), OtherMax = Other.getSignedMax();
1742e3d3e862SNikita Popov 
1743e3d3e862SNikita Popov   APInt SignedMin = APInt::getSignedMinValue(getBitWidth());
1744e3d3e862SNikita Popov   APInt SignedMax = APInt::getSignedMaxValue(getBitWidth());
1745e3d3e862SNikita Popov 
1746e3d3e862SNikita Popov   // a s- b overflows high iff a s>=0 && b s< 0 && a s> smax + b.
1747e3d3e862SNikita Popov   // a s- b overflows low iff a s< 0 && b s>= 0 && a s< smin + b.
1748e3d3e862SNikita Popov   if (Min.isNonNegative() && OtherMax.isNegative() &&
1749e3d3e862SNikita Popov       Min.sgt(SignedMax + OtherMax))
1750332c1005SNikita Popov     return OverflowResult::AlwaysOverflowsHigh;
1751e3d3e862SNikita Popov   if (Max.isNegative() && OtherMin.isNonNegative() &&
1752e3d3e862SNikita Popov       Max.slt(SignedMin + OtherMin))
1753332c1005SNikita Popov     return OverflowResult::AlwaysOverflowsLow;
1754e3d3e862SNikita Popov 
1755e3d3e862SNikita Popov   if (Max.isNonNegative() && OtherMin.isNegative() &&
1756e3d3e862SNikita Popov       Max.sgt(SignedMax + OtherMin))
1757e3d3e862SNikita Popov     return OverflowResult::MayOverflow;
1758e3d3e862SNikita Popov   if (Min.isNegative() && OtherMax.isNonNegative() &&
1759e3d3e862SNikita Popov       Min.slt(SignedMin + OtherMax))
1760e3d3e862SNikita Popov     return OverflowResult::MayOverflow;
1761e3d3e862SNikita Popov 
1762e3d3e862SNikita Popov   return OverflowResult::NeverOverflows;
1763e3d3e862SNikita Popov }
1764e3d3e862SNikita Popov 
unsignedMulMayOverflow(const ConstantRange & Other) const1765e319eafbSNikita Popov ConstantRange::OverflowResult ConstantRange::unsignedMulMayOverflow(
1766e319eafbSNikita Popov     const ConstantRange &Other) const {
1767e319eafbSNikita Popov   if (isEmptySet() || Other.isEmptySet())
1768e319eafbSNikita Popov     return OverflowResult::MayOverflow;
1769e319eafbSNikita Popov 
1770e319eafbSNikita Popov   APInt Min = getUnsignedMin(), Max = getUnsignedMax();
1771e319eafbSNikita Popov   APInt OtherMin = Other.getUnsignedMin(), OtherMax = Other.getUnsignedMax();
1772e319eafbSNikita Popov   bool Overflow;
1773e319eafbSNikita Popov 
1774e319eafbSNikita Popov   (void) Min.umul_ov(OtherMin, Overflow);
1775e319eafbSNikita Popov   if (Overflow)
1776332c1005SNikita Popov     return OverflowResult::AlwaysOverflowsHigh;
1777e319eafbSNikita Popov 
1778e319eafbSNikita Popov   (void) Max.umul_ov(OtherMax, Overflow);
1779e319eafbSNikita Popov   if (Overflow)
1780e319eafbSNikita Popov     return OverflowResult::MayOverflow;
1781e319eafbSNikita Popov 
1782e319eafbSNikita Popov   return OverflowResult::NeverOverflows;
1783e319eafbSNikita Popov }
1784e319eafbSNikita Popov 
print(raw_ostream & OS) const17858cd041efSChandler Carruth void ConstantRange::print(raw_ostream &OS) const {
17868cd041efSChandler Carruth   if (isFullSet())
17878cd041efSChandler Carruth     OS << "full-set";
17888cd041efSChandler Carruth   else if (isEmptySet())
17898cd041efSChandler Carruth     OS << "empty-set";
17908cd041efSChandler Carruth   else
17918cd041efSChandler Carruth     OS << "[" << Lower << "," << Upper << ")";
17928cd041efSChandler Carruth }
17938cd041efSChandler Carruth 
1794615eb470SAaron Ballman #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const1795eb2a2546SYaron Keren LLVM_DUMP_METHOD void ConstantRange::dump() const {
17968cd041efSChandler Carruth   print(dbgs());
17978cd041efSChandler Carruth }
17988c209aa8SMatthias Braun #endif
1799ecdd58f1SPeter Collingbourne 
getConstantRangeFromMetadata(const MDNode & Ranges)1800ecdd58f1SPeter Collingbourne ConstantRange llvm::getConstantRangeFromMetadata(const MDNode &Ranges) {
1801ecdd58f1SPeter Collingbourne   const unsigned NumRanges = Ranges.getNumOperands() / 2;
1802ecdd58f1SPeter Collingbourne   assert(NumRanges >= 1 && "Must have at least one range!");
1803ecdd58f1SPeter Collingbourne   assert(Ranges.getNumOperands() % 2 == 0 && "Must be a sequence of pairs");
1804ecdd58f1SPeter Collingbourne 
1805ecdd58f1SPeter Collingbourne   auto *FirstLow = mdconst::extract<ConstantInt>(Ranges.getOperand(0));
1806ecdd58f1SPeter Collingbourne   auto *FirstHigh = mdconst::extract<ConstantInt>(Ranges.getOperand(1));
1807ecdd58f1SPeter Collingbourne 
1808ecdd58f1SPeter Collingbourne   ConstantRange CR(FirstLow->getValue(), FirstHigh->getValue());
1809ecdd58f1SPeter Collingbourne 
1810ecdd58f1SPeter Collingbourne   for (unsigned i = 1; i < NumRanges; ++i) {
1811ecdd58f1SPeter Collingbourne     auto *Low = mdconst::extract<ConstantInt>(Ranges.getOperand(2 * i + 0));
1812ecdd58f1SPeter Collingbourne     auto *High = mdconst::extract<ConstantInt>(Ranges.getOperand(2 * i + 1));
1813ecdd58f1SPeter Collingbourne 
1814ecdd58f1SPeter Collingbourne     // Note: unionWith will potentially create a range that contains values not
1815ecdd58f1SPeter Collingbourne     // contained in any of the original N ranges.
1816ecdd58f1SPeter Collingbourne     CR = CR.unionWith(ConstantRange(Low->getValue(), High->getValue()));
1817ecdd58f1SPeter Collingbourne   }
1818ecdd58f1SPeter Collingbourne 
1819ecdd58f1SPeter Collingbourne   return CR;
1820ecdd58f1SPeter Collingbourne }
1821