summaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
AgeCommit message (Collapse)Author
2025-07-01[Reland][IPO] Added attributor for identifying invariant loads (#146584)zGoldthorpe
Patched and tested the `AAInvariantLoadPointer` attributor from #141800, which identifies pointers whose loads are eligible to be marked as `!invariant.load`. The bug in the attributor was due to `AAMemoryBehavior` always identifying pointers obtained from `alloca`s as having no writes. I'm not entirely sure why `AAMemoryBehavior` behaves this way, but it seems to be beceause it identifies the scope of an `alloca` to be limited to only that instruction (and, certainly, no memory writes occur within the `alloca` instructin). This patch just adds a check to disallow all loads from `alloca` pointers from being marked `!invariant.load` (since any well-defined program will have to write to stack pointers at some point).
2025-06-18Revert "[IPO] Added attributor for identifying invariant loads" (#144808)zGoldthorpe
Reverts llvm/llvm-project#141800 The implementation critically misunderstands the `AAMemoryBehavior` attributor, which it relies on heavily. @shiltian, since I do not have commit permissions.
2025-06-16[IPO] Added attributor for identifying invariant loads (#141800)zGoldthorpe
The attributor conservatively marks pointers whose loads are eligible to be marked as `!invariant.load`. It does so by identifying: 1. Pointers marked `noalias` and `readonly` 2. Pointers whose underlying objects are all eligible for invariant loads. The attributor then manifests this attribute at non-atomic non-volatile load instructions.
2025-06-09[Attributor] Use known non-flat AS before `getAssumedAddrSpace` (#143221)Shilei Tian
If the underlying object already has a non-flat address space, we simply use that before calling `getAssumedAddrSpace`. Partially fixes SWDEV-536263.
2025-06-02[llvm] Use *Set::insert_range (NFC) (#138237)Kazu Hirata
2025-05-30Reapply "Reapply "[AMDGPU] Make `getAssumedAddrSpace` return AS1 for pointer ↵Shilei Tian
kernel arguments (#137488)"" This reverts commit 37ea3b32cdcb6c0dcecbcc4bf844f5190c7378dd.
2025-05-30Revert "Reapply "[AMDGPU] Make `getAssumedAddrSpace` return AS1 for pointer ↵Shilei Tian
kernel arguments (#137488)"" This reverts commit 4efc13f8ff1eaf4f9fb1fcea8d4552b3eca052ca.
2025-05-30Reapply "[AMDGPU] Make `getAssumedAddrSpace` return AS1 for pointer kernel ↵Shilei Tian
arguments (#137488)" This reverts commit 3c6211c183885afb5d89259a53c4f4f46a6bf399.
2025-05-30Revert "[AMDGPU] Make `getAssumedAddrSpace` return AS1 for pointer kernel ↵Shilei Tian
arguments (#137488)" This reverts commit 9bf6b2a8cb0467b62173659306e43a0346f063a2.
2025-05-30[AMDGPU] Make `getAssumedAddrSpace` return AS1 for pointer kernel arguments ↵Shilei Tian
(#137488)
2025-05-22Reland "[NVPTX] Unify and extend barrier{.cta} intrinsic support" (#141143)Alex MacLean
Note: This relands #140615 adding a ".count" suffix to the non-".all" variants. Our current intrinsic support for barrier intrinsics is confusing and incomplete, with multiple intrinsics mapping to the same instruction and intrinsic names not clearly conveying intrinsic semantics. Further, we lack support for some variants. This change unifies the IR representation to a single consistently named set of intrinsics. - llvm.nvvm.barrier.cta.sync.aligned.all(i32) - llvm.nvvm.barrier.cta.sync.aligned.count(i32, i32) - llvm.nvvm.barrier.cta.arrive.aligned.count(i32, i32) - llvm.nvvm.barrier.cta.sync.all(i32) - llvm.nvvm.barrier.cta.sync.count(i32, i32) - llvm.nvvm.barrier.cta.arrive.count(i32, i32) The following Auto-Upgrade rules are used to maintain compatibility with IR using the legacy intrinsics: * llvm.nvvm.barrier0 --> llvm.nvvm.barrier.cta.sync.aligned.all(0) * llvm.nvvm.barrier.n --> llvm.nvvm.barrier.cta.sync.aligned.all(x) * llvm.nvvm.bar.sync --> llvm.nvvm.barrier.cta.sync.aligned.all(x) * llvm.nvvm.barrier --> llvm.nvvm.barrier.cta.sync.aligned.count(x, y) * llvm.nvvm.barrier.sync --> llvm.nvvm.barrier.cta.sync.all(x) * llvm.nvvm.barrier.sync.cnt --> llvm.nvvm.barrier.cta.sync.count(x, y)
2025-05-22Revert "[NVPTX] Unify and extend barrier{.cta} intrinsic support (#140615)"Alex Maclean
This reverts commit 735209c0688b10a66c24750422b35d8c2ad01bb5.
2025-05-21[NVPTX] Unify and extend barrier{.cta} intrinsic support (#140615)Alex MacLean
Our current intrinsic support for barrier intrinsics is confusing and incomplete, with multiple intrinsics mapping to the same instruction and intrinsic names not clearly conveying intrinsic semantics. Further, we lack support for some variants. This change unifies the IR representation to a single consistently named set of intrinsics. - llvm.nvvm.barrier.cta.sync.aligned.all(i32) - llvm.nvvm.barrier.cta.sync.aligned(i32, i32) - llvm.nvvm.barrier.cta.arrive.aligned(i32, i32) - llvm.nvvm.barrier.cta.sync.all(i32) - llvm.nvvm.barrier.cta.sync(i32, i32) - llvm.nvvm.barrier.cta.arrive(i32, i32) The following Auto-Upgrade rules are used to maintain compatibility with IR using the legacy intrinsics: * llvm.nvvm.barrier0 --> llvm.nvvm.barrier.cta.sync.aligned.all(0) * llvm.nvvm.barrier.n --> llvm.nvvm.barrier.cta.sync.aligned.all(x) * llvm.nvvm.bar.sync --> llvm.nvvm.barrier.cta.sync.aligned.all(x) * llvm.nvvm.barrier --> llvm.nvvm.barrier.cta.sync.aligned(x, y) * llvm.nvvm.barrier.sync --> llvm.nvvm.barrier.cta.sync.all(x) * llvm.nvvm.barrier.sync.cnt --> llvm.nvvm.barrier.cta.sync(x, y)
2025-05-11[llvm] Use std::tie to implement operator< (NFC) (#139487)Kazu Hirata
2025-04-26[llvm] Use llvm::interleaved (NFC) (#137496)Kazu Hirata
2025-04-24Attributor: Don't rely on use_empty for constants (#137218)Matt Arsenault
This allows inferring noalias on a null argument parameter. This avoids a non-NFC diff in a future change.
2025-04-17[CaptureTracking] Remove dereferenceable_or_null special case (#135613)Nikita Popov
Remove the special case where comparing a dereferenceable_or_null pointer with null results in captures(none) instead of captures(address_is_null). This special case is not entirely correct. Let's say we have an allocated object of size 2 at address 1 and have a pointer `%p` pointing either to address 1 or 2. Then passing `gep p, -1` to a `dereferenceable_or_null(1)` function is well-defined, and allows us to distinguish between the two possible pointers, capturing information about the address. Now that we ignore address captures in alias analysis, I think we're ready to drop this special case. Additionally, if there are regressions in other places, the fact that this is inferred as address_is_null should allow us to easily address them if necessary.
2025-04-08Attributor: Propagate align to cmpxchg instructions (#134838)Matt Arsenault
Fixes #134480
2025-04-08Attributor: Propagate align to atomicrmw instructions (#134837)Matt Arsenault
Partially fixes #134480
2025-04-07Attributor: Don't follow uses of ConstantData (#134573)Matt Arsenault
These should not really have uselists, and it's not worth the compile time of looking at all uses of trivial constants. The main observable change of this is it no longer adds align attributes on constant null uses, but those are not useful. Some of these cases should potentially be more aggressive and not look at any Constant users.
2025-03-28[Analysis][NFC] Extract KnownFPClass (#133457)Tim Gymnich
- extract KnownFPClass for future use inside of GISelKnownBits --------- Co-authored-by: Matt Arsenault <arsenm2@gmail.com>
2025-03-19[Transforms] Use *Set::insert_range (NFC) (#132056)Kazu Hirata
DenseSet, SmallPtrSet, SmallSet, SetVector, and StringSet recently gained C++23-style insert_range. This patch replaces: Dest.insert(Src.begin(), Src.end()); with: Dest.insert_range(Src); This patch does not touch custom begin like succ_begin for now.
2025-03-17[Transforms] Avoid repeated hash lookups (NFC) (#131554)Kazu Hirata
2025-02-27[Attributor][NFC] Clang format (#129163)Johannes Doerfert
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-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-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[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-29[Attributor] Check correct IRPosition in AANoCapture::isImpliedByIR()Nikita Popov
This case is intended to check the callee argument, not the call-site. Fixes an issue introduced in #123181.
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-24[NFC][DebugInfo] Use iterator moveBefore at many call-sites (#123583)Jeremy Morse
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 moveBefore use iterators. This patch adds a (guaranteed dereferenceable) iterator-taking moveBefore, and changes a bunch of call-sites where it's obviously safe to change to use it by just calling getIterator() on an instruction pointer. A follow-up patch will contain less-obviously-safe changes. We'll eventually deprecate and remove the instruction-pointer insertBefore, but not before adding concise documentation of what considerations are needed (very few).
2025-01-21[IR] Replace of PointerType::get(Type) with opaque version (NFC) (#123617)Mats Jun Larsen
In accordance with https://github.com/llvm/llvm-project/issues/123569 In order to keep the patch at reasonable size, this PR only covers for the llvm subproject, unittests excluded.
2025-01-14[Attributor][NFC] Performance improvements (#122923)macurtis-amd
` forallInterferingAccesses` is a hotspot and for large modules these changes make a measurable improvement in compilation time. For LTO kernel compilation of 519.clvleaf (SPEChpc 2021) I measured the following: ``` | Measured times (s) | Average | speedup --------------------+------------------------+---------+--------- Baseline | 33.268 33.332 33.275 | 33.292 | 0% Cache "kernel" | 30.543 30.339 30.607 | 30.496 | 9.2% templatize callback | 30.981 30.97 30.964 | 30.972 | 7.5% Both changes | 29.284 29.201 29.053 | 29.179 | 14.1% ```
2024-11-04[llvm-project] Fix typo "propogate" (#114795)Jay Foad
2024-11-03[IPO] Remove unused includes (NFC) (#114716)Kazu Hirata
Identified with misc-include-cleaner.
2024-10-09[Attributor] Take the address space from addrspacecast directly (#108258)Shilei Tian
Currently `AAAddressSpace` relies on identifying the address spaces of all underlying objects. However, it might infer sub-optimal address space when the underlying object is a function argument. In `AMDGPUPromoteKernelArgumentsPass`, the promotion of a pointer kernel argument is by adding a series of `addrspacecast` instructions (as shown below), and hoping `InferAddressSpacePass` can pick it up and do the rewriting accordingly. Before promotion: ``` define amdgpu_kernel void @kernel(ptr %to_be_promoted) { %val = load i32, ptr %to_be_promoted ... ret void } ``` After promotion: ``` define amdgpu_kernel void @kernel(ptr %to_be_promoted) { %ptr.cast.0 = addrspace cast ptr % to_be_promoted to ptr addrspace(1) %ptr.cast.1 = addrspace cast ptr addrspace(1) %ptr.cast.0 to ptr # all the use of %to_be_promoted will use %ptr.cast.1 %val = load i32, ptr %ptr.cast.1 ... ret void } ``` When `AAAddressSpace` analyzes the code after promotion, it will take `%to_be_promoted` as the underlying object of `%ptr.cast.1`, and use its address space (which is 0) as its final address space, thus simply do nothing in `manifest`. The attributor framework will them eliminate the address space cast from 0 to 1 and back to 0, and replace `%ptr.cast.1` with `%to_be_promoted`, which basically reverts all changes by `AMDGPUPromoteKernelArgumentsPass`. IMHO I'm not sure if `AMDGPUPromoteKernelArgumentsPass` promotes the argument in a proper way. To improve the handling of this case, this PR adds an extra handling when iterating over all underlying objects. If an underlying object is a function argument, it means it reaches a terminal such that we can't futher deduce its underlying object further. In this case, we check all uses of the argument. If they are all `addrspacecast` instructions and their destination address spaces are same, we take the destination address space. Fixes: SWDEV-482640.
2024-10-01[Attributor][FIX] Track returned pointer offsets (#110534)Johannes Doerfert
If the pointer returned by a function is not "the base pointer" but has an offset, we need to track the offset such that users can apply it to their offset chain when they create accesses. This was reported by @ye-luo and reduced test cases are included. The OffsetInfo was moved and the container was replaced with a set to avoid excessive growth. Otherwise, the patch just replaces the "returns pointer" flag with the "returned offsets", and deals with the applying to offsets at the call site. --------- Co-authored-by: Johannes Doerfert <jdoerfert@llnl.gov>
2024-09-30[NFC] Use initial-stack-allocations for more data structures (#110544)Jeremy Morse
This replaces some of the most frequent offenders of using a DenseMap that cause a malloc, where the typical element-count is small enough to fit in an initial stack allocation. Most of these are fairly obvious, one to highlight is the collectOffset method of GEP instructions: if there's a GEP, of course it's going to have at least one offset, but every time we've called collectOffset we end up calling malloc as well for the DenseMap in the MapVector.
2024-09-27[Attributor] Use more appropriate approach to check flat address space (#108713)Shilei Tian
2024-09-19[Attributor] Report change when updating ReachesReturn (#108965)macurtis-amd
2024-09-12[NFC][Attributor] Use unsigned integer for address space tracking (#108447)Shilei Tian
2024-09-10[Attributor] Keep track of reached returns in AAPointerInfo (#107479)Johannes Doerfert
Instead of visiting call sites in Attribute::checkForAllUses, we now keep track of returns in AAPointerInfo and use the call site return information as required. This way, the user of AAPointerInfo(CallSite)Argument can determine if the call return should be visited. We do not collect them as "may accesses" in the AAPointerInfo(CallSite)Argument itself in case a return user is found.
2024-09-06[Attributor] Add support for atomic operations in `AAAddressSpace` (#106927)Shilei Tian
2024-09-06[Attributor] Skip AS specialization for volatile memory instructions (#107250)Shilei Tian
2024-09-05[Attributor][FIX] Ensure to always translate call site arguments (#107323)Johannes Doerfert
When we propagate call site arguments we always need to translate them, this is important as we ended up picking the function argument for a recurisve call not the call site argument. `@recBad` and `@recGood` in `returned.ll` show the problem as they used to transform them the same way. The restructuring cleans the code up and helps derive more "returned" arguments and better information in the presence of recursive calls. The "dropped" attributes are simply dropped because we do not query them anymore, not because we cannot derive them.
2024-09-05[Attributor][FIX] Mark "may" accesses through call sites as such (#107439)Johannes Doerfert
Before, we kept the call site access kind (may/must) when we translated the access. However, the pointer we access it through (by passing it to the callee) might not be the underlying object. We have similar logic when we add store and load accesses.
2024-08-27[NFC][Attributor] Track the number of promoted indirect calls (#106214)Anshil Gandhi
2024-08-21[Transforms] Construct SmallVector with iterator ranges (NFC) (#105607)Kazu Hirata
2024-08-20[Attributor] Improve AAUnderlyingObjects (#104835)Johannes Doerfert
- Allocas and GlobalValues cannot be simplified, so we should not try. - If we never used any assumed state, the AAUnderlyingObjects doesn't require an additional update. - If we have seen an object (or it's underlying object) before, we do not need to inspect it anymore. The original logic for "SeenObjects" was flawed and caused us to add intermediate values to the underlying object list if a PHI or select instruction referenced the same underlying object twice. The test changes are all instances of this situation and we now correctly derive `memory(none)` for the functions that only access stack memory. --------- Co-authored-by: Shilei Tian <i@tianshilei.me>