135 Commits

Author SHA1 Message Date
Andreas Jonson
ca7ffaaeeb [ConstantRange] add nuw support to truncate (NFC) (#152990) 2025-08-12 12:26:35 +02:00
Ramkumar Ramachandra
8eba128b2d
ConstRange: exhaustively test makeExactICmpRegion (#127058)
Exhaustively test makeExactICmpRegion by comparing makeAllowedICmpRegion
against makeSatisfyingICmpRegion for all APInts.
2025-02-17 12:30:07 +00:00
Ramkumar Ramachandra
8ac5d2d180
ConstRange: test edge-cases of makeAllowedICmpRegion (#127080)
Exhaustively test signed-unsigned min-max edge-cases of
makeAllowedICmpRegion.
2025-02-16 12:40:03 +00:00
Ramkumar Ramachandra
b403004035
ConstRange: factor and introduce splitPosNeg (NFC) (#126528)
Factor out some code that splits a ConstantRange into positive and
negative components, introducing ConstantRange::splitPosNeg.
2025-02-15 17:25:03 +00:00
Stephen Senran Zhang
2feffecb88
[ConstantRange] Estimate tighter lower (upper) bounds for masked binary and (or) (#120352)
Fixes #118108.

Co-author: Yingwei Zheng (@dtcxzyw)
2024-12-31 18:40:17 -08:00
Nikita Popov
9e85efb0de [ConstantRangeTest] Set APInt signed flags where needed (NFC)
Split out from https://github.com/llvm/llvm-project/pull/80309 to
avoid assertion failures in the future.
2024-09-05 16:11:00 +02:00
Yingwei Zheng
07b29fc808
[ConstantRange] Improve shlWithNoWrap (#101800)
Closes https://github.com/dtcxzyw/llvm-tools/issues/22.
2024-08-07 02:00:33 +08:00
Yingwei Zheng
1a5d8926c5
[ConstantRange] Add support for shlWithNoWrap (#100594)
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-08-02 00:03:44 +08:00
Yingwei Zheng
ca00cec997
[ConstantRange] Infer nonnegative for mul nuw nsw (#100554)
Alive2: https://alive2.llvm.org/ce/z/byzmsV
2024-07-25 21:29:18 +08:00
Ramkumar Ramachandra
edbbc832a5
ConstantRange: add query for isAllPositive (#97420)
ConstantRange has queries for isAllNegative and isAllNonNegative, but
misses a query for isAllPositive. Add this function.
2024-07-03 10:50:22 +01:00
Antonio Frighetto
c22d3917b9 [LVI][ConstantRange] Generalize mask not equal conditions handling
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-06-17 21:13:52 +02:00
Antonio Frighetto
e897b0bbe9 [ConstantRange][LVI] Add support for multiplyWithNoWrap
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-05-24 19:25:09 +02:00
Craig Topper
12836467b7
[ConstantRange] Fix off by 1 bugs in UIToFP and SIToFP handling. (#86041)
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-03-21 09:25:13 -07:00
Yingwei Zheng
d9e92765c5
[ConstantRange] Improve ConstantRange::binaryXor (#80146)
`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.
2024-02-08 22:34:52 +08:00
Yingwei Zheng
6f1d3b97c7
[ConstantRange] Handle Intrinsic::cttz (#67917)
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 19:17:39 +08:00
Yingwei Zheng
b6deea1b53
[ConstantRange] Handle Intrinsic::ctpop (#68310)
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-11-06 15:59:50 +08:00
Nikita Popov
4dd392fcd7 [ConstantRange] Make shl() for negative LHS more precise
This differs from the positive case in that shifting by a larger
amount makes the result smaller, not larger.
2023-08-29 14:48:33 +02:00
Nikita Popov
7cf567d461 [ConstantRange] Calculate precise range for multiply by -1
These are pretty common in SCEV, so make sure we get a precise
result by mapping to the sub() operation.
2023-06-23 12:17:48 +02:00
Kazu Hirata
5e111eb275 Migrate away from the soft-deprecated functions in APInt.h (NFC)
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-20 00:58:29 -08:00
Kazu Hirata
f8f3db2756 Use APInt::count{l,r}_{zero,one} (NFC) 2023-02-19 22:04:47 -08:00
Antonio Frighetto
65898e5260 [ConstantRange] Handle Intrinsic::ctlz
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-02-17 09:57:35 +01:00
Nikita Popov
bd66251864 [ConstantRange] Test 1 bit ranges in exhaustive tests (NFC)
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 16:57:08 +01:00
Nikita Popov
fd07583ca4 [ConstantRange] Fix single bit abs range (PR59887)
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.
2023-01-09 16:34:09 +01:00
Kazu Hirata
77c90c8ce0 [llvm] Use std::optional instead of 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-12-20 15:42:32 -08:00
Nikita Popov
b04fc99c34 [ConstantRange] Fix nsw nowrap region for 1 bit integers (PR59301)
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-06 16:37:43 +01:00
Fangrui Song
89fae41ef1 [IR] llvm::Optional => std::optional
Many llvm/IR/* files have been migrated by other contributors.
This migrates most remaining files.
2022-12-05 04:13:11 +00:00
Kazu Hirata
b6a01caa64 [llvm/unittests] Use std::nullopt instead of None (NFC)
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-12-02 22:10:37 -08:00
Nikita Popov
2e91266942 [ConstantRangeTest] Migrate known bits test to generic infrastructure (NFC)
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 15:20:35 +02:00
Nikita Popov
b57d61384c [ConstantRangeTest] Move nowrap binop tests to generic infrastructure (NFC)
Move testing for add/sub with nowrap flags to TestBinaryOpExhaustive,
rather than separate homegrown exhaustive testing functions.
2022-07-18 15:14:17 +02:00
Nikita Popov
ba1e04b966 [ConstantRange] Fix sdiv() with one bit values (PR56333)
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-07-01 15:44:59 +02:00
Kazu Hirata
d152e50c15 [llvm] Don't use Optional::{hasValue,getValue} (NFC) 2022-06-25 11:24:23 -07:00
Alexander Shaposhnikov
9398caf399 Recommit "[ConstantRange] Improve the implementation of binaryOr"
This recommits https://reviews.llvm.org/rG6990e7477d24ff585ae86549f5280f0be65422a6
as the problematic test has been updated updated in
https://reviews.llvm.org/rG3bd112c720dc614a59e3f34ebf9b45075037bfa0.
2022-05-20 18:39:58 +00:00
Douglas Yung
54e3bf5f37 Revert "[ConstantRange] Improve the implementation of binaryOr"
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-20 10:24:20 -07:00
Alexander Shaposhnikov
6990e7477d [ConstantRange] Improve the implementation of binaryOr
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-19 21:39:19 +00:00
Alexander Shaposhnikov
0f4d9f9b71 [ConstantRange] Improve the implementation of binaryAnd
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 22:06:03 +00:00
Nikita Popov
2db4dc7ec0 [ConstantRange] Implement binaryXor() using known bits
This allows us to compute known high bits. It's not optimal, but
better than nothing.
2022-05-17 10:05:12 +02:00
Nikita Popov
a694546f7c [KnownBits] Add operator==
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-17 09:38:13 +02:00
Nikita Popov
8ab819ad90 [ConstantRange] Add toKnownBits() method
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.
2022-05-16 16:12:25 +02:00
Nikita Popov
1c5d636af1 [ConstantRangeTest] Add helper to enumerate APInts (NFC)
While ForeachNumInConstantRange(ConstantRange::getFull(Bits))
works, it's somewhat roundabout, and I keep looking for this
function.
2021-11-12 18:18:51 +01:00
Nikita Popov
2060895c9c [ConstantRange] Add exact union/intersect (NFC)
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 21:46:06 +01:00
Nikita Popov
cf71a5ea8f [ConstantRange] Support zero size in isSizeLargerThan()
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-07 21:22:45 +01:00
Nikita Popov
9f0194be45 [ConstantRange] Add getEquivalentICmp() variant with offset (NFCI)
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-06 21:59:45 +01:00
Jakub Kuderski
3348b841d3 Make enum iteration with seq safe by default
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-11-03 20:52:21 -04:00
Roman Lebedev
03a4f1f3b8
[ConstantRange] Sign-flipping of signedness-invariant comparisons
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-31 22:53:17 +03:00
Roman Lebedev
25043c8276
[NFCI] Introduce ICmpInst::compare() and use it where appropriate
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-30 17:50:06 +03:00
Nikita Popov
274b2439f8 [ConstantRange] Add fast signed multiply
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-17 16:41:49 +02:00
Nikita Popov
587493b441 [ConstantRange] Compute precise shl range for single elements
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 23:44:41 +02:00
Nikita Popov
9eb8040a28 [ConstantRange] Support checking optimality for subset of inputs (NFC)
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 22:48:07 +02:00
Nikita Popov
82e858d1bf [ConstantRange] Better diagnostic for correctness test failure (NFC)
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-15 21:52:17 +02:00
Jay Foad
a9bceb2b05 [APInt] Stop using soft-deprecated constructors and methods in llvm. NFC.
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-10-04 08:57:44 +01:00