aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/IR/ConstantRangeTest.cpp
AgeCommit message (Collapse)AuthorFilesLines
2025-02-17ConstRange: exhaustively test makeExactICmpRegion (#127058)Ramkumar Ramachandra1-0/+11
Exhaustively test makeExactICmpRegion by comparing makeAllowedICmpRegion against makeSatisfyingICmpRegion for all APInts.
2025-02-16ConstRange: test edge-cases of makeAllowedICmpRegion (#127080)Ramkumar Ramachandra1-3/+27
Exhaustively test signed-unsigned min-max edge-cases of makeAllowedICmpRegion.
2025-02-15ConstRange: factor and introduce splitPosNeg (NFC) (#126528)Ramkumar Ramachandra1-0/+10
Factor out some code that splits a ConstantRange into positive and negative components, introducing ConstantRange::splitPosNeg.
2024-12-31[ConstantRange] Estimate tighter lower (upper) bounds for masked binary and ↵Stephen Senran Zhang1-0/+31
(or) (#120352) Fixes #118108. Co-author: Yingwei Zheng (@dtcxzyw)
2024-09-05[ConstantRangeTest] Set APInt signed flags where needed (NFC)Nikita Popov1-116/+124
Split out from https://github.com/llvm/llvm-project/pull/80309 to avoid assertion failures in the future.
2024-08-07[ConstantRange] Improve `shlWithNoWrap` (#101800)Yingwei Zheng1-3/+36
Closes https://github.com/dtcxzyw/llvm-tools/issues/22.
2024-08-02 [ConstantRange] Add support for `shlWithNoWrap` (#100594)Yingwei Zheng1-0/+42
This patch adds initial support for `ConstantRange:: shlWithNoWrap` to fold https://github.com/dtcxzyw/llvm-tools/issues/22. However, this patch cannot fix the original issue. Improvements will be submitted in subsequent patches.
2024-07-25[ConstantRange] Infer nonnegative for mul nuw nsw (#100554)Yingwei Zheng1-0/+18
Alive2: https://alive2.llvm.org/ce/z/byzmsV
2024-07-03ConstantRange: add query for isAllPositive (#97420)Ramkumar Ramachandra1-2/+10
ConstantRange has queries for isAllNegative and isAllNonNegative, but misses a query for isAllPositive. Add this function.
2024-06-17[LVI][ConstantRange] Generalize mask not equal conditions handlingAntonio Frighetto1-0/+48
Extend `V & Mask != 0` for non-zero constants if satisfiable, when retrieving constraint value information from a non-equality comparison. Proof: https://alive2.llvm.org/ce/z/dc5BeT. Motivating example: https://github.com/gcc-mirror/gcc/blob/master/gcc/testsuite/gcc.dg/tree-ssa/vrp76.c.
2024-05-24[ConstantRange][LVI] Add support for `multiplyWithNoWrap`Antonio Frighetto1-7/+95
Introduce support for computing multiplication ranges when nowrap flags are known. This is achieved by intersecting the multiplication range with the saturating one. Note that we may still conservatively return overdefined when handling non-wrapped/non-sign-wrapped ranges.
2024-03-21[ConstantRange] Fix off by 1 bugs in UIToFP and SIToFP handling. (#86041)Craig Topper1-0/+18
We were passing the min and max values of the range to the ConstantRange constructor, but the constructor expects the upper bound to 1 more than the max value so we need to add 1. We also need to use getNonEmpty so that passing 0, 0 to the constructor creates a full range rather than an empty range. And passing smin, smax+1 doesn't cause an assertion. I believe this fixes at least some of the reason #79158 was reverted.
2024-02-08[ConstantRange] Improve ConstantRange::binaryXor (#80146)Yingwei Zheng1-0/+6
`ConstantRange::binaryXor` gives poor results as it currently depends on `KnownBits::operator^`. Since `sub A, B` is canonicalized into `xor A, B` if `B` is the subset of `A`, this patch reverts the transform in `ConstantRange::binaryXor`, which will give better results. Alive2: https://alive2.llvm.org/ce/z/bmTMV9 Fixes #79696.
2023-11-06[ConstantRange] Handle `Intrinsic::cttz` (#67917)Yingwei Zheng1-0/+14
This patch adds support for `Intrinsic::cttz` in ConstantRange. It calculates the range in O(1) with the LCP-based method. Migrated from https://reviews.llvm.org/D153505.
2023-11-06[ConstantRange] Handle `Intrinsic::ctpop` (#68310)Yingwei Zheng1-0/+6
This patch adds support for `Intrinsic::ctpop` in ConstantRange. It calculates the range in O(1) with the LCP-based method. Migrated from https://reviews.llvm.org/D153505.
2023-08-29[ConstantRange] Make shl() for negative LHS more preciseNikita Popov1-0/+7
This differs from the positive case in that shifting by a larger amount makes the result smaller, not larger.
2023-06-23[ConstantRange] Calculate precise range for multiply by -1Nikita Popov1-0/+20
These are pretty common in SCEV, so make sure we get a precise result by mapping to the sub() operation.
2023-02-20Migrate away from the soft-deprecated functions in APInt.h (NFC)Kazu Hirata1-1/+1
Note that those functions on the left hand side are soft-deprecated in favor of those on the right hand side: getMinSignedBits -> getSignificantBits getNullValue -> getZero isNullValue -> isZero isOneValue -> isOne
2023-02-19Use APInt::count{l,r}_{zero,one} (NFC)Kazu Hirata1-5/+4
2023-02-17[ConstantRange] Handle `Intrinsic::ctlz`Antonio Frighetto1-0/+15
Introduce ConstantRange support for ctlz intrinsic, including exhaustive testing. Among other things, LVI may now be able to propagate information about cltz constant ranges lattice values. Differential Revision: https://reviews.llvm.org/D142234
2023-01-09[ConstantRange] Test 1 bit ranges in exhaustive tests (NFC)Nikita Popov1-51/+50
There have been multiple cases where range calculations were wrong in the 1 bit case. Make sure we catch these by not specifying the bit width explicitly, and letting the test framework pick it (which will now always test 1 and 4 bits both).
2023-01-09[ConstantRange] Fix single bit abs range (PR59887)Nikita Popov1-8/+9
For a full range input, we would produce an empty range instead of a full range. The change to the SMin.isNonNegative() branch is an optimality fix, because we should account for the potentially discarded SMin value in the IntMinIsPoison case. Change TestUnaryOpExhaustive to test both 4 and 1 bits, to both cover this specific case in unit tests, and make sure all other unary operations deal with 1-bit inputs correctly. Fixes https://github.com/llvm/llvm-project/issues/59887.
2022-12-20[llvm] Use std::optional instead of OptionalKazu Hirata1-31/+23
This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-06[ConstantRange] Fix nsw nowrap region for 1 bit integers (PR59301)Nikita Popov1-23/+24
The special case for V=1 was incorrect for one bit types, where 1 is also -1. Remove it, and use getNonEmpty() to handle the full range case instead. Adjust the exhaustive nowrap tests to test both 5 bit and 1 bit types. Fixes https://github.com/llvm/llvm-project/issues/59301.
2022-12-05[IR] llvm::Optional => std::optionalFangrui Song1-1/+1
Many llvm/IR/* files have been migrated by other contributors. This migrates most remaining files.
2022-12-02[llvm/unittests] Use std::nullopt instead of None (NFC)Kazu Hirata1-10/+10
This patch mechanically replaces None with std::nullopt where the compiler would warn if None were deprecated. The intent is to reduce the amount of manual work required in migrating from Optional to std::optional. This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-07-18[ConstantRangeTest] Migrate known bits test to generic infrastructure (NFC)Nikita Popov1-57/+6
This can't make use of TestBinaryOpExhaustive, but it can make use of the general TestRange approach that collects the precise elements in a bit vector. This allows us to remove the obsolete "op range gatherer" infrastructure.
2022-07-18[ConstantRangeTest] Move nowrap binop tests to generic infrastructure (NFC)Nikita Popov1-132/+78
Move testing for add/sub with nowrap flags to TestBinaryOpExhaustive, rather than separate homegrown exhaustive testing functions.
2022-07-01[ConstantRange] Fix sdiv() with one bit values (PR56333)Nikita Popov1-0/+3
Signed one bit values can only be -1 or 0, not positive. The code was interpreting the 1 as -1 and intersecting with a full range rather than an empty one. Fixes https://github.com/llvm/llvm-project/issues/56333.
2022-06-25[llvm] Don't use Optional::{hasValue,getValue} (NFC)Kazu Hirata1-1/+1
2022-05-20Recommit "[ConstantRange] Improve the implementation of binaryOr"Alexander Shaposhnikov1-0/+38
This recommits https://reviews.llvm.org/rG6990e7477d24ff585ae86549f5280f0be65422a6 as the problematic test has been updated updated in https://reviews.llvm.org/rG3bd112c720dc614a59e3f34ebf9b45075037bfa0.
2022-05-20Revert "[ConstantRange] Improve the implementation of binaryOr"Douglas Yung1-38/+0
This reverts commit 6990e7477d24ff585ae86549f5280f0be65422a6. This change was causing the test compiler-rt/test/fuzzer/merge_two_step.test to fail on our internal bot as well as other build bots such as https://lab.llvm.org/buildbot/#/builders/179/builds/3712.
2022-05-19[ConstantRange] Improve the implementation of binaryOrAlexander Shaposhnikov1-0/+38
This diff adjusts binaryOr to take advantage of the analysis based on KnownBits. Differential revision: https://reviews.llvm.org/D125933 Test plan: 1/ ninja check-llvm 2/ ninja check-llvm-unit
2022-05-17[ConstantRange] Improve the implementation of binaryAndAlexander Shaposhnikov1-0/+32
This diff adjusts binaryAnd to take advantage of the analysis based on KnownBits. Differential revision: https://reviews.llvm.org/D125603 Test plan: 1/ ninja check-llvm 2/ ninja check-llvm-unit
2022-05-17[ConstantRange] Implement binaryXor() using known bitsNikita Popov1-4/+14
This allows us to compute known high bits. It's not optimal, but better than nothing.
2022-05-17[KnownBits] Add operator==Nikita Popov1-2/+1
Checking whether two KnownBits are the same is somewhat common, mainly in test code. I don't think there is a lot of room for confusion with "determine what the KnownBits for an icmp eq would be", as that has a different result type (this is what the eq() method implements, which returns Optional<bool>). Differential Revision: https://reviews.llvm.org/D125692
2022-05-16[ConstantRange] Add toKnownBits() methodNikita Popov1-0/+19
Add toKnownBits() method to mirror fromKnownBits(). We know the top bits that are constant between min and max. The return value for an empty range is chosen to be conservative.
2021-11-12[ConstantRangeTest] Add helper to enumerate APInts (NFC)Nikita Popov1-5/+13
While ForeachNumInConstantRange(ConstantRange::getFull(Bits)) works, it's somewhat roundabout, and I keep looking for this function.
2021-11-07[ConstantRange] Add exact union/intersect (NFC)Nikita Popov1-2/+15
For some optimizations on comparisons it's necessary that the union/intersect is exact and not a superset. Add methods that return Optional<ConstantRange> only if the result is exact. For the sake of simplicity this is implemented by comparing the subset and superset approximations for now, but it should be possible to do this more directly, as unionWith() and intersectWith() already distinguish the cases where the result is imprecise for the preferred range type functionality.
2021-11-07[ConstantRange] Support zero size in isSizeLargerThan()Nikita Popov1-0/+11
From an API perspective, it does not make a lot of sense that 0 is not a valid argument to this function. Add the exact check needed to support it.
2021-11-06[ConstantRange] Add getEquivalentICmp() variant with offset (NFCI)Nikita Popov1-0/+17
Add a variant of getEquivalentICmp() that produces an optional offset. This allows us to create an equivalent icmp for all ranges. Use this in the with.overflow folding code, which was doing this adjustment separately -- this clarifies that the fold will indeed always apply.
2021-11-03Make enum iteration with seq safe by defaultJakub Kuderski1-8/+4
By default `llvm::seq` would happily iterate over enums, which may be unsafe if the enum values are not continuous. This patch disable enum iteration with `llvm::seq` and `llvm::seq_inclusive` and adds two new functions: `enum_seq` and `enum_seq_inclusive`. To make sure enum iteration is safe, we require users to declare their enum types as iterable by specializing `enum_iteration_traits<SomeEnum>`. Because it's not always possible to add these traits next to enum definition (e.g., for enums defined in external libraries), we provide an escape hatch to allow iteration on per-callsite basis by passing `force_iteration_on_noniterable_enum`. The main benefit of this approach is that these global declarations via traits can appear just next to enum definitions, making easy to spot when enums are miss-labeled, e.g., after introducing new enum values, whereas `force_iteration_on_noniterable_enum` should stand out and be easy to grep for. This emerged from a discussion with gchatelet@ about reusing llvm's `Sequence.h` in lieu of https://github.com/GPUOpen-Drivers/llpc/blob/dev/lgc/interface/lgc/EnumIterator.h. Reviewed By: dblaikie, gchatelet, aaron.ballman Differential Revision: https://reviews.llvm.org/D107378
2021-10-31[ConstantRange] Sign-flipping of signedness-invariant comparisonsRoman Lebedev1-1/+77
For certain combination of LHS and RHS constant ranges, the signedness of the relational comparison predicate is irrelevant. This implements complete and precise model for all predicates, as confirmed by the brute-force tests. I'm not sure if there are some more cases that we can handle here. In a follow-up, CVP will make use of this. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D90924
2021-10-30[NFCI] Introduce `ICmpInst::compare()` and use it where appropriateRoman Lebedev1-29/+3
As noted in https://reviews.llvm.org/D90924#inline-1076197 apparently this is a pretty common pattern, let's not repeat it yet again, but have it in a common place. There may be some more places where it could be used, but these are the most obvious ones.
2021-10-17[ConstantRange] Add fast signed multiplyNikita Popov1-0/+14
The multiply() implementation is very slow -- it performs six multiplications in double the bitwidth, which means that it will typically work on allocated APInts and bypass fast-path implementations. Add an additional implementation that doesn't try to produce anything better than a full range if overflow is possible. At least for the BasicAA use-case, we really don't care about more precise modeling of overflow behavior. The current use of multiply() is fine while the implementation is limited to a single index, but extending it to the multiple-index case makes the compile-time impact untenable.
2021-10-15[ConstantRange] Compute precise shl range for single elementsNikita Popov1-1/+17
For the common case where the shift amount is constant (a single element range) we can easily compute a precise range (up to unsigned envelope), so do that.
2021-10-15[ConstantRange] Support checking optimality for subset of inputs (NFC)Nikita Popov1-23/+30
We always want to check correctness, but for some operations we can only guarantee optimality for a subset of inputs. Accept an additional predicate that determines whether optimality for a given pair of ranges should be checked.
2021-10-15[ConstantRange] Better diagnostic for correctness test failure (NFC)Nikita Popov1-2/+12
Print a friendly error message including the inputs, result and not-contained element if an exhaustive correctness test fails, same as we do if the optimality test fails.
2021-10-04[APInt] Stop using soft-deprecated constructors and methods in llvm. NFC.Jay Foad1-5/+5
Stop using APInt constructors and methods that were soft-deprecated in D109483. This fixes all the uses I found in llvm, except for the APInt unit tests which should still test the deprecated methods. Differential Revision: https://reviews.llvm.org/D110807
2021-09-09[APInt] Normalize naming on keep constructors / predicate methods.Chris Lattner1-13/+9
This renames the primary methods for creating a zero value to `getZero` instead of `getNullValue` and renames predicates like `isAllOnesValue` to simply `isAllOnes`. This achieves two things: 1) This starts standardizing predicates across the LLVM codebase, following (in this case) ConstantInt. The word "Value" doesn't convey anything of merit, and is missing in some of the other things. 2) Calling an integer "null" doesn't make any sense. The original sin here is mine and I've regretted it for years. This moves us to calling it "zero" instead, which is correct! APInt is widely used and I don't think anyone is keen to take massive source breakage on anything so core, at least not all in one go. As such, this doesn't actually delete any entrypoints, it "soft deprecates" them with a comment. Included in this patch are changes to a bunch of the codebase, but there are more. We should normalize SelectionDAG and other APIs as well, which would make the API change more mechanical. Differential Revision: https://reviews.llvm.org/D109483