3089 Commits

Author SHA1 Message Date
Philip Reames
a21fb74c0c
[RISCV][TTI] Implement getPartialReductionCost for the vqdotq cases (#140974)
Doing so tells the loop vectorizer that the partial.reduce intrinsic is
profitable to use over the plain extend/multiply/reduce.add sequence.
2025-05-23 07:15:06 -07: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
Mohammad Bashir
bcdce987c0
Fix regression tests with bad FileCheck checks (#140373)
Fixes https://github.com/llvm/llvm-project/issues/140149
2025-05-22 07:59:57 +03:00
Philip Reames
c21416d1f9 [RISCV][TTI] Add test coverage for getPartialReductionCost [nfc]
Adding testing in advance of a change to cost the zvqdotq instructions
such that we emit them from LV.
2025-05-21 15:12:23 -07: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
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
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
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
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
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
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
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
5fa64d65e9
[VPlan] Use printPhiOperands for VPPhi.
Split off from  https://github.com/llvm/llvm-project/pull/139151 to land
printing improvements separately.

Updates printing of VPPhi operands to be consistent with
VPWidenPHIRecipe.
2025-05-10 12:49:29 +01:00
Florian Hahn
8c6c525a6b
[LV] Don't consider FORs as profitable to scalarize.
Fixed-order recurrence phis cannot be scalarized, they will always be
widened at the moment. Make sure they are not incorrectly considered
profitable to scalarize, similar to 41c1a7be3f1a2556e.

Fixes https://github.com/llvm/llvm-project/issues/139060.
Fixes https://github.com/llvm/llvm-project/issues/139065.
2025-05-09 20:29:22 +01:00
Ramkumar Ramachandra
f058333941
[LV] Regen a test with UTC (#139235) 2025-05-09 14:26:20 +01:00
Florian Hahn
e854c381c6
[VPlan] Manage noalias/alias_scope metadata in VPlan. (#136450)
Use VPIRMetadata added in
https://github.com/llvm/llvm-project/pull/135272
to also manage no-alias metadata added by versioning.

Note that this means we have to build the no-alias metadata up-front
once. If it is not used, it will be discarded automatically.

This also fixes a case where incorrect metadata was added to wide
loads/stores that got converted from an interleave group.

Compile-time impact is neutral:

https://llvm-compile-time-tracker.com/compare.php?from=38bf1af41c5425a552a53feb13c71d82873f1c18&to=2fd7844cfdf5ec0f1c2ce0b9b3ae0763245b6922&stat=instructions:u
2025-05-09 11:19:12 +01:00
Florian Hahn
d06d43a9e8
[VPlan] Add printPhiOperands to VPPhiAccessors, use for wide phis.
(NFC modulo debug output changes)

Add generic helper to print phi operands (incoming values) together with
their incoming blocks.

As more and more transforms are added, keeping the incoming blocks of
phis becomes more important. Print incoming blocks via VPPhiAcessors, to
make debugging easier.
2025-05-08 20:56:48 +01:00
Florian Hahn
339dc9500b
[VPlan] Retain exit conditions and edges in initial VPlan (NFC). (#137709)
Update initial VPlan construction to include exit conditions and edges.

The loop region is now first constructed without entry/exiting. Those
are set after inserting the region in the CFG, to preserve the original
predecessor/successor order of blocks.

For now, all early exits are disconnected before forming the regions,
but a follow-up will update uncountable exit handling to also happen
here. This is required to enable VPlan predication and remove the
dependence any IR BBs
(https://github.com/llvm/llvm-project/pull/128420).

PR: https://github.com/llvm/llvm-project/pull/137709
2025-05-08 18:10:52 +01:00
Ramkumar Ramachandra
c4f723a7c3
[LV] Strip unmaintainable MinBWs assert (#136858)
tryToWiden attempts to replace an Instruction with a Constant from SCEV,
but forgets to erase the Instruction from the MinBWs map, leading to an
assert in VPlanTransforms::truncateToMinimalBitwidths. Going forward,
the assertion in truncateToMinimalBitwidths is unmaintainable, as LV
could simplify the expression at any point: fix the bug by stripping the
unmaintable assertion.

Fixes #125278.
2025-05-08 11:49:54 +01:00
Luke Lau
1484f82cbc
[VPlan] Add VPInstruction::StepVector and use it in VPWidenIntOrFpInductionRecipe (#129508)
Split off from #118638, this adds VPInstruction::StepVector, which
generates integer step vectors (0,1,2,...,VF). This is a step towards
eventually modelling all the separate parts of
VPWidenIntOrFpInductionRecipe in VPlan.

This is then used by VPWidenIntOrFpInductionRecipe, where we materialize
it just before unrolling so the operands stay in a fixed position.

The need for a separate operand in VPWidenIntOrFpInductionRecipe, as
well as the need to update it in
optimizeVectorInductionWidthForTCAndVFUF, should be removed with #118638
when everything is expanded in convertToConcreteRecipes.
2025-05-08 18:47:44 +08:00
Florian Hahn
127f48668b
[LV] Add test showing incorrect metadata merging when narrowing IGs.
Add test showing that incorrect tbaa metadata is added to the widened
loads and stores when narrowing interleave groups.

The widened loads/stores currently have the TBAA metadata of the first
load/store, even though the wide accesses also access data with types of
the second load/store.
2025-05-08 11:13:25 +01:00
Paul Walker
01813e8929
[LLVM][VecLib] Refactor LIBMVEC integration to be target neutral. (#138262)
Renames LIBMVEC-X86 to LIBMVEC and updates TLI to only add the existing
x86 specific mapping when targeting x86.
2025-05-07 11:05:25 +01:00
Min-Yih Hsu
e0537c0768
[LV][EVL] Attach a new metadata on EVL vectorized loops (#131000)
This patch attaches a new metadata, `llvm.loop.isvectorized.withevl`, on
loops vectorized with explicit vector length. This will help other
optimizations down in the pipeline that focus on EVL-vectorized loop

This approach is much safer than, said IR pattern matching to figure out
if a loop is EVL-vectorized or not.
2025-05-06 10:06:37 -07:00
Maryam Moghadas
a750893fea
[VPlan][LV] Fix invalid truncation in VPScalarIVStepsRecipe (#137832)
Replace CreateTrunc with CreateSExtOrTrunc in VPScalarIVStepsRecipe to
safely handle type conversion. This prevents assertion failures from
invalid truncation when StartIdx0 has a smaller integer type than
IntStepTy. The assertion was introduced by commit 783a846.
Fixes https://github.com/llvm/llvm-project/issues/137185
2025-05-06 12:48:21 -04:00
Florian Hahn
9a26b2903b
[VPlan] Don't rely on region check in isUniformAfterVectorization. (#137883)
Generalize isUniformAfterVectorization check to not rely on the region,
but purely work on checking operands and opcodes.

This will be needed when disolving the vector region
(https://github.com/llvm/llvm-project/pull/117506) and improves codegen
slightly in some cases.

PR: https://github.com/llvm/llvm-project/pull/137883
2025-05-02 15:42:21 +01:00
Sam Tebbs
2876dbcd66
[AArch64] Don't allow mixed partial reductions without i8mm (#137602)
Partial reductions with mixed extends should only be allowed if i8mm is
present.
2025-05-01 16:06:37 +01:00
Samuel Tebbs
fa769655e7 [LV] NFC: Make VPPartialReductionRecipe a VPReductionRecipe 2025-04-30 19:44:40 +01:00
Luke Lau
2cd829fc2c
[VectorUtils][VPlan] Consolidate VPWidenIntrinsicRecipe::onlyFirstLaneUsed and isVectorIntrinsicWithScalarOpAtArg (#137497)
We can reuse isVectorIntrinsicWithScalarOpAtArg in VectorUtils to
determine if only the first lane will be used for a
VPWidenIntrinsicRecipe, provided that we also move the VP EVL operand
check into it.

This was needed by a local patch I was working on that created a
VPWidenIntrinsicRecipe with a VP intrinsic, and prevents the need to
update the scalar arguments in two places.
2025-05-01 01:25:41 +08:00
Florian Hahn
7e71466900
[VPlan] Preserve dbg location on canonical IVs in native path.
Pass the debug location of the primary IV to addCanonicalIVRecipes in
the native path, matching the behavior of inner loop vectorization.
2025-04-29 21:40:42 +01:00
Ramkumar Ramachandra
49842426f3
[LV] Fix MinBWs in WidenIntrinsic case (#137005)
There is a bug in the computation and handling of MinBWs in the case of
VPWidenIntrinsicRecipe: a crash is observed in
VPlanTransforms::truncateToMinimalBitwidths due to a mismatch between
the number of recipes processed and the number of entries in MinBWs. Fix
handling of calls in llvm::computeMinimumValueSizes, and handle
VPWidenIntrinsicRecipe in truncateToMinimalBitwidths, fixing the bug.

Fixes #87407.
2025-04-29 09:47:38 +01:00
Elvis Wang
1fc0a1401a
[LV][AArch64] Add test for fp128 fmuladd reduction.(NFC) (#137576)
This patch add the test for the fmuladd reduction to show the test
change/fail for the cost model change.

Note that without the fp128 load and trunc, there is no failure.

Pre-commit test for #113903.
2025-04-29 09:18:07 +08:00
Florian Hahn
043b04acff
Reapply "[VPlan] Fold NOT into predicate of wide compares." (#130347)
This reverts commit 8dd160f4767f971572eac065c8650d9202ff5bf9.

The recommit contains an adjustment to planContainsAdditionalSimplifications,
which considers changes to the original predicate for compares.

Original commit message:

Add simplification to fold negation into a compare, if the negation is
the only user of the compare. This removes a number of redundant
negations.

Alive2 Proofs for FPCMP test changes:  https://alive2.llvm.org/ce/z/WGDz9U

PR: https://github.com/llvm/llvm-project/pull/129430
2025-04-28 20:01:37 +01:00
Florian Hahn
ec1016f7ef
[IVDescriptors] Support reductions with minimumnum/maximumnum. (#137335)
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-04-28 11:16:36 +01:00
Florian Hahn
92bfbbc4e5
[VPlan] Invert condition if needed when creating inner regions. (#132292)
As pointed out by @iamlouk in
https://github.com/llvm/llvm-project/pull/129402, the current code
doesn't handle latches with different successor orders correctly.
Introduce a `NOT`, if needed.

Depends on  https://github.com/llvm/llvm-project/pull/129402

PR: https://github.com/llvm/llvm-project/pull/132292
2025-04-28 09:40:43 +01:00
YunQiang Su
e9a34e4236
[RISCV] Support vectorizing FMINIMUMNUM and FMAXIMUMNUM (#135727)
RISC-V V extension support vfmax and vfmin, which follow IEEE754-2019.
We can use them directly.
2025-04-27 19:10:02 +08:00
Florian Hahn
df21288247
[VPlan] Replace ExtractFromEnd with Extract(Last|Penultimate)Element (NFC). (#137030)
ExtractFromEnd only has 2 uses, extracting the last and penultimate
elements. Replace it with 2 separate opcodes, removing the need to
materialize and handle a constant argument.

PR: https://github.com/llvm/llvm-project/pull/137030
2025-04-25 16:27:29 +01:00
Florian Hahn
c39cc9f48f
[LV] Add tests for maximumnum/minimumnum reductions.
Add reduction tests with maximumnum/minimumnum intrinsics.
2025-04-25 15:07:22 +01:00
Ramkumar Ramachandra
4955c3c476
[LV] Strip bad FIXME in test (#137142)
See https://github.com/llvm/llvm-project/pull/130118/files#r1983745712
for context.
2025-04-25 09:47:47 +01:00
Florian Hahn
15bb1db4a9
[VPlan] Remove ILV::sinkScalarOperands. (#136023)
Remove legacy ILV sinkScalarOperands, which is superseded by the
sinkScalarOperands VPlan transforms.

There are a few cases that aren't handled by VPlan's sinkScalarOperands,
because the recipes doesn't support replicating. Those are pointer
inductions and blends.

We could probably improve this further, by allowing replication for more
recipes, but I don't think the extra complexity is warranted.

Depends on https://github.com/llvm/llvm-project/pull/136021.

PR: https://github.com/llvm/llvm-project/pull/136023
2025-04-24 08:37:49 +01:00
Ramkumar Ramachandra
bdf21ca8ac
[LV] Fix missing entry in willGenerateVectors (#136712)
willGenerateVectors switches on opcodes of a recipe, but Histogram is
missing in the switch statement, which could cause a crash in some
cases. The crash was initially observed when developing another patch.
2025-04-23 19:06:38 +01:00
Nicholas Guy
1ce709cb84
[LV] Fix crash when building partial reductions using types that aren't known scale factors (#136680) 2025-04-23 13:19:18 +01:00
David Sherwood
ef72b93626
[LV] Use requested calling convention for vector math routines (#136122)
Some vector math routines, e.g. ArmPL, specify a particular
calling convention on the routines which can help improve
performance by specifying what registers have to be preserved
across the call.
2025-04-22 09:33:52 +01:00
Florian Hahn
5739a22fbb
[VPlan] Also duplicated scalar-steps when it enables sinking scalars. (#136021)
Extend sinking logic to duplicate scalar steps recipe if it enables
sinking, that is if all users in a destination block require all lanes.

This should be the last step before removing legacy sinkScalarOperands.

PR: https://github.com/llvm/llvm-project/pull/136021
2025-04-21 18:36:43 +01:00
Florian Hahn
e232d28eff
[VPlan] Move plain CFG construction to VPlanConstruction. (NFC)
Follow-up as discussed in https://github.com/llvm/llvm-project/pull/129402.

After bc03d6cce257, the VPlanHCFGBuilder doesn't actually build a HCFG
any longer. Move what remains directly into VPlanConstruction.cpp.
2025-04-18 21:52:05 +01:00
Luke Lau
41675fa5b8
[VPlan] Simplify vp.merge true, (or x, y), x -> vp.merge y, true, x (#135017)
With EVL tail folding an AnyOf reduction will emit an i1 vp.merge like

vp.merge true, (or phi, cond), phi, evl

We can remove the or and optimise this to

vp.merge cond, true, phi, evl

Which makes it slightly easier to pattern match in #134898.

This also adds a pattern matcher for calls to help match this.

Blended AnyOf reductions will use an and instead of an or, which we may
also be able to simplify in a later patch.
2025-04-17 16:31:14 +02:00
David Sherwood
927a0cb8d6
[LV][NFC] Regenerate AArch64/veclib-* test CHECK lines (#136138) 2025-04-17 15:07:33 +01:00
Sander de Smalen
f9c01b59e3
[LV] Fix '-1U' bits for smallest type in getSmallestAndWidestTypes (#135783)
For loops without loads/stores, where the smallest/widest types are
calculated from the reduction, the smallest type returned is always -1U
and it actually returns the smallest type as the widest type. This PR
fixes the calculation.

This follows from
https://github.com/llvm/llvm-project/pull/132190#discussion_r2044232607
2025-04-17 13:26:15 +01:00
John Brawn
eafbb879f6
[LoopVectorize] Don't replicate blocks with optsize (#129265)
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-17 11:50:49 +01:00
Florian Hahn
41c1a7be3f
[LV] Don't add fixed-order recurrence phis to forced scalars.
Fixed-order recurrence phis cannot be forced to be scalar, they will
always be widened at the moment.

Make sure we don't add them to ForcedScalars, otherwise the legacy cost
model will compute incorrect costs.

This fixes an assertion reported with
https://github.com/llvm/llvm-project/pull/129645.
2025-04-16 22:58:10 +02:00
Florian Hahn
bc03d6cce2
[VPlan] Introduce all loop regions as VPlan transform. (NFC) (#129402)
Further simplify VPlan CFG builder by moving introduction of inner
regions to a VPlan transform, building on
https://github.com/llvm/llvm-project/pull/128419.

The HCFG builder now only constructs plain CFGs. I will move it to
VPlanConstruction as follow-up.

Depends on https://github.com/llvm/llvm-project/pull/128419.

PR: https://github.com/llvm/llvm-project/pull/129402
2025-04-16 13:30:45 +02:00