summaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/LoopUtils.cpp
AgeCommit message (Collapse)Author
2025-06-29[LV] Add support for cmp reductions with decreasing IVs. (#140451)Florian Hahn
Similar to FindLastIV, add FindFirstIVSMin to support select (icmp(), x, y) reductions where one of x or y is a decreasing induction, producing a SMin reduction. It uses signed max as sentinel value. PR: https://github.com/llvm/llvm-project/pull/140451
2025-06-23[LV] Extend FindLastIV to unsigned case (#141752)Ramkumar Ramachandra
Split the FindLastIV RecurKind into SMax and UMax variants, depending on the reduction op produced.
2025-06-12[LV] Simplify creation of vp.load/vp.store/vp.reduce intrinsics (#143804)Philip Reames
The use of VectorBuilder here was simply obscuring what was actually going on. For vp.load and vp.store, the resulting code is significantly more idiomatic. For the vp.reduce cases, we remove several layers of indirection, including passing parameters via implicit state on the builder. In both cases, the code is significantly easier to follow.
2025-06-11Reapply 76197ea6f91f after removing an assertionJeremy Morse
Specifically this is the assertion in BasicBlock.cpp. Now that we're not examining or setting that flag consistently (because it'll be deleted in about an hour) there's no need to keep this assertion. Original commit title: [DebugInfo][RemoveDIs] Remove some debug intrinsic-only codepaths (#143451)
2025-06-11Revert "[DebugInfo][RemoveDIs] Remove some debug intrinsic-only codepaths ↵Jeremy Morse
(#143451)" This reverts commit c71a2e688828ab3ede4fb54168a674ff68396f61. /me squints -- this is hitting an assertion I thought had been deleted, will revert and investigate for a bit.
2025-06-11[DebugInfo][RemoveDIs] Remove some debug intrinsic-only codepaths (#143451)Jeremy Morse
These are opportunistic deletions as more places that make use of the IsNewDbgInfoFormat flag are removed. It should (TM)(R) all be dead code now that `IsNewDbgInfoFormat` should be true everywhere. FastISel: we don't need to do debug-aware instruction counting any more, because there are no debug instructions, Autoupgrade: you can no-longer avoid autoupgrading of intrinsics to records DIBuilder: Delete the code for creating debug intrinsics (!) LoopUtils: No need to handle debug instructions, they don't exist
2025-06-10[llvm] annotate interfaces in llvm/Transforms for DLL export (#143413)Andrew Rogers
## Purpose This patch is one in a series of code-mods that annotate LLVM’s public interface for export. This patch annotates the `llvm/Transforms` library. These annotations currently have no meaningful impact on the LLVM build; however, they are a prerequisite to support an LLVM Windows DLL (shared library) build. ## Background This effort is tracked in #109483. Additional context is provided in [this discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307), and documentation for `LLVM_ABI` and related annotations is found in the LLVM repo [here](https://github.com/llvm/llvm-project/blob/main/llvm/docs/InterfaceExportAnnotations.rst). The bulk of these changes were generated automatically using the [Interface Definition Scanner (IDS)](https://github.com/compnerd/ids) tool, followed formatting with `git clang-format`. The following manual adjustments were also applied after running IDS on Linux: - Removed a redundant `operator<<` from Attributor.h. IDS only auto-annotates the 1st declaration, and the 2nd declaration being un-annotated resulted in an "inconsistent linkage" error on Windows when building LLVM as a DLL. - `#include` the `VirtualFileSystem.h` in PGOInstrumentation.h and remove the local declaration of the `vfs::FileSystem` class. This is required because exporting the `PGOInstrumentationUse` constructor requires the class be fully defined because it is used by an argument. - Add #include "llvm/Support/Compiler.h" to files where it was not auto-added by IDS due to no pre-existing block of include statements. - Add `LLVM_TEMPLATE_ABI` and `LLVM_EXPORT_TEMPLATE` to exported instantiated templates. ## Validation Local builds and tests to validate cross-platform compatibility. This included llvm, clang, and lldb on the following configurations: - Windows with MSVC - Windows with Clang - Linux with GCC - Linux with Clang - Darwin with Clang
2025-05-28[LoopUtils] Pass sentinel value directly to createFindLastIVRed (NFC).Florian Hahn
Now that there is only a single FindLastIV recurrence kind, simply pass the sentinel value instead of the full recurrence descriptor to tighten the interface.
2025-05-28[LoopUtils] Pass start value directly to createAnyOfReduction (NFC).Florian Hahn
Now that there is only a single AnyOf recurrence kind, simply pass the start value instead of the full recurrence descriptor, to tighten the interface.
2025-04-28[IVDescriptors] Support reductions with minimumnum/maximumnum. (#137335)Florian Hahn
Add a new reduction recurrence kind for reductions with minimumnum/maximumnum. Such reductions can be vectorized without nsz/nnans, same as reductions with maximum/minimum intrinsics. Note that a new reduction kind is needed to make sure partial reductions are also combined with minimumnum/maximumnum. Note that the final reduction to a scalar value is performed with vector.reduce.fmin/fmax. This should be fine, as the results of the partial reductions with maximumnum/minimumnum silences any sNaNs. In-loop and reductions in SLP are not supported yet, as there's no reduction version of maximumnum/minimumnum yet and fmax may be incorrect. PR: https://github.com/llvm/llvm-project/pull/137335
2025-03-27[VPlan] Manage FindLastIV start value in ComputeFindLastIVResult (NFC) (#132690)Florian Hahn
Keep the start value as operand of ComputeFindLastIVResult. A follow-up patch will use this to make sure the start value is frozen if needed. Depends on https://github.com/llvm/llvm-project/pull/132689 PR: https://github.com/llvm/llvm-project/pull/132690
2025-03-23[llvm] Use range constructors for *Set (NFC) (#132636)Kazu Hirata
2025-03-22[llvm] Use *Set::insert_range (NFC) (#132591)Kazu Hirata
DenseSet, SmallPtrSet, SmallSet, SetVector, and StringSet recently gained C++23-style insert_range. This patch uses insert_range with iterator ranges. For each case, I've verified that foos is defined as make_range(foo_begin(), foo_end()) or in a similar manner.
2025-03-20[LV] Get FMFs from VectorBuilder in createSimpleReduction. NFC (#132017)Luke Lau
The other createSimpleReduction takes the FMFs from the IRBuilder, so this aligns the VectorBuilder variant to do the same and reduce the possibility of there being a mismatch in flags.
2025-03-19[LV] Split RecurrenceDescriptor into RecurKind + FastMathFlags in LoopUtils. ↵Luke Lau
NFC (#132014) Split off from #131300, this splits up RecurrenceDescriptor arguments so that arbitrary recurrence kinds may be used down the line.
2025-03-18[VPlan] Remove createReduction. NFCI (#131336)Luke Lau
This is split off from #131300. A VPReductionRecipe will never have a AnyOf or FindLastIV recurrence, so when it calls createReduction it always calls createSimpleReduction. If we replace the call then it leaves createReduction with one user in VPInstruction::ComputeReductionResult, which we can inline and then remove.
2025-03-06[LoopUtils] Rename a var in addDiffRuntimeChecks (NFC) (#130128)Ramkumar Ramachandra
2025-03-05[LoopUtils] Saturate at INT_MAX when estimating TC (#129683)Ramkumar Ramachandra
getLoopEstimatedTripCount returns std::nullopt when the trip count would overflow the return type, but since it is an estimate anyway, we might as well saturate at UINT_MAX, improving results.
2025-03-04[LoopUtils] Don't wrap in getLoopEstimatedTripCount (#129080)Ramkumar Ramachandra
getLoopEstimatedTripCount returns the trip count based on profiling data, and its documentation says that it could return 0 when the trip count is zero, but this is not the case: a valid trip count can never be zero, and it returns 0 when the unsigned ExitCount is incremented by 1 and wraps. Some callers are careful about checking for this zero value in an std::optional, but it makes for an API with footguns, as a std::optional return value indicates that a non-nullopt value would be a valid trip count. Fix this by explicitly returning std::nullopt when the return value would wrap, and strip additional checks in callers. This also fixes a minor bug in LoopVectorize.
2025-02-22[VectorCombine] Fold binary op of reductions. (#121567)Mikhail Gudim
Replace binary of of two reductions with one reduction of the binary op applied to vectors. For example: ``` %v0_red = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %v0) %v1_red = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %v1) %res = add i32 %v0_red, %v1_red ``` gets transformed to: ``` %1 = add <16 x i32> %v0, %v1 %res = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %1) ```
2024-12-12[LoopVectorize] Vectorize select-cmp reduction pattern for increasing ↵Mel Chen
integer induction variable (#67812) Consider the following loop: ``` int rdx = init; for (int i = 0; i < n; ++i) rdx = (a[i] > b[i]) ? i : rdx; ``` We can vectorize this loop if `i` is an increasing induction variable. The final reduced value will be the maximum of `i` that the condition `a[i] > b[i]` is satisfied, or the start value `init`. This patch added new RecurKind enums - IFindLastIV and FFindLastIV. --------- Co-authored-by: Alexey Bataev <5361294+alexey-bataev@users.noreply.github.com>
2024-09-29[LICM] Use DomTreeUpdater version of SplitBlockPredecessors, nfc (#107190)Joshua Cao
The DominatorTree version is marked for deprecation, so we use the DomTreeUpdater version. We also update sinkRegion() to iterate over basic blocks instead of DomTreeNodes. The loop body calls SplitBlockPredecessors. The DTU version calls DomTreeUpdater::apply_updates(), which may call DominatorTree::reset(). This invalidates the worklist of DomTreeNodes to iterate over.
2024-09-04Consolidate all IR logic for getting the identity value of a reduction [nfc]Philip Reames
This change merges the three different places (at the IR layer) for finding the identity value of a reduction into a single copy. This depends on several prior commits which fix ommissions and bugs in the distinct copies, but this patch itself should be fully non-functional. As the new comments and naming try to make clear, the identity value is a property of the @llvm.vector.reduce.* intrinsic, not of e.g. the recurrence descriptor. (We still provide an interface for clients using recurrence descriptors, but the implementation simply translates to the intrinsic which each corresponds to.) As a note, the getIntrinsicIdentity API does not support fminnum/fmaxnum or fminimum/fmaximum which is why we still need manual logic (but at least only one copy of manual logic) for those cases.
2024-09-03Remove "Target" from createXReduction naming [nfc]Philip Reames
Despite the stale comments, none of these actually use TTI, and they're solely generating standard LLVM IR.
2024-09-03Prefer use of 0.0 over -0.0 for fadd reductions w/nsz (in IR) (#106770)Philip Reames
This is a follow up to 924907bc6, and is mostly motivated by consistency but does include one additional optimization. In general, we prefer 0.0 over -0.0 as the identity value for an fadd. We use that value in several places, but don't in others. So, let's be consistent and use the same identity (when nsz allows) everywhere. This creates a bunch of test churn, but due to 924907bc6, most of that churn doesn't actually indicate a change in codegen. The exception is that this change enables the use of 0.0 for nsz, but *not* reasoc, fadd reductions. Or said differently, it allows the neutral value of an ordered fadd reduction to be 0.0.
2024-08-30Reuse getBinOpIdentity in createAnyOfTargetReduction [nfc]Philip Reames
Consolidating code so that we have one copy instead of multiple reasoning about identity element. Note that we're (deliberately) not passing the FMF flags to common utility to preserve behavior in this change.
2024-08-30Restructure createSimpleTargetReduction to match VP path [NFC]Philip Reames
Reduces code significantly, but more importantly makes it obvious that this variant matches the VP variant just below.
2024-08-02[llvm] Make InstSimplifyFolder constructor explicit (NFC) (#101654)Sergei Barannikov
2024-07-25[VP] Refactor VectorBuilder to avoid layering violation. NFC (#99276)Mel Chen
This patch refactors the handling of reduction to eliminate layering violations. * Introduced `getReductionIntrinsicID` in LoopUtils.h for mapping recurrence kinds to llvm.vector.reduce.* intrinsic IDs. * Updated `VectorBuilder::createSimpleTargetReduction` to accept llvm.vector.reduce.* intrinsic directly. * New function `VPIntrinsic::getForIntrinsic` for mapping intrinsic ID to the same functional VP intrinsic ID.
2024-07-17[TTI][WebAssembly] Pairwise reduction expansion (#93948)Sam Parker
WebAssembly doesn't support horizontal operations nor does it have a way of expressing fast-math or reassoc flags, so runtimes are currently unable to use pairwise operations when generating code from the existing shuffle patterns. This patch allows the backend to select which, arbitary, shuffle pattern to be used per reduction intrinsic. The default behaviour is the same as the existing, which is by splitting the vector into a top and bottom half. The other pattern introduced is for a pairwise shuffle. WebAssembly enables pairwise reductions for int/fp add/sub.
2024-07-16[LV][EVL] Support in-loop reduction using tail folding with EVL. (#90184)Mel Chen
Following from #87816, add VPReductionEVLRecipe to describe vector predication reduction. Address one of TODOs from #76172.
2024-06-27[IR] Add getDataLayout() helpers to BasicBlock and Instruction (#96902)Nikita Popov
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-04[LV] Apply loop guards when checking recur during hoisting RT checks.Florian Hahn
Apply loop guards when checking if the recurrence is non-negative in cases where runtime checks are hoisted out of an inner loop.
2024-06-04[LoopUtils] Simplify code for runtime check generation a bit (NFCI).Florian Hahn
Store getSE result in variable to re-use and use structured bindings when looping over bounds.
2024-05-22Revert "[indvars] Missing variables at Og (#88270)" (#93016)Carlos Alberto Enciso
This reverts commit 89e1f7784be40bea96d5e65919ce8d34151c1d69. https://github.com/llvm/llvm-project/pull/88270#discussion_r1609559724 https://github.com/llvm/llvm-project/pull/88270#discussion_r1609552972 Main concerns from @nikic are the interaction between the 'IndVars' and 'LoopDeletion' passes, increasing build times and adding extra complexity.
2024-05-22[indvars] Missing variables at Og (#88270)Carlos Alberto Enciso
https://bugs.llvm.org/show_bug.cgi?id=51735 https://github.com/llvm/llvm-project/issues/51077 In the given test case: ``` 4 ... 5 void bar() { 6 int End = 777; 7 int Index = 27; 8 char Var = 1; 9 for (; Index < End; ++Index) 10 ; 11 nop(Index); 12 } 13 ... ``` Missing local variable `Index` after loop `Induction Variable Elimination`. When adding a breakpoint at line `11`, LLDB does not have information on the variable. But it has info on `Var` and `End`.
2024-05-04[Transforms] Use StringRef::operator== instead of StringRef::equals (NFC) ↵Kazu Hirata
(#91072) I'm planning to remove StringRef::equals in favor of StringRef::operator==. - StringRef::operator==/!= outnumber StringRef::equals by a factor of 31 under llvm/ in terms of their usage. - The elimination of StringRef::equals brings StringRef closer to std::string_view, which has operator== but not equals. - S == "foo" is more readable than S.equals("foo"), especially for !Long.Expression.equals("str") vs Long.Expression != "str".
2024-05-03Reapply "[LV] Improve AnyOf reduction codegen. (#78304)"Florian Hahn
This reverts the revert commit c6e01627acf859. This patch includes a fix for any-of reductions and epilogue vectorization. Extra test coverage for the issue that caused the revert has been added in bce3bfced5fe0b019 and an assertion has been added in c7209cbb8be7a3c65813. -------------------------------- Original commit message: Update AnyOf reduction code generation to only keep track of the AnyOf property in a boolean vector in the loop, only selecting either the new or start value in the middle block. The patch incorporates feedback from https://reviews.llvm.org/D153697. This fixes the #62565, as now there aren't multiple uses of the start/new values. Fixes https://github.com/llvm/llvm-project/issues/62565 PR: https://github.com/llvm/llvm-project/pull/78304
2024-04-29[LoopUnswitch] Allow i1 truncs in loop unswitch (#89738)Matthew Devereau
With the addition of #84628, truncs to i1 are being emitted as conditions to branch instructions. This caused significant regressions in cases which were previously improved by loop unswitch. Adding truncs to i1 restore the previous performance seen.
2024-04-16Revert "Reapply "[LV] Improve AnyOf reduction codegen. (#78304)""Arthur Eubanks
This reverts commit c6e38b928c56f562aea68a8e90f02dbdf0eada85. Causes miscompiles, see comments on #78304.
2024-04-08Revert "[indvars] Missing variables at Og: (#69920)"Nikita Popov
This reverts commit 739fa1c84b92b8af7dceedf2e5ad808a64e85a57. This introduces a layering violation by using IR in Support headers.
2024-04-08[indvars] Missing variables at Og: (#69920)Carlos Alberto Enciso
https://bugs.llvm.org/show_bug.cgi?id=51735 https://github.com/llvm/llvm-project/issues/51077 In the given test case: ``` 4 ... 5 void bar() { 6 int End = 777; 7 int Index = 27; 8 char Var = 1; 9 for (; Index < End; ++Index) 10 ; 11 nop(Index); 12 } 13 ... ``` Missing local variable `Index` after loop `Induction Variable Elimination`. When adding a breakpoint at line `11`, LLDB does not have information on the variable. But it has info on `Var` and `End`.
2024-04-05Reapply "[LV] Improve AnyOf reduction codegen. (#78304)"Florian Hahn
This reverts the revert commit 589c7abb03448. This patch includes a fix for any-of reductions and epilogue vectorization. Extra test coverage for the issue that caused the revert has been added in 399ff08e29d. -------------------------------- Original commit message: Update AnyOf reduction code generation to only keep track of the AnyOf property in a boolean vector in the loop, only selecting either the new or start value in the middle block. The patch incorporates feedback from https://reviews.llvm.org/D153697. This fixes the #62565, as now there aren't multiple uses of the start/new values. Fixes https://github.com/llvm/llvm-project/issues/62565 PR: https://github.com/llvm/llvm-project/pull/78304
2024-03-19[RemoveDIs][NFC] Rename DPValue -> DbgVariableRecord (#85216)Stephen Tozer
This is the major rename patch that prior patches have built towards. The DPValue class is being renamed to DbgVariableRecord, which reflects the updated terminology for the "final" implementation of the RemoveDI feature. This is a pure string substitution + clang-format patch. The only manual component of this patch was determining where to perform these string substitutions: `DPValue` and `DPV` are almost exclusively used for DbgRecords, *except* for: - llvm/lib/target, where 'DP' is used to mean double-precision, and so appears as part of .td files and in variable names. NB: There is a single existing use of `DPValue` here that refers to debug info, which I've manually updated. - llvm/tools/gold, where 'LDPV' is used as a prefix for symbol visibility enums. Outside of these places, I've applied several basic string substitutions, with the intent that they only affect DbgRecord-related identifiers; I've checked them as I went through to verify this, with reasonable confidence that there are no unintended changes that slipped through the cracks. The substitutions applied are all case-sensitive, and are applied in the order shown: ``` DPValue -> DbgVariableRecord DPVal -> DbgVarRec DPV -> DVR ``` Following the previous rename patches, it should be the case that there are no instances of any of these strings that are meant to refer to the general case of DbgRecords, or anything other than the DPValue class. The idea behind this patch is therefore that pure string substitution is correct in all cases as long as these assumptions hold.
2024-03-14Revert "[LV] Improve AnyOf reduction codegen. (#78304)"Kirill Stoimenov
Broke sanitizer bots: https://lab.llvm.org/buildbot/#/builders/74/builds/26697 This reverts commit 95fef1dfefd5467206e74c089d29806fcd82889b.
2024-03-14[RemoveDIs][NFC] Move DPValue::filter -> filterDbgVars (#85208)Stephen Tozer
This patch changes DPValue::filter to be a non-member method filterDbgVars. There are two reasons for this: firstly, the name of DPValue is about to change to DbgVariableRecord, which will result in every `for` loop that uses DPValue::filter to require a line break. This is a small thing, but it makes the rename patch more difficult to review, and is just generally more awkward for what is a fairly common loop. Secondly, the intent is to later break up the DPValue class into subclasses, at which point it would be better to have a non-member function that allows template arguments for the cases we want to filter with greater specificity.
2024-03-14[LV] Improve AnyOf reduction codegen. (#78304)Florian Hahn
Update AnyOf reduction code generation to only keep track of the AnyOf property in a boolean vector in the loop, only selecting either the new or start value in the middle block. The patch incorporates feedback from https://reviews.llvm.org/D153697. This fixes the #62565, as now there aren't multiple uses of the start/new values. Fixes https://github.com/llvm/llvm-project/issues/62565 PR: https://github.com/llvm/llvm-project/pull/78304
2024-03-12[RemoveDIs][NFC] Rename common interface functions for DPValues->DbgRecords ↵Stephen Tozer
(#84793) As part of the effort to rename the DbgRecord classes, this patch renames the widely-used functions that operate on DbgRecords but refer to DbgValues or DPValues in their names to refer to DbgRecords instead; all such functions are defined in one of `BasicBlock.h`, `Instruction.h`, and `DebugProgramInstruction.h`. This patch explicitly does not change the names of any comments or variables, except for where they use the exact name of one of the renamed functions. The reason for this is reviewability; this patch can be trivially examined to determine that the only changes are direct string substitutions and any results from clang-format responding to the changed line lengths. Future patches will cover renaming variables and comments, and then renaming the classes themselves.
2024-03-04[LSR][term-fold] Ensure the simple recurrence is from the current loop (#83085)Patrick O'Neill
If the phi node found by matchSimpleRecurrence is not from the current loop, then isAlmostDeadIV panics. With this patch we bail out early. Signed-off-by: Patrick O'Neill <patrick@rivosinc.com> --------- Signed-off-by: Patrick O'Neill <patrick@rivosinc.com>
2024-02-20[RemoveDIs][NFC] Introduce DbgRecord base class [1/3] (#78252)Orlando Cazalet-Hyams
Patch 1 of 3 to add llvm.dbg.label support to the RemoveDIs project. The patch stack adds a new base class -> 1. Add DbgRecord base class for DPValue and the not-yet-added DPLabel class. 2. Add the DPLabel class. 3. Enable dbg.label conversion and add support to passes. Patches 1 and 2 are NFC. In the near future we also will rename DPValue to DbgVariableRecord and DPLabel to DbgLabelRecord, at which point we'll overhaul the function names too. The name DPLabel keeps things consistent for now.