3833 Commits

Author SHA1 Message Date
Florian Hahn
5131186506
[VPlan] Use UTC to auto-generate more VPlan checks.
Update more VPlan tests to use auto-generated check lines via new UTC
support.
2026-02-10 20:56:05 +00:00
Luke Lau
f81889da29
[VPlan] Fix convertToPhisToBlends folding non poison blend to poison (#180686)
This fixes a miscompile in #180005 where we didn't check that the first
incoming value isn't poison.

We should use the first non-poison incoming value if it exists, or just
poison if all the incoming values are poison.
2026-02-10 16:15:57 +00:00
Andrei Elovikov
f96c1ccc1e
[VPlan] Add -vplan-print-after= option (#178700)
UpdateTestChecks support is updated in subsequent
https://github.com/llvm/llvm-project/pull/178736.
2026-02-10 16:07:25 +00:00
Nikita Popov
067f1c95a4 [LoopVectorizer] Generate test checks (NFC) 2026-02-10 17:01:49 +01:00
Sander de Smalen
3157758190
[LV] Handle partial sub-reductions with sub in middle block. (#178919)
Sub-reductions can be implemented in two ways:
(1) negate the operand in the vector loop (the default way).
(2) subtract the reduced value from the init value in the middle block.

Note that both ways keep the reduction itself as an 'add' reduction,
which is necessary because only llvm.vector.partial.reduce.add exists.

The ISD nodes for partial reductions don't support folding the
sub/negation into its operands because the following is not a valid
transformation:
```
     sub(0, mul(ext(a), ext(b)))
  -> mul(ext(a), ext(sub(0, b)))
```
It can therefore be better to choose option (2) such that the partial
reduction is always positive (starting at '0') and to do a final
subtract in the middle block.

For AArch64 there are no dot-product instructions that can
do a `partial.reduce.sub(acc, mul(ext(a), ext(b)))` operation.
I'm not sure if such instructions exist for other targets.
(If so then we may want to make this decision a target option)

This PR also increases the AArch64 cost of a partial sub-reduction
when this exists in an 'add-sub' reduction chain.

Fixes https://github.com/llvm/llvm-project/issues/178703
2026-02-10 11:00:32 +00:00
Benjamin Maxwell
f22a178b13
Reland "[LV] Support conditional scalar assignments of masked operations" (#180708)
This patch extends the support added in #158088 to loops where the
assignment is non-speculatable (e.g. a conditional load or divide).

For example, the following loop can now be vectorized:

```
int simple_csa_int_load(
  int* a, int* b, int default_val, int N, int threshold)
{
  int result = default_val;
  for (int i = 0; i < N; ++i)
    if (a[i] > threshold)
      result = b[i];
  return result;
}
```

It does this by extending the recurrence matching from only looking for
selects, to include phis where all operands are the header phi, except
for one which can be an arbitrary value outside the recurrence.

---

Reverts llvm/llvm-project#180275 (original PR: #178862)

Additional type legalization for `ISD::VECTOR_FIND_LAST_ACTIVE` was
added in #180290, which should resolve the backend crashes on x86.
2026-02-10 09:57:48 +00:00
Matt Arsenault
302ff8fd00
InstCombine: Use SimplifyDemandedFPClass on fmul (#177490)
Start trying to use SimplifyDemandedFPClass on instructions, starting
with fmul. This subsumes the old transform on multiply of 0. The
main change is the introduction of nnan/ninf. I do not think anywhere
was systematically trying to introduce fast math flags before, though
a few odd transforms would set them.

Previously we only called SimplifyDemandedFPClass on function returns
with nofpclass annotations. Start following the pattern of
SimplifyDemandedBits, where this will be called from relevant root
instructions.

I was wondering if this should go into InstCombineAggressive, but that
apparently does not make use of InstCombineInternal's worklist.
2026-02-10 09:49:31 +00:00
Mel Chen
7e5d9189d2
[VPlan] Simplify true && x -> x (#179426) 2026-02-10 08:49:03 +00:00
Florian Hahn
68d4175cc1
[LV] Add FindLast tests where IV-based expression could be sunk. (NFC)
Add set of FindLast tests where the selected expression is based on an
IV and could be sunk.
2026-02-09 23:31:39 +00:00
Florian Hahn
06cffa5ee3
[VPlan] Auto-generate CHECKs in some VPlan printing tests.
Use new UTC support to re-generate check lines.
2026-02-09 23:22:18 +00:00
Florian Hahn
2b9a1aee5a
[LV] Add additional tests for reductions with intermediate stores. (NFC)
Adds missing test coverage for reductions with intermediate stores,
including partial reductions with intermediate stores, as well as
chained min/max reductions with intermediate stores.
2026-02-09 23:14:26 +00:00
Florian Hahn
d1ec04dfd4
[VPlan] Simplify single-entry VPWidenPHIRecipe.
Include VPWidenPHIRecipe in phi simplification if there's a single
incoming value.
2026-02-09 22:10:13 +00:00
Vishruth Thimmaiah
84f4b1e52d Reland "[LoopVectorize] Support vectorization of overflow intrinsics" (#180526)
Enables support for marking overflow intrinsics `uadd`, `sadd`, `usub`,
`ssub`, `umul` and `smul` as trivially vectorizable.

Fixes #174617

---

This patch is a reland of #174835.

Reverts #179819
2026-02-09 15:32:04 +00:00
hanbeom
77ccd853d0
[IVDesc] Check loop-preheader for loop-legality when pass-remarks enabled (#166310)
When `-pass-remarks=loop-vectorize` is specified, the subsequent logic
is executed to display detailed debug messages even if no PreHeader
exists in the loop.

Therefore, an assert occurs when the `getLoopPreHeader()` function is
called. This commit resolves that issue.

Fixed: #165377
2026-02-10 00:02:13 +09:00
Luke Lau
ed19bbfe01 Revert "[VPlan] Add missing REQUIRES: asserts to VPlan output test"
This reverts commit 2805c8aaa61a94ef22ac76c8dac56f7dfe970651.

This added the REQUIRES line to the wrong test, 041ce9f added it to the
correct one.
2026-02-09 22:00:42 +08:00
David Sherwood
041ce9fe0f
[LV][NFC] Add "REQUIRES: assert" to new test file (#180522)
Fixes a minor test regression introduced by
https://github.com/llvm/llvm-project/pull/180226 in file
llvm/test/Transforms/LoopVectorize/phi-with-fastflags-vplan.ll
2026-02-09 13:55:35 +00:00
David Sherwood
44031ae79f
[LV] Fix issue in VPFirstOrderRecurrencePHIRecipe::usesFirstLaneOnly (#179977)
In some cases we decide to vectorise loops with first-order recurrences
using VF=1, IC>1. We then attempt to unroll a vplan in replicateByVF,
however when trying to erase the list of values from the parent we
trigger the following assert:

```
virtual llvm::VPRecipeValue::~VPRecipeValue(): Assertion `Users.empty()
  && "trying to delete a VPRecipeValue with remaining users"' failed.
```

The problem seems to stem from this code:

```
  DefR->replaceUsesWithIf(LaneDefs[0], [DefR](VPUser &U, unsigned) {
    return U.usesFirstLaneOnly(DefR);
  });
```

since usesFirstLaneOnly returns false and we fail to replace uses of
DefR with LaneDefs[0]. Upon inspection the only VPUser objects that
return false are VPInstruction::FirstOrderRecurrenceSplice and
VPFirstOrderRecurrencePHIRecipe. Since the values are all scalar it's
simply not possible for us to be using anything other than the first
lane. I've fixed this by bailing out of replicateByVF early for plans with
only a scalar VF.

Fixes https://github.com/llvm/llvm-project/issues/179671
2026-02-09 13:42:26 +00:00
Florian Hahn
7defb0a4a3
[VPlan] Skip applying InstsToScalarize with forced instr costs. (#168269)
ForceTargetInstructionCost in the legacy cost model overrides any costs
from InstsToScalarize. Match the behavior in the VPlan-based cost model.
This fixes a crash with -force-target-instr-cost for the added test
case.

PR: https://github.com/llvm/llvm-project/pull/168269
2026-02-09 13:20:44 +00:00
Luke Lau
2805c8aaa6 [VPlan] Add missing REQUIRES: asserts to VPlan output test
Should fix https://lab.llvm.org/buildbot/#/builders/11/builds/33293
2026-02-09 20:40:10 +08:00
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
6324ee32c1
[VPlan] Use PredBB's terminator as insert point for VPIRPhi extracts.
Use PredBB's terminator as insert point in VPIRPhi::execute to make sure
the extracts are placed after any possibly sunk instructions.

Fixes https://github.com/llvm/llvm-project/issues/180363.
2026-02-08 20:36:36 +00:00
Florian Hahn
3c5b05427d
[VPlan] Pass underlying instr to getMemoryOpCost in ::computeCost.
Pass underlying instruction to getMemoryOpCost in
VPReplicateRecipe::computeCost if UsedByLoadStoreAddress is true.
Some targets use the underlying instruction to improve costs,
and this is needed to match the legacy cost model.

Fixes https://github.com/llvm/llvm-project/issues/177780.
Fixes https://github.com/llvm/llvm-project/issues/177772.
2026-02-08 16:15:39 +00:00
Florian Hahn
3192fe2c7b
[VPlan] Fall back to legacy cost model if PtrSCEV is nullptr.
There are some cases when PtrSCEV can be nullptr. Fall back to legacy
cost model, to not call isLoopInvariant with nullptr.

Fixes a crash after 0c4f8094939d2.
2026-02-08 11:55:12 +00:00
Kewen Meng
703c2762d3
Revert "[LV] Support conditional scalar assignments of masked operations" (#180275)
Reverts llvm/llvm-project#178862 

revert to unblock bot:
https://lab.llvm.org/buildbot/#/builders/206/builds/13225
2026-02-06 13:24:40 -08:00
Florian Hahn
bd40d1de9c
Reapply "[SCEVExp] Use SCEVPtrToAddr in tryToReuseLCSSAPhi if possible. (#180257)"
This reverts commit cb905605b2e95f88296afe136b21a7d2476cb058.

Recommit the patch with a small change to check the destination
type matches the address type, to avoid a crash on mismatch.

Original message:

This patch updates tryToReuseLCSSAPhi to use SCEVPtrToAddr, unless using
SCEVPtrToInt allows re-use, because the IR already contains a re-usable
phi using PtrToInt.

This is a first step towards migrating to SCEVPtrToAddr and avoids
regressions in follow-up changes.

PR: https://github.com/llvm/llvm-project/pull/178727
2026-02-06 21:14:41 +00:00
Florian Hahn
cb905605b2
Revert "[SCEVExp] Use SCEVPtrToAddr in tryToReuseLCSSAPhi if possible." (#180257)
Reverts llvm/llvm-project#178727

triggers asserts in on some build bots
2026-02-06 18:26:37 +00:00
Florian Hahn
c32cde4182
[SCEVExp] Use SCEVPtrToAddr in tryToReuseLCSSAPhi if possible. (#178727)
This patch updates tryToReuseLCSSAPhi to use SCEVPtrToAddr, unless using
SCEVPtrToInt allows re-use, because the IR already contains a re-usable
phi using PtrToInt.

This is a first step towards migrating to SCEVPtrToAddr and avoids
regressions in follow-up changes.

PR: https://github.com/llvm/llvm-project/pull/178727
2026-02-06 17:38:24 +00:00
Ramkumar Ramachandra
901d175d18
[VPlan] Simplify x & AllOnes -> x (#180049) 2026-02-06 13:42:58 +00:00
Florian Hahn
fdce0ea708
[VPlan] Add ExitingIVValue VPInstruction. (#175651)
Add a new VPInstruction opcode to compute the exiting value of an
induction variable after vectorization. This replaces the pattern of
extracting the last lane from the last part of the induction backedge
value when applicable.

This allows us to always use the pre-computed IV end value. It will also
allow unifying end value creation for both induction resume and exit
values.

PR: https://github.com/llvm/llvm-project/pull/175651
2026-02-06 12:27:31 +00:00
Benjamin Maxwell
4f90eb6427
[LV] Support conditional scalar assignments of masked operations (#178862)
This patch extends the support added in #158088 to loops where the
assignment is non-speculatable (e.g. a conditional load or divide).

For example, the following loop can now be vectorized:

```
int simple_csa_int_load(
  int* a, int* b, int default_val, int N, int threshold)
{
  int result = default_val;
  for (int i = 0; i < N; ++i)
    if (a[i] > threshold)
      result = b[i];
  return result;
}
```

It does this by extending the recurrence matching from only looking for
selects, to include phis where all operands are the header phi, except
for one which can be an arbitrary value outside the recurrence.
2026-02-06 11:43:06 +00:00
Luke Lau
33a2c3ee9c
[VPlan] Ignore poison incoming values when creating blend (#180005)
We have an optimization in VPPredicator when creating blends where if
all the incoming values are the same, we just return that value.

This extends it to handle cases like "phi [%x, %x, poison, %x]" by
ignoring poison values.

This is split off from #176143 to prevent regressions when maintaining
SSA by adding PHIs with a poison incoming value.
2026-02-06 19:09:43 +08:00
Ramkumar Ramachandra
30986dc3ff
[LV] Regen a VPlan-printing test with UTC (#179948)
Post 49288b65 ([UTC] Add initial VPlan support, #178534), we can
generate VPlan-printing tests with UTC. Do it for one test, with the
caveat that two Final VPlan prints are no longer checked.
2026-02-05 22:52:42 +00:00
Florian Hahn
e524ee5a7d
[VPlan] Auto-generate some VPlan check lines.
Use new UTC support to auto-generate some check lines to make them
easier to update in the future.
2026-02-05 21:52:37 +00:00
David Green
8f484ff2a0
[AArch64] Add FeatureUseFixedOverScalableIfEqualCost to Neoverse-V3 and Neoverse-V3ae (#179903)
This was missing from neoverse-v3 and neoverse-v3ae, but should be
present like neoverse-v2.
2026-02-05 17:55:49 +00:00
Alexander Kornienko
7165353506
Revert "[LoopVectorize] Support vectorization of overflow intrinsics" (#179819)
Reverts llvm/llvm-project#174835, which causes clang crashes.

See
https://github.com/llvm/llvm-project/pull/174835#issuecomment-3844233831
and https://github.com/llvm/llvm-project/issues/179671 for details.
2026-02-05 15:41:49 +01: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
nora
3bbf748a63
[VPlan] Create edge mask for single-destination switch (#179107)
When converting phis to blends, the `VPPredicator` expects to have edge
masks to the phi node if the phi node has different incoming blocks.
This was not the case if the predecessor of the phi was a switch where a
conditional destination was the same as the default destination.

This was because when creating edge masks in `createSwitchEdgeMasks`,
edge masks are set in a loop through the *non-default* destinations. But
when there are no non-default destinations (but at least one condition,
otherwise an earlier condition would trigger and just forward the source
mask), this loop is never executed, so the masks are never set.

To resolve this, we explicitly forward the source mask for these cases
as well, which is correct because it is an unconditional branch, just a
very convoluted one.

fixes #179074
2026-02-05 15:50:57 +08:00
Florian Hahn
d97ce9bc04 [LV] Use DomTree DFS numbers to sort early exit blocks.
properlyDominates does not provide a strict weak ordering. Use DFS in
numbers instead, to avoid ordering violations.
2026-02-04 21:52:27 +00:00
Florian Hahn
49288b6523
[UTC] Add initial VPlan support. (#178534)
Add support for extracting a VPlan from LV debug output and generalizing
matching for unnamed VPValues.

Once we have support for -vplan-print-after=xxxx we can strip the logic
to extract a VPlan manually. We cannot use regex, as we need to match
from start opening bracket to the correct closing bracket.

PR: PR: https://github.com/llvm/llvm-project/pull/178534
2026-02-04 20:29:22 +00:00
Florian Hahn
792f7b089a
[VPlan] Refine exit select check in transformtoPartialReduction.
Make sure we find the actual select for the exit users and only use it
for the final link in the chain. This fixes a miscompile after
90b3712d8a20efa2cbaadc177da576e485dce038.
2026-02-03 21:07:02 +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
Florian Hahn
beb0e7e150
[VPlan] Fold (x | !x) -> true. (#177887)
PR: https://github.com/llvm/llvm-project/pull/177887
2026-02-01 20:12:21 +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
Florian Hahn
a0b99e32d3
[LV] Add additional partial reduction test coverage for #167851.
Add test cases for which earlier versions of
https://github.com/llvm/llvm-project/pull/167851 was not NFC.

Test chained_sext_adds is moved to a new file.
2026-01-30 20:31:32 +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
Florian Hahn
abfd56293c
[VPlan] Mark VPActiveLaneMaskPHIRecipe as readnone. (#177886)
VPWidenActiveLaneMaskPHIRecipe does not have side-effects and also does
not access memory. Mark accordingly. This allows hoisting of some
invariant loads out of loops and also removing unused phi recipes in the
future.

In
llvm/test/Transforms/LoopVectorize/AArch64/conditional-branches-cost.ll,
the hoisting makes vectorization profitable.

PR: https://github.com/llvm/llvm-project/pull/177886
2026-01-30 16:12:30 +00:00
Sander de Smalen
a726b1907a NFC: Cleanup AArch64/partial-reduce-chained.ll
This had some loop attributes that were unused.
Also cleaned up the flags a little bit.
2026-01-30 14:59:38 +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