2874 Commits

Author SHA1 Message Date
Luke Lau
8cd86ff284
[VPlan] Propagate FastMathFlags from phis to blends (#180226)
If a phi has fast math flags, we can propagate it to the widened select.
To do this, this patch makes VPPhi and VPBlendRecipe subclasses of
VPRecipeWithIRFlags, and propagates it through PlainCFGBuilder and
VPPredicator.

Alive2 proofs for some of the FMFs (it looks like it can't reason about
the full "fast" set yet)
nnan: https://alive2.llvm.org/ce/z/f0bRd4
nsz: https://alive2.llvm.org/ce/z/u9P96T

The actual motivation for this to eventually be able to move the special
casing for tail folding in
LoopVectorizationPlanner::addReductionResultComputation into the CFG in
#176143, which requires passing through FMFs.
2026-02-09 19:38:58 +08:00
Florian Hahn
7509cad693
[VPlan] Support masked VPInsts, use for predication (NFC) (#142285)
Add support for mask operands to most VPInstructions, using
getNumOperandsForOpcode.

This allows VPlan predication to predicate VPInstructions directly. The
mask will then be dropped or handled when creating wide recipes.

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

PR: https://github.com/llvm/llvm-project/pull/142285
2026-02-08 18:23:36 +00:00
Florian Hahn
0c4f809493
[VPlan] Compute predicated load/store costs in VPlan. (NFC) (#179129)
Update VPReplicateReicpe::computeCost to compute predicated load/store
costs directly, unless the pointer is uniform. In that case, the legacy
cost model uses a different logic, which will be migrated separately.

PR: https://github.com/llvm/llvm-project/pull/179129
2026-02-07 20:02:54 +00:00
Florian Hahn
05a2b146fb
[LV] Optimize FindLast recurrences to FindIV (NFCI). (#177870)
This patch restructures Find(First|Last)IV handling. Instead of
differentiating between FindLast, FindFirstIV and FindLastIV up front,
this patch simplifies the logic in IVDescriptor to just identify the
FindLast pattern up-front.

It then adds a new VPlan transformation to optimize FindLast reductions
to FindIV reductions if there is a suitable sentinel value.
Find(Last|First)IV recurrence kinds to a single FindIV kind.

This is simpler and more accurate, given selecting the first/last
induction of the final IV reduction is directly controlled by the
corresponding recurrence kind of the ComputeReductionResult.

The new structure also allows further optimizations, like vectorizing
FindLastIV with another boolean reduction that tracks if the condition
in the loop was ever true, if there is no suitable sentinel value.

PR: https://github.com/llvm/llvm-project/pull/177870
2026-02-05 13:57:20 +00:00
Florian Hahn
8240cf337a
[VPlan] Always set flags for overflowing ops etc via VPIRFlags. (#179138)
Enforce that all VPInstructions set the correct OpType of the VPIRFlags.
Flag mis-matches (e.g. VPInstruction Add without `OverflowingBinOp`
being set) can cause crashes (e.g. in CSE) or potentially mis-compiles.

Add a few helpers in VPBuilder to create common instructions with
correct flags.

PR: https://github.com/llvm/llvm-project/pull/179138
2026-02-03 12:33:23 +00:00
Mel Chen
8c6658aca6
[VPlan] Sink recipes from the vector loop region in licm. (#168031)
When a recipe can be safely sunk and all of its users are outside the
vector loop region in the same dedicated exit block, the recipe does not
need to be executed on every iteration.
This patch extends the VPlan-based LICM (Loop Invariant Code Motion) to
also sink such recipes from the vector loop region into the exit block.
This reduces redundant computation and improves cost model accuracy.

TODO: Support nested loop sinking
TODO: Support sinking `VPReplicateRecipe` (requires `replicateByVF`
fixes)
TODO: Support recipes with multiple defined values (e.g., interleaved
loads)
TODO: Clone recipes without users to all exit blocks
TODO: Support PHI node users by checking incoming value blocks
TODO: Support sinking when users are in multiple blocks
TODO: Clone recipes when users are on multiple exit paths

Co-authored-by: Luke Lau <luke@igalia.com>

---------

Co-authored-by: Luke Lau <luke@igalia.com>
Co-authored-by: Luke Lau <luke_lau@icloud.com>
2026-02-03 07:57:15 +00:00
Luke Lau
bb14eabaca
[VPlan] Split out EVL exit cond transform from canonicalizeEVLLoops. NFC (#178181)
This is split out from #177114.

In order to make canonicalizeEVLLoops a generic "convert to variable
stepping" transform, move the code that changes the exit condition to a
separate transform since not all variable stepping loops will want to
transform the exit condition. Run it before canonicalizeEVLLoops before
VPEVLBasedIVPHIRecipe is expanded.

Also relax the assertion for VPInstruction::ExplicitVectorLength to just
bail instead, since eventually VPEVLBasedIVPHIRecipe will be used by
other loops that aren't EVL tail folded.
2026-02-02 04:45:43 +00:00
Florian Hahn
90b3712d8a
Reapply "[VPlan] Detect and create partial reductions in VPlan. (NFCI) (#167851)"
This reverts commit d1e477b00b49c63ff4dd513eeb14a5b18bc055d7.

Recommit with a extra checks making sure extends are VPWidenCastRecipes,
rejecting VPReplicateRecipes.

Original message:
As a first step, move the existing partial reduction detection logic to
VPlan, trying to preserve the existing code structure & behavior as
closely as possible.

With this, partial reductions are detected and created together in a
single step.

This allows forming partial reductions and bundling them up if
profitable together in a follow-up.

PR: https://github.com/llvm/llvm-project/pull/167851
2026-02-01 16:27:27 +00:00
Martin Storsjö
d1e477b00b Revert "[VPlan] Detect and create partial reductions in VPlan. (NFCI) (#167851)"
This reverts commit f4e8cc1a2229dca76d21c8d37439c4c194b06b86.

This change wasn't NFC; it causes failed asserts when building
ffmpeg for i686 windows, see
https://github.com/llvm/llvm-project/pull/167851 for details.
2026-02-01 14:35:02 +02:00
Florian Hahn
f4e8cc1a22
[VPlan] Detect and create partial reductions in VPlan. (NFCI) (#167851)
As a first step, move the existing partial reduction detection logic to
VPlan, trying to preserve the existing code structure & behavior as
closely as possible.

With this, partial reductions are detected and created together in a
single step.

This allows forming partial reductions and bundling them up if
profitable together in a follow-up.

PR: https://github.com/llvm/llvm-project/pull/167851
2026-01-31 19:44:46 +00:00
Andrei Elovikov
d8621d665d
Reapply "[VPlan] Add hidden -vplan-print-after-all option" (#178547)
Re-commit of https://github.com/llvm/llvm-project/pull/175839 after
fixing build without `LLVM_ENABLE_DUMP`.

This consists of the following changes:

* Merge several overloads of `VPlanTransforms::runPass` into a single
function to avoid code duplication.

* Add helper macro `RUN_VPLAN_PASS` to capture the transformation name
  and pass it to the helper above for printing.

* Add new `-vplan-print-after-all` option (somewhat similar to existing
  `-vplan-verify-each`).

* Add two empty passes `printAfterInitialConstruction`/`printFinalVPlan`
so that initial/final VPlans would be supported in `-vplan-print-after-all`

This follows the original future plans in
https://github.com/llvm/llvm-project/pull/123640.
2026-01-30 19:55:09 +00:00
Sander de Smalen
b4c7518a0f
[LV] Add support for extended fadd reductions (#178447)
This makes use of the llvm.vector.partial.reduce.fadd intrinsics added
in #163975 to handle the following with FDOT:
```
float32_t fdot(float16_t *src, int N) {
  float32_t sum = 0.0f;
  for (int i=0; i<N; ++i)
    sum += src[i];
  return sum;
}
```
2026-01-30 08:27:57 +00:00
Florian Hahn
eabcdb572b
Revert "[VPlan] Add hidden -vplan-print-after-all option (#175839)" (#178544)
This reverts commit 97e1df149de213b760aae4060ee9e25dc9908125.

It looks like the commit caused some build bot failures. Revert back to green
so the failures can be investigated.

https://lab.llvm.org/buildbot/#/builders/159/builds/39803
https://lab.llvm.org/buildbot/#/builders/2/builds/43204
2026-01-28 23:49:24 +00:00
Andrei Elovikov
97e1df149d
[VPlan] Add hidden -vplan-print-after-all option (#175839)
This consists of the following changes: 
        
* Merge several overloads of `VPlanTransforms::runPass` into a single
function
  to avoid code duplication.
  
* Add helper macro `RUN_VPLAN_PASS` to capture the transformation name
  and pass it to the helper above for printing.

* Add new `-vplan-print-after-all` option (somewhat similar to existing
  `-vplan-verify-each`).
  
* Add two empty passes `printAfterInitialConstruction`/`printFinalVPlan`
so that initial/final
   VPlans would be supported in `-vplan-print-after-all`

This follows the original future plans in
https://github.com/llvm/llvm-project/pull/123640.
2026-01-28 22:25:54 +00:00
Jakub Kuderski
55fbb71db1
[llvm] Fix new clang-tidy warning llvm-type-switch-case-types. NFC. (#178502)
Pre-commiting this before landing the new check in
https://github.com/llvm/llvm-project/pull/177892
2026-01-28 15:44:04 -05:00
Damian Heaton
762ba885f9
[LV] Add support for llvm.vector.partial.reduce.fadd (#163975)
Allows the Loop Vectorizer to generate `llvm.vector.partial.reduce.fadd`
intrinsics when sequences which match its requirements are found.
2026-01-28 15:05:34 +00:00
Florian Hahn
b794baf8e7
[TTI] Add VectorInstrContext for context-aware insert/extract costs. (#175982)
This commit introduces the VectorInstrContext (VIC) infrastructure to
improve cost estimates for insert/extracts based on the context
instruction in which the insert/extract is used.

This is similar to CastContextHint, and allows providing context on how
the insert/extract is going to be used before creating IR. This is
useful in the LoopVectorizer, where costs need to estimated before
creating IR.

The new hint currently only replaces an existing check in AArch64,
but new uses will be introduced in follow-ups, including
https://github.com/llvm/llvm-project/pull/177201.

PR: https://github.com/llvm/llvm-project/pull/175982
2026-01-27 16:30:29 +00:00
Florian Hahn
1251751c16
[VPlan] Consistently check ComputeReductionResult in prepareForEpi (NFCI)
Always use the information from ComputeReductionResult to identify
recurrence kinds when connecting main and epilogue plans. Connecting the
live-outs involves the reduction result computations, so it is natural
and more accurate to check the reduction result for the correct
structure.

Suggested cleanup from https://github.com/llvm/llvm-project/pull/170223
2026-01-26 20:51:20 +00:00
Florian Hahn
1650782144
[VPlan] Share and re-use logic to find FindIVResult (NFC).
Move logic to look for FindIVResult pattern out of LoopVectorize to
allow for re-use in current code and follow-up patches.
2026-01-24 20:55:41 +00:00
Florian Hahn
a871b707b7
Reapply "[VPlan] Move VDef subclass ID to VPRecipeBase (NFC). (#174282)"
Move SubclassID to VPRecipeBase, and store VPRecipeBase directly in
VPRecipeValue, instead of VPDef. This allows for some additional
simplifications and VPDef now just holds various helpers to deal with
removing and adding VPValues.

This reverts commit 16395da0ff577750571b99fe28281ce6fb6a3ae8.

PR: https://github.com/llvm/llvm-project/pull/174282
2026-01-24 13:22:48 +00:00
Florian Hahn
16395da0ff
Revert "[VPlan] Fold VPDef into VPRecipeBase (NFC). (#174282)"
This reverts commit f3ae334f4b7a8cf4fe0eb6ee7b2f2ef0879f522d.

Committed with out-of-date message, revert to reland with updated
message.
2026-01-24 13:16:45 +00:00
Florian Hahn
f3ae334f4b
[VPlan] Fold VPDef into VPRecipeBase (NFC). (#174282)
A separate VDef is not needed any longer, fold i into VPRecipeBase to
simplify code and class hierarchy.

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

PR: https://github.com/llvm/llvm-project/pull/174282
2026-01-24 13:16:12 +00:00
Mel Chen
149c76538e
[LV] Separate runtime check cost from total overhead in profitability check (#176754)
In isOutsideLoopWorkProfitable function, there are two places where only
the runtime check cost (RtC) should be used, but incorrectly included
the costs of middle blocks and early-exit blocks.
1. VectorizeMemoryCheckThreshold comparison for interleaving-only
2. Minimum trip count that bounds runtime check overhead, i.e. MinTC2
calculation
This results in an overly conservative minimum profitable trip count.

This patch separates the runtime check cost from the total overhead
cost, and uses only RtC for VectorizeMemoryCheckThreshold comparison and
the MinTC2 calculation.
2026-01-23 07:29:56 +00:00
Florian Hahn
8a954feb3e
[LV] Replace legacy FindLast check with VPlan-based one (NFCI).
Checking directly in VPlan is more accurate, as the reductions could
have been transformed. This does not happen yet, so currently NFC.
2026-01-22 23:23:02 +00:00
Florian Hahn
7ea1fa591a
[LV] Skip FindLast reductions in collectInLoopReductions.
FindLast in-loop reductions are not supported, similarly to FindLastIV
reductions. Skip them in collectInLoopReductions, to avoid a crash for
loops with FindLast reductions and in-loop reductions preferred.
2026-01-22 21:49:52 +00:00
Florian Hahn
14a209f852
[VPlan] Replace ComputeFindIVRes with ComputeRdxRes + cmp + sel (NFC) (#176672)
Replace ComputeFindIVResult with ComputeReductionResult + explicit
compare + select, to more explicitly and simpler model computing finding
the first/last induction, which boils down to a min/max reduction +
compare and select of the sentinel value.

PR: https://github.com/llvm/llvm-project/pull/176672
2026-01-22 19:28:47 +00:00
Florian Hahn
d2c40c358a
[LV] Check if VPlan contains FindLast reduction directly (NFC).
Directly check the VPlan to see if there are any FindLast reductions.
Currently this is NFC, but checking in the VPlan is more future proof,
e.g. if reductions are simplified, removed or transformed. Then checking
in legacy LoopVectorizationLegality is inaccruate.
2026-01-20 21:33:47 +00:00
Florian Hahn
d3f2f1366d
[LV] Consider UserIC when limiting VF. (#174573)
If a UserIC is provided, the vector loop will process VF * UserIC. Pass
it through UserIC to computeFeasibleMaxVF and use it to limit the max VF
to factors where VF * UserIC <= MaxTripCount. This avoids creating dead
vector loops with user provided interleave counts.

PR: https://github.com/llvm/llvm-project/pull/174573
2026-01-20 14:19:11 +00:00
Ramkumar Ramachandra
302565b39e
[VPlan] Move VPDerivedIVRecipe::execute to VPlanRecipes (NFC) (#176577) 2026-01-19 13:06:37 +00:00
Florian Hahn
5e5d6389f6
[LV] Allow loops with multiple early exits in legality checks. (#176403)
This patch removes the single uncountable exit constraint, allowing
loops with multiple early exits, if the exits form a dominance chain and
all other constraints hold for all uncountable early exits.

While legality now accepts such loops, vectorization is not yet
supported. VPlan support will be added in a follow up:
https://github.com/llvm/llvm-project/pull/174864

PR: https://github.com/llvm/llvm-project/pull/176403
2026-01-19 12:32:04 +00:00
Florian Hahn
ae1bd068db
[VPlan] Replace PhiR operand of ComputeAnyOfResult with VPIRFlags. (#175657)
Replace the Phi recipe operand of ComputeAnyOfVResult with VPIRFlags,
building on top of https://github.com/llvm/llvm-project/pull/174026.

PR: https://github.com/llvm/llvm-project/pull/175657
2026-01-18 20:29:38 +00:00
Florian Hahn
497a6d6722
Recommit "[VPlan] Only use isAddressSCEVForCost in legacy getAddressAccSCEV"
This reverts commit ed004cf42bf57ca79b57bc3076ef83a8477426ea.

The original commit exposed an independent cost issue, triggering an
assertion. That issue has been fixed in 3457e7efc3.

Reland the patch now that the assertion has been fixed.
2026-01-18 19:55:46 +00:00
Florian Hahn
459990dcf7
[VPlan] Replace PhiR operand of ComputeFindIVResult with VPIRFlags. #174026 (#175461)
Replace the Phi recipe operand of ComputeFindIVResult with VPIRFlags,
building on top of https://github.com/llvm/llvm-project/pull/174026.

PR: https://github.com/llvm/llvm-project/pull/175461
2026-01-17 16:23:33 +00:00
Florian Hahn
d528686f43
[VPlan] Add VPConstantInt for VPIRValues wrapping ConstantInts (NFC) (#175458)
Follow-up to https://github.com/llvm/llvm-project/pull/174282: Introduce
a new VPConstantInt overlay for VPIRValue, to make it easier to check
and access constant int IR values.

PR: https://github.com/llvm/llvm-project/pull/175458
2026-01-16 11:27:07 +00:00
Graham Hunter
2abd6d6d7a
[LV] Vectorize conditional scalar assignments (#158088)
Based on Michael Maitland's previous work:
https://github.com/llvm/llvm-project/pull/121222

This PR uses the existing recurrences code instead of introducing a
new pass just for CSA autovec. I've also made recipes that are more
generic.
2026-01-14 14:59:18 +00:00
Florian Hahn
d5c11b9a24
[VPlan] Replace PhiR operand of ComputeRdxResult with VPIRFlags. (#174026)
Remove the artificial PhiR operand of ComputeReductionResult, which was
only used to look up recurrence kind, in-loop and ordered properties.

Instead, encode them as VPIRFlags as suggested by @ayalz in
https://github.com/llvm/llvm-project/pull/170223.

This addresses a TODO to make codegen for ComputeReductionResult
independent of looking up information from other recipes.

This is NFC w.r.t. codegen, the printing has been improved to include
the reduction type, and whether it is in-loop/ordered.

PR: https://github.com/llvm/llvm-project/pull/174026
2026-01-14 07:45:44 +00:00
David Sherwood
48ce7bb038
[LV] Fix bug in setVectorizedCallDecision (#175742)
There is a bug in this logic:

```
   InstructionCost Cost = ScalarCost;
   InstWidening Decision = CM_Scalarize;

   if (VectorCost <= Cost) {
     Cost = VectorCost;
     Decision = CM_VectorCall;
   }

   if (IntrinsicCost <= Cost) {
     Cost = IntrinsicCost;
     Decision = CM_IntrinsicCall;
   }
```

because it assumes that the comparisons behave sensibly in the face of
invalid costs. Unfortunately, PR #174835 exposes an issue when
attempting to vectorise the new test
uadd_with_overflow_i32 for AArch64 targets. Specifically, there are
situations where all costs are invalid (e.g. VF=vscale x 1), but some
costs are more invalid than others. For example, when querying the
intrinsic cost via the TTI hook we get an invalid cost with a non-zero
value, whereas the vector cost is invalid with a zero value. That leads
to us erroneously choosing CM_VectorCall as the call widening decision,
despite the lack of a vector math variant. Inevitably this causes
crashes because we create a VPCallWidenRecipe without a variant
function.

Fix this by only performing comparisons if the costs are valid. It now
leads to us choosing CM_Scalarize more often, but it's a toin coss
anyway between CM_Scalarize and CM_IntrinsicCall when both strategies
are invalid. Potentially we could also create a new strategy called
CM_Invalid, and avoid the creation of VPlans entirely.
2026-01-14 07:28:38 +00:00
Luke Lau
0ae23ca9e6
[VPlan] Split out optimizeEVLMasks. NFC (#174925)
Addresses part of #153144 and splits off part of #166164

There are two parts to the EVL transform:

1) Convert the loop so the number of elements processed each iteration
is EVL, not VF. The IV and header mask are replaced with EVL-based
variants.
2) Optimize users of the EVL based header mask to VP intrinsic based
recipes.

(1) changes the semantics of the vector loop region, whereas (2) needs
to preserve them. This splits (2) out so we don't mix the two up, and
allows us to move (1) earlier in the pipeline in a future PR.
2026-01-14 07:01:14 +00:00
Florian Hahn
d27d75ee94
[VPlan] Use createHeaderPHIRecipes in native path (NFCI).
Simplify tryToBuildVPlan by using createHeaderPHIRecipes in the native
path as well.
2026-01-13 20:12:21 +00:00
Florian Hahn
d620ea7657
[LV] Handle live-ins in findRecipe.
Skip live-ins in findRecipe to prevent a crash for cases with degenerate
reductions (where the backedge value is a live-in). Such reductions
should be removed, but this requires further changes.

Fixes https://github.com/llvm/llvm-project/issues/175229.
2026-01-11 11:19:30 +00:00
Hans Wennborg
ed004cf42b Revert "[VPlan] Only use isAddressSCEVForCost in legacy getAddressAccSCEV (NFCI)"
This caused assertion failures:

  llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:7265:
  VectorizationFactor llvm::LoopVectorizationPlanner::computeBestVF():
  Assertion `(BestFactor.Width == LegacyVF.Width || BestPlan.hasEarlyExit() || !Legal->getLAI()->getSymbolicStrides().empty() || UsesEVLGatherScatter || planContainsAdditionalSimplifications( getPlanFor(BestFactor.Width), CostCtx, OrigLoop, BestFactor.Width) || planContainsAdditionalSimplifications( getPlanFor(LegacyVF.Width), CostCtx, OrigLoop, LegacyVF.Width))
  && " VPlan cost model and legacy cost model disagreed"' failed.

see comment on https://github.com/llvm/llvm-project/pull/171204

This reverts commit 01d34eb38fa0587cb95eedd3bada8257abc122f8.
2026-01-09 15:38:32 +01:00
Florian Hahn
4998280c3f
[LV] Find reduction result VPInstruction from backedge value (NFC).
Split off from https://github.com/llvm/llvm-project/pull/174026. Make
the lookup of the reduction phi recipe/compute-reduction-result
VPInstruction independent of the latter having the reduction phi as
operand.
2026-01-07 21:12:07 +00:00
Florian Hahn
31b93d6e38
[VPlan] Add specialized VPValue subclasses for different types (NFC) (#172758)
This patch adds VPValue sub-classes for the different cases we currently
have:
 * VPIRValue: A live-in VPValue that wraps an underlying IR value
* VPSymbolicValue: A symbolic VPValue not tied to an underlying value,
e.g. the vector trip count or VF VPValues
 * VPRecipeValue: A VPValue defined by a VPDef/VPRecipeBase.

This has multiple benefits:
 * clearer constructors for each kind of VPValue
* limited scope: for example allows moving VPDef member to VPRecipeValue,
reducing size of other VPValues.
* stricter type checking for member variables (e.g. using VPLiveIn in
the Value -> live-in map in VPlan, or using VPSymbolicValue for symbolic
member VPValues)

There probably are additional opportunities for cleanups as follow-ups.

PR: https://github.com/llvm/llvm-project/pull/172758
2026-01-07 20:29:05 +00:00
Shih-Po Hung
39d6f10e33
[LV] Conservatively predicate SDiv/SRem (#170818)
Conservatively predicate sdiv/srem:
- RHS may carry poison in masked‑off lanes.
- RHS could be −1 while LHS has masked‑off lanes (risking INT_MIN/−1
overflow).

We’ll relax this once we can prove non‑wrap/non‑poison conditions.

Fixes #170775.
2026-01-07 04:25:38 +00:00
Florian Hahn
01d34eb38f
[VPlan] Only use isAddressSCEVForCost in legacy getAddressAccSCEV (NFCI)
Follow-up to https://github.com/llvm/llvm-project/pull/171204 and
1f331e453f to only rely on isAddressSCEVForCost in legacy isAddressSCEVForCost,
completely aligning the decisions of VPlan and legacy cost model.
2026-01-06 19:18:13 +00:00
Florian Hahn
16830b2164
[VPlan] Remove VPWidenSelectRecipe, use VPWidenRecipe instead (NFCI). (#174234)
All extra state has been removed from VPWidenSelectRecipe at this point.
There's no benefit of having a separate recipe and Select can easily be
handled by the existing VPWidenRecipe.

PR: https://github.com/llvm/llvm-project/pull/174234
2026-01-05 22:33:37 +00:00
Florian Hahn
990883a690
[VPlan] Handle Alloca in VPReplicateRecipe::computeCost. (NFCI)
Handle Alloca in the VPlan-based cost mode. This also updates the cost
in the legacy cost model to clarify that we always compute the scalar
cost.
2026-01-03 17:40:51 +00:00
Florian Hahn
2d60f87111
[VPlan] Only use legacy cost for instructions only used by exit conds. (#174029)
Currently we need to precompute costs for exit conditions, to match the
legacy cost, as they will get replaced by a compare against the
canonical IV (or others, like active-lane-mask or EVL based) and the
original compare will get removed.

This is not true for instructions with users other than the exit
condition. Those will remain, and we can just use the VPlan-based cost
model to get more accurate results.

This improves results in some cases, like
@test_value_in_exit_compare_chain_used_outside because the IV increment
user outside the loop is replaced by computing the final value outside
the loop.

It also fixes a crash introduced by f196b1d66ff (#146525).

PR: https://github.com/llvm/llvm-project/pull/174029
2025-12-31 13:34:54 +00:00
Florian Hahn
524b1788c4
[VPlan] Add BranchOnTwoConds, use for early exit plans. (#172750)
This PR introduces a new BranchOnTwoConds VPInstruction, that takes 2
boolean operands and must be placed in a block with 3 successors.

If condition I is true, branches to successor I, otherwise falls through
to check the next condition. If both conditions are false, branch to the
third successor.

This new branch recipe is used for early-exit loops, to simplify the
representation in VPlan initially, by avoid the need for splitting the
middle block early on, in a way that preserves the single-exit block
property of regions. All exits still go through the latch block, but
they can go to more than 2 successors.

This idea was part of one of the original proposals for how to model
early exits in VPlan, but at that point in time, there was no good way
to handle this during code-gen, and we went with the early split-middle
block approach initially.

Now that we dissolve regions before ::execute, the new recipe can be
lowered nicely after regions have been removed, to a set of VPBBs and
BranchOnCond recipes. The initial lowering preserves the original
structure with the split middle blocks. Follow-ups will improve the
lowering to avoid this splitting, providing performance gains.

PR: https://github.com/llvm/llvm-project/pull/172750
2025-12-29 19:39:38 +00:00
Florian Hahn
d777b1a230
[VPlan] Skip phi recipes in tryToBuildVPlan (NFC).
No phi recipes are being transformed in the main loop any longer, so
skip phi recipes.

This also allows to clarify which recipes need skipping explicitly.
Those are recipes that have been already transformed.

Follow-up to post-commit comment in
https://github.com/llvm/llvm-project/pull/168291.
2025-12-27 17:02:48 +00:00