summaryrefslogtreecommitdiff
path: root/llvm/test/Transforms/LoopVectorize/ARM
AgeCommit message (Collapse)Author
2025-07-01[VPlan] Add VPExpressionRecipe, replacing extended reduction recipes. (#144281)Florian Hahn
This patch adds a new recipe to combine multiple recipes into an 'expression' recipe, which should be considered as single entity for cost-modeling and transforms. The recipe needs to be 'decomposed', i.e. replaced by its individual recipes before execute. This subsumes VPExtendedReductionRecipe and VPMulAccumulateReductionRecipe and should make it easier to extend to include more types of bundled patterns, like e.g. extends folded into loads or various arithmetic instructions, if supported by the target. It allows avoiding re-creating the original recipes when converting to concrete recipes, together with removing the need to record various information. The current version of the patch still retains the original printing matching VPExtendedReductionRecipe and VPMulAccumulateReductionRecipe, but this specialized print could be replaced with printing the bundled recipes directly. PR: https://github.com/llvm/llvm-project/pull/144281
2025-06-19[LV] Add tests interleaving extended and multiply/accumulate reductions.Florian Hahn
Add missing test coverage for interleaving with VPExtendedReduction/VPMulAccumulateReduction recipes. Adds missing test coverage in preparation for https://github.com/llvm/llvm-project/pull/144281.
2025-06-17[VPlan] Expand VPWidenIntOrFpInductionRecipe into separate recipes (#118638)Luke Lau
The motivation of this PR is to make #115274 easier to implement, and should allow us to add EVL support by just passing EVL to the VF operand. The current difficulty with widening IVs with EVL is that VPWidenIntOrFpInductionRecipe generates its own backedge value. Since it's a VPHeaderPHIRecipe the VF operand must be in the preheader, which means we can't use the EVL since it's defined in the loop body. The gist in this PR is to take the approach in #114305 and expand VPWidenIntOrFpInductionRecipe into several recipes for the initial value, phi and backedge value just before execution. I.e. this example: ``` vector.ph: Successor(s): vector loop <x1> vector loop: { vector.body: WIDEN-INDUCTION %i = phi %start, %step, %vf ... EMIT branch-on-count ... No successors } ``` gets expanded to: ``` vector.ph: ... vp<%induction.start> = ... vp<%induction.increment> = ... Successor(s): vector loop <x1> vector loop: { vector.body: ir<%i> = WIDEN-PHI vp<%induction.start>, vp<%vec.ind.next> ... vp<%vec.ind.next> = add ir<%i>, vp<%induction.increment> EMIT branch-on-count ... No successors } ``` This allows us to a value defined in the loop in the backedge value, and also means we can just reuse the existing backedge fixups in VPlan::execute without having to specially handle it ourselves. After this #115274 should just become a matter of setting the VF operand to EVL (and building the increment step in the loop body, not the preheader).
2025-06-16[LV] Fix MVE regression from #132190 (#141736)Sam Tebbs
Register pressure was only considered if the vector bandwidth was being maximised (chosen either by the target or user options), but #132190 inadvertently caused high pressure VFs to be pruned even when max bandwidth wasn't enabled. This PR returns to the previous behaviour.
2025-05-29[VPlan] Implement VPlan-based cost model for VPReduction, ↵Elvis Wang
VPExtendedReduction and VPMulAccumulateReduction. (#113903) This patch implement the VPlan-based cost model for VPReduction, VPExtendedReduction and VPMulAccumulateReduction. With this patch, we can calculate the reduction cost by the VPlan-based cost model so remove the reduction costs in `precomputeCost()`. Ref: Original instruction based implementation: https://reviews.llvm.org/D93476
2025-05-28[VPlan] Use InstSimplifyFolder instead of TargetFolder (#141222)Ramkumar Ramachandra
For more powerful folding with operands that are not necessarily all-constant, use InstSimplifyFolder instead of TargetFolder in tryToConstantFold, and rename the function tryToFoldLiveIns.
2025-05-19[LoopVectorizer] Prune VFs based on plan register pressure (#132190)Sam Tebbs
This PR moves the register usage checking to after the plans are created, so that any recipes that optimise register usage (such as partial reductions) can be properly costed and not have their VF pruned unnecessarily. Depends on https://github.com/llvm/llvm-project/pull/137746
2025-05-16[VPlan] Implement VPExtendedReduction, VPMulAccumulateReductionRecipe and ↵Elvis Wang
corresponding vplan transformations. (#137746) This patch introduce two new recipes. * VPExtendedReductionRecipe - cast + reduction. * VPMulAccumulateReductionRecipe - (cast) + mul + reduction. This patch also implements the transformation that match following patterns via vplan and converts to abstract recipes for better cost estimation. * VPExtendedReduction - reduce(cast(...)) * VPMulAccumulateReductionRecipe - reduce.add(mul(...)) - reduce.add(mul(ext(...), ext(...)) - reduce.add(ext(mul(ext(...), ext(...)))) The converted abstract recipes will be lower to the concrete recipes (widen-cast + widen-mul + reduction) just before recipe execution. Note that this patch still relies on legacy cost model the calculate the cost for these patters. Will enable vplan-based cost decision in #113903. Split from #113903.
2025-04-17[LoopVectorize] Don't replicate blocks with optsize (#129265)John Brawn
Any VPlan we generate that contains a replicator region will result in replicated blocks in the output, causing a large code size increase. Reject such VPlans when optimizing for size, as the code size impact is usually worse than having a scalar epilogue, which we already forbid with optsize. This change requires a lot of test changes. For tests of optsize specifically I've updated the test with the new output, otherwise the tests have been adjusted to not rely on optsize. Fixes #66652
2025-04-14[InstCombine] Handle "add like" in ADD+GEP->GEP+GEP rewrites (#135156)Björn Pettersson
Considering that "or disjoint" is the canonical for certain add operations, then I think we want to support such "add like" operations when doing ADD+GEP->GEP+GEP rewrites to make things more consistent. Problem was found when improving ValueTracking, which turned an ADD into OR, and then suddenly optimizations got worse due to these rewrites no longer triggering.
2025-04-04[VPlan] Add initial CFG simplification, removing BranchOnCond true. (#106748)Florian Hahn
Add an initial CFG simplification transform, which removes the dead edges for blocks terminated with BranchOnCond true. At the moment, this removes the edge between middle block and scalar preheader when folding the tail. PR: https://github.com/llvm/llvm-project/pull/106748
2025-03-28[LV] Optimize VPWidenIntOrFpInductionRecipe for known TC (#118828)Hari Limaye
Optimize the IR generated for a VPWidenIntOrFpInductionRecipe to use the narrowest type necessary, when the trip-count of a loop is known to be constant and the only use of the recipe is the condition used by the vector loop's backedge branch.
2025-03-27[LV] Make cost model tests independent of VPValue numbers.Florian Hahn
Update tests to not rely on hard-coded VPValue numbers.
2025-03-26[VPlan] Generalize SCALAR-STEPS removal to any unroll factor.Florian Hahn
Follow-up to dfca6c0d3bf9d1a056 to extend isUnrolled handle any unrolled VPlan, which means there's a single UF, but it will be > 1 if unrolling took place.
2025-03-25[VPlan] Remove no-op SCALAR-STEPS after unrolling. (#123655)Florian Hahn
After unrolling, there may be additional simplifications that can be applied. One example is removing SCALAR-STEPS for the first part where only the first lane is demanded. This removes redundant adds of 0 from a large number of tests (~200), many which I am still working on updating. In preparation for removing redundant WideIV steps added in https://github.com/llvm/llvm-project/pull/119284. PR: https://github.com/llvm/llvm-project/pull/123655
2025-03-15[VPlan] Don't access canonical IV in VPWidenPointerInduction::execute.Florian Hahn
This updates VPWidenPointerInductionRecipe::execute to not use the canonical IV to determine the insert point. Instead, it relies on the current recipe position. In cases where this is not sufficient, set the insert point to the first non-phi instruction, to ensure phis are created together.
2025-02-27[VPlan] Simplify BLEND %a, %b, NOT(%m) -> BLEND %b, %a, %m. (#128375)Florian Hahn
Avoid negations for normalized blends by reordering operands. PR: https://github.com/llvm/llvm-project/pull/128375
2025-02-27[LV] Fix tests after 8150ab93f741.Florian Hahn
PR #124119 wasn't rebased & tested before merging. Update the failing tests.
2025-02-27[LoopVectorize] Use CodeSize as the cost kind for minsize (#124119)John Brawn
Functions marked with minsize should aim for minimum code size, so the vectorizer should use CodeSize for the cost kind and also the cost we compare should be the cost for the entire loop: it shouldn't be divided by the number of vector elements and block costs shouldn't be divided by the block probability. Possibly we should also be doing this for optsize as well, but there are a lot of tests that assume the current behaviour and the definition of optsize is less clear than minsize (for minsize the goal is to "keep the code size of this function as small as possible" whereas for optsize it's "keep the code size of this function low").
2025-02-09[VPlan] Add incoming values for all predecessor to ResumePHI (NFCI).Florian Hahn
Follow-up as discussed when using VPInstruction::ResumePhi for all resume values (#112147). This patch explicitly adds incoming values for each predecessor in VPlan. This simplifies codegen and allows transformations adjusting the predecessors of blocks with NFC modulo incoming block order in phis.
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-29[LoopVectorize][NFC] Disable output for tests that don't need it (#124747)David Sherwood
There are a lot of tests that do not depend upon the IR output for validation, relying instead on the debug output. For these tests we can add the -disable-output command line argument.
2025-01-02[LoopVectorize] Make needsExtract notice scalarized instructions (#119720)John Brawn
LoopVectorizationCostModel::needsExtract should recognise instructions that have been widened by scalarizing as scalar instructions, and thus not needing an extract when used by later scalarized instructions. This fixes an incorrect cost calculation in computePredInstDiscount, where we are adding a scalarization overhead cost when we shouldn't, though I haven't come up with a test case where it makes a difference. It will make a difference when the cost model switches to using the cost kind TCK_CodeSize for optsize, as not doing this causes the test LoopVectorize/X86/small-size.ll to get worse.
2024-12-24[VPlan] Remove stray space when printing VPWidenCastRecipe.Florian Hahn
printFlags() already takes care of printing a single space if there are no flags. Remove the extra space when printing a recipe without flags.
2024-12-17[VPlan] Remove reverse() of predecessors from VPInstruction::generate.Florian Hahn
This was originally done to reduce the diff for the change. Remove it and update the remaining tests. NFC modulo reordering of incoming values. Clean up after https://github.com/llvm/llvm-project/pull/114292.
2024-12-12[LV] Remove hard-coded VPValue numbers in test check lines. (NFC)Florian Hahn
Make tests independent of VPlan value numbers.
2024-12-05[InstCombine] Move gep of phi fold into separate functionNikita Popov
This makes sure that an early return during this fold doesn't end up skipping later gep folds.
2024-12-05[InstCombine] Infer nusw + nneg -> nuw for getelementptr (#111144)Nikita Popov
If the gep is nusw (usually via inbounds) and the offset is non-negative, we can infer nuw. Proof: https://alive2.llvm.org/ce/z/ihztLy
2024-11-28[LV] Use IVUpdateMayOverflow to set HasNUW. (#111758)Florian Hahn
If IVUpdateMayOverflow is false, we proved that the induction increment cannot overflow in the vector loop. This allows setting NUW in some cases when folding the tail. PR: https://github.com/llvm/llvm-project/pull/111758
2024-11-20Fix test failures introduced by PR #113697 (#116941)David Sherwood
Don't match the entire floating point debug output since it's prone to rounding errors depending upon the target.
2024-11-19[LoopVectorize][NFC] Rewrite tests to check output of vplan cost model (#113697)David Sherwood
Currently it's very difficult to improve the cost model for tail-folded loops because as soon as you add a VPInstruction::computeCost function that adds the costs of instructions such as VPInstruction::ActiveLaneMask and VPInstruction::ExplicitVectorLength the assert in LoopVectorizationPlanner::computeBestVF fails for some tests. This is because the VF chosen by the legacy cost model doesn't match the vplan cost model. See PR #90191. This assert is currently making it difficult to improve the cost model. Hopefully we will be in a position to remove the assert soon, however in order to do that we have to fix up a whole bunch of tests that rely upon the legacy cost model output. I've tried my best to update these tests to use vplan output instead. There is still work needed for the VF=1 case because the vplan cost model is not printed out in this case. I've not attempted to fix those in this patch.
2024-11-12[ARM] Extra MVE reduction test cases. NFCDavid Green
2024-11-08[ARM] Add a couple of new MVE reduction tests. NFCDavid Green
Nowadays we generate add(zext(mul(sext, sext)) with nneg zext and the multi-use test is awkward to get right. This should help our test coverage with the vplan cost transition.
2024-11-06[LLVM][IR] Use splat syntax when printing Constant[Data]Vector. (#112548)Paul Walker
2024-11-01[Reland][InstCombine] Fix FMF propagation in `foldSelectIntoOp` (#114499)Yingwei Zheng
Relands #114356. Compared to the last version, this patch only merges poison-generating/nsz flags from the select to fix LV regression in `llvm/test/Transforms/PhaseOrdering/AArch64/predicated-reduction.ll`.
2024-10-31[ValueTracking] Compute KnownFP state from recursive select/phi. (#113686)David Green
Given a recursive phi with select: %p = phi [ 0, entry ], [ %sel, loop] %sel = select %c, %other, %p The fp state can be calculated using the knowledge that the select/phi pair can only be the initial state (0 here) or from %other. This adds a short-cut into computeKnownFPClass for PHI to detect that the select is recursive back to the phi, and if so use the state from the other operand. This helps to address a regression from #83200.
2024-10-08[VPlan] Don't created GEP x, 0 for interleave group pointers.Florian Hahn
The GEP with offet 0 is redundant, remove it. This addresses a TODO from 7f74651837b ((#106431).
2024-09-11[LV] Assign cost to all interleave members when not interleaving.Florian Hahn
At the moment, the full cost of all interleave group members is assigned to the instruction at the group's insert position, even if the decision was to not form an interleave group. This can lead to inaccurate cost estimates, e.g. if the instruction at the insert position is dead. If the decision is to not vectorize but scalarize or scather/gather, then the cost will be to total cost for all members. In those cases, assign individual the cost per member, to more closely reflect to choice per instruction. This fixes a divergence between legacy and VPlan-based cost model. Fixes https://github.com/llvm/llvm-project/issues/108098.
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-21[InstCombine] Remove some of the complexity-based canonicalization (#91185)Nikita Popov
The idea behind this canonicalization is that it allows us to handle less patterns, because we know that some will be canonicalized away. This is indeed very useful to e.g. know that constants are always on the right. However, this is only useful if the canonicalization is actually reliable. This is the case for constants, but not for arguments: Moving these to the right makes it look like the "more complex" expression is guaranteed to be on the left, but this is not actually the case in practice. It fails as soon as you replace the argument with another instruction. The end result is that it looks like things correctly work in tests, while they actually don't. We use the "thwart complexity-based canonicalization" trick to handle this in tests, but it's often a challenge for new contributors to get this right, and based on the regressions this PR originally exposed, we clearly don't get this right in many cases. For this reason, I think that it's better to remove this complexity canonicalization. It will make it much easier to write tests for commuted cases and make sure that they are handled.
2024-08-05[ARM] Add scalar add_sat costs. (#100988)David Green
These can usually generate: - qadd / qsub for signed i32 scalars - uqadd16 / qadd16 / uqsub16 / qsub16 with an extend for signed/unsigned i8/i16 - Are expanded to an add + cmp + sel otherwise This can lead to differences in unrolling etc, but should be a better cost for the instructions.
2024-07-21[LV] Update tests to not have dead interleave groups.Florian Hahn
Update existing tests with dead interleave groups by adding users. This ensures the tests keep testing what they were intended to test with a planned change to skip unused instructions in cost computations.
2024-07-05[VPlan] Model branch cond to enter scalar epilogue in VPlan. (#92651)Florian Hahn
This patch moves branch condition creation to enter the scalar epilogue loop to VPlan. Modeling the branch in the middle block also requires modeling the successor blocks. This is done using the recently introduced VPIRBasicBlock. Note that the middle.block is still created as part of the skeleton and then patched in during VPlan execution. Unfortunately the skeleton needs to create the middle.block early on, as it is also used for induction resume value creation and is also needed to properly update the dominator tree during skeleton creation. After this patch lands, I plan to move induction resume value and phi node creation in the scalar preheader to VPlan. Once that is done, we should be able to create the middle.block in VPlan directly. This is a re-worked version based on the earlier https://reviews.llvm.org/D150398 and the main change is the use of VPIRBasicBlock. Depends on https://github.com/llvm/llvm-project/pull/92525 PR: https://github.com/llvm/llvm-project/pull/92651
2024-06-25LoopInfo: introduce Loop::getLocStr; unify debug output (#93051)Ramkumar Ramachandra
Introduce a Loop::getLocStr stolen from LoopVectorize's static function getDebugLocString in order to have uniform debug output headers across LoopVectorize, LoopAccessAnalysis, and LoopDistribute. The motivation for this change is to have UpdateTestChecks recognize the headers and automatically generate CHECK lines for debug output, with minimal special-casing.
2024-06-20[VPlan] Model middle block via VPIRBasicBlock. (#95816)Florian Hahn
Use VPIRBasicBlock to wrap the middle block and implement patching up branches in predecessors in VPIRBasicBlock::execute. The IR middle block is only created after skeleton creation. Initially a regular VPBasicBlock is created, which will later be replaced by a VPIRBasicBlock once the middle IR basic block has been created. Note that this slightly changes the order of instructions created in the middle block; code generated by recipe execution in the middle block will now be inserted before the terminator (and in between the compare to used by the terminator). The original order will be restored in https://github.com/llvm/llvm-project/pull/92651. PR: https://github.com/llvm/llvm-project/pull/95816
2024-05-23[ARM] Add a extra MVE low-trip-count loop. NFCDavid Green
This makes use of half floats, which makes the masked stores expensive.
2024-04-29[ARM] Ensure extra uses are not dead in tail-folding-counting-down.ll. NFCDavid Green
This might help keep the test valid if vplan is removing dead intructions.
2024-03-19[InstCombine] Fix for folding `select` into floating point binary operators. ↵Michele Scandale
(#83200) Folding a `select` into a floating point binary operators can only be done if the result is preserved for both case. In particular, if the other operand of the `select` can be a NaN, then the transformation won't preserve the result value.
2024-01-24[InstCombine] Canonicalize constant GEPs to i8 source element type (#68882)Nikita Popov
This patch canonicalizes getelementptr instructions with constant indices to use the `i8` source element type. This makes it easier for optimizations to recognize that two GEPs are identical, because they don't need to see past many different ways to express the same offset. This is a first step towards https://discourse.llvm.org/t/rfc-replacing-getelementptr-with-ptradd/68699. This is limited to constant GEPs only for now, as they have a clear canonical form, while we're not yet sure how exactly to deal with variable indices. The test llvm/test/Transforms/PhaseOrdering/switch_with_geps.ll gives two representative examples of the kind of optimization improvement we expect from this change. In the first test SimplifyCFG can now realize that all switch branches are actually the same. In the second test it can convert it into simple arithmetic. These are representative of common optimization failures we see in Rust. Fixes https://github.com/llvm/llvm-project/issues/69841.
2024-01-04[VPlan] Introduce ComputeReductionResult VPInstruction opcode. (#70253)Florian Hahn
This patch introduces a new ComputeReductionResult opcode to compute the final reduction result in the middle block. The code from fixReduction has been moved to ComputeReductionResult, after some earlier cleanup changes to model parts of fixReduction explicitly elsewhere as needed. The recipe may be broken down further in the future. Note that the phi nodes to merge the reduction result from the trip count check and the middle block, to be used as resume value for the scalar remainder loop are also generated based on ComputeReductionResult. Once we have a VPValue for the reduction result, this can also be modeled explicitly and moved out of the recipe.