7352 Commits

Author SHA1 Message Date
Alexey Bataev
88f830aed8 [SLP]Do not try to reduced instruction, marked for deletion in previous attempts
Need to skip instructions, which were vectorized and marked for deletion
to prevent a compiler crash
2026-03-22 10:10:48 -07:00
Florian Hahn
d3c7f23d2f
[VPlan] Remove unused VPlan friend declaration from VPValue (NFC)
VPlan only accesses VPValue through public APIs (getUnderlyingValue(),
etc.), so the friend declaration is unnecessary.
2026-03-21 20:37:05 +00:00
Alexey Bataev
616240369e [SLP]Do not consider copyable node with SplitVectorize parent
If the copyables are schedulable and the parent node is plit vectorize,
need to skip the scheduling analysis for such nodes to avoid a compiler
crash
2026-03-21 06:56:59 -07:00
Alexey Bataev
db143fb2b9 [SLP][NFC]Use block number instead of pointer for stable sorting, NFC 2026-03-21 04:30:32 -07:00
vporpo
720615f495
[SandboxVec][DAG] Fix DAG update when user is scheduled (#187148)
This patch fixes the update of the DAGNode UnscheduledSucc counter when
a use edge is modified. This is the result of a setOperand() or a RAUW
(and friends) operation.

Before this patch we would not check if the User (i.e., the consumer of
the use-def edge) is scheduled and we would update the definition's
UnscheduledSucc counter, resulting in counting errors.

For example, consider the following IR:
```
  %A = ...
  %B = ...
  %U = %A  ; scheduled
```
Note that %U's DAGNode is marked as "scheduled" while %A and %B are not.

If we change %U's operand from %A to %B then we should not attempt to
update %A's or %B's UnscheduledSuccs because %U is scheduled so it
should not get counted as an "unscheduled" successor.
2026-03-20 15:43:27 -07:00
Alexey Bataev
b260861b38 [SLP]Update values after ordered vectorization
Need to update matching between the original reduced values and their
vectorized matches after ordered reduction vectorization to avoid
a compiler crash
2026-03-20 13:33:40 -07:00
Alexey Bataev
94e366ef20
[SLP] Initial support for ordered reductions
Patch models ordered reductions as a series of extractelements for the
cases which cannot be modeled as unordered reductions.

Fixes #50590

Reviewers: RKSimon, hiraditya

Pull Request: https://github.com/llvm/llvm-project/pull/182644
2026-03-20 13:45:14 -04:00
Alexey Bataev
2bb0fa46a8
[SLP]Prefer copyable over alternate
If the instructions state is alternate and/or contains non-directly
matching instructions, need to check if it is better to represent such
operations as non-alternate with copyables.
To do this, we need to compare operands between the instructions in their
different representations and choose the best one for optimal
vectorization.

Reviewers: RKSimon, hiraditya

Pull Request: https://github.com/llvm/llvm-project/pull/183777
2026-03-20 11:59:59 -04:00
Florian Hahn
19b0c68ee0
[VPlan] Skip epilogue vectorization if dead after narrowing IGs. (#187016)
When narrowing interleave groups, the main vector loop processes IC
iterations instead of VF * IC. Update selectEpilogueVectorizationFactor
to use the effective VF, checking if the canonical IV controlling the
loop now steps by UF instead of VFxUF.

This avoids epilogue vectorization with dead epilogue vector loops and
also prevents crashes in cases where we can prove both the epilogue and
scalar loop are dead.

Fixes https://github.com/llvm/llvm-project/issues/186846

PR: https://github.com/llvm/llvm-project/pull/187016
2026-03-20 12:33:16 +00:00
Ramkumar Ramachandra
1dfd268f10
[VPlan] Simplify mul x, -1 -> sub 0, x (#187551)
Simplify exactly as InstCombine does. A follow-up would include
simplifying add x, (sub 0, y) -> sub x, y.

Alive2 proof: https://alive2.llvm.org/ce/z/Af7QiD
2026-03-20 12:07:51 +00:00
Benjamin Maxwell
4b17135d14
[LV] Simplify matchExtendedReductionOperand() (NFCI) (#185821)
This updates `matchExtendedReductionOperand` so the simple case of
`UpdateR(PrevValue, ext(...))` is matched first as an early exit. The
binop matching is then flattened to remove the extra layer of the
`MatchExtends` lambda.
2026-03-20 09:29:28 +00:00
Sander de Smalen
a971089cb8
[LV] Explain why a less profitable VF was chosen (NFCI) (#187469)
I was very puzzled the other day when it showed that VF 8 had a cost of
X and VF 16 had a cost of X/2, yet it still choose VF 8. This PR adds
some extra debug output to explain why this happens.
2026-03-20 07:21:17 +00:00
Florian Hahn
fd3cf1c160
[LV] Move dereferenceability check from Legal to VPlan (NFC) (#185323)
Instead of checking dereferenceability early during
LoopVectorizationLegality, defer the check to VPlan construction via
areAllLoadsDereferenceable.

This in preparation for supporting early exit vectorization of
non-dereferencable loads, e.g. via speculative loads
(https://discourse.llvm.org/t/rfc-provide-intrinsics-for-speculative-loads/89692)
or first-faulting loads. Detection in VPlan allows easily replacing
potentially non-deref loads with other loads as needed.

PR: https://github.com/llvm/llvm-project/pull/185323
2026-03-19 19:21:45 +00:00
Alexey Bataev
7d76a3122d
[SLP]Improve analysis for the shl-based reduced values with copyables (#185485)
shl-based reduced values in many cases serve as a bitcast/bswap-based
transfromation root, but need to improve analysis for better matching.
This patch merges reduction candidates into a single reduced value
array, if there are only 2 different candidate arrays, one of them has
only single element, the second is a list of shl instructions. Also,
sorts these shl instructions by their shift amount and merges with the
single candidate, if it is profitable to have a copyable reduction.
2026-03-19 14:16:53 -04:00
vporpo
467cf7caed
[SandboxIR] Implement UncondBrInst and CondBrInst (#187196)
This patch implements the unconditional and conditional branch
instructions mirroring the newly added LLVM IR instructions.

So now we have two new classes UncondBrInst and CondBrInst inheriting
from BranchInst.

The original Br opcode has been removed in favor of UncondBr and CondBr.
2026-03-19 10:28:32 -07:00
Weiwen He
2ec08b3194
[LSV] Added check for mismatched GEP strides in getConstantOffsetComplexAddrs (#186671)
When two GEPs A & B with variable indices have source element types of
different sizes (e.g. i8 vs i32), their offsets cannot be constants.
Currently the `getConstantOffsetComplexAddrs` does not check this and
simply use the stride of GEP A assuming they are equal, resulting in
miscompile.

Add a check that the source element types are the same, otherwise bail
out.

Fixes #186327
2026-03-19 17:10:30 +01:00
Alexey Bataev
9050794e06
[SLP]Improve reductions for copyables/split nodes
The original support for copyables leads to a regression in x264 in
RISCV, this patch improves detection of the copyable candidates by more
precise checking of the profitability and adds and extra check for
splitnode reduction, if it is profitable.

Fixes #184313

Reviewers: hiraditya, RKSimon

Pull Request: https://github.com/llvm/llvm-project/pull/185697
2026-03-19 12:03:05 -04:00
Florian Hahn
cdaf29f84d
Revert "[LV] Simplify and unify resume value handling for epilogue vec." (#187504)
Reverts llvm/llvm-project#185969

This is suspected to cause a miscompile in 549.fotonik3d_r from SPEC 2017 FP
2026-03-19 14:38:37 +00:00
Graham Hunter
b227fab5a6
[NFC][LV] Introduce enums for uncountable exit detail and style (#184808)
Recursively splitting out some work from #183318; this covers
the enums for early exit loop type (none, readonly, readwrite)
and the style used (just readonly and
masked-handle-ee-in-scalar-tail for now) and refactoring for
basic use of those enums.
2026-03-19 14:17:25 +00:00
Florian Hahn
78a8f00977
Revert "[VPlan] Create header phis once regions have been created (NFC)."
This reverts commit 91b928f919364b29e241821fc639b9ef56dab1a5.

This complicates some analysis that need the happen on the scalar VPlan,
before regions have been created, e.g.
https://github.com/llvm/llvm-project/pull/185323/.
2026-03-19 12:53:12 +00:00
Alexey Bataev
582fa78753
[SLP]Do not match buildvector node, if current node is part of its combined nodes
If current buildvector node is part of the combined nodes of the
matching candidate node, this matching candidate must be considered as
non-matching to prevent wrong def-use chain

Reviewers: 

Pull Request: https://github.com/llvm/llvm-project/pull/187491
2026-03-19 08:15:32 -04:00
John Brawn
191c84b822
[VPlan] Permit derived IV in isHeaderMask (#187360)
When matching scalar steps of the canonical IV, also match a derived IV
of the canonical IV if the derivation is essentially a no-op. Fixes a
failure in the mve-reg-pressure-spills.ll test when expensive checks are
enabled.
2026-03-19 12:05:07 +00:00
vporpo
77066a3d33
[SandboxVec][SeedCollection] Aux pass argument for enabling different types (#155079)
This patch implements the auxiliary pass argument, a secondary argument
that can be passed to Sandbox IR passes.

It also updates the SeedCollection pass to accept the auxiliary argument
"enable-diff-types", which enables collection of seeds of different
types. This will be used in a follow-up patch.
2026-03-18 17:11:01 -07:00
Elvis Wang
53f8f3b017
Reland [LV] Replace remaining LogicalAnd to vp.merge in EVL optimization. (#184068) (#187199)
This patch replace the remaining LogicalAnd to vp.merge in the second
pass to not break the `m_RemoveMask` pattern in the optimizeMaskToEVL.

Also skip cost model comparison when the plan contains `vp_merge` which
won't be calculated by the legacy model.

This can help to remove header mask for FindLast reduction (CSA) loops.

Original PR: https://github.com/llvm/llvm-project/pull/184068
Original built-bot failure:
https://lab.llvm.org/buildbot/#/builders/213/builds/2497
2026-03-19 07:56:42 +08:00
Alexey Bataev
abdcde9bbc
[SLP] Loop aware cost model/tree building
Currently, SLP vectorizer do not care about loops and their trip count.
It may lead to inefficient vectorization in some cases. Patch adds loop
nest-aware tree building and cost estimation.
When it comes to tree building, it now checks that tree do not span
across different loop nests. The nodes from other loop nests are
immediate buildvector nodes.
The cost model adds the knowledge about loop trip count. If it is
unknown, the default value is used, controlled by the
-slp-cost-loop-min-trip-count=<value> option. The cost of the vector
nodes in the loop is multiplied by the number of iteration (trip count),
because each vector node will be executed the trip count number of
times. This allows better cost estimation.

Original Reviewers:
jdenny-ornl, vporpo, hiraditya, RKSimon

Original PR: https://github.com/llvm/llvm-project/pull/150450

Recommit after revert in c7bd3062f1dac975cf9b706f457b3c55b4bf57ff and in 4e500bd0015042b0cd4b7c87b81caeea06072d24

Reviewers: 

Pull Request: https://github.com/llvm/llvm-project/pull/187391
2026-03-18 17:54:01 -04:00
Florian Hahn
fce100e26e
[VPlan] Fix masked_cond expansion.
masked_cond is used to combine early-exit conditions with masks from
predicate. The early-exit condition should only be evaluated if the mask
is true. Emit the mask first, to avoid incorrect poison propagation.

Fixes https://github.com/llvm/llvm-project/issues/187061.
2026-03-18 20:26:04 +00:00
Florian Hahn
0ea2e5813f
[VPlan] Account for early-exit dispatch blocks when updating LI. (#185618)
Now that we can vectorize loops with multiple early exits, we emit
dispatch blocks after the middle block to go to a specific exit or
continue in the dispatch chain.

With that, we need to be a bit more careful when it comes to picking the
loop the dispatch block belongs to. The dispatch block will belong to
the innermost loop of all exit blocks reachable from the current block.

Fixes https://github.com/llvm/llvm-project/issues/185362

PR: https://github.com/llvm/llvm-project/pull/185618
2026-03-18 18:37:34 +00:00
Alexey Bataev
4e500bd001 Revert "[SLP] Loop aware cost model/tree building"
This reverts commit 6261cb4487f153c599a040d7a77524561b520240 to try to
fix compile time regressions
2026-03-18 09:46:39 -07:00
Florian Hahn
13a093b2b2
[VPlan] Compute cost for predicated loads/stores to invariant address. (#181572)
Update VPReplicateRecipe::computeCost to compute the cost for stores to
invariant addresses only masked by the header mask.

This matches the legacy cost model logic, but it is slightly odd that
the legacy cost model only seems to do this for stores predicated by the
header mask (i.e. tail-folding and not executed conditionally
otherwise). This is probably something we want to re-evaluate
eventually.

PR: https://github.com/llvm/llvm-project/pull/181572
2026-03-18 16:21:02 +00:00
John Brawn
a083e19efe
[VPlan] Add the cost of spills when considering register pressure (#179646)
Currently when considering register pressure is enabled, we reject any
VF that has higher pressure than the number of registers. However this
can result in failing to vectorize in cases where it's beneficial, as
the cost of the extra spills is less than the benefit we get from
vectorizing.

Deal with this by instead calculating the cost of spills and adding that
to the rest of the cost, so we can detect this kind of situation and
still vectorize while avoiding vectorizing in cases where the extra cost
makes it not with it.
2026-03-18 15:30:39 +00:00
Luke Lau
9871ad1c8a [VPlan] Rename DataLayout -> DL
To fix the buildbot failure in https://lab.llvm.org/buildbot/#/builders/97/builds/12155
2026-03-18 23:13:19 +08:00
Alexis Engelke
080bc25728
[IR][NFCI] Remove *WithoutDebug (#187240)
The function instructionsWithoutDebug serves two uses: skipping debug
intrinsics and skipping pseudo instructions. Nonetheless, these
functions are expensive due to out-of-line filtering using
std::function. Ideally, the filter should be inlined, but that would
require including IntrinsicInst.h in BasicBlock.h.

We no longer use debug intrinsics, so the first use (parameter false) is
no longer needed. The second use is sometimes needed, but the
distinction between PseudoProbe instructions can be made at the call
sites more easily in many cases.

Therefore, remove instructionsWithoutDebug/sizeWithoutDebug.

c-t-t stage2-O3 -0.21%.
2026-03-18 15:08:41 +00:00
Luke Lau
bf46a95f2c
[VPlan] Use target's index type for {First,Last}ActiveLane instead of i64 (#186361)
Fixes #186005

On RV32 with zve32x, i.e. no legal 64 bit types either scalar or vector,
@llvm.cttz.elts.i64 cannot be lowered and so returns an illegal cost for
scalable VFs. However VPInstruction::FirstActiveLane and
VPInstruction::LastActiveLane always use a hardcoded i64 type.

This causes a legacy/VPlan cost model mismatch in the live-out.ll test,
and in early-exit-live-out.ll prevents the scalable VF from being
chosen.

This PR teaches the two VPInstructions to use the target's index type,
i.e. the width of a pointer in the default address space, so it will
generate a 32 bit cttz.elts on RV32. This should be large enough to hold
the maximum number of elements in a vector, as if the vector was any
bigger it would imply it isn't accessible by memory.

I considered using the canonical IV type but I don't think that will
work since the canonical IV can be i64 on RV32, and it causes
regressions due to extra zexting on 64-bit targets with a 32-bit IV.
2026-03-18 15:01:21 +00:00
Alexey Bataev
6261cb4487 [SLP] Loop aware cost model/tree building
Currently, SLP vectorizer do not care about loops and their trip count.
It may lead to inefficient vectorization in some cases. Patch adds loop
nest-aware tree building and cost estimation.
When it comes to tree building, it now checks that tree do not span
across different loop nests. The nodes from other loop nests are
immediate buildvector nodes.
The cost model adds the knowledge about loop trip count. If it is
unknown, the default value is used, controlled by the
-slp-cost-loop-min-trip-count=<value> option. The cost of the vector
nodes in the loop is multiplied by the number of iteration (trip count),
because each vector node will be executed the trip count number of
times. This allows better cost estimation.

Reviewers: jdenny-ornl, vporpo, hiraditya, RKSimon

Pull Request: https://github.com/llvm/llvm-project/pull/150450

Recommit after revert in c7bd3062f1dac975cf9b706f457b3c55b4bf57ff
2026-03-18 07:33:07 -07:00
Ramkumar Ramachandra
f7763570e5
[VPlan] Improve code in VPlanRecipes using VPlanPatternMatch (NFC) (#187130) 2026-03-18 09:41:04 +00:00
Ramkumar Ramachandra
e762078424
[VPlan] Use auto return in VPlanPatternMatch (NFC) (#187210) 2026-03-18 08:54:23 +00:00
Elvis Wang
3eb8b788b7
Revert "[LV] Replace remaining LogicalAnd to vp.merge in EVL optimization." (#187170)
Reverts llvm/llvm-project#184068

This hit the cost model assertion in rva23 stage2 build bot.
https://lab.llvm.org/buildbot/#/builders/213/builds/2497
2026-03-18 09:21:40 +08:00
Elvis Wang
52089f895e
[LV] Replace remaining LogicalAnd to vp.merge in EVL optimization. (#184068)
This patch replace the remaining LogicalAnd to vp.merge in the second
pass to not break the `m_RemoveMask` pattern in the optimizeMaskToEVL.

This can help to remove header mask for FindLast reduction (CSA) loops.

PR: https://github.com/llvm/llvm-project/pull/184068
2026-03-18 08:39:27 +08:00
Ryan Buchner
af67e30a63
[SLP][NFC] Refactor BinOpSameOpcodeHelper BIT enum (#187067)
More readable syntax and increase type width to avoid silent errors if
we reach 17 members.
2026-03-17 12:38:14 -07:00
vporpo
b686f5e62e
[SandboxVec][BottomUpVec] Fix crash caused by Cmps with different operand types (#186550)
This patch disables vectorizing Cmps with different operand types
because we can't form a legal vector.
This used to cause an assertion check crash once we attempted to pack
the bundle formed by Cmp's operands.
2026-03-17 10:18:37 -07:00
Alexis Engelke
43ec60eee5
Reland "[DomTree] Assert non-null block for pre-dom tree" (#187005)
Reland #186790 with fix for SCEV. A loop can have more than one latch,
in which case getLoopLatch returns null.
2026-03-17 14:10:04 +00:00
David Sherwood
6f966fb5da
[LV] Add select instruction to VPReplicateRecipe::computeCost (#186825)
I've added the Instruction::Select opcode to the existing list of
opcodes that call getCostForRecipeWithOpcode. There are currently 5
tests that ask for the cost of the select:

  Transforms/LoopVectorize/AArch64/widen-gep-all-indices-invariant.ll
  Transforms/LoopVectorize/first-order-recurrence-with-uniform-ops.ll
  Transforms/LoopVectorize/narrow-to-single-scalar.ll
  Transforms/LoopVectorize/replicate_fneg.ll
  Transforms/LoopVectorize/single-scalar-cast-minbw.ll

The fact they all pass with this change is hopefully proof enough that
the costs are correct.
2026-03-17 09:38:13 +00:00
Ramkumar Ramachandra
56d7920c09
[VPlan] Factor collectGroupedReplicateMemOps (NFC) (#186820)
Factor out a collectGroupedReplicateMemOps from
collectComplementaryPredicatedMemOps, so it can be re-used in other
places.
2026-03-17 09:15:46 +00:00
Florian Hahn
91b928f919
[VPlan] Create header phis once regions have been created (NFC).
Since 1b29ac1d1857ea42273fc7862ea019a74a55195d, regions are constructed
as part of the scalar transforms; moving header phi creation after
region creation slightly simplifies the code.
2026-03-17 08:02:56 +00:00
Elvis Wang
51b3b9b039
[LV] Optimize x && (x && y) -> x && y (#185806)
This patch removes the extra logical-and in `x && (x && y)` and `x && (y && x)` to `x && y`.
This helps to simplify mask calculation in the FindLast reduction and
exposes more opportunities to replace to EVL.

PR link: https://github.com/llvm/llvm-project/pull/185806
2026-03-17 13:03:04 +08:00
Florian Hahn
013f2542a2
[LV] Simplify and unify resume value handling for epilogue vec. (#185969)
This patch tries to drastically simplify resume value handling for the
scalar loop when vectorizing the epilogue.

It uses a simpler, uniform approach for updating all resume values in
the scalar loop:

1. Create ResumeForEpilogue recipes for all scalar resume phis in the
main loop (the epilogue plan will have exactly the same scalar resume
phis, in exactly the same order)
2. Update ::execute for ResumeForEpilogue to set the underlying value
when executing. This is not super clean, but allows easy lookup of the
generated IR value when we update the resume phis in the epilogue. Once
we connect the 2 plans together explicitly, this can be removed.
3. Use the list of ResumeForEpilogue VPInstructions from the main loop
to update the resume/bypass values from the epilogue.

This simplifies the code quite a bit, makes it more robust (should fix
https://github.com/llvm/llvm-project/issues/179407) and also fixes a
mis-compile in the existing tests (see change in
llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-sub-epilogue-vec.ll,
where previously we would incorrectly resume using the start value when
the epilogue iteration check failed)

In some cases, we get simpler code, due to additional CSE, in some cases
the induction end value computations get moved from the epilogue
iteration check to the vector preheader. We could try to sink the
instructions as cleanup, but it is probably not worth the trouble.

Fixes https://github.com/llvm/llvm-project/issues/179407.
2026-03-16 21:21:59 +00:00
Alexey Bataev
d117f98ff6 [SLP]Fix legality checks for bswap-based transformations
Fix the checks for the non-power-of-2 base bswaps by checking the
power-of-2 of the source type, not the target scalar type. Plus, add
cost estimation for zext, if the source type does not match the scalar type and fixes final bitcasting for the reduced values.

Fixes https://github.com/llvm/llvm-project/pull/184018#issuecomment-4053477562
2026-03-16 11:56:24 -07:00
Alexis Engelke
e30aa40aa6
Revert "[DomTree] Assert non-null block for pre-dom tree" (#186831)
Reverts llvm/llvm-project#186790

Breaks buildbots, there are more SLPVectorizer problems.

https://lab.llvm.org/buildbot/#/builders/52/builds/15810
2026-03-16 17:29:35 +01:00
Alexey Bataev
61a9e30045 Revert "[SLP]Fix legality checks for bswap-based transformations"
This reverts commit 2d4daea3b66469420fc164e76c15558b34e44c75 to fix
a buildbot https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flab.llvm.org%2Fbuildbot%2F%23%2Fbuilders%2F164%2Fbuilds%2F19737&data=05%7C02%7C%7C672461616e0d4b66614208de8374a0ff%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C639092734113272365%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=%2B23yMlvZzYt7bB2gM6MmcEwPkIKQogXjcKYIZ%2Bz79zQ%3D&reserved=0
2026-03-16 09:01:49 -07:00
Florian Hahn
dff0d290e8
[VPlan] Check isa<VPRecipeValue> directly, remove unused variable (NFC). 2026-03-16 15:45:24 +00:00