118 Commits

Author SHA1 Message Date
Craig Topper
e8a0b40d6c
[SCCP] Correct range calculation for get.vector.length to use getUnsignedMax instead of getUpper. (#176493)
getUpper returns 1 more than the maxium value included in the range.
This may be 0. We should not use this in a umin. Instead we should
get the maximum value included in the range and use that for the umin.
Then convert that to Upper for the new range by adding 1.

The test was manually reduced from a downstream failure, but I couldn't
get it behave exactly the same way without more instructions. It should
be enough to show an incorrect range being calculated.

Fixes #176471
2026-01-17 21:32:33 -08:00
Miloš Poletanović
991455e69e
[SCCP] Use mergeInValue instead of markConstant when folding CastInst (#173190)
Fixes #173180 

The crash occurs when a vector constant refines its value during
iterative analysis.
In `SCCPInstVisitor::visitCastInst`, the logic for folding constants
through a `CastInst` uses `markConstant`. This function is strictly
designed for initial assignments and contains an assertion that prevents
a lattice element from being updated with a different constant pointer.

During the analysis of loops or complex data flows, a vector constant
may "refine." For example:

First Pass: SCCP identifies a value as `<4 x i64> {poison, poison,
poison, 0}`.

Second Pass: The value refines to `<4 x i64> zeroinitializer`.

Because these are distinct `Constant*` objects, `markConstant` triggers
a `"Marking constant with different value"` assertion failure.

The call to `markConstant` is replaced with `mergeInValue`. Unlike the
former, `mergeInValue` is lattice-aware, it allows for valid refinement
(moving from a less-defined to a more-defined state) and gracefully
handles transitions to Overdefined if a true conflict occurs. This
brings BitCast handling in line with how Trunc and Ext instructions are
already safely handled in the same pass.

Co-authored-by: Milos Poletanovic <mpoletanovic@syrmia.com>
2025-12-25 20:41:50 +08:00
Luke Lau
d0df51bc93
[ConstantRange] Allow casting to the same bitwidth. NFC (#170102)
From the review in
https://github.com/llvm/llvm-project/pull/169527#discussion_r2567122387,
there are some users where we want to extend or truncate a ConstantRange
only if it's not already the destination bitwidth. Previously this
asserted, so this PR relaxes it to just be a no-op, similar to
IRBuilder::createZExt and friends.
2025-12-01 19:51:56 +08:00
Luke Lau
2c9e9ffa77
[SCCP] Handle llvm.experimental.get.vector.length calls (#169527)
As noted in the reproducer provided in
https://github.com/llvm/llvm-project/issues/164762#issuecomment-3554719231,
on RISC-V after LTO we sometimes have trip counts exposed to vectorized
loops. The loop vectorizer will have generated calls to
@llvm.experimental.get.vector.length, but there are [some
properties](https://llvm.org/docs/LangRef.html#id2399) about the
intrinsic we can use to simplify it:

- The result is always less than both Count and MaxLanes
- If Count <= MaxLanes, then the result is Count

This teaches SCCP to handle these cases with the intrinsic, which allows
some single-iteration-after-LTO loops to be unfolded.

#169293 is related and also simplifies the intrinsic in InstCombine via
computeKnownBits, but it can't fully remove the loop since
computeKnownBits only does limited reasoning on recurrences.
2025-12-01 10:29:21 +00:00
aokblast
a3082c9d90
[SCCP] Support constant structure in PhiNode (#163713)
This patch adds support for constant propagation of individual structure
members through Phi nodes. Each member is handled independently,
allowing optimization opportunities when specific members become
constant.

Also, update the testcase since we are able to optimize the call
parameter now.
2025-10-19 03:57:56 +00:00
Yingwei Zheng
5d22980ed4
[LVI][SCCP] Avoid copying ValueLatticeElement (#163901)
Copying ValueLatticeElement becomes expensive after
https://github.com/llvm/llvm-project/pull/111544. This patch eliminates
some redundant copies to improve performance. The code change has been
carefully reviewed to ensure that there is no dangling reference.

Compile-time improvement:
https://llvm-compile-time-tracker.com/compare.php?from=f4359301c033694d36865c7560714164d2050240&to=4ea449bd53feef43403c35d8b815ddca752dbc17&stat=instructions%3Au
2025-10-19 00:58:05 +08:00
Yingwei Zheng
5e92e7f4c0
[SCCP] Strengthen two-instruction range checks (#162008)
This patch implements the todo discussed in
https://github.com/llvm/llvm-project/pull/158495#discussion_r2349609838.
It also fixes a regression introduced by
https://github.com/llvm/llvm-project/pull/161000. See also
https://github.com/dtcxzyw/llvm-opt-benchmark/pull/2890#discussion_r2404016316.

IR diff: https://github.com/dtcxzyw/llvm-opt-benchmark/pull/2892
2025-10-06 07:14:46 +00:00
Yingwei Zheng
05c4681668
[SCCP] Relax two-instruction range checks (#158495)
If we know x in R1, the range check `x in R2` can be relaxed into `x in
Union(R2, Inverse(R1))`. The latter one may be more efficient if we can
represent it with one icmp.
Fixes regressions introduced by
https://github.com/llvm/llvm-project/pull/156497.

Proof for `(X & -Pow2) == C -> (X - C) < Pow2`:
https://alive2.llvm.org/ce/z/HMgkuu

Compile-time impact:
https://llvm-compile-time-tracker.com/compare.php?from=ead4f3e271fdf6918aef2ede3a7134811147d276&to=bee3d902dd505cf9b11499ba4f230e4e8ae96b92&stat=instructions%3Au
2025-09-17 23:50:38 +08:00
Andreas Jonson
1840106ddf
[SCCP] Add support for trunc nuw range. (#152990)
proof: https://alive2.llvm.org/ce/z/_7PVxq
2025-08-12 13:48:55 +02:00
Nikita Popov
35bad229c1
[PredicateInfo] Use bitcast instead of ssa.copy (#151174)
PredicateInfo needs some no-op to which the predicate can be attached.
Currently this is an ssa.copy intrinsic. This PR replaces it with a
no-op bitcast.
    
Using a bitcast is more efficient because we don't have the overhead of
an overloaded intrinsic. It also makes things slightly simpler overall.
2025-08-11 09:25:01 +02:00
Nikita Popov
fa6965f722 [SCCP] Extract PredicateInfo handling into separate method (NFC) 2025-07-29 16:36:33 +02:00
Yingwei Zheng
9e587ce6f0
[SCCP] Simplify [us]cmp(X, Y) into X - Y (#144717)
If the difference between [us]cmp's operands is not greater than 1, we
can simplify it into `X - Y`.
Alive2: https://alive2.llvm.org/ce/z/JS55so
llvm-opt-benchmark diff:
https://github.com/dtcxzyw/llvm-opt-benchmark/pull/2464/files
2025-07-20 15:01:44 +08:00
Nikita Popov
545cdca488
[SCCP] Improve worklist management (#146321)
SCCP currently stores instructions whose lattice value has changed in a
worklist, and then updates their users in the main loop. This may result
in instructions unnecessarily being visited multiple times (as an
instruction will often use multiple other instructions). Additionally,
we'd often redundantly visit instructions that were already visited when
the containing block first became executable.

Instead, change the worklist to directly store the instructions that
need to be revisited. Additionally, do not add instructions to the
worklist that will already be covered by the main basic block walk.

This change is conceptually NFC, but is expected to produce minor
differences in practice, because the visitation order interacts with the
range widening limit.
2025-06-30 17:17:30 +02:00
Nikita Popov
d46a69cab4
[PredicateInfo] Use BumpPtrAllocator for predicates (NFC) (#145692)
Currently predicates are allocated on the heap and tracked with an
intrusive list. Use a bump pointer allocator instead, which is more
efficient. The list is no longer needed, as we don't have to track
predicates for freeing.

The bump pointer allocator is provided as a parameter for PredicateInfo
to allow reusing the same allocator for all functions during IPSCCP.
2025-06-26 09:04:41 +02:00
Nikita Popov
b85387dfe8 [SCCP] Check instruction type before querying PredicateInfo (NFC)
Do the cheap intrinsic check before the hash lookup for the
PredicateInfo.
2025-06-20 11:08:11 +02:00
Nikita Popov
f4db14229c [SCCP] Move logic for removing ssa.copy into Solver (NFC)
So it can be reused between IPSCCP and SCCP.

Make the implementation a bit more efficient by only lookup the
PredicateInfo once.
2025-06-19 17:28:39 +02:00
Stephen Tozer
aa8a1fa6f5
[DLCov][NFC] Annotate intentionally-blank DebugLocs in existing code (#136192)
Following the work in PR #107279, this patch applies the annotative
DebugLocs, which indicate that a particular instruction is intentionally
missing a location for a given reason, to existing sites in the compiler
where their conditions apply. This is NFC in ordinary LLVM builds (each
function `DebugLoc::getFoo()` is inlined as `DebugLoc()`), but marks the
instruction in coverage-tracking builds so that it will be ignored by
Debugify, allowing only real errors to be reported. From a developer
standpoint, it also communicates the intentionality and reason for a
missing DebugLoc.

Some notes for reviewers:

- The difference between `I->dropLocation()` and
`I->setDebugLoc(DebugLoc::getDropped())` is that the former _may_ decide
to keep some debug info alive, while the latter will always be empty; in
this patch, I always used the latter (even if the former could
technically be correct), because the former could result in some
(barely) different output, and I'd prefer to keep this patch purely NFC.
- I've generally documented the uses of `DebugLoc::getUnknown()`, with
the exception of the vectorizers - in summary, they are a huge cause of
dropped source locations, and I don't have the time or the domain
knowledge currently to solve that, so I've plastered it all over them as
a form of "fixme".
2025-06-11 17:42:10 +01:00
Yingwei Zheng
519cb460f6
[SCCP] Remove masking operations (#142736)
CVP version:
2d5820cd72
Compile-time impact:
https://llvm-compile-time-tracker.com/compare.php?from=3ec0c5c7fef03985b43432c6b914c289d8a5435e&to=92b4df90695dd37defdabf8a30f0b0322b648a00&stat=instructions:u
2025-06-04 22:31:08 +08:00
Kazu Hirata
99779b42d3
[SCCPSolver] Mark several functions const (NFC) (#140926) 2025-05-21 13:57:50 -07:00
Kazu Hirata
5a3776af52
[SCCPSolver] Make getMRVFunctionsTracked return a reference (NFC) (#140851)
This patch makes getMRVFunctionsTracked return a reference.
runIPSCCP, the sole user of getMRVFunctionsTracked, just needs a
read-access to the map.

The missing "&" is most likely an oversight as two "sibling" functions
getTrackedRetVals and getTrackedGlobals return maps by const
reference.
2025-05-21 08:56:15 -07:00
Kazu Hirata
fe6290ef5b
[llvm] Use *Map::try_emplace (NFC) (#140843)
try_emplace can default-construct values, so we do not need to do so
on our own.  Plus, try_emplace(Key) is much shorter than
insert(std::make_pair(Key, Value()).
2025-05-21 01:11:01 -07:00
Kazu Hirata
58dd3eda4e
[Utils] Avoid repeated hash lookups (NFC) (#131723) 2025-03-18 00:27:23 -07:00
Nikita Popov
b569ec6de6
[SCCP] Infer nuw for gep nusw with non-negative offsets (#118819)
If the GEP is nusw/inbounds and has all-non-negative offsets infer nuw
as well.

This doesn't have measurable compile-time impact.

Proof: https://alive2.llvm.org/ce/z/ihztLy
2024-12-06 09:52:32 +01:00
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