aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/Loads.cpp
AgeCommit message (Collapse)AuthorFilesLines
2 hours[Loads] Handle ptrtoaddr in isPointerUseReplaceable()Nikita Popov1-1/+3
Unlike the ptrtoint case, this is actually correct for ptrtoaddr.
2 days[Loads] Check if Ptr can be freed between Assume and CtxI. (#161255)Florian Hahn1-10/+14
When using information from dereferenceable assumptions, we need to make sure that the memory is not freed between the assume and the specified context instruction. Instead of just checking canBeFreed, check if there any calls that may free between the assume and the context instruction. Note that this also adjusts the context instruction to be the terminator in the loop predecessor, if there is one and it is a branch (to avoid things like invoke). PR: https://github.com/llvm/llvm-project/pull/161255
2025-09-09[InstCombine] Support GEP chains in foldCmpLoadFromIndexedGlobal() (#157447)Nikita Popov1-0/+64
Currently this fold only supports a single GEP. However, in ptradd representation, it may be split across multiple GEPs. In particular, PR #151333 will split off constant offset GEPs. To support this, add a new helper decomposeLinearExpression(), which decomposes a pointer into a linear expression of the form BasePtr + Index * Scale + Offset. I plan to also extend this helper to look through mul/shl on the index and use it in more places that currently use collectOffset() to extract a single index * scale. This will make sure such optimizations are not affected by the ptradd migration.
2025-09-05[LV] Add initial legality checks for loops with unbound loads. (#152422)Shih-Po Hung1-3/+6
This patch splits out the legality checks from PR #151300, following the landing of PR #128593. It is a step toward supporting vectorization of early-exit loops that contain potentially faulting loads. In this commit, an early-exit loop is considered legal for vectorization if it satisfies the following criteria: 1. it is a read-only loop. 2. all potentially faulting loads are unit-stride, which is the only type currently supported by vp.load.ff.
2025-09-04[LAA] Support assumptions with non-constant deref sizes. (#156758)Florian Hahn1-1/+2
Update evaluatePtrAddrecAtMaxBTCWillNotWrap to support non-constant sizes in dereferenceable assumptions. Apply loop-guards in a few places needed to reason about expressions involving trip counts of the from (BTC - 1). PR: https://github.com/llvm/llvm-project/pull/156758
2025-09-03Reapply "[LAA,Loads] Use loop guards and max BTC if needed when checking ↵Florian Hahn1-20/+11
deref. (#155672)" This reverts commit f0df1e3dd4ec064821f673ced7d83e5a2cf6afa1. Recommit with extra check for SCEVCouldNotCompute. Test has been added in b16930204b. Original message: Remove the fall-back to constant max BTC if the backedge-taken-count cannot be computed. The constant max backedge-taken count is computed considering loop guards, so to avoid regressions we need to apply loop guards as needed. Also remove the special handling for Mul in willNotOverflow, as this should not longer be needed after 914374624f (https://github.com/llvm/llvm-project/pull/155300). PR: https://github.com/llvm/llvm-project/pull/155672
2025-09-02Revert "[LAA,Loads] Use loop guards and max BTC if needed when checking ↵Florian Hahn1-11/+20
deref. (#155672)" This reverts commit 08001cf340185877665ee381513bf22a0fca3533. This triggers an assertion in some build configs, e.g. https://lab.llvm.org/buildbot/#/builders/24/builds/12211
2025-09-02[Loads] Apply loop guards to IRArgValue from assumption.Florian Hahn1-3/+4
Applying loop guards to IRArgValue can improve results in some cases.
2025-09-02[LAA,Loads] Use loop guards and max BTC if needed when checking deref. (#155672)Florian Hahn1-19/+10
Remove the fall-back to constant max BTC if the backedge-taken-count cannot be computed. The constant max backedge-taken count is computed considering loop guards, so to avoid regressions we need to apply loop guards as needed. Also remove the special handling for Mul in willNotOverflow, as this should not longer be needed after 914374624f (https://github.com/llvm/llvm-project/pull/155300). PR: https://github.com/llvm/llvm-project/pull/155672
2025-09-02[Loads] Apply loop guards to maximum pointer difference.Florian Hahn1-1/+4
Applying loop guards to MaxPtrDiff can improve results in some cases.
2025-09-02[Loads] Check for overflow when adding MaxPtrDiff + Offset.Florian Hahn1-1/+4
MaxPtrDiff + Offset may wrap, leading to incorrect results. Use uadd_ov to check for overflow.
2025-08-27[SCEV][LAA] Support multiplication overflow computation (#155236)annamthomas1-1/+6
Add support for identifying multiplication overflow in SCEV. This is needed in LoopAccessAnalysis and that limitation was worked around by 484417a. This allows early-exit vectorization to work as expected in vect.stats.ll test without needing the workaround.
2025-08-10[Analysis] Remove an unreachable check. NFC. (#152874)Yingwei Zheng1-2/+1
Binops never produce pointer values.
2025-08-05[InstCombine] Support offsets in `memset` to load forwarding (#151924)Pedro Lobo1-4/+8
Adds support for load offsets when performing `memset` load forwarding.
2025-08-04[GVN] Avoid creating lifetime of non-allocaNikita Popov1-0/+4
There is a larger problem here in that we should not be performing arbitrary pointer replacements for assumes. This is handled for branches, but assume goes through a different code path. Fixes https://github.com/llvm/llvm-project/issues/151785.
2025-08-01[LAA] Support assumptions in evaluatePtrAddRecAtMaxBTCWillNotWrap (#147047)Florian Hahn1-1/+1
This patch extends the logic added in https://github.com/llvm/llvm-project/pull/128061 to support dereferenceability information from assumptions as well. Unfortunately both assumption cache and the dominator tree need to be threaded through multiple layers to make them available where needed. PR: https://github.com/llvm/llvm-project/pull/147047
2025-07-14[Loads] Keep using constant max BTCs for loops w/o computable BTCs.Florian Hahn1-0/+8
Follow-up to cad62df49a to preserve the existing behavior for early-exit loops, to fix vec.stats.ll test failure.
2025-07-14[Loads] Support dereferenceable assumption with variable size. (#128436)Florian Hahn1-35/+53
Update isDereferenceableAndAlignedPointer to make use of dereferenceable assumptions with variable sizes via SCEV. To do so, factor out the logic to check via an assumption to a helper, and use SE to check if the access size is less than the dereferenceable size. PR: https://github.com/llvm/llvm-project/pull/128436
2025-06-23[LAA] Be more careful when evaluating AddRecs at symbolic max BTC. (#128061)Florian Hahn1-1/+6
Evaluating AR at the symbolic max BTC may wrap and create an expression that is less than the start of the AddRec due to wrapping (for example consider MaxBTC = -2). If that's the case, set ScEnd to -(EltSize + 1). ScEnd will get incremented by EltSize before returning, so this effectively sets ScEnd to unsigned max. Note that LAA separately checks that accesses cannot not wrap (52ded672492, https://github.com/llvm/llvm-project/pull/127543), so unsigned max represents an upper bound. When there is a computable backedge-taken count, we are guaranteed to execute the number of iterations, and if any pointer would wrap it would be UB (or the access will never be executed, so cannot alias). It includes new tests from the previous discussion that show a case we wrap with a BTC, but it is UB due to the pointer after the object wrapping (in `evaluate-at-backedge-taken-count-wrapping.ll`) When we have only a maximum backedge taken count, we instead try to use dereferenceability information to determine if the pointer access must be in bounds for the maximum backedge taken count. PR: https://github.com/llvm/llvm-project/pull/128061
2025-06-17[DebugInfo][RemoveDIs] Remove a swathe of debug-intrinsic code (#144389)Jeremy Morse1-1/+1
Seeing how we can't generate any debug intrinsics any more: delete a variety of codepaths where they're handled. For the most part these are plain deletions, in others I've tweaked comments to remain coherent, or added a type to (what was) type-generic-lambdas. This isn't all the DbgInfoIntrinsic call sites but it's most of the simple scenarios. Co-authored-by: Nikita Popov <github@npopov.com>
2025-05-09Analysis: Remove no-AssumptionCache path in getKnowledgeForValue (#139232)Matt Arsenault1-2/+2
As requested in https://github.com/llvm/llvm-project/pull/138961#discussion_r2078483175
2025-02-13[AssumeBundles] Dereferenceable used in bundle only applies at assume. (#126117)Florian Hahn1-3/+6
Update LangRef and code using `Dereferenceable` in assume bundles to only use the information if it is safe at the point of use. `Dereferenceable` in an assume bundle is only guaranteed at the point of the assumption, but may not be guaranteed at later points, because the pointer may have been freed. Update code using `Dereferenceable` to only use it if the pointer cannot be freed. This can further be refined to check if the pointer could be freed between assume and use. This follows up on https://github.com/llvm/llvm-project/pull/123196. With that change, it should be safe to expose dereferenceable assumptions more widely as in https://github.com/llvm/llvm-project/pull/121789 PR: https://github.com/llvm/llvm-project/pull/126117
2025-01-28[NFC][DebugInfo] Use iterators for insertion at some final callsitesJeremy Morse1-1/+1
These are the callsites that have materialised in the last three weeks since I last built with deprecation warnings.
2025-01-27Reland "[LoopVectorize] Add support for reverse loops in ↵David Sherwood1-53/+60
isDereferenceableAndAlignedInLoop #96752" (#123616) The last attempt failed a sanitiser build because we were creating a reference to a null Predicates pointer in isDereferenceableAndAlignedInLoop. This was exposed by the unit test IsDerefReadOnlyLoop in unittests/Analysis/LoadsTest.cpp. I fixed this by falling back on getConstantMaxBackedgeTakenCount if Predicates is null - see line 316 in llvm/lib/Analysis/Loads.cpp. There are no other changes.
2025-01-24[NFC][DebugInfo] Use iterator-flavour getFirstNonPHI at many call-sites ↵Jeremy Morse1-1/+1
(#123737) As part of the "RemoveDIs" project, BasicBlock::iterator now carries a debug-info bit that's needed when getFirstNonPHI and similar feed into instruction insertion positions. Call-sites where that's necessary were updated a year ago; but to ensure some type safety however, we'd like to have all calls to getFirstNonPHI use the iterator-returning version. This patch changes a bunch of call-sites calling getFirstNonPHI to use getFirstNonPHIIt, which returns an iterator. All these call sites are where it's obviously safe to fetch the iterator then dereference it. A follow-up patch will contain less-obviously-safe changes. We'll eventually deprecate and remove the instruction-pointer getFirstNonPHI, but not before adding concise documentation of what considerations are needed (very few). --------- Co-authored-by: Stephen Tozer <Melamoto@gmail.com>
2025-01-17[Loads] Respect UseDerefAtPointSemantics in isDerefAndAlignedPointer. (#123196)Florian Hahn1-1/+3
If a pointer gets freed, it may not be dereferenceable any longer, even though there is a dominating dereferenceable assumption. As first step, only consider assumptions if the pointer value cannot be freed if UseDerefAtPointSemantics is used. PR: https://github.com/llvm/llvm-project/pull/123196
2025-01-15Revert "[LoopVectorize] Add support for reverse loops in ↵David Sherwood1-57/+52
isDereferenceableAndAlignedInLoop (#96752)" (#123057) This reverts commit bfedf6460c2cad6e6f966b457d8d27084579dcd8.
2025-01-15[LoopVectorize] Add support for reverse loops in ↵David Sherwood1-52/+57
isDereferenceableAndAlignedInLoop (#96752) Currently when we encounter a negative step in the induction variable isDereferenceableAndAlignedInLoop bails out because the element size is signed greater than the step. This patch adds support for negative steps in cases where we detect the start address for the load is of the form base + offset. In this case the address decrements in each iteration so we need to calculate the access size differently. I have done this by caling getStartAndEndForAccess from LoopAccessAnalysis.cpp. The motivation for this patch comes from PR #88385 where a reviewer requested reusing isDereferenceableAndAlignedInLoop, but that PR itself does support reverse loops. The changed test in LoopVectorize/X86/load-deref-pred.ll now passes because previously we were calculating the total access size incorrectly, whereas now it is 412 bytes and fits perfectly into the alloca.
2025-01-09[Loads] Also consider getPointerAlignment when checking assumptions. (#120916)Florian Hahn1-2/+4
Also use getPointerAlignment when trying to use alignment and dereferenceable assumptions. This catches cases where dereferencable is known via the assumption but alignment is known via getPointerAlignment (e.g. via argument attribute or align of 1) PR: https://github.com/llvm/llvm-project/pull/120916
2025-01-08[Loads] Drop dead Offset argument (NFC)Nikita Popov1-7/+4
The argument is always zero now.
2024-11-05[Analysis] Remove unused includes (NFC) (#114936)Kazu Hirata1-1/+0
Identified with misc-include-cleaner.
2024-10-17[APInt] Fix APInt constructions where value does not fit bitwidth (NFCI) ↵Nikita Popov1-4/+2
(#80309) This fixes all the places that hit the new assertion added in https://github.com/llvm/llvm-project/pull/106524 in tests. That is, cases where the value passed to the APInt constructor is not an N-bit signed/unsigned integer, where N is the bit width and signedness is determined by the isSigned flag. The fixes either set the correct value for isSigned, set the implicitTrunc flag, or perform more calculations inside APInt. Note that the assertion is currently still disabled by default, so this patch is mostly NFC.
2024-09-23[Analysis] Teach isDereferenceableAndAlignedInLoop about SCEV predicates ↵David Sherwood1-9/+8
(#106562) Currently if a loop contains loads that we can prove at compile time are dereferenceable when certain conditions are satisfied the function isDereferenceableAndAlignedInLoop will still return false because getSmallConstantMaxTripCount will return 0 when SCEV predicates are required. This patch changes getSmallConstantMaxTripCount to take an optional Predicates pointer argument so that we can permit functions such as isDereferenceableAndAlignedInLoop to consider more cases.
2024-09-23[Loads] Check context instruction for context-sensitive derefability (#109277)Nikita Popov1-0/+11
If a dereferenceability fact is provided through `!dereferenceable` (or similar), it may only hold on the given control flow path. When we use `isSafeToSpeculativelyExecute()` to check multiple instructions, we might make use of `!dereferenceable` information that does not hold at the speculation target. This doesn't happen when speculating instructions one by one, because `!dereferenceable` will be dropped while speculating. Fix this by checking whether the instruction with `!dereferenceable` dominates the context instruction. If this is not the case, it means we are speculating, and cannot guarantee that it holds at the speculation target. Fixes https://github.com/llvm/llvm-project/issues/108854.
2024-09-18[Loads] Extract some checks into a lambda (NFC)Nikita Popov1-14/+20
This makes it easier to add additional checks.
2024-07-29[InstCombine][asan] Don't speculate loads before `select ptr` (#100773)Vitaly Buka1-2/+6
Even if memory is valid from `llvm` point of view, e.g. local alloca, sanitizers have API for user specific memory annotations. These annotations can be used to track size of the local object, e.g. inline vectors may prevent accesses beyond the current vector size. So valid programs should not access those parts of alloca before checking preconditions. Fixes #100639.
2024-07-29[NFC][Load] Find better place for `mustSuppressSpeculation` (#100794)Vitaly Buka1-0/+13
And extract `suppressSpeculativeLoadForSanitizers`. For #100639.
2024-07-22[GVN] Look through select/phi when determining underlying object (#99509)Nikita Popov1-3/+2
This addresses an optimization regression in Rust we have observed after https://github.com/llvm/llvm-project/pull/82458. We now only perform pointer replacement if they have the same underlying object. However, getUnderlyingObject() by default only looks through linear chains, not selects/phis. In particular, this means that we miss cases involving involving pointer induction variables. This patch fixes this by introducing a new helper getUnderlyingObjectAggressive() which basically does what getUnderlyingObjects() does, just specialized to the case where we must arrive at a single underlying object in the end, and with a limit on the number of inspected values. Doing this more expensive underlying object check has no measurable compile-time impact on CTMark.
2024-07-22[Analysis] Bail out for negative offsets in ↵David Sherwood1-0/+7
isDereferenceableAndAlignedInLoop (#99490) This patch now bails out explicitly for negative offsets so that it's more consistent with the unsigned remainder and add calculations, and it fixes a genuine bug as shown with the new test.
2024-07-19[Analysis] Add new function isDereferenceableReadOnlyLoop (#97292)David Sherwood1-0/+15
I created this patch due to a reviewer request on PR #88385 to split off the analysis changes, however without the other code in that PR I can only test the new function with unit tests.
2024-06-28[Loads] Const correct the Size argument to isSafeToLoadUnconditionally. NFC ↵Craig Topper1-1/+1
(#96993) The APInt is not modified so we should pass by const reference.
2024-06-27[IR] Add getDataLayout() helpers to BasicBlock and Instruction (#96902)Nikita Popov1-3/+3
This is a helper to avoid writing `getModule()->getDataLayout()`. I regularly try to use this method only to remember it doesn't exist... `getModule()->getDataLayout()` is also a common (the most common?) reason why code has to include the Module.h header.
2024-06-18[Loads] Pass DominatorTree if available (#95752)Ruiling, Song1-1/+1
For better dominance check inside the function.
2024-04-24[GVN] Restrict equality propagation for pointers (#82458)Usman Nadeem1-16/+56
This patch does the following: Adds the following functions: - replaceDominatedUsesWithIf() that takes a callback. - canReplacePointersIfEqual(...) returns true if the underlying object is the same, and for null and const dereferencable pointer replacements. - canReplacePointersIfEqualInUse(...) returns true for the above as well as if the use is in icmp/ptrtoint or phi/selects feeding into them. Updates GVN using the functions above so that the pointer replacements are only made using the above API. https://reviews.llvm.org/D143129
2024-04-16[ValueTracking] Restore isKnownNonZero parameter order. (#88873)Harald van Dijk1-2/+2
Prior to #85863, the required parameters of llvm::isKnownNonZero were Value and DataLayout. After, they are Value, Depth, and SimplifyQuery, where SimplifyQuery is implicitly constructible from DataLayout. The change to move Depth before SimplifyQuery needed callers to be updated unnecessarily, and as commented in #85863, we actually want Depth to be after SimplifyQuery anyway so that it can be defaulted and the caller does not need to specify it.
2024-04-12[ValueTracking] Convert `isKnownNonZero` to use SimplifyQuery (#85863)Yingwei Zheng1-2/+4
This patch converts `isKnownNonZero` to use SimplifyQuery. Then we can use the context information from `DomCondCache`. Fixes https://github.com/llvm/llvm-project/issues/85823. Alive2: https://alive2.llvm.org/ce/z/QUvHVj
2024-02-23[Loads] Fix crash in isSafeToLoadUnconditionally with scalable accessed type ↵Luke Lau1-3/+3
(#82650) This fixes #82606 by updating isSafeToLoadUnconditionally to handle fixed sized loads from a scalable accessed type.
2024-01-24[Loads] Use BatchAAResults for available value APIs (NFCI)Nikita Popov1-5/+4
This allows caching AA queries both within and across the calls, and enables us to use a custom AAQI configuration.
2023-06-30Analysis: Fix assertion when load alignment exceeds address space sizeMatt Arsenault1-3/+1
Apparently the maximum alignment no longer fits in 32-bits now, which overflows a 32-bit offset and would fail on the isPowerOf2 assert.
2023-06-11[NFC] Replace ;; with ;David Green1-1/+1