6040 Commits

Author SHA1 Message Date
Florian Hahn
672e9263cb
Reapply "[VPlan] Support cloning initial VPlan (NFC)."
This reverts commit 204252e2df80876702616518a5154dccacf3ebac.

Recommit with a fix for the leak in a unit test.
2025-05-23 21:22:31 +01:00
Ramkumar Ramachandra
0240129218
[IVDesc] Unify RecurKinds [I|F]AnyOf (#118393)
Co-authored-by: Mel Chen <mel.chen@sifive.com>
2025-05-23 11:57:30 +01:00
Ramkumar Ramachandra
b81170ecff
[IVDesc] Unify RecurKinds [I|F]FindLastIV (NFC) (#141082) 2025-05-22 22:48:01 +01:00
Florian Hahn
95ba5508e5
Reapply "[VPlan] Move predication to VPlanTransform (NFC). (#128420)"
This reverts commit 793bb6b257fa4d9f4af169a4366cab3da01f2e1f.

The recommitted version contains a fix to make sure only the original
phis are processed in convertPhisToBlends nu collecting them in a vector
first. This fixes a crash when no mask is needed, because there is only
a single incoming value.

Original message:
This patch moves the logic to predicate and linearize a VPlan to a
dedicated VPlan transform. It mostly ports the existing logic directly.

There are a number of follow-ups planned in the near future to
further improve on the implementation:
* Edge and block masks are cached in VPPredicator, but the block masks
are still made available to VPRecipeBuilder, so they can be accessed
during recipe construction. As a follow-up, this should be replaced by
adding mask operands to all VPInstructions that need them and use that
during recipe construction.
* The mask caching in a map also means that this map needs updating each
time a new recipe replaces a VPInstruction; this would also be handled
by adding mask operands.

PR: https://github.com/llvm/llvm-project/pull/128420
2025-05-22 08:16:15 +01:00
Florian Hahn
bf15aadcbc
[VPlan] Don't try to narrow predicated VPReplicateRecipe.
We cannot convert predicated recipes to uniform ones at the moment.
This fixes a crash reported for https://github.com/llvm/llvm-project/pull/139150.
2025-05-21 22:13:55 +01:00
Florian Hahn
793bb6b257
Revert "[VPlan] Move predication to VPlanTransform (NFC). (#128420)"
This reverts commit b263c08e1a0b54a871915930aa9a1a6ba205b099.

Looks like this triggers a crash in one of the Fortran tests. Reverting
while I investigate
    https://lab.llvm.org/buildbot/#/builders/41/builds/6825
2025-05-21 19:24:21 +01:00
Kazu Hirata
a28d753e96 [Vectorize] Fix a warning
This patch fixes:

  llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:8564:20: error:
  unused variable 'LoopRegionOf' [-Werror,-Wunused-variable]
2025-05-21 08:03:16 -07:00
Florian Hahn
b263c08e1a
[VPlan] Move predication to VPlanTransform (NFC). (#128420)
This patch moves the logic to predicate and linearize a VPlan to a
dedicated VPlan transform. It mostly ports the existing logic directly.

There are a number of follow-ups planned in the near future to
further improve on the implementation:
* Edge and block masks are cached in VPPredicator, but the block masks
are still made available to VPRecipeBuilder, so they can be accessed
during recipe construction. As a follow-up, this should be replaced by
adding mask operands to all VPInstructions that need them and use that
during recipe construction.
* The mask caching in a map also means that this map needs updating each
time a new recipe replaces a VPInstruction; this would also be handled
by adding mask operands.


PR: https://github.com/llvm/llvm-project/pull/128420
2025-05-21 15:47:33 +01:00
Luke Lau
d827588c36
[VectorCombine] Scalarize binop-like intrinsics (#138095)
Currently VectorCombine can scalarize vector compares and binary ops.
This extends it to also scalarize binary-op like intrinsics like umax,
minnum etc.

The motivation behind this is to scalarize more intrinsics in
VectorCombine rather than in DAGCombine, so we can sink splats across
basic blocks: see #137786

This currently has very little effect on generated code because
InstCombine doesn't yet canonicalize binary intrinsics where one operand
is a constant into the form that VectorCombine expects, i.e. `binop
(shuffle insert) const --> shuffle (binop insert const)`. The plan is to
land this first and then in a subsequent patch teach InstCombine to do
the canonicalization to avoid regressions in the meantime.

This uses `isTriviallyVectorizable` to determine whether or not an
intrinsic is safe to scalarize. There's also `isTriviallyScalarizable`,
but this seems more geared towards the Scalarizer pass and includes
intrinsics with multiple return values.

It also only handles intrinsics with two operands with the same type as
the return type. In the future we would generalize this to handle
arbitrary numbers of operands, including unary operators too, e.g. fneg
or fma, as well as different operand types, e.g. powi or scmp
2025-05-21 09:24:11 +01:00
Alexey Bataev
2318491432 [SLP][NFC]Do the analysis first and then actual codegen, NFC 2025-05-20 08:12:53 -07:00
Alexey Bataev
a0058d1851
[SLP][NFC]Make TreeEntry a class and store "need-to-schedule" state
TreeEntry should be a class, not a struct, since it has private members.
Also, do no repeat Does-Not-Need-To-Schedule analysis during codegen,
codegen may affect the result of the analysis in future patches.

Reviewers: hiraditya, HanKuanChen, RKSimon

Reviewed By: RKSimon

Pull Request: https://github.com/llvm/llvm-project/pull/140734
2025-05-20 10:33:59 -04:00
Ramkumar Ramachandra
cf1f116f78
[VPlan] Introduce constant folder in simplifyRecipe (#125365)
Introduce a VPlan-level constant folder in simplifyRecipe that tries to
fold a recipe to a constant using TargetFolder.
2025-05-20 14:16:01 +01:00
Alexey Bataev
3918ef3688
[SLP]Fix the analysis for masked compress loads
Need to remove the check for Orders in interleaved loads analysis and
estimate shuffle cost without the reordering to correctly handle the
costs of masked compress loads.

Reviewers: hiraditya, HanKuanChen, RKSimon

Reviewed By: HanKuanChen, RKSimon

Pull Request: https://github.com/llvm/llvm-project/pull/140647
2025-05-20 07:31:16 -04:00
Alexey Bataev
30ebcf6280
[SLP][NFC]Store operand entries in the map
Instead of looking through all the vectorizable tree to find the operand
entry, better to store it in a separate map and perform quick lookup,
basing on user tree entry and operand index.
It allows to remove lots of duplicated code, simplify processing and fix
potential future issues with the analysis, affected by the codegen.
Also, improves compile time.

Reviewers: HanKuanChen, RKSimon, hiraditya

Reviewed By: hiraditya

Pull Request: https://github.com/llvm/llvm-project/pull/140549
2025-05-19 19:53:47 -04:00
Sam Tebbs
70501ed2f0
[LoopVectorizer] Prune VFs based on plan register pressure (#132190)
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-19 13:27:17 +01:00
Mel Chen
1b711b27d2
[VPlan] Clean up the function VPInstruction::generate for ComputeReductionResult, nfc (#140245)
When reducing unrolled parts, explicitly check for min/max reductions
using the function RecurrenceDescriptor::isMinMaxRecurrenceKind. Only if
the reduction is not min/max reduction, call
RecurrenceDescriptor::getOpcode() to handle other cases via CreateBinOp.

Based on https://github.com/llvm/llvm-project/pull/140242
Related to https://github.com/llvm/llvm-project/pull/118393
2025-05-19 17:31:23 +08:00
Mel Chen
f594cd0936
[IVDescriptor][LV] Return Instruction::Or for IAnyOf/FAnyOf in getOpcode(), nfc (#140242) 2025-05-19 16:17:04 +08:00
Alexey Bataev
bb8e2a8937 [SLP]Relax assertion to avoid compiler crash
Need to relax the assertion to fix a compiler crash in case if the
reordered compress loads are more profitable than the ordered ones.

Fixes #140334
2025-05-18 14:26:36 -07:00
Florian Hahn
204252e2df
Revert "[VPlan] Support cloning initial VPlan (NFC)."
This reverts commit 5fa985e751c8f890fff31e190473aeeb6f7a9fc5.

Revert as this seems to introduce a call to a pure virtual function on a
few configs, e.g.
    https://lab.llvm.org/buildbot/#/builders/169/builds/11535
2025-05-18 22:03:00 +01:00
Alexey Bataev
fb86b3d96b [SLP]Change the insertion point for outside-block-used nodes and prevec phi operand gathers
Need to set the insertion point for (non-schedulable) vector node after
the last instruction in the node to avoid def-use breakage. But it also
causes miscompilation with gather/buildvector operands of the phi nodes,
used in the same phi only in the block.
These nodes supposed to be inserted at the end of the block and after
changing the insertion point for the non-schedulable vec block, it also
may break def-use dependencies. Need to prevector such nodes, to emit
them as early as possible, so the vectorized nodes are inserted before
these nodes.

Fixes #139728

Recommit after revert 60fb92179291e848eb7b04913bdc818d081db296

Reviewers: hiraditya, HanKuanChen, RKSimon

Reviewed By: RKSimon

Pull Request: https://github.com/llvm/llvm-project/pull/139917
2025-05-18 12:59:36 -07:00
Florian Hahn
5fa985e751
[VPlan] Support cloning initial VPlan (NFC).
Support cloning VPlans as they are created by the initial buildVPlan,
i.e. scalar header not yet connected and no trip-count set. This is not
used yet but will in follow-up changes/

Also add a unit test for cloning & printing.
2025-05-18 19:37:17 +01:00
Florian Hahn
07c085af3e
[VPlan] Add narrowToSingleScalarRecipe transform. (#139150)
Add a new convertToUniformRecipes transform which uses VPlan-based
uniformity analysis to determine if wide recipes and replicate recipes
can be converted to uniform recipes.

There are a few places where we ad-hoc convert recipes to uniform
recipes, which this transform will eventually replace. There are a few
more generalizations required to do so which I plan to do as follow-ups.

By converting the recipes to uniform recipes, we effectively materialize
the information from the VPlan-based analysis.

Note that there is one regression at the moment in SystemZ/pr47665.ll
due to trivial constant folding opportunities in the input IR. This will
be fixed by VPlan-based constant folding
(https://github.com/llvm/llvm-project/pull/125365/)

PR: https://github.com/llvm/llvm-project/pull/139150
2025-05-18 09:32:27 +01:00
Jon Chesterfield
9c60431b67
[NFC] Add a specialization of DenseMapInfo for SmallVector (#140380)
Equivalent to the three existing uses I found which were all pointers.
Implementing the general pattern so SmallVector<int> etc will work as
well.

Added to the SmallVector.h header as opposed to DenseMapInfo.h following
the StringRef.h and SmallBitVector.h prior art.

Noticed while writing an unrelated patch which currently wants a map
from small vectors to other things and cleaner to generalise than add
another specialisation to said patch.
2025-05-17 19:13:30 +01:00
Alexey Bataev
60fb921792 Revert "[SLP]Change the insertion point for outside-block-used nodes and prevec phi operand gathers"
This reverts commit d79d9b8fbfc7e8411aeaf2f5e1be9d4247594fee to fix
a bug reported in https://github.com/llvm/llvm-project/pull/139917#issuecomment-2888216404
2025-05-17 11:06:37 -07:00
Florian Hahn
e81fab6847
[VPlan] Verify final VPlan, just before execution. (NFC)
Add additional verifier call just before execution, to make sure the
final VPlan is valid.

Note that this currently requires disabling a small number of checks
when running late.
2025-05-17 17:53:06 +01:00
Florian Hahn
b3e7e4bb25
[VPlan] Also specialize getNumIncoming for VPWidenPointerInd (NFC).
Similar to VPWidenIntOrFpInductionRecipe, VPWidenPointerInductionRecipe
only has a single incoming value and no backedge value.

Currently NFC as there are no problematic uses at the moment.
2025-05-16 22:00:31 +01:00
Florian Hahn
ba93685ea2
[VPlan] Also use original parent loop for exit VPBBs.
When vectorizing loops with early exits that is nested within another
one, one of the loop exits may be outside both loops, so setting adding
it to the parent loop is incorrect. Also use the original parent loop
for exit blocks.
2025-05-16 21:12:39 +01:00
Alexey Bataev
d79d9b8fbf
[SLP]Change the insertion point for outside-block-used nodes and prevec phi operand gathers
Need to set the insertion point for (non-schedulable) vector node after
the last instruction in the node to avoid def-use breakage. But it also
causes miscompilation with gather/buildvector operands of the phi nodes,
used in the same phi only in the block.
These nodes supposed to be inserted at the end of the block and after
changing the insertion point for the non-schedulable vec block, it also
may break def-use dependencies. Need to prevector such nodes, to emit
them as early as possible, so the vectorized nodes are inserted before
these nodes.

Fixes #139728

Reviewers: hiraditya, HanKuanChen, RKSimon

Reviewed By: RKSimon

Pull Request: https://github.com/llvm/llvm-project/pull/139917
2025-05-16 12:52:27 -04:00
Florian Hahn
04fde85057
[VPlan] Rename isUniform(AfterVectorization) to isSingleScalar (NFC). (#140134)
Update the naming in VPReplicateRecipe and vputils to the more accurate
isSingleScalar, as the functions check for cases where only a single
scalar is needed, either because it produces the same value for all
lanes or has only their first lane used.

Discussed in https://github.com/llvm/llvm-project/pull/139150.

PR: https://github.com/llvm/llvm-project/pull/140134
2025-05-16 16:38:39 +01:00
Elvis Wang
664c937b43
[VPlan] Implement VPExtendedReduction, VPMulAccumulateReductionRecipe and 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-05-16 10:25:38 +08:00
Florian Hahn
efae492ad1
[VPlan] Add VPTypeAnalysis constructor taking a VPlan (NFC).
Add constructor that retrieves the scalar type from the trip count
expression, if no canonical IV is available. Used in the verifier, in
preparation for late verification, when the canonical IV has been
dissolved.
2025-05-15 22:19:36 +01:00
Florian Hahn
6c405694d1
[VPlan] Get type from start value for VPWidenIntOrFpInduction (NFC).
NFC for now but this can cause verification failures in the future,
since after bf5627c85e697 wide induction may be narrowed. By using the
type from the start value, we will always return the correct type.
2025-05-15 21:31:04 +01:00
Florian Hahn
8bbe0d050a
[VPlan] Verify dominance for incoming values of phi-like recipes. (#124838)
Update the verifier to verify dominance for incoming values for phi-like
recipes. The defining recipe must dominate the incoming block for the
incoming value.

Builds on top of https://github.com/llvm/llvm-project/pull/138472 to
retrieve incoming values & corresponding blocks for phi-like recipes.

PR: https://github.com/llvm/llvm-project/pull/124838
2025-05-15 12:20:54 +01:00
Ramkumar Ramachandra
c807395011
[LAA/SLP] Don't truncate APInt in getPointersDiff (#139941)
Change getPointersDiff to return an std::optional<int64_t>, and fill
this value with using APInt::trySExtValue. This simple change requires
changes to other functions in LAA, and major changes in SLPVectorizer
changing types from 32-bit to 64-bit.

Fixes #139202.
2025-05-15 10:08:05 +01:00
George Chaltas
c4f7ab1d2e
[LV] Initialize IR block pointers in ILV. (NFC) (#139807)
Setting unitialized pointers to nullptr in InnerLoopVectorizer()
constructor. These were noticed during a review of the code. Seems like
a good idea to clean them up.
2025-05-15 09:18:45 +01:00
Kazu Hirata
690a30f3fd
[llvm] Construct SmallVector with ArrayRef (NFC) (#139992) 2025-05-14 22:30:38 -07:00
Min-Yih Hsu
0ab67ec191
[LV][EVL] Introduce the EVLIndVarSimplify Pass for EVL-vectorized loops (#131005)
When we enable EVL-based loop vectorization w/ predicated tail-folding,
each vectorized loop has effectively two induction variables: one
calculates the step using (VF x vscale) and the other one increases the
IV by values returned from experiment.get.vector.length. The former,
also known as canonical IV, is more favorable for analyses as it's
"countable" in the sense of SCEV; the latter (EVL-based IV), however, is
more favorable to codegen, at least for those that support scalable
vectors like AArch64 SVE and RISC-V.

The idea is that we use canonical IV all the way until the end of all
vectorizers, where we replace it with EVL-based IV using EVLIVSimplify
introduced here. Such that we can have the best from both worlds.

This Pass is enabled by default in RISC-V. However, since we haven't
really vectorize loops with predicate tail-folding by default, this Pass
is no-op at this moment.
2025-05-14 13:49:50 -07:00
Alexey Bataev
a05cf2927a [SLP][NFC]Use WeakTrackVH instead of Instruction in EntryToLastInstruction
Use WEakTrackVH to prevent instability in the vectorizer.

Fixes #139729
2025-05-14 11:19:54 -07:00
Graham Hunter
5b9246517f
[LV] Fix ScalarIVSteps vplan pattern matcher, remove m_CanonicalIV() (#138298)
783a846 changed VPScalarIVStepsRecipe to take 3 arguments (adding
VF explicitly) instead of 2, but didn't change the corresponding
pattern matcher.

This matcher was only used in vputils::isHeaderMask, and no test
ever reached that function with a ScalarIVSteps recipe for the
value being matched -- it was always a WideCanonicalIV. So the
matcher bailed out immediately before checking arguments and
asserting that the number of arguments in the recipe was the
same provided by the matcher.

Since the constructors for ScalarIVSteps take 3 values, we should
be safe to update the matcher and guard it with a dedicated gtest.

m_CanonicalIV() on the other hand is removed; as a phi recipe it
may not have a consistent number of arguments to match, only
requiring one (the start value) when being constructed with the
assumption that a second incoming value is added for the backedge
later. In order to keep the matcher we would need to add multiple
matchers with different numbers of arguments for it depending on
what phase of vplan construction we were in, and ensure that we
never reorder matcher usage vs. vplan transformation. Since the
main IR PatternMatch.h doesn't contain any matchers for PHI nodes,
I think we can just remove it and match via m_Specific() using the
VPValue we get from Plan.getCanonicalIV().
2025-05-14 15:01:03 +01:00
Florian Hahn
7a9fd62278
[VPlan] Use VPlan operand order for VPBlendRecipes. (#139475)
Don't use the order of incoming values of IR phis when creating 
VPBlendRecipes. Instead, simply use the incoming operands and
blocks from the VPWidenPHIRecipe.

Note that this changes the order of the incoming operands/masks for some
blends.

PR: https://github.com/llvm/llvm-project/pull/139475
2025-05-14 14:56:35 +01:00
Florian Hahn
98683b0a48
[VPlan] Construct VPBlendRecipe from VPWidenPHIRecipe (NFC).
Update VPRecipeBuilder to construct VPBlendRecipe from VPWidenPHIRecipe,
starting to thread recipes through the builder instead of the
underlying IR instruction up-front.

Landing first part of approved
https://github.com/llvm/llvm-project/pull/139475 separately as NFC as
suggested.
2025-05-14 11:17:26 +01:00
Florian Hahn
8767d55ff3
[VPlan] Consistently use VPlanTransforms::runPass if possible (NFC).
Update some more transforms to use ::runPass.
2025-05-13 20:50:27 +01:00
Florian Hahn
ba2dacd276
[VPlan] Print use and definition in verifier on violation.
Improves the error message when a use comes before the def by including
the use and def, when print utilities are available.
2025-05-13 09:52:02 +01:00
Florian Hahn
045fdda39d
[VPlan] Replace TTI::getOperandInfo with Ctx.getOperandInfo (NFC).
Update to use VPlan-based implementation of getOperandInfo, removing
uses of underlying IR references.
2025-05-12 22:44:54 +01:00
Alexey Bataev
e1ea86e849 [SLP]Do not try to use interleaved loads, if reordering is required
If the interleaved loads require reordering, better to avoid generate
load + shuffle sequence, which in this case cannot be recognized as
interleaved load. Also, it fixes the issue with the incorrect codegen.

Fixes #138923
2025-05-12 14:12:51 -07:00
Florian Hahn
fb017a52e7
[VPlan] Use load/store opcode for VPWiden(Load|Store)EVLRecipe (NFC).
Removes unnecessary uses of Ingredient.
2025-05-12 21:30:18 +01:00
Ramkumar Ramachandra
4f0be9414c
[LV] Improve code in selectInterleaveCount (NFC) (#128002)
Use the fact that getSmallBestKnownTC returns an exact trip count, if
possible, and falls back to returning an estimate, to factor some code
in selectInterleaveCount.
2025-05-12 17:20:10 +01:00
Han-Kuan Chen
53df6400af
[SLP] Fix incorrect operand order in interchangeable instruction. (#139225) 2025-05-12 20:03:45 +08:00
Florian Hahn
2f55123cbb
[VPlan] Handle early exit before forming regions. (NFC) (#138393)
Move early-exit handling up front to original VPlan construction, before
introducing early exits.

This builds on https://github.com/llvm/llvm-project/pull/137709, which
adds exiting edges to the original VPlan, instead of adding exit blocks
later.

This retains the exit conditions early, and means we can handle early
exits before forming regions, without the reliance on VPRecipeBuilder.

Once we retain all exits initially, handling early exits before region
construction ensures the regions are valid; otherwise we would leave
edges exiting the region from elsewhere than the latch.

Removing the reliance on VPRecipeBuilder removes the dependence on
mapping IR BBs to VPBBs and unblocks predication as VPlan transform:
https://github.com/llvm/llvm-project/pull/128420.

Depends on https://github.com/llvm/llvm-project/pull/137709 (included in
PR).

PR: https://github.com/llvm/llvm-project/pull/138393
2025-05-12 12:53:20 +01:00
Mel Chen
688bccb290
[TTI][LV] Simplify the prototype of preferPredicatedReductionSelect. nfc (#139265) 2025-05-12 17:24:37 +08:00