summaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/SCCPSolver.cpp
AgeCommit message (Collapse)Author
2025-06-30[SCCP] Improve worklist management (#146321)Nikita Popov
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-26[PredicateInfo] Use BumpPtrAllocator for predicates (NFC) (#145692)Nikita Popov
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-20[SCCP] Check instruction type before querying PredicateInfo (NFC)Nikita Popov
Do the cheap intrinsic check before the hash lookup for the PredicateInfo.
2025-06-19[SCCP] Move logic for removing ssa.copy into Solver (NFC)Nikita Popov
So it can be reused between IPSCCP and SCCP. Make the implementation a bit more efficient by only lookup the PredicateInfo once.
2025-06-11[DLCov][NFC] Annotate intentionally-blank DebugLocs in existing code (#136192)Stephen Tozer
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-04[SCCP] Remove masking operations (#142736)Yingwei Zheng
CVP version: https://github.com/llvm/llvm-project/commit/2d5820cd72255e04aaef2da3c21d62396fdd7fb9 Compile-time impact: https://llvm-compile-time-tracker.com/compare.php?from=3ec0c5c7fef03985b43432c6b914c289d8a5435e&to=92b4df90695dd37defdabf8a30f0b0322b648a00&stat=instructions:u
2025-05-21[SCCPSolver] Mark several functions const (NFC) (#140926)Kazu Hirata
2025-05-21[SCCPSolver] Make getMRVFunctionsTracked return a reference (NFC) (#140851)Kazu Hirata
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[llvm] Use *Map::try_emplace (NFC) (#140843)Kazu Hirata
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-03-18[Utils] Avoid repeated hash lookups (NFC) (#131723)Kazu Hirata
2024-12-06[SCCP] Infer nuw for gep nusw with non-negative offsets (#118819)Nikita Popov
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-10-31[SCCP] Handle llvm.vscale intrinsic calls (#114033)Hari Limaye
Teach SCCP to compute a constant range for calls to llvm.vscale intrinsics.
2024-10-16[SCCP] Simplify code with DenseMap::operator[] (NFC) (#112473)Kazu Hirata
2024-09-16[IPSCCP] Infer attributes on arguments (#107114)Nikita Popov
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-06[SCCP] Remove LoadInst if it loaded from Constant GlobalVariable (#107245)hanbeom
This patch removes the `LoadInst` when it loaded from Constant GlobalVariable. This allows `canRemoveInstruction` function to be removed.
2024-09-03[SCCP] Explicitly mark gep as overdefined if ct eval failsNikita Popov
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-02[SCCP] Infer return attributes in SCCP as well (#106732)Nikita Popov
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-08-29[IPSCCP] Intersect attribute info for interprocedural args (#106397)Nikita Popov
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-27[SCCP] Add more non-null rootsNikita Popov
Also consider allocas non-null (subject to the usual caveats), and consider nonnull/dereferenceable metadata on calls.
2024-08-27[SCCP] Propagate non-null pointers (#106090)Nikita Popov
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-26[SCCP] Avoid some uses of SCCPSolver::isOverdefined (NFCI)Nikita Popov
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-23[SCCP] fix non-determinism (#105758)Florian Mayer
the visit order depended on hashing because we iterated over a SmallPtrSet
2024-08-22[NFC] [SCCP] remove unused functions (#105603)Florian Mayer
2024-07-29[SCCP] Add context to SimplifyQuery (#100831)Thomas Hashem
2024-07-18[DebugInfo][SCCPSolver] Fix missing debug locations (#98876)Sudharsan Veeravalli
Fixes #98875
2024-07-09[SCCP] Add support for vectors (#98026)Nikita Popov
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-08[SCCP] Skip bitcasts entirelyNikita Popov
The only bitcasts the existing code might be able to handle are bitcasts between iN and <1 x iN>. Don't bother.
2024-05-23[SCCP] Don't allow undef ranges when performing operations (#93163)Nikita Popov
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-07[SCCP] Add `nneg` flag to `uitofp` if its operand is non-negativeNoah Goldstein
Similiar to the `InstCombine` changes, just furthering the support of the `uitofp nneg` support. Closes #86154
2024-04-12[SCCP] Refine trunc with nsw/nuw flags (#87926)XChy
Following #85592, add support for nsw/nuw flags of trunc in SCCP.
2024-04-11[IPSCCP] Add range attribute handling (#86747)Andreas Jonson
Support the new range attribute to infer ConstantRanges in IPSCCP.
2024-03-14[SCCP] Extend `visitBinaryOperator` to overflowing binary opsAntonio Frighetto
Leverage more refined ranges results when handling overflowing binary operators.
2024-03-04[RemoveDIs] Reapply 3fda50d3915, insert instructions using iteratorsJeremy Morse
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-02-29Revert "[NFC][RemoveDIs] Bulk update utilities to insert with iterators"Jeremy Morse
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[NFC][RemoveDIs] Bulk update utilities to insert with iteratorsJeremy Morse
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-01-08[SCCP] Check whether the default case is reachable (#76295)Yingwei Zheng
This patch eliminates unreachable default cases using range information. Fixes #76085.
2023-11-16[SCCP] Propagate exact flags (#72432)Yingwei Zheng
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-14[SCCP] Infer nneg on existing zext (#72143)Yingwei Zheng
This patch infers `nneg` flags for existing zext instructions in SCCP. Similar patch: https://github.com/llvm/llvm-project/pull/72052
2023-10-30[SCCP] Infer nneg on zext when forming from non-negative sext. (#70730)Craig Topper
Builds on #67982 which recently introduced the nneg flag on a zext instruction.
2023-10-02[IR] Mark zext/sext constant expressions as undesirableNikita Popov
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-08-25[IR] Treat callbr as special terminator (PR64215)Nikita Popov
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-11[SCCP] Do not attempt to create constexpr for a scalable vector GEPRahul Anand Radhakrishnan
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-06-23[SCCPSolver] Speed up SCCPSolver by avoiding repeated work list elementsTamás Danyluk
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-19[SCCP] Fix conversion of range to constant for vectors (PR63380)Nikita Popov
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-12Revert "[SCCP] Replace new value's value state with removed value's"Vitaly Buka
Breaks all sanitizers bootstrap bots: https://lab.llvm.org/buildbot/#/waterfall?tags=sanitizer This reverts commit cf79773a9006a7e22f3919268b7db381ddcb3abc.
2023-06-12[SCCP] Replace new value's value state with removed value'sluxufan
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-10[SCCP] Skip computing intrinsics if one of its args is unknownOrUndefluxufan
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-08Reland "[FuncSpec] Replace LoopInfo with BlockFrequencyInfo"Alexandros Lamprineas
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-05Reapply [SCCP] Constant propagation through freeze instructionMikhail Gudim
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-01[IPSCCP] Decouple queries for function analysis results.Alexandros Lamprineas
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