aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/Loads.cpp
AgeCommit message (Collapse)AuthorFilesLines
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
2022-04-08[Loads] Check type size in bits during store to load forwardingNikita Popov1-2/+2
Rather than checking the rounded type store size, check the type size in bits. We don't want to forward a store of i1 to a load of i8 for example, even though they have the same type store size. The padding bits have unspecified contents. This is a partial fix for the issue reported at https://reviews.llvm.org/D115924#inline-1179482, the problem also needs to be addressed more generally in the constant folding code.
2022-03-01Cleanup includes: LLVMAnalysisserge-sans-paille1-5/+0
Number of lines output by preprocessor: before: 1065940348 after: 1065307662 Discourse thread: https://discourse.llvm.org/t/include-what-you-use-include-cleanup Differential Revision: https://reviews.llvm.org/D120659
2022-01-28[Loads] Require Align in isDereferenceableAndAlignedPointer() (NFC)Nikita Popov1-3/+1
Now that loads always have an alignment, we should not perform an ABI alignment fallback here.
2021-11-16[Loads] Handle addrspacecast constant expressions when determining ↵Arthur Eubanks1-1/+1
dereferenceability Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D114015
2021-10-22[Loads] Use more powerful constant folding APINikita Popov1-2/+5
This follows up on D111023 by exporting the generic "load value from constant at given offset as given type" and using it in the store to load forwarding code. We now need to make sure that the load size is smaller than the store size, previously this was implicitly ensured by ConstantFoldLoadThroughBitcast(). Differential Revision: https://reviews.llvm.org/D112260
2021-09-28Fix incorrect GEP bitwidth in areNonOverlapSameBaseLoadAndStore()Alex Richardson1-2/+2
When using a datalayout that has pointer index width != pointer size this code triggers an assertion in Value::stripAndAccumulateConstantOffsets(). I encountered this this while compiling FreeBSD for CHERI-RISC-V. Also update LoadsTest.cpp to use a DataLayout with index width != pointer width to ensure this case is tested. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D110406
2021-04-26[CSSPGO] Unblock optimizations with pseudo probe instrumentation part 2.Hongtao Yu1-2/+2
As a follow-up to D95982, this patch continues unblocking optimizations that are blocked by pseudu probe instrumention. The optimizations unblocked are: - In-block load propagation. - In-block dead store elimination - Memory copy optimization that turns stores to consecutive memories into a memset. These optimizations are local to a block, so they shouldn't affect the profile quality. Reviewed By: wmi Differential Revision: https://reviews.llvm.org/D100075
2021-04-13fix whitespace typePhilip Reames1-1/+1
2021-04-10[Analysis] isDereferenceableAndAlignedPointer(): recurse into select's handsRoman Lebedev1-0/+10
By doing this within the method itself, we support traversing multiple levels of selects (TODO: PHI's), fixing the SROA `std::clamp()` testcase. Fixes https://bugs.llvm.org/show_bug.cgi?id=47271 Mostly fixes https://bugs.llvm.org/show_bug.cgi?id=49909
2021-04-06Move GCRelocateInst and GCResultInst to IntrinsicInst.h [nfc]Philip Reames1-1/+0
These two are part of the IntrinsicInst class hierarchy and it helps to cut down on some redundant includes.
2021-04-03[Loads] Forward constant vector store to load of first elementNikita Popov1-4/+7
InstCombine performs simple forwarding from stores to loads, but currently only handles the case where the load and store have the same size. This extends it to also handle a store of a constant with a larger size followed by a load with a smaller size. This is implemented through ConstantFoldLoadThroughBitcast() which is fairly primitive (e.g. does not allow storing a large integer and then loading a small one), but at least can forward the first element of a vector store. Unfortunately it seems that we currently don't have a generic helper for "read a constant value as a different type", it's all tangled up with other logic in either ConstantFolding or VNCoercion. Differential Revision: https://reviews.llvm.org/D98114
2021-04-01Infer dereferenceability from malloc and friendsPhilip Reames1-2/+1
Hookup TLI when inferring object size from allocation calls. This allows the analysis to prove dereferenceability for known allocation functions (such as malloc/new/etc) in addition to those marked explicitly with the allocsize attribute. This is a follow up to 0129cd5 now that the bug fixed by e2c6621e6 is resolved. As noted in the test, this relies on being able to prove that there is no free between allocation and context (e.g. hoist location). At the moment, this is handled conservatively. I'm working strengthening out ability to reason about no-free regions separately. Differential Revision: https://reviews.llvm.org/D99737
2021-04-01[deref-at-point] restrict inference of dereferenceability based on allocsize ↵Philip Reames1-10/+2
attribute Support deriving dereferenceability facts from allocation sites with known object sizes while correctly accounting for any possibly frees between allocation and use site. (At the moment, we're conservative and only allowing it in functions where we know we can't free.) This is part of the work on deref-at-point semantics. I'm making the change unconditional as the miscompile in this case is way too easy to trip by accident, and the optimization was only recently added (by me). There will be a follow up patch wiring through TLI since that should now be doable without introducing widespread miscompiles. Differential Revision: https://reviews.llvm.org/D95815
2021-03-24Make FindAvailableLoadedValue TBAA awareThomas Preud'homme1-24/+24
FindAvailableLoadedValue() relies on FindAvailablePtrLoadStore() to run the alias analysis when searching for an equivalent value. However, FindAvailablePtrLoadStore() calls the alias analysis framework with a memory location for the load constructed from an address and a size, which thus lacks TBAA metadata info. This commit modifies FindAvailablePtrLoadStore() to accept an optional memory location as parameter to allow FindAvailableLoadedValue() to create it based on the load instruction, which would then have TBAA metadata info attached. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D99206
2021-03-19Update basic deref API to account for possiblity of free [NFC]Philip Reames1-3/+5
This patch is plumbing to support work towards the goal outlined in the recent llvm-dev post "[llvm-dev] RFC: Decomposing deref(N) into deref(N) + nofree". The point of this change is purely to simplify iteration on other pieces on way to making the switch. Rebuilding with a change to Value.h is slow and painful, so I want to get the API change landed. Once that's done, I plan to more closely audit each caller, add the inference rules in their own patch, then post a patch with the langref changes and test diffs. The value of the command line flag is that we can exercise the inference logic in standalone patches without needing the whole switch ready to go just yet. Differential Revision: https://reviews.llvm.org/D98908
2021-03-06[Loads] Restructure getAvailableLoadStore implementation (NFC)Nikita Popov1-15/+19
Separate out some conditions with early exits, to make it easier to support additional cases.
2021-02-21[Loads] Add optimized FindAvailableLoadedValue() overload (NFCI)Nikita Popov1-0/+45
FindAvailableLoadedValue() accepts an iterator by reference. If no available value is found, then the iterator will either be left at a clobbering instruction or the beginning of the basic block. This allows using FindAvailableLoadedValue() across multiple blocks. If this functionality is not needed, as is the case in InstCombine, then we can use a much more efficient implementation: First try to find an available value, and only perform clobber checks if we actually found one. As this function only looks at a very small number of instructions (6 by default) and usually doesn't find an available value, this saves many expensive alias analysis queries.
2021-02-21[Loads] Extract helper frunction for available load/store (NFC)Nikita Popov1-33/+47
This contains the logic for extracting an available load/store from a given instruction, to be reused in a following patch.
2021-02-13reland [InstCombine] convert assumes to operand bundlesTyker1-0/+26
Instcombine will convert the nonnull and alignment assumption that use the boolean condtion to an assumption that uses the operand bundles when knowledge retention is enabled. Differential Revision: https://reviews.llvm.org/D82703
2021-02-10Revert "[InstCombine] convert assumes to operand bundles"Tyker1-26/+0
This reverts commit 5eb2e994f9b3a5aff0a156d0a1f7e6121342cc11.
2021-02-09[InstCombine] convert assumes to operand bundlesTyker1-0/+26
Instcombine will convert the nonnull and alignment assumption that use the boolean condtion to an assumption that uses the operand bundles when knowledge retention is enabled. Differential Revision: https://reviews.llvm.org/D82703
2021-02-01[Loads] Plumb through TLI argument [NFC]Philip Reames1-17/+27
This is a (rather delayed) follow up to commit 0129cd5. This commit is entirely NFC, the semantic change to leverage the new information will be submitted separate with a test case.
2020-12-03Use deref facts derived from minimum object size of allocationsPhilip Reames1-1/+42
This change should be fairly straight forward. If we've reached a call, check to see if we can tell the result is dereferenceable from information about the minimum object size returned by the call. To control compile time impact, I'm only adding the call for base facts in the routine. getObjectSize can also do recursive reasoning, and we don't want that general capability here. As a follow up patch (without separate review), I will plumb through the missing TLI parameter. That will have the effect of extending this to known libcalls - malloc, new, and the like - whereas currently this only covers calls with the explicit allocsize attribute. Differential Revision: https://reviews.llvm.org/D90341
2020-10-28[Deref] Use maximum trip count instead of exact trip countPhilip Reames1-3/+1
When trying to prove that a memory access touches only dereferenceable memory across all iterations of a loop, use the maximum exit count rather than an exact one. In many cases we can't prove exact exit counts whereas we can prove an upper bound. The test included is for a single exit loop with a min(C,V) exit count, but the true motivation is support for multiple exits loops. It's just really hard to write a test case for multiple exits because the vectorizer (the primary user of this API), bails far before this. For multiple exits, this allows a mix of analyzeable and unanalyzable exits when only analyzeable exits are needed to prove deref.
2020-10-26[SVE][AArch64] Fix TypeSize warning in loop vectorization legalityJoe Ellis1-1/+1
The warning would fire when calling isDereferenceableAndAlignedInLoop with a scalable load. Calling isDereferenceableAndAlignedInLoop with a scalable load would result in the use of the now deprecated implicit cast of TypeSize to uint64_t through the overloaded operator. This patch fixes this issue by: - no longer considering vector loads as candidates in canVectorizeWithIfConvert. This doesn't make sense in the context of identifying scalar loads to vectorize. - making use of getFixedSize inside isDereferenceableAndAlignedInLoop -- this removes the dependency on the deprecated interface, and will trigger an assertion error if the function is ever called with a scalable type. Reviewed By: sdesmalen Differential Revision: https://reviews.llvm.org/D89798
2020-09-29Revert "Recommit "[SCCP] Do not replace deref'able ptr with un-deref'able one.""Florian Hahn1-4/+0
Looks like there is still another remaining issue: http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap-msan/builds/22273/steps/build%20libcxx%2Fmsan/logs/stdio This reverts commit 86a20d9e34f5a9989da72097f23f3b0a44157e73.
2020-09-29Recommit "[SCCP] Do not replace deref'able ptr with un-deref'able one."Florian Hahn1-0/+4
This version includes an small fix allowing function pointers to be unconditionally replaced for now. This reverts commit 4c5e4aa89b11ec3253258b8df5125833773d1b1e.
2020-09-01[NFC] Fix unused var in release buildJordan Rupprecht1-1/+1
2020-09-01[Loads] Add canReplacePointersIfEqual helper.Florian Hahn1-0/+20
This patch adds an initial, incomeplete and unsound implementation of canReplacePointersIfEqual to check if a pointer value A can be replaced by another pointer value B, that are deemed to be equivalent through some means (e.g. information from conditions). Note that is in general not sound to blindly replace pointers based on equality, for example if they are based on different underlying objects. LLVM's memory model is not completely settled as of now; see https://bugs.llvm.org/show_bug.cgi?id=34548 for a more detailed discussion. The initial version of canReplacePointersIfEqual only rejects a very specific case: replacing a pointer with a constant expression that is not dereferenceable. Such a replacement is problematic and can be restricted relatively easily without impacting most code. Using it to limit replacements in GVN/SCCP/CVP only results in small differences in 7 programs out of MultiSource/SPEC2000/SPEC2006 on X86 with -O3 -flto. This patch is supposed to be an initial step to improve the current situation and the helper should be made stricter in the future. But this will require careful analysis of the impact on performance. Reviewed By: aqjune Differential Revision: https://reviews.llvm.org/D85524
2020-06-27[Analysis] isDereferenceableAndAlignedPointer(): don't crash on `bitcast <1 ↵Roman Lebedev1-4/+6
x ???*> to ???*`
2020-06-24Loads.h - reduce AliasAnalysis.h include to forward declarations. NFC.Simon Pilgrim1-2/+2
Fix implicit include dependencies in source files.
2020-05-20Make Value::getPointerAlignment() return an Align, not a MaybeAlign.Eli Friedman1-16/+4
If we don't know anything about the alignment of a pointer, Align(1) is still correct: all pointers are at least 1-byte aligned. Included in this patch is a bugfix for an issue discovered during this cleanup: pointers with "dereferenceable" attributes/metadata were assumed to be aligned according to the type of the pointer. This wasn't intentional, as far as I can tell, so Loads.cpp was fixed to stop making this assumption. Frontends may need to be updated. I updated clang's handling of C++ references, and added a release note for this. Differential Revision: https://reviews.llvm.org/D80072
2020-05-18[Loads] Require Align in isSafeToLoadUnconditionally() (NFC)Nikita Popov1-13/+8
Now that load/store have required alignment, accept Align here. This also avoids uses of getPointerElementType(), which is incompatible with opaque pointers.
2020-05-17[Alignment] Remove unnecessary getValueOrABITypeAlignment calls (NFC)Nikita Popov1-2/+1
Now that load/store alignment is required, we no longer need most of them. Also switch the getLoadStoreAlignment() helper to return Align instead of MaybeAlign.
2020-04-23[SVE] Remove calls to VectorType::isScalable from analysisChristopher Tetreault1-2/+1
Reviewers: efriedma, sdesmalen, chandlerc, sunfish Reviewed By: efriedma Subscribers: tschuett, hiraditya, rkruppe, psnobl, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D77692