95 Commits

Author SHA1 Message Date
Hari Limaye
b396921d0c
[SCCP] Handle llvm.vscale intrinsic calls (#114033)
Teach SCCP to compute a constant range for calls to llvm.vscale
intrinsics.
2024-10-31 12:22:15 +00:00
Kazu Hirata
e1d205a385
[SCCP] Simplify code with DenseMap::operator[] (NFC) (#112473) 2024-10-16 00:09:12 -07:00
Nikita Popov
b7e51b4f13
[IPSCCP] Infer attributes on arguments (#107114)
During inter-procedural SCCP, also infer attributes on arguments, not
just return values. This allows other non-interprocedural passes to make
use of the information later.
2024-09-16 10:23:41 +02:00
hanbeom
861caf9b31
[SCCP] Remove LoadInst if it loaded from Constant GlobalVariable (#107245)
This patch removes the `LoadInst` when it loaded from Constant
GlobalVariable. This allows `canRemoveInstruction` function to be
removed.
2024-09-06 10:16:30 +02:00
Nikita Popov
0797c184c6 [SCCP] Explicitly mark gep as overdefined if ct eval fails
Don't just leave the result as unknown. I think this currently
works out thanks to undef resolution, but the correct thing to
do is set it to overdefined explicitly.
2024-09-03 14:39:31 +02:00
Nikita Popov
24fe1d4fd6
[SCCP] Infer return attributes in SCCP as well (#106732)
We can infer the range/nonnull attributes in non-interprocedural SCCP as
well. The results may be better after the function has been simplified.
2024-09-02 11:44:37 +02:00
Nikita Popov
7f59264d46
[IPSCCP] Intersect attribute info for interprocedural args (#106397)
IPSCCP can currently return worse results than SCCP for arguments that
are tracked interprocedurally, because information from attributes is
not used for them.

Fix this by intersecting in the attribute information when propagating
lattice values from calls.
2024-08-29 09:34:56 +02:00
Nikita Popov
657f26f038 [SCCP] Add more non-null roots
Also consider allocas non-null (subject to the usual caveats),
and consider nonnull/dereferenceable metadata on calls.
2024-08-27 15:53:22 +02:00
Nikita Popov
1cea5c2138
[SCCP] Propagate non-null pointers (#106090)
Add NotConstant(Null) roots for nonnull arguments and then propagate
them through nuw/inbounds GEPs.

Having this functionality in SCCP is useful because it allows reliably
eliminating null comparisons, independently of how deeply nested they
are in selects/phis. This handles cases that would hit a cutoff in
ValueTracking otherwise.

The implementation is something of a MVP, there are a number of obvious
extensions (e.g. allocas are also non-null).
2024-08-27 09:13:41 +02:00
Nikita Popov
0e24c32a6d [SCCP] Avoid some uses of SCCPSolver::isOverdefined (NFCI)
This is a confusingly named helper than means "is not unknown,
undef or constant". Prefer the more obvious ValueLattice API
instead. Most of these checks are for values which are forced to
overdefined by undef resolution, in which case only actual
overdefined values are relevant.
2024-08-26 17:15:07 +02:00
Florian Mayer
aec3ec04ac
[SCCP] fix non-determinism (#105758)
the visit order depended on hashing because we iterated over a
SmallPtrSet
2024-08-23 09:45:42 -07:00
Florian Mayer
bc860b49a8
[NFC] [SCCP] remove unused functions (#105603) 2024-08-22 09:55:24 -07:00
Thomas Hashem
e6fa09f445
[SCCP] Add context to SimplifyQuery (#100831) 2024-07-29 15:21:57 +02:00
Sudharsan Veeravalli
26af44b398
[DebugInfo][SCCPSolver] Fix missing debug locations (#98876)
Fixes #98875
2024-07-18 09:03:03 +01:00
Nikita Popov
6b76c1e64c
[SCCP] Add support for vectors (#98026)
Add preliminary support for vectors of integers by using the
`ValueLatticeElement::asConstantRange()` helper instead of a custom
implementation, and relxing various integer type checks.

This enables just the part that works automatically, e.g. icmps with a
constant vector operand aren't supported yet.

The change in ssa.copy handling is because asConstantRange() returns an
unknown LV for empty range, while SCCP's getConstantRange() returned a
full range. I've made the change to preserve the existing behavior.
2024-07-09 12:25:53 +02:00
Nikita Popov
12d6832d86 [SCCP] Skip bitcasts entirely
The only bitcasts the existing code might be able to handle are
bitcasts between iN and <1 x iN>. Don't bother.
2024-07-08 16:10:58 +02:00
Nikita Popov
27392a35ef
[SCCP] Don't allow undef ranges when performing operations (#93163)
When performing some range operation (e.g. and) on a constant range that
includes undef, we currently just ignore the undef value, which is
obviously incorrect. Instead, we can do one of two things:
 * Say that the result range also includes undef.
 * Treat undef as a full range.

This patch goes with the second approach -- I'd expect it to be a bit
better overall, e.g. it allows preserving the fact that a zext of a
range with undef isn't a full range.

Fixes https://github.com/llvm/llvm-project/issues/93096.
2024-05-23 15:14:34 +02:00
Noah Goldstein
6243395d7f [SCCP] Add nneg flag to uitofp if its operand is non-negative
Similiar to the `InstCombine` changes, just furthering the support of
the `uitofp nneg` support.

Closes #86154
2024-05-07 14:57:29 -05:00
XChy
b1822ef311
[SCCP] Refine trunc with nsw/nuw flags (#87926)
Following #85592, add support for nsw/nuw flags of trunc in SCCP.
2024-04-12 02:36:32 +08:00
Andreas Jonson
e7bc537264
[IPSCCP] Add range attribute handling (#86747)
Support the new range attribute to infer ConstantRanges in IPSCCP.
2024-04-11 18:42:59 +09:00
Antonio Frighetto
6ae4fcfd4c [SCCP] Extend visitBinaryOperator to overflowing binary ops
Leverage more refined ranges results when handling overflowing
binary operators.
2024-03-14 16:02:29 +01:00
Jeremy Morse
6b62a9135a [RemoveDIs] Reapply 3fda50d3915, insert instructions using iterators
I'd reverted this in 6c7805d5d1 after a bad stage. Original commit
messsage follows:

[NFC][RemoveDIs] Bulk update utilities to insert with iterators

As part of the RemoveDIs project we need LLVM to insert instructions using
iterators wherever possible, so that the iterators can carry a bit of
debug-info. This commit implements some of that by updating the contents of
llvm/lib/Transforms/Utils to always use iterator-versions of instruction
constructors.

There are two general flavours of update:
 * Almost all call-sites just call getIterator on an instruction
 * Several make use of an existing iterator (scenarios where the code is
   actually significant for debug-info)
The underlying logic is that any call to getFirstInsertionPt or similar
APIs that identify the start of a block need to have that iterator passed
directly to the insertion function, without being converted to a bare
Instruction pointer along the way.

I've also switched DemotePHIToStack to take an optional iterator: it needs
to take an iterator, and having a no-insert-location behaviour appears to
be important. The constructors for ICmpInst and FCmpInst have been updated
too. They're the only instructions that take block _references_ rather than
pointers for certain calls, and a future patch is going to make use of
default-null block insertion locations.

All of this should be NFC.
2024-03-04 13:14:39 +00:00
Jeremy Morse
6c7805d5d1 Revert "[NFC][RemoveDIs] Bulk update utilities to insert with iterators"
This reverts commit 3fda50d3915b2163a54a37b602be7783a89dd808.

Apparently I've missed a hunk while staging this; will back out for now.

Picked up here: https://lab.llvm.org/buildbot/#/builders/139/builds/60429/steps/6/logs/stdio
2024-02-29 16:50:22 +00:00
Jeremy Morse
3fda50d391 [NFC][RemoveDIs] Bulk update utilities to insert with iterators
As part of the RemoveDIs project we need LLVM to insert instructions using
iterators wherever possible, so that the iterators can carry a bit of
debug-info. This commit implements some of that by updating the contents of
llvm/lib/Transforms/Utils to always use iterator-versions of instruction
constructors.

There are two general flavours of update:
 * Almost all call-sites just call getIterator on an instruction
 * Several make use of an existing iterator (scenarios where the code is
   actually significant for debug-info)
The underlying logic is that any call to getFirstInsertionPt or similar
APIs that identify the start of a block need to have that iterator passed
directly to the insertion function, without being converted to a bare
Instruction pointer along the way.

I've also switched DemotePHIToStack to take an optional iterator: it needs
to take an iterator, and having a no-insert-location behaviour appears to
be important. The constructors for ICmpInst and FCmpInst have been updated
too. They're the only instructions that take block _references_ rather than
pointers for certain calls, and a future patch is going to make use of
default-null block insertion locations.

All of this should be NFC.
2024-02-29 16:39:09 +00:00
Yingwei Zheng
d218092543
[SCCP] Check whether the default case is reachable (#76295)
This patch eliminates unreachable default cases using range information.
Fixes #76085.
2024-01-08 20:08:42 +08:00
Yingwei Zheng
c3b9c36f3a
[SCCP] Propagate exact flags (#72432)
This patch propagates exact flags for `ashr->lshr` and `sdiv->udiv` in
SCCP.

This missed optimization is discovered with the help of
https://github.com/AliveToolkit/alive2/pull/962.
2023-11-16 14:05:28 +08:00
Yingwei Zheng
ed96430402
[SCCP] Infer nneg on existing zext (#72143)
This patch infers `nneg` flags for existing zext instructions in SCCP.

Similar patch: https://github.com/llvm/llvm-project/pull/72052
2023-11-14 10:18:23 +08:00
Craig Topper
b1c59b516c
[SCCP] Infer nneg on zext when forming from non-negative sext. (#70730)
Builds on #67982 which recently introduced the nneg flag on a zext
instruction.
2023-10-30 15:07:22 -07:00
Nikita Popov
3b25407d97 [IR] Mark zext/sext constant expressions as undesirable
Introduce isDesirableCastOp() which determines whether IR builder
and constant folding should produce constant expressions for a
given cast type. This mirrors what we do for binary operators.

Mark zext/sext as undesirable, which prevents most creations of such
constant expressions. This is still somewhat incomplete and there
are a few more places that can create zext/sext expressions.

This is part of the work for
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179.

The reason for the odd result in the constantexpr-fneg.c test is
that initially the "a[]" global is created with an [0 x i32] type,
at which point the icmp expression cannot be folded. Later it is
replaced with an [1 x i32] global and the icmp gets folded away.
But at that point we no longer fold the zext.
2023-10-02 12:40:20 +02:00
Nikita Popov
4eafc9b6ff [IR] Treat callbr as special terminator (PR64215)
isLegalToHoistInto() currently return true for callbr instructions.
That means that a callbr with one successor will be considered a
proper loop preheader, which may result in instructions that use
the callbr return value being hoisted past it.

Fix this by adding callbr to isExceptionTerminator (with a rename
to isSpecialTerminator), which also fixes similar assumptions in
other places.

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

Differential Revision: https://reviews.llvm.org/D158609
2023-08-25 09:20:18 +02:00
Rahul Anand Radhakrishnan
18423c7e1f [SCCP] Do not attempt to create constexpr for a scalable vector GEP
Scalable vector GEPs are not constants and trying to create one for
these GEPs causes an assertion failure.

Reviewed By: nikic, paulwalker-arm

Differential Revision: https://reviews.llvm.org/D157590
2023-08-11 11:06:07 +00:00
Tamás Danyluk
248b85344b [SCCPSolver] Speed up SCCPSolver by avoiding repeated work list elements
If a value is already the last element of the worklist, then I think that we don't have to add it again, it is not needed to process it repeatedly.

For some long Triton-generated LLVM IR, this can cause a ~100x speedup.

Differential Revision: https://reviews.llvm.org/D153561
2023-06-23 10:23:53 +02:00
Nikita Popov
664b7a4cd5 [SCCP] Fix conversion of range to constant for vectors (PR63380)
The ConstantRange specifies the range of the scalar elements in the
vector. When converting into a Constant, we need to create a vector
splat with the correct type. For that purpose, pass in the expected
type for the constant.

Fixes https://github.com/llvm/llvm-project/issues/63380.
2023-06-19 12:29:44 +02:00
Vitaly Buka
23ea58f374 Revert "[SCCP] Replace new value's value state with removed value's"
Breaks all sanitizers bootstrap bots:
https://lab.llvm.org/buildbot/#/waterfall?tags=sanitizer

This reverts commit cf79773a9006a7e22f3919268b7db381ddcb3abc.
2023-06-12 11:07:46 -07:00
luxufan
cf79773a90 [SCCP] Replace new value's value state with removed value's
In replaceSignedInst, if a signed instruction can be repalced with
unsigned instruction, we created a new instruction and removed the old
instruction's value state. If the following instructions has this new
instruction as a use operand, transformations like replaceSignedInst and
refineInstruction would be blocked. The reason is there is no value
state for the new instrution.

This patch set the new instruction's value state with the removed
instruction's value state. I believe it is correct bacause when we
repalce a signed instruction with unsigned instruction, the value state
is not changed.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D152337
2023-06-12 11:40:47 +08:00
luxufan
25d9fde22e [SCCP] Skip computing intrinsics if one of its args is unknownOrUndef
For constant range supported intrinsics, we got consantrange from args
no matter if they are unknown or undef. And the constant range computed
from unknown or undef value state is full range.

I think compute with full constant range is harmful since although we
can do mergeIn after these args value state are changed, the merge
operation of two constant ranges is union.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D152499
2023-06-10 15:48:46 +08:00
Alexandros Lamprineas
475ddca56e Reland "[FuncSpec] Replace LoopInfo with BlockFrequencyInfo"
Using AvgLoopIters on any loop is too imprecise making the cost model
favor users inside loop nests regardless of the actual tripcount.

Differential Revision: https://reviews.llvm.org/D150375
2023-06-08 17:44:47 +01:00
Mikhail Gudim
d37d4072f2 Reapply [SCCP] Constant propagation through freeze instruction
Reapply with extra check for struct types, which caused buildbot
failures last time.

-----

The freeze instruction has not been handled by SCCPInstVisitor.
This patch adds SCCPInstVisitor::visitFreezeInst(FreezeInst &I)
method to handle freeze instructions.

Differential Revision: https://reviews.llvm.org/D151659
2023-06-05 11:47:36 +02:00
Alexandros Lamprineas
b1f41685a6 [IPSCCP] Decouple queries for function analysis results.
The SCCPSolver is using a structure (AnalysisResultsForFn) where it keeps
pointers to various analyses needed by the IPSCCP pass. These analyses are
requested all at the same time, which can become problematic in some cases.
For example one could be retrieved via getCachedAnalysis() prior to the
actual execution of the analysis. In more detail:

The IPSCCP pass uses a DomTreeUpdater to preserve the PostDominatorTree
in case the PostDominatorTreeAnalysis had run before IPSCCP. Starting with
commit 1b1232047e83b the IPSCCP pass may use BlockFrequencyAnalysis for
some functions in the module. As a result, the PostDominatorTreeAnalysis
may not run until the BlockFrequencyAnalysis has run, since the latter
analysis depends on the former. Currently, we setup the DomTreeUpdater
using getCachedAnalysis to retrieve a PostDominatorTree. This happens
before BlockFrequencyAnalysis has run, therefore the cached analysis can
become invalid by the time we use it.

Differential Revision: https://reviews.llvm.org/D151666
2023-06-01 16:38:04 +01:00
Nikita Popov
223f9b096e Revert "[SCCP] Constant propagation through freeze instruction"
This reverts commit 559d47a1790e1a9f9b1f8838a443eb7624ef1ac7.

Caused failure on sanitizer-aarch64-linux-bootstrap-ubsan:

    clang++: /b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm-project/llvm/lib/Transforms/Utils/SCCPSolver.cpp:442: llvm::ValueLatticeElement &llvm::SCCPInstVisitor::getValueState(llvm::Value *): Assertion `!V->getType()->isStructTy() && "Should use getStructValueState"' failed.
2023-06-01 15:30:46 +02:00
Mikhail Gudim
559d47a179 [SCCP] Constant propagation through freeze instruction
The freeze instruction has not been handled by SCCPInstVisitor.
This patch adds SCCPInstVisitor::visitFreezeInst(FreezeInst &I)
method to handle freeze instructions.

Differential Revision: https://reviews.llvm.org/D151659
2023-06-01 15:06:59 +02:00
Nikita Popov
96a14f388b Revert "[FuncSpec] Replace LoopInfo with BlockFrequencyInfo"
As reported on https://reviews.llvm.org/D150375#4367861 and
following, this change causes PDT invalidation issues. Revert
it and dependent commits.

This reverts commit 0524534d5220da5ecb2cd424a46520184d2be366.
This reverts commit ced90d1ff64a89a13479a37a3b17a411a3259f9f.
This reverts commit 9f992cc9350a7f7072a6dbf018ea07142ea7a7ed.
This reverts commit 1b1232047e83b69561fd64b9547cb0a0d374473a.
2023-05-30 14:49:03 +02:00
Alexandros Lamprineas
1b1232047e [FuncSpec] Replace LoopInfo with BlockFrequencyInfo.
Using AvgLoopIters on any loop is too imprecise making the cost model
favor users inside loop nests regardless of the actual tripcount.

Differential Revision: https://reviews.llvm.org/D150375
2023-05-22 17:49:52 +01:00
Alexandros Lamprineas
54e5fb789c [FuncSpec] Track the return values of specializations.
To track the return values of specializations, we need to invalidate all
the lattice values across the use-def chain which originates from the
callsites, recompute and propagate.

Differential Revision: https://reviews.llvm.org/D146158
2023-04-24 13:18:49 +01:00
Alexandros Lamprineas
7ea597ead9 [FuncSpec] Consider constant struct arguments when specializing.
Optionally enabled just like integer and floating point arguments.

Differential Revision: https://reviews.llvm.org/D145374
2023-04-17 18:39:21 +01:00
Florian Hahn
7d10213317
Recommit "[SCCP] Support NUW/NSW inference for all overflowing binary operators."
This reverts commit 43acb61a08fffada31fb2e20e45fcc8492ef76b9.

Recommit the patch after fixing the issue causing the revert in 4e607ec4987.
Extra tests have been added in 5c6cb61ad416a544.

Original commit message:

   Extend the NUW/NSW inference logic add in 72121a20cd and cdeaf5f28c3dc
    to all overflowing binary operators.

    Reviewed By: nikic

    Differential Revision: https://reviews.llvm.org/D142721
2023-01-30 20:15:28 +00:00
Florian Hahn
4e607ec498
[SCCP] Flip range arguments for NSW region check.
This brings the operand order in line with the NUW handling, which was
missed out in 72121a20cda4dc91d0ef5548f930.

At the moment this is NFC as we only additions, but it
should fix miscompiles with 024115ab14822a recommitted.
2023-01-30 18:03:18 +00:00
Florian Hahn
43acb61a08
Revert "[SCCP] Support NUW/NSW inference for all overflowing binary operators."
This reverts commit 024115ab14822a97c09adcd2545c14e78b843b36.

I suspect that this may be causing some buildbot bootstrapping failures.
Revert while I investigate.
2023-01-28 21:33:28 +00:00
Florian Hahn
024115ab14
[SCCP] Support NUW/NSW inference for all overflowing binary operators.
Extend the NUW/NSW inference logic add in 72121a20cd and cdeaf5f28c3dc
to all overflowing binary operators.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D142721
2023-01-28 17:40:41 +00:00
Florian Hahn
72121a20cd
[SCCP] Use range info to prove AddInst has NSW flag.
This patch updates SCCP to use the value ranges of AddInst operands to
try to prove the AddInst does not overflow in the signed sense and
adds the NSW flag. The reasoning is done with
makeGuaranteedNoWrapRegion (thanks @nikic for point it out!).

Follow-ups will include extending this to more
OverflowingBinaryOperators.

Depends on D142387.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D142390
2023-01-27 14:09:26 +00:00