aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/Loads.cpp
AgeCommit message (Collapse)AuthorFilesLines
2 days[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
2023-04-02[Loads] Support SCEVAddExpr as start for pointer AddRec.Florian Hahn1-5/+25
Extend handling to support `%base + offset` as start for AddRecs in isDereferenceableAndAlignedInLoop. This is done by adjusting AccessSize by the offset and effectively checking if the full object starting from %base to %base + offset + access-size is dereferenceable. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D147260
2023-03-21[LV] Use speculatability within entire loop to avoid strided load predicationAnna Thomas1-4/+11
Use existing functionality for identifying total access size by strided loads. If we can speculate the load across all vector iterations, we can avoid predication for these strided loads (or masked gathers in architectures which support it). Differential Revision: https://reviews.llvm.org/D145616
2023-03-02[AArch64][SME2] Add CodeGen support for target("aarch64.svcount").Sander de Smalen1-1/+1
This patch adds AArch64 CodeGen support such that the type can be passed and returned to/from functions, and also adds support to use this type in load/store operations and PHI nodes. Reviewed By: paulwalker-arm Differential Revision: https://reviews.llvm.org/D136862
2023-01-11[NFC] Use TypeSize::geFixedValue() instead of TypeSize::getFixedSize()Guillaume Chatelet1-2/+2
This change is one of a series to implement the discussion from https://reviews.llvm.org/D141134.
2023-01-06Revert D141134 "[NFC] Only expose getXXXSize functions in TypeSize"Guillaume Chatelet1-1/+1
The patch should be discussed further. This reverts commit dd56e1c92b0e6e6be249f2d2dd40894e0417223f.
2023-01-06[NFC] Only expose getXXXSize functions in TypeSizeGuillaume Chatelet1-1/+1
Currently 'TypeSize' exposes two functions that serve the same purpose: - getFixedSize / getFixedValue - getKnownMinSize / getKnownMinValue source : https://github.com/llvm/llvm-project/blob/bf82070ea465969e9ae86a31dfcbf94c2a7b4c4c/llvm/include/llvm/Support/TypeSize.h#L337-L338 This patch offers to remove one of the two and stick to a single function in the code base. Differential Revision: https://reviews.llvm.org/D141134
2022-11-17[Analysis] `isSafeToLoadUnconditionally()`: `lifetime` intrinsics can be ignoredRoman Lebedev1-1/+1
In practice this means that we can speculate more loads in SROA. This e.g. comes up in https://godbolt.org/z/G8716s6sj, although we are missing second half of the puzzle to optimize that.
2022-11-11Analysis: Reorder code in isDereferenceableAndAlignedPointerMatt Arsenault1-63/+65
GEPs should be the most common and basic case, so try that first.
2022-11-07[InstCombine] Handle load smaller than one byte in memset forwardNikita Popov1-4/+8
APInt::getSplat() requires that the new size is >= the original one. If we're loading less than 8 bits, truncate instead. Fixes https://github.com/llvm/llvm-project/issues/58845.
2022-11-03[InstCombine] Perform memset -> load forwardingNikita Popov1-0/+33
InstCombine does some basic store to load forwarding. One case it currently misses is the case where the store is actually a memset. This patch adds support for this case. This is a minimal implementation that only handles a load at the memset base address, without an offset. GVN is already capable of performing this optimization. Having it in InstCombine can help with phase ordering issues, similar to the existing store to load forwarding. Differential Revision: https://reviews.llvm.org/D137323
2022-09-20Analysis: Remove redundant assertionMatt Arsenault1-6/+2
This assert guards the same assertion inside getTypeStoreSizeInBits
2022-09-20Analysis: Pass AssumptionCache through isKnownNonZeroMatt Arsenault1-2/+2
Pass this through now that isDereferenceableAndAlignedPointer has access to this.
2022-09-19VectorCombine: Pass through AssumptionCacheMatt Arsenault1-3/+6
2022-09-19Analysis: Add AssumptionCache argument to isDereferenceableAndAlignedPointerMatt Arsenault1-34/+34
This does not try to pass it through from the end users.
2022-07-13[InstCombine][SVE] Bail out of isSafeToLoadUnconditionally for scalable typesPeter Waller1-1/+4
`isSafeToLoadUnconditionally` currently assumes sized types. Bail out for now. This fixes a TypeSize warning reachable from instcombine via (load (select cond, ptr, ptr)). Differential Revision: https://reviews.llvm.org/D129477