390 Commits

Author SHA1 Message Date
Nikita Popov
0d3d445223 [LVI] Remove unnecessary TLI dependency
Only used in ConstantFoldCompareInstOperands(), which does not
actually use TLI.
2023-12-19 14:32:43 +01:00
Nikita Popov
1f5ee80789 [LVI] Don't return optional from getEdgeValueLocal() (NFC)
The general convention inside LVI is that std::nullopt means that
a value has been pushed to the worklist. However, getEdgeValueLocal()
used it as an additional spelling for getOverdefined() instead.
2023-12-12 15:32:26 +01:00
Nikita Popov
7de592b9f9 [LVI] Move bulk of getConstantRangeAtUse() implementation into Impl (NFC)
Make the layering here similar to all the other methods:
LazyValueInfoImpl implements the underlying API returning a
ValueLatticeElement, and then LazyValueInfo exposes this as a
ConstantRange publicly.
2023-12-12 15:27:00 +01:00
Nikita Popov
edcc7fe9aa [LVI] Reuse LatticeValue to ConstantRange conversion more
Use the helper in the getConstantRange() and
getConstantRangeAtUse() APIs as well. For that purpose move the
handling of isUnknown() into the helper as well.
2023-12-12 14:42:24 +01:00
Nikita Popov
bfebadc8c3 [LVI] Don't require DataLayout in getConstantRangeOrFull() (NFC)
We're only working on integers here, so we don't need DataLayout
to determine the width.
2023-12-12 14:29:08 +01:00
Nikita Popov
0c2b6a0225 [LVI] Drop bitcast handling (NFCI)
The code only works on integer casts, and the only bitcasts
involving integers are trivial. The code as previously written
would try to handle things like float to integer bitcasts by
fetching a ConstantRange of a float value, which is an ill-defined
operation.
2023-12-12 13:09:51 +01:00
Nikita Popov
516e34d98a [LVI] Switch getValueFromCondition() to use recursion
The current implementation using a worklist and visited map adds
a significant amount of additional complexity and compile-time
overhead. All we really care about here is that we don't overflow
the stack or cause exponential complexity in degenerate cases. We
can achieve this with a simple depth limit.
2023-12-12 10:55:10 +01:00
Nikita Popov
4275da2278 [ValueTracking] Add isGuaranteedNotToBeUndef() variant (NFC)
We have a bunch of places where we have to guard against undef
to avoid multi-use issues, but would be fine with poison. Use a
different function for these to make it clear, and to indicate that
this check can be removed once we no longer support undef. I've
replaced some of the obvious cases, but there's probably more.

