ConstantRanges have an annoying special case: If upper and lower are
the same, it can be either an empty or a full set. When constructing
constant ranges nearly always a full set is intended, but this still
requires an explicit check in many places.
This revision adds a getNonEmpty() constructor that disambiguates this
case: If upper and lower are the same, a full set is created.
Differential Revision: https://reviews.llvm.org/D60947
llvm-svn: 358854
getSetSize returns an APInt that is 1 bit wider. The APInt is typically 65-bit and requires memory allocation. isSizeStrictlySmallerThan and isSizeLargerThan are preferred. The last use of this helper method was removed by rL302385.
llvm-svn: 358347
As motivated in D60598, this drops support for specifying both NUW and
NSW in makeGuaranteedNoWrapRegion(). None of the users of this function
currently make use of this.
When both NUW and NSW are specified, the exact nowrap region has two
disjoint parts and makeGNWR() returns one of them. This result doesn't
seem to be useful for anything, but makes the semantics of the function
fuzzier.
Differential Revision: https://reviews.llvm.org/D60632
llvm-svn: 358340
makeGuaranteedNoWrapRegion() is actually makeExactNoWrapRegion() as
long as only one of NUW or NSW is specified. This is not obvious from
the current documentation, and some code seems to think that it is
only exact for single-element ranges. Clarify docs and add tests to
be more confident this really holds.
There are currently no users of makeGuaranteedNoWrapRegion() that
pass both NUW and NSW. I think it would be best to drop support for
this entirely and then rename the function to makeExactNoWrapRegion().
Knowing that the no-wrap region is exact is useful, because we can
backwards-constrain values. What I have in mind in particular is
that LVI should be able to constrain values on edges where the
with.overflow overflow flag is false.
Differential Revision: https://reviews.llvm.org/D60598
llvm-svn: 358305
Same as the other ConstantRange overflow checking methods, but for
unsigned mul. In this case there is no cheap overflow criterion, so
using umul_ov for the implementation.
Differential Revision: https://reviews.llvm.org/D60574
llvm-svn: 358228
This extends D59959 to unionWith(), allowing to specify that a
non-wrapping unsigned/signed range is preferred. This is somewhat
less useful than the intersect case, because union operations are
rarer. An example use would the the phi union computed in SCEV.
The implementation is mostly a straightforward use of getPreferredRange(),
but I also had to adjust some <=/< checks to make sure that no ranges with
lower==upper get constructed before they're passed to getPreferredRange(),
as these have additional constraints.
Differential Revision: https://reviews.llvm.org/D60377
llvm-svn: 357876
The intersection of two ConstantRanges may consist of two disjoint
ranges. As we can only return one range as the result, we need to
return one of the two possible ranges that cover both. Currently the
result is picked based on set size. However, this is not always
optimal: If we're in an unsigned context, we'd prefer to get a large
unsigned range over a small signed range -- the latter effectively
becomes a full set in the unsigned domain.
This revision adds a PreferredRangeType, which can be either Smallest,
Unsigned or Signed. Smallest is the current behavior and Unsigned and
Signed are new variants that prefer not to wrap the unsigned/signed
domain. The new type isn't used anywhere yet (but SCEV will be a good
first user, see D60035).
I've also added some comments to illustrate the various cases in
intersectWith(), which should hopefully make it more obvious what is
going on.
Differential Revision: https://reviews.llvm.org/D59959
llvm-svn: 357873
Add isAllNegative() and isAllNonNegative() methods to ConstantRange,
which determine whether all values in the constant range are
negative/non-negative.
This is useful for replacing KnownBits isNegative() and isNonNegative()
calls when changing code to use constant ranges.
Differential Revision: https://reviews.llvm.org/D60264
llvm-svn: 357871
if we do SHL of two 16-bit ranges like [0, 30000) with [1,2) we get
"full-set" instead of what I would have expected [0, 60000) which is
still in the 16-bit unsigned range.
This patch changes the SHL algorithm to allow getting a usable range
even in this case.
Differential Revision: https://reviews.llvm.org/D57983
llvm-svn: 357854
Split off from D59749. This adds isWrappedSet() and
isUpperSignWrapped() set with the same behavior as isSignWrappedSet()
and isUpperWrapped() for the respectively other domain.
The methods isWrappedSet() and isSignWrappedSet() will not consider
ranges of the form [X, Max] == [X, 0) and [X, SignedMax] == [X, SignedMin)
to be wrapping, while isUpperWrapped() and isUpperSignWrapped() will.
Also replace the checks in getUnsignedMin() and friends with method
calls that implement the same logic.
llvm-svn: 357112
Split out from D59749. The current implementation of isWrappedSet()
doesn't do what it says on the tin, and treats ranges like
[X, Max] as wrapping, because they are represented as [X, 0) when
using half-inclusive ranges. This also makes it inconsistent with
the semantics of isSignWrappedSet().
This patch renames isWrappedSet() to isUpperWrapped(), in preparation
for the introduction of a new isWrappedSet() method with corrected
behavior.
llvm-svn: 357107
Split off from D59749. This uses a simpler and more efficient
implementation of isSignWrappedSet(), and considers full sets
as non-wrapped, to be consistent with isWrappedSet(). Otherwise
the behavior is unchanged.
There are currently only two users of this function and both already
check for isFullSet() || isSignWrappedSet(), so this is not going to
cause a change in overall behavior.
Differential Revision: https://reviews.llvm.org/D59848
llvm-svn: 357039
This adds ConstantRange::getFull(BitWidth) and
ConstantRange::getEmpty(BitWidth) named constructors as more readable
alternatives to the current ConstantRange(BitWidth, /* full */ false)
and similar. Additionally private getFull() and getEmpty() member
functions are added which return a full/empty range with the same bit
width -- these are commonly needed inside ConstantRange.cpp.
The IsFullSet argument in the ConstantRange(BitWidth, IsFullSet)
constructor is now mandatory for the few usages that still make use of it.
Differential Revision: https://reviews.llvm.org/D59716
llvm-svn: 356852
Following the suggestion in D59450, I'm moving the code for constructing
a ConstantRange from KnownBits out of ValueTracking, which also allows us
to test this code independently.
I'm adding this method to ConstantRange rather than KnownBits (which
would have been a bit nicer API wise) to avoid creating a dependency
from Support to IR, where ConstantRange lives.
Differential Revision: https://reviews.llvm.org/D59475
llvm-svn: 356339
Add functions to ConstantRange that determine whether the
unsigned/signed addition/subtraction of two ConstantRanges
may/always/never overflows. This will allow checking overflow
conditions based on known constant ranges in addition to known bits.
I'm implementing these methods on ConstantRange to allow them to be
unit tested independently of any ValueTracking machinery. The tests
include exhaustive testing on 4-bit ranges, to make sure the result
is both conservatively correct and maximally precise.
The OverflowResult enum is redeclared on ConstantRange, because
I wanted to avoid a dependency in either direction between
ValueTracking.h and ConstantRange.h.
Differential Revision: https://reviews.llvm.org/D59193
llvm-svn: 356276
to reflect the new license.
We understand that people may be surprised that we're moving the header
entirely to discuss the new license. We checked this carefully with the
Foundation's lawyer and we believe this is the correct approach.
Essentially, all code in the project is now made available by the LLVM
project under our new license, so you will see that the license headers
include that license only. Some of our contributors have contributed
code under our old license, and accordingly, we have retained a copy of
our old license notice in the top-level files in each project and
repository.
llvm-svn: 351636
Summary: This is trying to add support for r334428.
Reviewers: sanjoy
Subscribers: jlebar, hiraditya, bixia, llvm-commits
Differential Revision: https://reviews.llvm.org/D48399
llvm-svn: 335646
See r331124 for how I made a list of files missing the include.
I then ran this Python script:
for f in open('filelist.txt'):
f = f.strip()
fl = open(f).readlines()
found = False
for i in xrange(len(fl)):
p = '#include "llvm/'
if not fl[i].startswith(p):
continue
if fl[i][len(p):] > 'Config':
fl.insert(i, '#include "llvm/Config/llvm-config.h"\n')
found = True
break
if not found:
print 'not found', f
else:
open(f, 'w').write(''.join(fl))
and then looked through everything with `svn diff | diffstat -l | xargs -n 1000 gvim -p`
and tried to fix include ordering and whatnot.
No intended behavior change.
llvm-svn: 331184
Extend the ConstantRange implementation to compute the range of possible values resulting from an arithmetic right shift operation.
There will be a follow up patch to leverage this constant range infrastructure in LazyValueInfo.
Patch by Surya Kumari Jangala!
Differential Revision: https://reviews.llvm.org/D40881
llvm-svn: 320976
Previously ConstantRange::makeGuaranteedNoWrapRegion only handled addition. This adds support for subtraction.
Differential Revision: https://reviews.llvm.org/D40036
llvm-svn: 319806
Summary:
Add LLVM_FORCE_ENABLE_DUMP cmake option, and use it along with
LLVM_ENABLE_ASSERTIONS to set LLVM_ENABLE_DUMP.
Remove NDEBUG and only use LLVM_ENABLE_DUMP to enable dump methods.
Move definition of LLVM_ENABLE_DUMP from config.h to llvm-config.h so
it'll be picked up by public headers.
Differential Revision: https://reviews.llvm.org/D38406
llvm-svn: 315590
Summary: As far as I can tell we should be able to implement these almost the same way we do unsigned, but using signed comparisons and checks for min signed value instead of min unsigned value.
Reviewers: pete, davide, sanjoy
Reviewed By: davide
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D33815
llvm-svn: 305607
I did this a long time ago with a janky python script, but now
clang-format has built-in support for this. I fed clang-format every
line with a #include and let it re-sort things according to the precise
LLVM rules for include ordering baked into clang-format these days.
I've reverted a number of files where the results of sorting includes
isn't healthy. Either places where we have legacy code relying on
particular include ordering (where possible, I'll fix these separately)
or where we have particular formatting around #include lines that
I didn't want to disturb in this patch.
This patch is *entirely* mechanical. If you get merge conflicts or
anything, just ignore the changes in this patch and run clang-format
over your #include lines in the files.
Sorry for any noise here, but it is important to keep these things
stable. I was seeing an increasing number of patches with irrelevant
re-ordering of #include lines because clang-format was used. This patch
at least isolates that churn, makes it easy to skip when resolving
conflicts, and gets us to a clean baseline (again).
llvm-svn: 304787
Truncate currently uses a udivrem call which is going to be slow particularly for larger than 64-bit widths.
As far as I can tell all we were trying to do was modulo LowerDiv by (MaxValue+1) and make sure whatever value was effectively subtracted from LowerDiv was also subtracted from UpperDiv.
This patch recognizes that MaxValue+1 is a power of 2 so we can just use a bitwise AND to accomplish a modulo operation or isolate the upper bits.
Differential Revision: https://reviews.llvm.org/D32672
llvm-svn: 304733
r271020 added an early out to skip the signed multiply portion of ConstantRange::multiply. The comment says we don't need to do signed multiply if the range is only positive numbers, but the implemented check only ensures that the start of the range is positive. It doesn't look at the end of the range.
This patch checks the end of the range instead. Because Upper is one more than the end we have to see if its positive or if its one past the last positive number.
llvm-svn: 302717
Previously SimplifyCFG used getSetSize which returns an APInt that is 1 bit wider than the ConstantRange's bit width. In the reasonably common case that the ConstantRange is 64-bits wide, this requires returning a 65-bit APInt. APInt's can only store 64-bits without a memory allocation so this is inefficient.
The new method takes the 8 as an input and tells if the range contains more than that many elements without requiring any wider math.
llvm-svn: 302385
We were default constructing the Lower/Upper APInts. Then creating min or max value, then doing a move assignment to Lower and copy assignment to upper. The copy assignment operator in particular has an out of line function call that has to examine whether or not a previous allocation exists that can be reused which of course it can't in this case.
The new code creates the min/max value first, move constructs Lower from it then copy constructs Upper from Lower.
This also seems to have convinced a self host build that this constructor can be inlined more readily into other methods in ConstantRange.
llvm-svn: 301736
We were creating an APInt at the top of these methods that isn't always returned. For ranges wider than 64-bits this results in an allocation and deallocation when its not used.
In getSignedMax we were creating Upper-1 to use in a compare and then creating it again for a return value. The compiler is unable to determine that these can be shared. So help it out and create the Upper-1 in a temporary that can be reused.
This provides a little compile time improvement.
llvm-svn: 300621
This typedef used to be conditional based on whether rvalue references were supported. Looks like it got left behind when we switched to always having rvalue references with c++11. I don't think it provides any value now.
llvm-svn: 300146
Summary:
ConstantRange class currently has a method getSetSize, which is mostly used to
compare set sizes of two constant ranges (there is only one spot where it's used
in a slightly different scenario). This patch introduces setSizeSmallerThanOf
method, which does such comparison in a more efficient way. In the original
method we have to extend our types to (BitWidth+1), which can result it using
slow case of APInt, extra memory allocations, etc.
The change is supposed to not change any functionality, but it slightly improves
compile time. Here is compile time improvements that I observed on CTMark:
* tramp3d-v4 -2.02%
* pairlocalalign -1.82%
* lencod -1.67%
Reviewers: sanjoy, atrick, pete
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D31104
llvm-svn: 298236