summaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
AgeCommit message (Collapse)Author
2025-07-01[FunctionAttrs] Handle ConstantRange overflow in memset initializes ↵Shivam Gupta
inference (#145739) Avoid constructing invalid ConstantRange when Offset + Length in memset overflows signed 64-bit integer space. This prevents assertion failures when inferring the initializes attribute. Fixes #140345
2025-05-06[FunctionAttrs] Only consider provenance capture in access attr inference ↵Nikita Popov
(#138535) For the purpose of inferring readonly/writeonly/readnone on arguments, we only care about provenance captures, not address captures.
2025-04-23[FunctionAttrs] Bail if initializes range overflows 64-bit signed int (#137053)Arthur Eubanks
Otherwise the range doesn't make sense since we interpret it as signed. Fixes #134115
2025-04-15[nfc] Expose `canReturn` from FunctionAttrs (#135650)Mircea Trofin
This is a fairly light-weight traversal and is needed in instrumentation. No need to run the whole `FunctionAttrs` pass at this stage. To avoid layering issues, this patch factors `canRun` and related under Analysis/CFG.
2025-03-23[Transforms] Use *Set::insert_range (NFC) (#132652)Kazu Hirata
We can use *Set::insert_range to collapse: for (auto Elem : Range) Set.insert(E); down to: Set.insert_range(Range); In some cases, we can further fold that into the set declaration.
2025-03-16[Transforms] Avoid repeated hash lookups (NFC) (#131497)Kazu Hirata
2025-03-09[IPO] Avoid repeated hash lookups (NFC) (#130462)Kazu Hirata
2025-03-03[IPO] Avoid repeated hash lookups (NFC) (#129467)Kazu Hirata
2025-02-28[FunctionAttrs] Consider non-willreturn functions during capture inferenceNikita Popov
Matching the CaptureTracking change in abd97d9685c07c4787ff22e56c0a7b8963630063, only directly infer captures(none) for readonly+nocapture+willreturn+void. Part of https://github.com/llvm/llvm-project/issues/129090.
2025-02-27Reapply [CaptureTracking][FunctionAttrs] Add support for CaptureInfo ↵Nikita Popov
(#125880) (#128020) Relative to the previous attempt this includes two fixes: * Adjust callCapturesBefore() to not skip captures(ret: address, provenance) arguments, as these will not count as a capture at the call-site. * When visiting uses during stack slot optimization, don't skip the ModRef check for passthru captures. Calls can both modref and be passthru for captures. ------ This extends CaptureTracking to support inferring non-trivial CaptureInfos. The focus of this patch is to only support FunctionAttrs, other users of CaptureTracking will be updated in followups. The key API changes here are: * DetermineUseCaptureKind() now returns a UseCaptureInfo where the UseCC component specifies what is captured at that Use and the ResultCC component specifies what may be captured via the return value of the User. Usually only one or the other will be used (corresponding to previous MAY_CAPTURE or PASSTHROUGH results), but both may be set for call captures. * The CaptureTracking::captures() extension point is passed this UseCaptureInfo as well and then can decide what to do with it by returning an Action, which is one of: Stop: stop traversal. ContinueIgnoringReturn: continue traversal but don't follow the instruction return value. Continue: continue traversal and follow the instruction return value if it has additional CaptureComponents. For now, this patch retains the (unsound) special logic for comparison of null with a dereferenceable pointer. I'd like to switch key code to take advantage of address/address_is_null before dropping it. This PR mainly intends to introduce necessary API changes and basic inference support, there are various possible improvements marked with TODOs.
2025-02-24[CaptureTracking] Remove StoreCaptures parameter (NFC)Nikita Popov
The implementation doesn't use it, and is unlikely to use it in the future. The places that do set StoreCaptures=false, do so incorrectly and would be broken if the parameter actually did anything.
2025-02-19Revert "Reapply [CaptureTracking][FunctionAttrs] Add support for CaptureInfo ↵Nico Weber
(#125880)" This reverts commit 0fab404ee874bc5b0c442d1841c7d2005c3f8729. Seems to break LTO builds of clang on Windows, see comments on https://github.com/llvm/llvm-project/pull/125880
2025-02-18[FunctionAttrs] Fix typo in `getArgumentAccessInfo` name (NFC)Antonio Frighetto
2025-02-14Reapply [CaptureTracking][FunctionAttrs] Add support for CaptureInfo (#125880)Nikita Popov
Relative to the previous attempt, this adjusts isEscapeSource() to not treat calls with captures(ret: address, provenance) or similar arguments as escape sources. This addresses the miscompile reported at: https://github.com/llvm/llvm-project/pull/125880#issuecomment-2656632577 The implementation uses a helper function on CallBase to make this check a bit more efficient (e.g. by skipping the byval checks) as checking attributes on all arguments if fairly expensive. ------ This extends CaptureTracking to support inferring non-trivial CaptureInfos. The focus of this patch is to only support FunctionAttrs, other users of CaptureTracking will be updated in followups. The key API changes here are: * DetermineUseCaptureKind() now returns a UseCaptureInfo where the UseCC component specifies what is captured at that Use and the ResultCC component specifies what may be captured via the return value of the User. Usually only one or the other will be used (corresponding to previous MAY_CAPTURE or PASSTHROUGH results), but both may be set for call captures. * The CaptureTracking::captures() extension point is passed this UseCaptureInfo as well and then can decide what to do with it by returning an Action, which is one of: Stop: stop traversal. ContinueIgnoringReturn: continue traversal but don't follow the instruction return value. Continue: continue traversal and follow the instruction return value if it has additional CaptureComponents. For now, this patch retains the (unsound) special logic for comparison of null with a dereferenceable pointer. I'd like to switch key code to take advantage of address/address_is_null before dropping it. This PR mainly intends to introduce necessary API changes and basic inference support, there are various possible improvements marked with TODOs.
2025-02-13Revert "[CaptureTracking][FunctionAttrs] Add support for CaptureInfo (#125880)"Nikita Popov
This reverts commit ee655ca27aad466bcc54f6eba03f7e564940ad5a. A miscompilation has been reported at: https://github.com/llvm/llvm-project/pull/125880#issuecomment-2656632577
2025-02-13[IR][ModRef] Introduce `errno` memory locationAntonio Frighetto
Model C/C++ `errno` macro by adding a corresponding `errno` memory location kind to the IR. Preliminary work to separate `errno` writes from other memory accesses, to the benefit of alias analyses and optimization correctness. Previous discussion: https://discourse.llvm.org/t/rfc-modelling-errno-memory-effects/82972.
2025-02-13[CaptureTracking][FunctionAttrs] Add support for CaptureInfo (#125880)Nikita Popov
This extends CaptureTracking to support inferring non-trivial CaptureInfos. The focus of this patch is to only support FunctionAttrs, other users of CaptureTracking will be updated in followups. The key API changes here are: * DetermineUseCaptureKind() now returns a UseCaptureInfo where the UseCC component specifies what is captured at that Use and the ResultCC component specifies what may be captured via the return value of the User. Usually only one or the other will be used (corresponding to previous MAY_CAPTURE or PASSTHROUGH results), but both may be set for call captures. * The CaptureTracking::captures() extension point is passed this UseCaptureInfo as well and then can decide what to do with it by returning an Action, which is one of: Stop: stop traversal. ContinueIgnoringReturn: continue traversal but don't follow the instruction return value. Continue: continue traversal and follow the instruction return value if it has additional CaptureComponents. For now, this patch retains the (unsound) special logic for comparison of null with a dereferenceable pointer. I'd like to switch key code to take advantage of address/address_is_null before dropping it. This PR mainly intends to introduce necessary API changes and basic inference support, there are various possible improvements marked with TODOs.
2025-01-30[FunctionAttrs] Remove dead code code in nocaptures inference (NFCI)Nikita Popov
An argument graph node without uses forms a trivial SCC, which will already be handled by the preceding branch. If a node in the SCC points to a node with empty uses, then it will be part of a different SCC, and as such assumed to be capturing if it does not have an attribute. There is no need to handle them separately.
2025-01-29[IR] Convert from nocapture to captures(none) (#123181)Nikita Popov
This PR removes the old `nocapture` attribute, replacing it with the new `captures` attribute introduced in #116990. This change is intended to be essentially NFC, replacing existing uses of `nocapture` with `captures(none)` without adding any new analysis capabilities. Making use of non-`none` values is left for a followup. Some notes: * `nocapture` will be upgraded to `captures(none)` by the bitcode reader. * `nocapture` will also be upgraded by the textual IR reader. This is to make it easier to use old IR files and somewhat reduce the test churn in this PR. * Helper APIs like `doesNotCapture()` will check for `captures(none)`. * MLIR import will convert `captures(none)` into an `llvm.nocapture` attribute. The representation in the LLVM IR dialect should be updated separately.
2025-01-18[FunctionAttrs] Handle zero writes in initializes inference.Florian Hahn
ConstantRange's constructor asserts that the range not empty, except if lower/upper are min or max values. Check if the length is strictly positive instead of just non-negative so std::nullopt is returned when the size is 0. If that's the case, the access doesn't initialize anything. This should fix a crash when building on macOS with ASan & UBsan after https://github.com/llvm/llvm-project/pull/97373 / https://github.com/llvm/llvm-project/pull/117104 landed: https://green.lab.llvm.org/job/llvm.org/job/clang-stage2-cmake-RgSan/664/console
2025-01-15[IR] Treat calls with byval ptrs as read-only (#122961)Alex MacLean
2025-01-14[FunctionAttrs] Use doesNotCapture()Nikita Popov
To be conservative, explicitly exclude byval arguments, which doesNotCapture() would otherwise allow. Even if byval has an initializes attribute, it would only apply to the implicit copy.
2025-01-13[FunctionAttrs] Treat byval calls as only reading ptrs (#122618)Alex MacLean
Since byval arguments are passed via a hidden copy of the pointee, they do not have the same semantics as normal pointer arguments. The callee cannot capture or write to the pointer and the copy is a read of the pointer.
2024-12-22Skip negative length while inferring initializes attr (#120874)Haopeng Liu
Bail out negative length while inferring initializes attr. Otherwise it causes an assertion error: `Attribute 'initializes' does not support unordered ranges`
2024-11-20Add the initializes attribute inference (#117104)Haopeng Liu
reland https://github.com/llvm/llvm-project/pull/97373 after fixing clang tests. Confirmed with "ninja check-llvm" and "ninja check-clang"
2024-11-19Revert "[FunctionAttrs] Add the "initializes" attribute inference (#97373)"Mikhail Goncharov
This reverts commit 661c593850715881d2805a59e90e6d87d8b9fbb8. Multiple buildbot failures, e.g. https://lab.llvm.org/buildbot/#/builders/108/builds/6096
2024-11-18[FunctionAttrs] Add the "initializes" attribute inference (#97373)Haopeng Liu
Add the "initializes" attribute inference. This change is expected to have ~0.09% compile time regression, which seems acceptable for interprocedural DSE. https://llvm-compile-time-tracker.com/compare.php?from=9f10252c4ad7cffbbcf692fa9c953698f82ac4f5&to=56345c1cee4375eb5c28b8e7abf4803d20216b3b&stat=instructions%3Au
2024-08-30Fix stack overflow in allPathsGoThroughCold past 6b11573b8c5e (#106384)Danial Klimkin
Recursion here causes stack overflow on large inputs. Fixing by unrolling via a stack.
2024-08-22Recommit "[FunctionAttrs] deduce attr `cold` on functions if all CG paths ↵Noah Goldstein
call a `cold` function" Fixed up the uar test that was failing. It seems with the new `cold` attribute the order of the functions is different. As far as I can tell this is not a concern. Closes #105559
2024-08-20Revert "[FunctionAttrs] deduce attr `cold` on functions if all CG paths call ↵Noah Goldstein
a `cold` function" This reverts commit b7eac8c6fea1ba3930d08011a0e5e3a262bfaece. Causing a test failure. Not 100% sure the issue so to reverting to unblock pipeline.
2024-08-20[FunctionAttrs] deduce attr `cold` on functions if all CG paths call a ↵Noah Goldstein
`cold` function Closes #101298
2024-07-24Reapply "[FunctionAttrs] Determine underlying object by ↵DianQK
`getUnderlyingObjectAggressive` (#100102)" Added handling for `AllocaInst`. This reverts commit 1ee686a55aa6365eff39bbd1dc2059b16be6c2f1.
2024-07-23Revert "[FunctionAttrs] Determine underlying object by ↵Nikita Popov
`getUnderlyingObjectAggressive` (#100102)" This reverts commit a213edd32abff8d154dad96824689b98ec7b5a35. Assertion failures on buildbots.
2024-07-23[FunctionAttrs] Determine underlying object by ↵DianQK
`getUnderlyingObjectAggressive` (#100102) Thanks to #99509, we can fix https://github.com/rust-lang/rust/issues/119573 too.
2024-06-28[IR] Add getDataLayout() helpers to Function and GlobalValue (#96919)Nikita Popov
Similar to https://github.com/llvm/llvm-project/pull/96902, this adds `getDataLayout()` helpers to Function and GlobalValue, replacing the current `getParent()->getDataLayout()` pattern.
2024-05-07[FunctionAttrs] Fix incorrect nonnull inference for non-inbounds GEP (#91180)Nikita Popov
For inbounds GEPs, if the source pointer is non-null, the result must also be non-null. However, this does not hold for non-inbounds GEPs. Fixes https://github.com/llvm/llvm-project/issues/91177.
2024-04-23[FunctionAttrs] Fix incorrect noundef inference with poison attrs (#89348)Nikita Popov
Currently, when inferring noundef, we only check that the return value is not undef/poison. However, we fail to account for the possibility that a poison-generating return attribute will convert the value to poison, and then violate the noundef attribute, resulting in immediate UB. For the relevant return attributes (align, nonnull and range), check whether we can trivially re-prove the relevant property, otherwise do not infer noundef. This fixes the FunctionAttrs side of https://github.com/llvm/llvm-project/issues/88026.
2024-04-16[ValueTracking] Restore isKnownNonZero parameter order. (#88873)Harald van Dijk
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 Zheng
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-01-02[FuncAttrs] Don't infer `noundef` for functions with `sanitize_memory` ↵Yingwei Zheng
attribute (#76691) MemorySanitizer assumes that the definition and declaration of a function will be consistent. If we add `noundef` for some definitions, it will break msan. Fix buildbot failure caused by #76553.
2023-12-31[FuncAttrs] Deduce `noundef` attributes for return values (#76553)Yingwei Zheng
This patch deduces `noundef` attributes for return values. IIUC, a function returns `noundef` values iff all of its return values are guaranteed not to be `undef` or `poison`. Definition of `noundef` from LangRef: ``` noundef This attribute applies to parameters and return values. If the value representation contains any undefined or poison bits, the behavior is undefined. Note that this does not refer to padding introduced by the type’s storage representation. ``` Alive2: https://alive2.llvm.org/ce/z/g8Eis6 Compile-time impact: http://llvm-compile-time-tracker.com/compare.php?from=30dcc33c4ea3ab50397a7adbe85fe977d4a400bd&to=c5e8738d4bfbf1e97e3f455fded90b791f223d74&stat=instructions:u |stage1-O3|stage1-ReleaseThinLTO|stage1-ReleaseLTO-g|stage1-O0-g|stage2-O3|stage2-O0-g|stage2-clang| |--|--|--|--|--|--|--| |+0.01%|+0.01%|-0.01%|+0.01%|+0.03%|-0.04%|+0.01%| The motivation of this patch is to reduce the number of `freeze` insts and enable more optimizations.
2023-12-27[FuncAttrs] Infer `norecurse` for funcs with calls to `nocallback` callees ↵Yingwei Zheng
(#76372) This patch adds missing `norecurse` attrs to funcs that only call intrinsics with `nocallback` attrs. Fixes the regression found in https://github.com/dtcxzyw/llvm-opt-benchmark/pull/45#discussion_r1436148743. The function loses `norecurse` attr because it calls `@llvm.fabs.f64`, which is not marked as `norecurse`. Since `norecurse` is not a default attribute of intrinsics and it is ambiguous for intrinsics, I decided to use the existing `callback` attributes. > nocallback This attribute indicates that the function is only allowed to jump back into caller’s module by a return or an exception, and is not allowed to jump back by invoking a callback function, a direct, possibly transitive, external function call, use of longjmp, or other means. It is a compiler hint that is used at module level to improve dataflow analysis, dropped during linking, and has no effect on functions defined in the current module. See also https://llvm.org/docs/LangRef.html#function-attributes.
2023-11-01[IR] Add writable attributeNikita Popov
This adds a writable attribute, which in conjunction with dereferenceable(N) states that a spurious store of N bytes is introduced on function entry. This implies that this many bytes are writable without trapping or introducing data races. See https://llvm.org/docs/Atomics.html#optimization-outside-atomic for why the second point is important. This attribute can be added to sret arguments. I believe Rust will also be able to use it for by-value (moved) arguments. Rust likely won't be able to use it for &mut arguments (tree borrows does not appear to allow spurious stores). In this patch the new attribute is only used by LICM scalar promotion. However, the actual motivation for this is to fix a correctness issue in call slot optimization, which needs this attribute to avoid optimization regressions. Followup to the discussion on D157499. Differential Revision: https://reviews.llvm.org/D158081
2023-10-24[FunctionAttrs] Improve handling of alias-preserving intrinsic calls (#68453)Krzysztof Drewniak
Fixes #68270 The function attribute analysis handles many instructions, like addrspacecast, which do not themselves read or write memory but which transform pointers into other values in the same alias set. There are intrinsic functions, such as ptrmask or the AMDGPU-specific make.buffer.rsrc, which also preserve membership in alias sets without capturing. This commit adds the addrspacecast-like behavior to these calls.
2023-10-20[FunctionAttrs] Only check ArgMem effects when inferring argument attrs (#69571)Nikita Popov
When inferring readonly/writeonly on arguments, if the argument is passed to a call, we should only check the ArgMem effects implied by the call -- we don't care whether the call reads/writes non-arg memory (captured pointers are not relevant here, because they will abort the analysis entirely). This also fixes a regression that was introduced when moving to MemoryEffects: The code was still checking the old WriteOnly attribute on functions, which no longer exists.
2023-08-14[FunctionAttrs] Consider recursive argmem effects (PR63936)Nikita Popov
When inspecting the function body, we can't simply ignore effects of functions in the SCC entirely, because an argmem access of a recursive call might result in an access to another location in the callee. Fix this by separately tracking memory effects that would occur if the SCC accesses argmem, and then later add those. Fixes https://github.com/llvm/llvm-project/issues/63936. Differential Revision: https://reviews.llvm.org/D155956
2023-08-10[FunctionAttrs] Extract some code into separate functions (NFC)Nikita Popov
To reduce diff in a future patch.
2023-08-09[FunctionAttrs] Unconditionally perform argument attribute inference in the ↵Changpeng Fang
first function-attrs pass Summary: Argument attributes like NoAlias and ReadOnly could affect memoryssa and thus earlyCSE in the function simplification pipeline. https://reviews.llvm.org/D145210 adjusted PostOrderFunctionAttrs placement and caused the argument attributes not referred for the use in the pipeline. This work (initiated by @nikic) unconditionally performs argument attribute inference in the first function-attrs pass. Reviewers: aeubanks and nikic Differential Revision: https://reviews.llvm.org/D156397
2023-07-03[MemoryEffects][NFCI] Make the MemoryEffects class reusableJohannes Doerfert
In a follow up we will reuse the logic in MemoryEffectsBase to merge AAMemoryLocation and AAMemoryBehavior without duplicating all the bit fiddling code already available in MemoryEffectsBase. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D153305
2023-06-13[FunctionAttrs] Remove errant whitespace; NFCNoah Goldstein