For now, the implementation is the same as UndefOrPoison, it just
has a more precise name.
2023-12-04 12:04:41 +01:00
Aiden Grossman
0bdb9cb1ea
[NewPM] Remove LazyValueInfoPrinter Pass (#73408)
This pass isn't used anywhere upstream and thus has no test coverage.
For these reasons, remove it.
2023-11-27 15:09:18 -08:00
Aiden Grossman
5a74805bd6
[LVI] Add NewPM printer pass (#73425)
This patch adds a NewPM printer pass for the LazyValueAnalysis.
2023-11-26 12:20:49 -08:00
Amara Emerson
9189822f2c
[LVI] Handle icmp of ashr. (#68010)
This handles the case where this combine:
icmp sgt (ashr X, ShAmtC), C --> icmp sgt X, ((C + 1) << ShAmtC) - 1

wasn't performed by instcombine.

Proof of the original combine: https://alive2.llvm.org/ce/z/SfpsvX

This is a port of the review in https://reviews.llvm.org/D151911 to
GitHub.
2023-10-20 11:16:05 -07:00
DianQK
81857940f2
[LVI][CVP] Treat undef like a full range (#68190)
When converting to ConstantRange, we should treat undef like a full range.
Fixes #68381.
2023-10-10 16:03:24 +08:00
Mikael Holmen
ee1a06b80f [Analysis] Fix gcc warnings about unused variables [NFC]
gcc warned with:
 [236/4788] Building CXX object lib/Analysis/CMakeFiles/LLVMAnalysis.dir/LazyValueInfo.cpp.o
 ../lib/Analysis/LazyValueInfo.cpp: In member function 'void llvm::LazyValueInfo::forgetValue(llvm::Value*)':
 ../lib/Analysis/LazyValueInfo.cpp:1978:13: warning: unused variable 'Impl' [-Wunused-variable]
  1978 |   if (auto *Impl = getImpl())
       |             ^~~~
 ../lib/Analysis/LazyValueInfo.cpp: In member function 'void llvm::LazyValueInfo::eraseBlock(llvm::BasicBlock*)':
 ../lib/Analysis/LazyValueInfo.cpp:1983:13: warning: unused variable 'Impl' [-Wunused-variable]
  1983 |   if (auto *Impl = getImpl())
       |             ^~~~
 ../lib/Analysis/LazyValueInfo.cpp: In member function 'void llvm::LazyValueInfo::clear()':
 ../lib/Analysis/LazyValueInfo.cpp:1988:13: warning: unused variable 'Impl' [-Wunused-variable]
  1988 |   if (auto *Impl = getImpl())
       |             ^~~~
 ../lib/Analysis/LazyValueInfo.cpp: In member function 'void llvm::LazyValueInfo::printLVI(llvm::Function&, llvm::DominatorTree&, llvm::raw_ostream&)':
 ../lib/Analysis/LazyValueInfo.cpp:1993:13: warning: unused variable 'Impl' [-Wunused-variable]
  1993 |   if (auto *Impl = getImpl())
       |             ^~~~

Use the locals instead of calling getImpl() again.
2023-09-29 11:25:36 +02:00
DianQK
7af408e89b
[JumpThreading][NFC] Improved access to LazyValueInfoImpl. 2023-09-04 11:50:14 +08:00
DianQK
7ded71b1e4
[JumpThreading] Invalidate LVI after combineMetadataForCSE. 2023-09-04 11:50:14 +08:00
Nikita Popov
781beb3de5 [LVI] Check ConstantFoldCompareInstOperands() failure (NFCI)
I don't believe this can happen right now (because we're only
working on icmps and as such can't hit the current fcmp null
paths), but this will be possible in the future when icmp
constant expressions are removed.
2023-07-20 14:51:03 +02:00
luxufan
82082b7da0 [LVI] Don't compute range on not guaranteed not to be undef condition in SelectInst
Fixes:https://github.com/llvm/llvm-project/issues/62901

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D151295
2023-05-24 16:02:13 +08:00
Kazu Hirata
1ca0cb717a [llvm] Replace None with std::nullopt in comments (NFC)
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
2023-04-25 23:53:32 -07:00
luxufan
1da0da903e [LVI][CVP] Don't compute CR at SelectInst Use if Cond value may not be well-defined
If the condition value of SelectInst may be a poison or undef value,
infer constant range at SelectInst use is in correct.

See https://alive2.llvm.org/ce/z/MWMTYn

Fixes: https://github.com/llvm/llvm-project/issues/62200

Differential Revision: https://reviews.llvm.org/D148709
2023-04-22 12:54:49 +08:00
Kazu Hirata
f8f3db2756 Use APInt::count{l,r}_{zero,one} (NFC) 2023-02-19 22:04:47 -08:00
Nikita Popov
bfbfbd8b65 [LVI] Fix and re-enable at-use reasoning (PR60629)
This fixes the handling of phi nodes in getConstantRangeAtUse()
and re-enables it, reverting the workaround from
c77c186a647b385c291ddabecd70a2b4f84ae342.

For phi nodes, while we can make use of the edge condition for the
incoming value, we shouldn't look past the phi node to look for
further conditions, because we might be reasoning about values
from two different cycle iterations (which will have the same
SSA value).

To handle this more specifically we would have to detect cycles,
and there doesn't seem to be any motivating case for that at this
point.
2023-02-14 15:56:39 +01:00
Dmitry Makogon
c77c186a64 [LVI] Don't traverse uses when calculating range at use
This effectively reverts 5c38c6a and 4f772b0.

A recently introduced LazyValueInfo::getConstantRangeAtUse returns incorrect
ranges for values in certain cases. One such example is described in PR60629.
The issue has something to do with traversing PHI uses of a value transitively.
As nikic pointed out, we're effectively reasoning about values from different
loop iterations.

In the faulting test case, CVP made a miscompilation because the calculated
range for a shift argument was incorrect. It returned empty-set, however it is
clearly not a dead code. CVP then erased the shift instruction because
of empty range.
2023-02-10 17:06:36 +07:00
Nikita Popov
2e9bc1b861 [LVI] Use !range metadata for supported intrinsics
Even if the intrinsic is supported by ConstantRange, we should
still make use of !range metadata. This doesn't matter much now,
but is important if we want to support ctlz style intrinsics,
which always have KnownBits-based !range metadata attached, which
might be better than what we can compute using ranges.
2023-01-26 15:09:48 +01:00
Nikita Popov
0a4d3eae33 [LVI] Check for non-speculatable instructions
When constraining an operand based on a condition at a (potentially
transitive) use site, make sure we don't skip over non-speculatable
instructions. While the result is only used under the condition,
the non-speculatable instruction may have a side-effect or UB.

Demonstrating this issue requires raising the limit on the walk,
so do that.
2023-01-13 16:10:12 +01:00
Nikita Popov
4f772b0955 [LVI][CVP] Make use of condition known at use
When an instruction is only used in a select or phi operand, we might
be able to make use of additional information from the select/branch
condition. For example in

  %sub = call i16 @llvm.usub.sat.i16(i16 %x, i16 10)
  %cmp = icmp uge i16 %x, 10
  %sel = select i1 %cmp, i16 %sub, i16 42

the usub.sat is only used in a select where %x uge 10 is known to
hold, so we can fold it based on that knowledge.

This addresses the regression reported at
https://reviews.llvm.org/D140798#4039748, but also provides a
solution to a recurring problem we've had, where we fail to make
use of range information after a branch+phi has been converted
into a select. Our current solution to this is to hope that IPSCCP
can perform the fold before that happens, but handling this in LVI
is a somewhat more general solution.

Currently we only make use of this for the willNotOverflow() fold,
but I plan to adjust other folds to use the new API as well.

Differential Revision: https://reviews.llvm.org/D141482
2023-01-12 16:41:31 +01:00
Keno Fischer
1436a9232b [LVI] Look through negations when evaluating conditions
This teaches LVI (and thus CVP) to extract range information
from branches whose condition is negated using (`xor %c, true`).
On the implementation side, we switch the cache to additionally
track whether we're looking for the inverted value or not and
otherwise using the existing support for computing inverted
conditions.

I think the biggest question here is why this negation shows up
here at all. After all, it should always be possible for some
other pass to fold such a negation into a branch, comparison or
some other logical operation. Indeed, instcombine does just that.
However, these negations can be otherwise fairly persistent, e.g.
instsimplify is not able to exchange branch conditions from
negations. In addition, jumpthreading, which sits at the same
point in default pass pipeline also handles this pattern, which
adds further evidence that we might expect these negations to
not have been canonicalized away yet at this point in the pass
pipeline.

In the particular case I was looking at there was a bit of a
circular dependency where flags computed by cvp were needed
by instcombine, and incstombine's folding of the negation was
needed for cvp. Adding a second instombine pass would have
worked of course, but instcombine can be somewhat expensive,
so it appeared desirable to not require it to have run
before cvp (as is the case in the default pass pipeline).

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D140933
2023-01-05 23:03:46 +00:00
Fangrui Song
2fa744e631 std::optional::value => operator*/operator->
value() has undesired exception checking semantics and calls
__throw_bad_optional_access in libc++. Moreover, the API is unavailable without
_LIBCPP_NO_EXCEPTIONS on older Mach-O platforms (see
_LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS).

This commit fixes LLVMAnalysis and its dependencies.
2022-12-16 22:44:08 +00:00
Kazu Hirata
6eb0b0a045 Don't include Optional.h
These files no longer use llvm::Optional.
2022-12-14 21:16:22 -08:00
Fangrui Song
d4b6fcb32e [Analysis] llvm::Optional => std::optional 2022-12-14 07:32:24 +00:00
Kazu Hirata
e275faa5fe [Analysis] Use std::optional in LazyValueInfo.cpp (NFC)
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-11 01:18:36 -08:00
Kazu Hirata
19aff0f37d [Analysis] 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 19:43:04 -08:00
Kazu Hirata
eb0b5a36be [Analysis] Use std::optional in LazyValueInfo.cpp (NFC)
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-11-25 10:25:36 -08:00
Nikita Popov
2f211f865d [LVI] Improve debug message (NFC) 2022-11-04 16:58:02 +01:00
Nikita Popov
68b24c3b44 [CVP] Simplify comparisons without constant operand
CVP currently only tries to simplify comparisons if there is a
constant operand. However, even if both are non-constant, we may
be able to determine the result of the comparison based on range
information.

IPSCCP is already capable of doing this, but because it runs very
early, it may miss some cases.

Differential Revision: https://reviews.llvm.org/D137253
2022-11-03 15:35:27 +01:00
Kazu Hirata
601b3a13de [Analysis] Qualify auto variables in for loops (NFC) 2022-07-16 23:26:34 -07:00
Kazu Hirata
611ffcf4e4 [llvm] Use value instead of getValue (NFC) 2022-07-13 23:11:56 -07:00
Kazu Hirata
a7938c74f1 [llvm] Don't use Optional::hasValue (NFC)
This patch replaces Optional::hasValue with the implicit cast to bool
in conditionals only.
2022-06-25 21:42:52 -07:00
Kazu Hirata
3b7c3a654c Revert "Don't use Optional::hasValue (NFC)"
This reverts commit aa8feeefd3ac6c78ee8f67bf033976fc7d68bc6d.
2022-06-25 11:56:50 -07:00
Kazu Hirata
aa8feeefd3 Don't use Optional::hasValue (NFC) 2022-06-25 11:55:57 -07:00
Kazu Hirata
7a47ee51a1 [llvm] Don't use Optional::getValue (NFC) 2022-06-20 22:45:45 -07:00
Kazu Hirata
e0e687a615 [llvm] Don't use Optional::hasValue (NFC) 2022-06-20 10:38:12 -07:00
Kazu Hirata
129b531c9c [llvm] Use value_or instead of getValueOr (NFC) 2022-06-18 23:07:11 -07:00
Simon Moll
b8c2781ff6 [NFC] format InstructionSimplify & lowerCaseFunctionNames
Clang-format InstructionSimplify and convert all "FunctionName"s to
"functionName".  This patch does touch a lot of files but gets done with
the cleanup of InstructionSimplify in one commit.

This is the alternative to the less invasive clang-format only patch: D126783

Reviewed By: spatel, rengolin

Differential Revision: https://reviews.llvm.org/D126889
2022-06-09 16:10:08 +02:00
Jay Foad
6bec3e9303 [APInt] Remove all uses of zextOrSelf, sextOrSelf and truncOrSelf
Most clients only used these methods because they wanted to be able to
extend or truncate to the same bit width (which is a no-op). Now that
the standard zext, sext and trunc allow this, there is no reason to use
the OrSelf versions.

The OrSelf versions additionally have the strange behaviour of allowing
extending to a *smaller* width, or truncating to a *larger* width, which
are also treated as no-ops. A small amount of client code relied on this
(ConstantRange::castOp and MicrosoftCXXNameMangler::mangleNumber) and
needed rewriting.

Differential Revision: https://reviews.llvm.org/D125557
2022-05-19 11:23:13 +01:00
Nikita Popov
b9b71c2b87 [LVI] Compute range for xor
We do have a non-trivial implementation for binaryXor() now.
2022-05-17 10:18:38 +02:00
Dmitry Makogon
361034ba78 [NFC] Add LazyValueInfo::clear method
This method just calls LazyValueInfoImpl::clear
2022-03-15 17:52:50 +07:00
serge-sans-paille
71c3a5519d Cleanup includes: LLVMAnalysis
Number of lines output by preprocessor:
before: 1065940348
after:  1065307662

Discourse thread: https://discourse.llvm.org/t/include-what-you-use-include-cleanup
Differential Revision: https://reviews.llvm.org/D120659
2022-03-01 18:01:54 +01:00
Nikita Popov
3ec7f46e99 [LVI] Handle implication from icmp of trunc (PR51867)
Similar to the existing urem code, if we have (trunc X) >= C,
then also X >= C.

Proof: https://alive2.llvm.org/ce/z/RF4YR2

Fixes https://github.com/llvm/llvm-project/issues/51867.
2022-01-18 11:24:11 +01:00
Nikita Popov
9e68557e64 [LVI] Handle commuted SPF min/max operands
We need to check that the operands of the min/max are the operands
of the select, but we don't care which order they are in.
2022-01-18 10:43:00 +01:00
Nikita Popov
d15823e300 [LVI] Compute SPF range even if one operands is overdefined
If we have a constant range for one operand but not the other,
we can generally still compute a useful results for SPF min/max.
2022-01-18 10:40:49 +01:00