We already infer this in IPSCCP (which runs very early, so cannot
benefit from inlining and simplifications) and SCCP (which runs without
PredicateInfo, so does not use assumes). Do it in CVP as well, so it can
handle cases that IPSCCP/SCCP can't.
Fixes https://github.com/llvm/llvm-project/issues/98946 (everything
apart from f2, where the assume is dropped by the frontend).
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.
Currently, the LVI analysis pass doesn't support InsertElementInst
vector instruction. Due to this, some optimization opportunities are
missed. For example, in the below example, ICMP instruction can be
folded but it doesn't.
```
...
%ie1 = insertelement <2 x i32> poison, i32 10, i64 0
%ie2 = insertelement <2 x i32> %ie1, i32 20, i64 1
%icmp = icmp <2 x i1> %ie2, <i32 40, i32 40>
...
```
This change adds InsertElementInst support in the LVI analysis pass to
fix the motivating example.
This is a followup to vector support in LVI/CVP/SCCP. In mergeIn(), if
one of the operands is a vector of integer constant, we should try to
convert it into a constant range, in case that allows performing a range
union to something better than overdefined.
Fixes#97674
After #97428 added support for vectors, our constant ranges can now be
from splat vectors so when they reduce to a singe constant value, we
need to return the original type as opposed to just an int.
The core change here is to add support for converting vector constants
into constant ranges. The rest is just relaxing isIntegerTy() checks and
making sure we don't use APIs that assume vectors.
There are a couple of places that don't support vectors yet, most
notably the "simplest" fold (comparisons to a constant) isn't supported
yet. I'll leave these to a followup.
This patch adds folds for calls to `ucmp`/`scmp` intrinsics where we can
establish that the range of the first operand is strictly to the left or
strictly to the right of the range of the second operand.
Remove support for the icmp and fcmp constant expressions.
This is part of:
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179
As usual, many of the updated tests will no longer test what they were
originally intended to -- this is hard to preserve when constant
expressions get removed, and in many cases just impossible as the
existence of a specific kind of constant expression was the cause of the
issue in the first place.
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.
This adds handling of range attribute for return values of Call and
Invoke in getFromRangeMetadata and handling of argument with range
attribute in solveBlockValueNonLocal.
There is one additional check of the range metadata at line 1120 in
getValueFromSimpleICmpCondition that is not covered in this PR as after
https://github.com/llvm/llvm-project/pull/75311 there is no test that
cover that check any more and I have not been able to create a test that
trigger that code.
We have more complete logic for handling `Add`, so try to use that
logic for `or disjoint` (which can definitionally be treated as
`add`).
Closes#86058
We're going from a single use to two independent uses, we need these two
to see consistent values for undef. As an example, consider x = 0x2 when
y = 0b00u1. If the sub use picks 0b0001 and the cmp use picks 0b0011,
that would be incorrect.
This reverts commit a034e65e972175a2465deacb8c78bc7efc99bd23.
Some protobuf users reported that this patch caused a significant
compile-time regression because `TailDuplicator` works poorly with a
specific pattern.
We will reland it once the codegen issue is fixed.
If one of the binop operands depends on the other, this may end
up evaluating them in the wrong order, producing sub-optimal
results.
Make sure that only one unevaluated operand gets pushed per
iteration.
Fixes https://github.com/llvm/llvm-project/issues/76705.
Currently, LVI will only use conditions like "X < C" to constrain the
value of X on the relevant edge. This patch extends it to handle
conditions like "X < Y" by querying the known range of Y.
This means that getValueFromCondition() and various related APIs can now
return nullopt to indicate that they have pushed to the worklist, and
need to be called again later. This behavior is currently controlled by
a UseBlockValue option, and only enabled for actual edge value handling.
All other places deriving constraints from conditions keep using the
previous logic for now.
This change was originally motivated as a fix for the regression
reported in
https://github.com/llvm/llvm-project/pull/73662#issuecomment-1849281758.
Unfortunately, it doesn't actually fix it, because we run into another
issue there (LVI currently is really bad at handling values used in
loops).
This change has some compile-time impact, but it's fairly small,
in the 0.05% range.
Currently isGuaranteedNotToBeUndef() is the same as
isGuaranteedNotToBeUndefOrPoison(). This function is used in places
where we only care about undef (due to multi-use issues), not poison.
Make it more precise by only considering instructions that can create
undef (like loads or call), and ignore those that can only create
poison. In particular, we can ignore poison-generating flags.
This means that inferring more flags has less chance to pessimize other
transforms.