aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/SCCPSolver.cpp
AgeCommit message (Collapse)AuthorFilesLines
12 days[SCCP] Relax two-instruction range checks (#158495)Yingwei Zheng1-0/+54
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-08-12[SCCP] Add support for trunc nuw range. (#152990)Andreas Jonson1-2/+6
proof: https://alive2.llvm.org/ce/z/_7PVxq
2025-08-11[PredicateInfo] Use bitcast instead of ssa.copy (#151174)Nikita Popov1-14/+12
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-07-29[SCCP] Extract PredicateInfo handling into separate method (NFC)Nikita Popov1-70/+73
2025-07-20[SCCP] Simplify [us]cmp(X, Y) into X - Y (#144717)Yingwei Zheng1-1/+35
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-06-30[SCCP] Improve worklist management (#146321)Nikita Popov1-101/+66
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 Popov1-1/+4
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 Popov1-3/+3
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 Popov1-0/+24
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 Tozer1-1/+3
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 Zheng1-22/+48
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 Hirata1-5/+6
2025-05-21[SCCPSolver] Make getMRVFunctionsTracked return a reference (NFC) (#140851)Kazu Hirata1-2/+2
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 Hirata1-4/+3
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 Hirata1-3/+4
2024-12-06[SCCP] Infer nuw for gep nusw with non-negative offsets (#118819)Nikita Popov1-0/+10
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 Limaye1-0/+6
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 Hirata1-4/+1
2024-09-16[IPSCCP] Infer attributes on arguments (#107114)Nikita Popov1-22/+45
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)hanbeom1-15/+2
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 Popov1-0/+2
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 Popov1-1/+29
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 Popov1-11/+15
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 Popov1-6/+19
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 Popov1-1/+33
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 Popov1-8/+5
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 Mayer1-1/+2
the visit order depended on hashing because we iterated over a SmallPtrSet
2024-08-22[NFC] [SCCP] remove unused functions (#105603)Florian Mayer1-8/+0
2024-07-29[SCCP] Add context to SimplifyQuery (#100831)Thomas Hashem1-1/+1
2024-07-18[DebugInfo][SCCPSolver] Fix missing debug locations (#98876)Sudharsan Veeravalli1-1/+3
Fixes #98875
2024-07-09[SCCP] Add support for vectors (#98026)Nikita Popov1-25/+21
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 Popov1-12/+4
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 Popov1-8/+13
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 Goldstein1-5/+7
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)XChy1-0/+21
Following #85592, add support for nsw/nuw flags of trunc in SCCP.
2024-04-11[IPSCCP] Add range attribute handling (#86747)Andreas Jonson1-2/+38
Support the new range attribute to infer ConstantRanges in IPSCCP.
2024-03-14[SCCP] Extend `visitBinaryOperator` to overflowing binary opsAntonio Frighetto1-1/+7
Leverage more refined ranges results when handling overflowing binary operators.
2024-03-04[RemoveDIs] Reapply 3fda50d3915, insert instructions using iteratorsJeremy Morse1-3/+3
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 Morse1-3/+3
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 Morse1-3/+3
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 Zheng1-3/+7
This patch eliminates unreachable default cases using range information. Fixes #76085.
2023-11-16[SCCP] Propagate exact flags (#72432)Yingwei Zheng1-0/+3
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 Zheng1-19/+26
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 Topper1-0/+1
Builds on #67982 which recently introduced the nneg flag on a zext instruction.
2023-10-02[IR] Mark zext/sext constant expressions as undesirableNikita Popov1-4/+6
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 Popov1-9/+3
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 Radhakrishnan1-5/+2
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 Danyluk1-3/+7
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 Popov1-27/+37
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 Buka1-15/+16
Breaks all sanitizers bootstrap bots: https://lab.llvm.org/buildbot/#/waterfall?tags=sanitizer This reverts commit cf79773a9006a7e22f3919268b7db381ddcb3abc.