//===-- ConstantRange.cpp - ConstantRange implementation ------------------===////// The LLVM Compiler Infrastructure//// This file is distributed under the University of Illinois Open Source// License. See LICENSE.TXT for details.////===----------------------------------------------------------------------===////// Represent a range of possible values that may occur when the program is run// for an integral value. This keeps track of a lower and upper bound for the// constant, which MAY wrap around the end of the numeric range. To do this, it// keeps track of a [lower, upper) bound, which specifies an interval just like// STL iterators. When used with boolean values, the following are important// ranges (other integral ranges use min/max values for special range values)://// [F, F) = {} = Empty set// [T, F) = {T}// [F, T) = {F}// [T, T) = {F, T} = Full set////===----------------------------------------------------------------------===//#include"llvm/InstrTypes.h"#include"llvm/Support/ConstantRange.h"#include"llvm/Support/Debug.h"#include"llvm/Support/raw_ostream.h"usingnamespacellvm;/// Initialize a full (the default) or empty set for the specified type.///ConstantRange::ConstantRange(uint32_tBitWidth,boolFull){if(Full)Lower=Upper=APInt::getMaxValue(BitWidth);elseLower=Upper=APInt::getMinValue(BitWidth);}/// Initialize a range to hold the single specified value.///ConstantRange::ConstantRange(constAPInt&V):Lower(V),Upper(V+1){}ConstantRange::ConstantRange(constAPInt&L,constAPInt&U):Lower(L),Upper(U){assert(L.getBitWidth()==U.getBitWidth()&&"ConstantRange with unequal bit widths");assert((L!=U||(L.isMaxValue()||L.isMinValue()))&&"Lower == Upper, but they aren't min or max value!");}ConstantRangeConstantRange::makeICmpRegion(unsignedPred,constConstantRange&CR){if(CR.isEmptySet())returnCR;uint32_tW=CR.getBitWidth();switch(Pred){default:llvm_unreachable("Invalid ICmp predicate to makeICmpRegion()");caseCmpInst::ICMP_EQ:returnCR;caseCmpInst::ICMP_NE:if(CR.isSingleElement())returnConstantRange(CR.getUpper(),CR.getLower());returnConstantRange(W);caseCmpInst::ICMP_ULT:{APIntUMax(CR.getUnsignedMax());if(UMax.isMinValue())returnConstantRange(W,/* empty */false);returnConstantRange(APInt::getMinValue(W),UMax);}caseCmpInst::ICMP_SLT:{APIntSMax(CR.getSignedMax());if(SMax.isMinSignedValue())returnConstantRange(W,/* empty */false);returnConstantRange(APInt::getSignedMinValue(W),SMax);}caseCmpInst::ICMP_ULE:{APIntUMax(CR.getUnsignedMax());if(UMax.isMaxValue())returnConstantRange(W);returnConstantRange(APInt::getMinValue(W),UMax+1);}caseCmpInst::ICMP_SLE:{APIntSMax(CR.getSignedMax());if(SMax.isMaxSignedValue())returnConstantRange(W);returnConstantRange(APInt::getSignedMinValue(W),SMax+1);}caseCmpInst::ICMP_UGT:{APIntUMin(CR.getUnsignedMin());if(UMin.isMaxValue())returnConstantRange(W,/* empty */false);returnConstantRange(UMin+1,APInt::getNullValue(W));}caseCmpInst::ICMP_SGT:{APIntSMin(CR.getSignedMin());if(SMin.isMaxSignedValue())returnConstantRange(W,/* empty */false);returnConstantRange(SMin+1,APInt::getSignedMinValue(W));}caseCmpInst::ICMP_UGE:{APIntUMin(CR.getUnsignedMin());if(UMin.isMinValue())returnConstantRange(W);returnConstantRange(UMin,APInt::getNullValue(W));}caseCmpInst::ICMP_SGE:{APIntSMin(CR.getSignedMin());if(SMin.isMinSignedValue())returnConstantRange(W);returnConstantRange(SMin,APInt::getSignedMinValue(W));}}}/// isFullSet - Return true if this set contains all of the elements possible/// for this data-typeboolConstantRange::isFullSet()const{returnLower==Upper&&Lower.isMaxValue();}/// isEmptySet - Return true if this set contains no members.///boolConstantRange::isEmptySet()const{returnLower==Upper&&Lower.isMinValue();}/// isWrappedSet - Return true if this set wraps around the top of the range,/// for example: [100, 8)///boolConstantRange::isWrappedSet()const{returnLower.ugt(Upper);}/// isSignWrappedSet - Return true if this set wraps around the INT_MIN of/// its bitwidth, for example: i8 [120, 140).///boolConstantRange::isSignWrappedSet()const{returncontains(APInt::getSignedMaxValue(getBitWidth()))&&contains(APInt::getSignedMinValue(getBitWidth()));}/// getSetSize - Return the number of elements in this set.///APIntConstantRange::getSetSize()const{if(isEmptySet())returnAPInt(getBitWidth()+1,0);if(isFullSet()){APIntSize(getBitWidth()+1,0);Size.setBit(getBitWidth());returnSize;}// This is also correct for wrapped sets.return(Upper-Lower).zext(getBitWidth()+1);}/// getUnsignedMax - Return the largest unsigned value contained in the/// ConstantRange.///APIntConstantRange::getUnsignedMax()const{if(isFullSet()||isWrappedSet())returnAPInt::getMaxValue(getBitWidth());returngetUpper()-1;}/// getUnsignedMin - Return the smallest unsigned value contained in the/// ConstantRange.///APIntConstantRange::getUnsignedMin()const{if(isFullSet()||(isWrappedSet()&&getUpper()!=0))returnAPInt::getMinValue(getBitWidth());returngetLower();}/// getSignedMax - Return the largest signed value contained in the/// ConstantRange.///APIntConstantRange::getSignedMax()const{APIntSignedMax(APInt::getSignedMaxValue(getBitWidth()));if(!isWrappedSet()){if(getLower().sle(getUpper()-1))returngetUpper()-1;returnSignedMax;}if(getLower().isNegative()==getUpper().isNegative())returnSignedMax;returngetUpper()-1;}/// getSignedMin - Return the smallest signed value contained in the/// ConstantRange.///APIntConstantRange::getSignedMin()const{APIntSignedMin(APInt::getSignedMinValue(getBitWidth()));if(!isWrappedSet()){if(getLower().sle(getUpper()-1))returngetLower();returnSignedMin;}if((getUpper()-1).slt(getLower())){if(getUpper()!=SignedMin)returnSignedMin;}returngetLower();}/// contains - Return true if the specified value is in the set.///boolConstantRange::contains(constAPInt&V)const{if(Lower==Upper)returnisFullSet();if(!isWrappedSet())returnLower.ule(V)&&V.ult(Upper);returnLower.ule(V)||V.ult(Upper);}/// contains - Return true if the argument is a subset of this range./// Two equal sets contain each other. The empty set contained by all other/// sets.///boolConstantRange::contains(constConstantRange&Other)const{if(isFullSet()||Other.isEmptySet())returntrue;if(isEmptySet()||Other.isFullSet())returnfalse;if(!isWrappedSet()){if(Other.isWrappedSet())returnfalse;returnLower.ule(Other.getLower())&&Other.getUpper().ule(Upper);}if(!Other.isWrappedSet())returnOther.getUpper().ule(Upper)||Lower.ule(Other.getLower());returnOther.getUpper().ule(Upper)&&Lower.ule(Other.getLower());}/// subtract - Subtract the specified constant from the endpoints of this/// constant range.ConstantRangeConstantRange::subtract(constAPInt&Val)const{assert(Val.getBitWidth()==getBitWidth()&&"Wrong bit width");// If the set is empty or full, don't modify the endpoints.if(Lower==Upper)return*this;returnConstantRange(Lower-Val,Upper-Val);}/// \brief Subtract the specified range from this range (aka relative complement/// of the sets).ConstantRangeConstantRange::difference(constConstantRange&CR)const{returnintersectWith(CR.inverse());}/// intersectWith - Return the range that results from the intersection of this/// range with another range. The resultant range is guaranteed to include all/// elements contained in both input ranges, and to have the smallest possible/// set size that does so. Because there may be two intersections with the/// same set size, A.intersectWith(B) might not be equal to B.intersectWith(A).ConstantRangeConstantRange::intersectWith(constConstantRange&CR)const{assert(getBitWidth()==CR.getBitWidth()&&"ConstantRange types don't agree!");// Handle common cases.if(isEmptySet()||CR.isFullSet())return*this;if(CR.isEmptySet()||isFullSet())returnCR;if(!isWrappedSet()&&CR.isWrappedSet())returnCR.intersectWith(*this);if(!isWrappedSet()&&!CR.isWrappedSet()){if(Lower.ult(CR.Lower)){if(Upper.ule(CR.Lower))returnConstantRange(getBitWidth(),false);if(Upper.ult(CR.Upper))returnConstantRange(CR.Lower,Upper);returnCR;}if(Upper.ult(CR.Upper))return*this;if(Lower.ult(CR.Upper))returnConstantRange(Lower,CR.Upper);returnConstantRange(getBitWidth(),false);}if(isWrappedSet()&&!CR.isWrappedSet()){if(CR.Lower.ult(Upper)){if(CR.Upper.ult(Upper))returnCR;if(CR.Upper.ule(Lower))returnConstantRange(CR.Lower,Upper);if(getSetSize().ult(CR.getSetSize()))return*this;returnCR;}if(CR.Lower.ult(Lower)){if(CR.Upper.ule(Lower))returnConstantRange(getBitWidth(),false);returnConstantRange(Lower,CR.Upper);}returnCR;}if(CR.Upper.ult(Upper)){if(CR.Lower.ult(Upper)){if(getSetSize().ult(CR.getSetSize()))return*this;returnCR;}if(CR.Lower.ult(Lower))returnConstantRange(Lower,CR.Upper);returnCR;}if(CR.Upper.ule(Lower)){if(CR.Lower.ult(Lower))return*this;returnConstantRange(CR.Lower,Upper);}if(getSetSize().ult(CR.getSetSize()))return*this;returnCR;}/// unionWith - Return the range that results from the union of this range with/// another range. The resultant range is guaranteed to include the elements of/// both sets, but may contain more. For example, [3, 9) union [12,15) is/// [3, 15), which includes 9, 10, and 11, which were not included in either/// set before.///ConstantRangeConstantRange::unionWith(constConstantRange&CR)const{assert(getBitWidth()==CR.getBitWidth()&&"ConstantRange types don't agree!");if(isFullSet()||CR.isEmptySet())return*this;if(CR.isFullSet()||isEmptySet())returnCR;if(!isWrappedSet()&&CR.isWrappedSet())returnCR.unionWith(*this);if(!isWrappedSet()&&!CR.isWrappedSet()){if(CR.Upper.ult(Lower)||Upper.ult(CR.Lower)){// If the two ranges are disjoint, find the smaller gap and bridge it.APIntd1=CR.Lower-Upper,d2=Lower-CR.Upper;if(d1.ult(d2))returnConstantRange(Lower,CR.Upper);returnConstantRange(CR.Lower,Upper);}APIntL=Lower,U=Upper;if(CR.Lower.ult(L))L=CR.Lower;if((CR.Upper-1).ugt(U-1))U=CR.Upper;if(L==0&&U==0)returnConstantRange(getBitWidth());returnConstantRange(L,U);}if(!CR.isWrappedSet()){// ------U L----- and ------U L----- : this// L--U L--U : CRif(CR.Upper.ule(Upper)||CR.Lower.uge(Lower))return*this;// ------U L----- : this// L---------U : CRif(CR.Lower.ule(Upper)&&Lower.ule(CR.Upper))returnConstantRange(getBitWidth());// ----U L---- : this// L---U : CR// <d1> <d2>if(Upper.ule(CR.Lower)&&CR.Upper.ule(Lower)){APIntd1=CR.Lower-Upper,d2=Lower-CR.Upper;if(d1.ult(d2))returnConstantRange(Lower,CR.Upper);returnConstantRange(CR.Lower,Upper);}// ----U L----- : this// L----U : CRif(Upper.ult(CR.Lower)&&Lower.ult(CR.Upper))returnConstantRange(CR.Lower,Upper);// ------U L---- : this// L-----U : CRassert(CR.Lower.ult(Upper)&&CR.Upper.ult(Lower)&&"ConstantRange::unionWith missed a case with one range wrapped");returnConstantRange(Lower,CR.Upper);}// ------U L---- and ------U L---- : this// -U L----------- and ------------U L : CRif(CR.Lower.ule(Upper)||Lower.ule(CR.Upper))returnConstantRange(getBitWidth());APIntL=Lower,U=Upper;if(CR.Upper.ugt(U))U=CR.Upper;if(CR.Lower.ult(L))L=CR.Lower;returnConstantRange(L,U);}/// zeroExtend - Return a new range in the specified integer type, which must/// be strictly larger than the current type. The returned range will/// correspond to the possible range of values as if the source range had been/// zero extended.ConstantRangeConstantRange::zeroExtend(uint32_tDstTySize)const{if(isEmptySet())returnConstantRange(DstTySize,/*isFullSet=*/false);unsignedSrcTySize=getBitWidth();assert(SrcTySize<DstTySize&&"Not a value extension");if(isFullSet()||isWrappedSet()){// Change into [0, 1 << src bit width)APIntLowerExt(DstTySize,0);if(!Upper)// special case: [X, 0) -- not really wrapping aroundLowerExt=Lower.zext(DstTySize);returnConstantRange(LowerExt,APInt(DstTySize,1).shl(SrcTySize));}returnConstantRange(Lower.zext(DstTySize),Upper.zext(DstTySize));}/// signExtend - Return a new range in the specified integer type, which must/// be strictly larger than the current type. The returned range will/// correspond to the possible range of values as if the source range had been/// sign extended.ConstantRangeConstantRange::signExtend(uint32_tDstTySize)const{if(isEmptySet())returnConstantRange(DstTySize,/*isFullSet=*/false);unsignedSrcTySize=getBitWidth();assert(SrcTySize<DstTySize&&"Not a value extension");if(isFullSet()||isSignWrappedSet()){returnConstantRange(APInt::getHighBitsSet(DstTySize,DstTySize-SrcTySize+1),APInt::getLowBitsSet(DstTySize,SrcTySize-1)+1);}returnConstantRange(Lower.sext(DstTySize),Upper.sext(DstTySize));}/// truncate - Return a new range in the specified integer type, which must be/// strictly smaller than the current type. The returned range will/// correspond to the possible range of values as if the source range had been/// truncated to the specified type.ConstantRangeConstantRange::truncate(uint32_tDstTySize)const{assert(getBitWidth()>DstTySize&&"Not a value truncation");if(isEmptySet())returnConstantRange(DstTySize,/*isFullSet=*/false);if(isFullSet())returnConstantRange(DstTySize,/*isFullSet=*/true);APIntMaxValue=APInt::getMaxValue(DstTySize).zext(getBitWidth());APIntMaxBitValue(getBitWidth(),0);MaxBitValue.setBit(DstTySize);APIntLowerDiv(Lower),UpperDiv(Upper);ConstantRangeUnion(DstTySize,/*isFullSet=*/false);// Analyze wrapped sets in their two parts: [0, Upper) \/ [Lower, MaxValue]// We use the non-wrapped set code to analyze the [Lower, MaxValue) part, and// then we do the union with [MaxValue, Upper)if(isWrappedSet()){// if Upper is greater than Max Value, it covers the whole truncated range.if(Upper.uge(MaxValue))returnConstantRange(DstTySize,/*isFullSet=*/true);Union=ConstantRange(APInt::getMaxValue(DstTySize),Upper.trunc(DstTySize));UpperDiv=APInt::getMaxValue(getBitWidth());// Union covers the MaxValue case, so return if the remaining range is just// MaxValue.if(LowerDiv==UpperDiv)returnUnion;}// Chop off the most significant bits that are past the destination bitwidth.if(LowerDiv.uge(MaxValue)){APIntDiv(getBitWidth(),0);APInt::udivrem(LowerDiv,MaxBitValue,Div,LowerDiv);UpperDiv=UpperDiv-MaxBitValue*Div;}if(UpperDiv.ule(MaxValue))returnConstantRange(LowerDiv.trunc(DstTySize),UpperDiv.trunc(DstTySize)).unionWith(Union);// The truncated value wrapps around. Check if we can do better than fullset.APIntUpperModulo=UpperDiv-MaxBitValue;if(UpperModulo.ult(LowerDiv))returnConstantRange(LowerDiv.trunc(DstTySize),UpperModulo.trunc(DstTySize)).unionWith(Union);returnConstantRange(DstTySize,/*isFullSet=*/true);}/// zextOrTrunc - make this range have the bit width given by \p DstTySize. The/// value is zero extended, truncated, or left alone to make it that width.ConstantRangeConstantRange::zextOrTrunc(uint32_tDstTySize)const{unsignedSrcTySize=getBitWidth();if(SrcTySize>DstTySize)returntruncate(DstTySize);if(SrcTySize<DstTySize)returnzeroExtend(DstTySize);return*this;}/// sextOrTrunc - make this range have the bit width given by \p DstTySize. The/// value is sign extended, truncated, or left alone to make it that width.ConstantRangeConstantRange::sextOrTrunc(uint32_tDstTySize)const{unsignedSrcTySize=getBitWidth();if(SrcTySize>DstTySize)returntruncate(DstTySize);if(SrcTySize<DstTySize)returnsignExtend(DstTySize);return*this;}ConstantRangeConstantRange::add(constConstantRange&Other)const{if(isEmptySet()||Other.isEmptySet())returnConstantRange(getBitWidth(),/*isFullSet=*/false);if(isFullSet()||Other.isFullSet())returnConstantRange(getBitWidth(),/*isFullSet=*/true);APIntSpread_X=getSetSize(),Spread_Y=Other.getSetSize();APIntNewLower=getLower()+Other.getLower();APIntNewUpper=getUpper()+Other.getUpper()-1;if(NewLower==NewUpper)returnConstantRange(getBitWidth(),/*isFullSet=*/true);ConstantRangeX=ConstantRange(NewLower,NewUpper);if(X.getSetSize().ult(Spread_X)||X.getSetSize().ult(Spread_Y))// We've wrapped, therefore, full set.returnConstantRange(getBitWidth(),/*isFullSet=*/true);returnX;}ConstantRangeConstantRange::sub(constConstantRange&Other)const{if(isEmptySet()||Other.isEmptySet())returnConstantRange(getBitWidth(),/*isFullSet=*/false);if(isFullSet()||Other.isFullSet())returnConstantRange(getBitWidth(),/*isFullSet=*/true);APIntSpread_X=getSetSize(),Spread_Y=Other.getSetSize();APIntNewLower=getLower()-Other.getUpper()+1;APIntNewUpper=getUpper()-Other.getLower();if(NewLower==NewUpper)returnConstantRange(getBitWidth(),/*isFullSet=*/true);ConstantRangeX=ConstantRange(NewLower,NewUpper);if(X.getSetSize().ult(Spread_X)||X.getSetSize().ult(Spread_Y))// We've wrapped, therefore, full set.returnConstantRange(getBitWidth(),/*isFullSet=*/true);returnX;}ConstantRangeConstantRange::multiply(constConstantRange&Other)const{// TODO: If either operand is a single element and the multiply is known to// be non-wrapping, round the result min and max value to the appropriate// multiple of that element. If wrapping is possible, at least adjust the// range according to the greatest power-of-two factor of the single element.if(isEmptySet()||Other.isEmptySet())returnConstantRange(getBitWidth(),/*isFullSet=*/false);APIntthis_min=getUnsignedMin().zext(getBitWidth()*2);APIntthis_max=getUnsignedMax().zext(getBitWidth()*2);APIntOther_min=Other.getUnsignedMin().zext(getBitWidth()*2);APIntOther_max=Other.getUnsignedMax().zext(getBitWidth()*2);ConstantRangeResult_zext=ConstantRange(this_min*Other_min,this_max*Other_max+1);returnResult_zext.truncate(getBitWidth());}ConstantRangeConstantRange::smax(constConstantRange&Other)const{// X smax Y is: range(smax(X_smin, Y_smin),// smax(X_smax, Y_smax))if(isEmptySet()||Other.isEmptySet())returnConstantRange(getBitWidth(),/*isFullSet=*/false);APIntNewL=APIntOps::smax(getSignedMin(),Other.getSignedMin());APIntNewU=APIntOps::smax(getSignedMax(),Other.getSignedMax())+1;if(NewU==NewL)returnConstantRange(getBitWidth(),/*isFullSet=*/true);returnConstantRange(NewL,NewU);}ConstantRangeConstantRange::umax(constConstantRange&Other)const{// X umax Y is: range(umax(X_umin, Y_umin),// umax(X_umax, Y_umax))if(isEmptySet()||Other.isEmptySet())returnConstantRange(getBitWidth(),/*isFullSet=*/false);APIntNewL=APIntOps::umax(getUnsignedMin(),Other.getUnsignedMin());APIntNewU=APIntOps::umax(getUnsignedMax(),Other.getUnsignedMax())+1;if(NewU==NewL)returnConstantRange(getBitWidth(),/*isFullSet=*/true);returnConstantRange(NewL,NewU);}ConstantRangeConstantRange::udiv(constConstantRange&RHS)const{if(isEmptySet()||RHS.isEmptySet()||RHS.getUnsignedMax()==0)returnConstantRange(getBitWidth(),/*isFullSet=*/false);if(RHS.isFullSet())returnConstantRange(getBitWidth(),/*isFullSet=*/true);APIntLower=getUnsignedMin().udiv(RHS.getUnsignedMax());APIntRHS_umin=RHS.getUnsignedMin();if(RHS_umin==0){// We want the lowest value in RHS excluding zero. Usually that would be 1// except for a range in the form of [X, 1) in which case it would be X.if(RHS.getUpper()==1)RHS_umin=RHS.getLower();elseRHS_umin=APInt(getBitWidth(),1);}APIntUpper=getUnsignedMax().udiv(RHS_umin)+1;// If the LHS is Full and the RHS is a wrapped interval containing 1 then// this could occur.if(Lower==Upper)returnConstantRange(getBitWidth(),/*isFullSet=*/true);returnConstantRange(Lower,Upper);}ConstantRangeConstantRange::binaryAnd(constConstantRange&Other)const{if(isEmptySet()||Other.isEmptySet())returnConstantRange(getBitWidth(),/*isFullSet=*/false);// TODO: replace this with something less conservativeAPIntumin=APIntOps::umin(Other.getUnsignedMax(),getUnsignedMax());if(umin.isAllOnesValue())returnConstantRange(getBitWidth(),/*isFullSet=*/true);returnConstantRange(APInt::getNullValue(getBitWidth()),umin+1);}ConstantRangeConstantRange::binaryOr(constConstantRange&Other)const{if(isEmptySet()||Other.isEmptySet())returnConstantRange(getBitWidth(),/*isFullSet=*/false);// TODO: replace this with something less conservativeAPIntumax=APIntOps::umax(getUnsignedMin(),Other.getUnsignedMin());if(umax.isMinValue())returnConstantRange(getBitWidth(),/*isFullSet=*/true);returnConstantRange(umax,APInt::getNullValue(getBitWidth()));}ConstantRangeConstantRange::shl(constConstantRange&Other)const{if(isEmptySet()||Other.isEmptySet())returnConstantRange(getBitWidth(),/*isFullSet=*/false);APIntmin=getUnsignedMin().shl(Other.getUnsignedMin());APIntmax=getUnsignedMax().shl(Other.getUnsignedMax());// there's no overflow!APIntZeros(getBitWidth(),getUnsignedMax().countLeadingZeros());if(Zeros.ugt(Other.getUnsignedMax()))returnConstantRange(min,max+1);// FIXME: implement the other tricky casesreturnConstantRange(getBitWidth(),/*isFullSet=*/true);}ConstantRangeConstantRange::lshr(constConstantRange&Other)const{if(isEmptySet()||Other.isEmptySet())returnConstantRange(getBitWidth(),/*isFullSet=*/false);APIntmax=getUnsignedMax().lshr(Other.getUnsignedMin());APIntmin=getUnsignedMin().lshr(Other.getUnsignedMax());if(min==max+1)returnConstantRange(getBitWidth(),/*isFullSet=*/true);returnConstantRange(min,max+1);}ConstantRangeConstantRange::inverse()const{if(isFullSet())returnConstantRange(getBitWidth(),/*isFullSet=*/false);if(isEmptySet())returnConstantRange(getBitWidth(),/*isFullSet=*/true);returnConstantRange(Upper,Lower);}/// print - Print out the bounds to a stream...///voidConstantRange::print(raw_ostream&OS)const{if(isFullSet())OS<<"full-set";elseif(isEmptySet())OS<<"empty-set";elseOS<<"["<<Lower<<","<<Upper<<")";}/// dump - Allow printing from a debugger easily...///voidConstantRange::dump()const{print(dbgs());}