3391 Commits

Author SHA1 Message Date
Florian Hahn
ec581e460a
[LV] Don't run instcombine for interleaved-accesses test.
Drop instcombine from the run-line to make test independent and make it
easier to follow the generated code for SCEV predicate checks.
2025-09-04 16:08:52 +01:00
Florian Hahn
a614807130
[LV] Add more tests for interleave groups requiring predicates.
Adds tests for https://github.com/llvm/llvm-project/issues/156849.

Also tidies up the existing related test a bit.
2025-09-04 15:45:15 +01:00
Florian Hahn
b400fd1151
[LAA] Support assumptions with non-constant deref sizes. (#156758)
Update evaluatePtrAddrecAtMaxBTCWillNotWrap to support non-constant
sizes in dereferenceable assumptions.

Apply loop-guards in a few places needed to reason about expressions
involving trip counts of the from (BTC - 1).

PR: https://github.com/llvm/llvm-project/pull/156758
2025-09-04 11:32:33 +01:00
Ramkumar Ramachandra
c14052e20b
[VPlan] Let Not preserve uniformity in isSingleScalar (#156676)
LogicalAnd and WidePtrAdd should also preserve uniformity, but we don't
have test coverage to enable adding them.
2025-09-04 11:27:14 +01:00
Ramkumar Ramachandra
e4c0b3e111
[VPlan] Simplify x && false -> false, x | 0 -> x (#156345)
The OR x, 0 -> x simplification has been introduced to avoid
regressions.
2025-09-04 10:29:59 +01:00
Florian Hahn
f1e91bff42
[LV] Regenerate more checks for missing branch weights. 2025-09-03 22:18:04 +01:00
Florian Hahn
ce5a1158b8
[LV] Regenerate checks for missing branch weights. 2025-09-03 21:37:52 +01:00
Florian Hahn
2729284db1
[LV] Add early-exit tests with deref assumptions and scaled sizes.
Add tests where the size of dereferenceable assumption is multiplied by
a constant.
2025-09-03 20:30:46 +01:00
Florian Hahn
a434a7a4f1
Reapply "[LAA,Loads] Use loop guards and max BTC if needed when checking deref. (#155672)"
This reverts commit f0df1e3dd4ec064821f673ced7d83e5a2cf6afa1.

Recommit with extra check for SCEVCouldNotCompute. Test has been added in
b16930204b.

Original message:
Remove the fall-back to constant max BTC if the backedge-taken-count
cannot be computed.

The constant max backedge-taken count is computed considering loop
guards, so to avoid regressions we need to apply loop guards as needed.

Also remove the special handling for Mul in willNotOverflow, as this
should not longer be needed after 914374624f
(https://github.com/llvm/llvm-project/pull/155300).

PR: https://github.com/llvm/llvm-project/pull/155672
2025-09-03 12:45:28 +01:00
Mel Chen
2f5500e4cf
[LV] Improve the test coverage for strided access. nfc (#155981)
Add tests for strided access with UF > 1, and introduce a new test case
@constant_stride_reinterpret.
2025-09-03 10:19:36 +00:00
Florian Hahn
b16930204b
[LV] Add additional tests for reasoning about dereferenceable loads.
Includes a test for the crash exposed by 08001cf340185877.
2025-09-03 10:46:46 +01:00
Luke Lau
c33ccfa52b
[VPlan] Reassociate (x & y) & z -> x & (y & z) (#155383)
This PR reassociates logical ands in order to enable more
simplifications.

The driving motivation for this is that with tail folding all blocks
inside the loop body will end up using the header mask. However this can
end up nestled deep within a chain of logical ands from other edges.

Typically the header mask will be a leaf nested in the LHS, e.g.
(headermask & y) & z. So pulling it out allows it to be simplified
further, e.g. allows it to be optimised away to VP intrinsics with EVL
tail folding.
2025-09-03 01:09:19 +00:00
Florian Hahn
f0df1e3dd4
Revert "[LAA,Loads] Use loop guards and max BTC if needed when checking deref. (#155672)"
This reverts commit 08001cf340185877665ee381513bf22a0fca3533.

This triggers an assertion in some build configs, e.g.
 https://lab.llvm.org/buildbot/#/builders/24/builds/12211
2025-09-02 21:44:30 +01:00
Florian Hahn
4efde3c8fd
[Loads] Apply loop guards to IRArgValue from assumption.
Applying loop guards to IRArgValue can improve results in some cases.
2025-09-02 21:17:51 +01:00
Florian Hahn
08001cf340
[LAA,Loads] Use loop guards and max BTC if needed when checking deref. (#155672)
Remove the fall-back to constant max BTC if the backedge-taken-count
cannot be computed.

The constant max backedge-taken count is computed considering loop
guards, so to avoid regressions we need to apply loop guards as needed.

Also remove the special handling for Mul in willNotOverflow, as this
should not longer be needed after 914374624f
(https://github.com/llvm/llvm-project/pull/155300).

PR: https://github.com/llvm/llvm-project/pull/155672
2025-09-02 18:58:33 +01:00
Florian Hahn
9a1e47839a
[Loads] Apply loop guards to maximum pointer difference.
Applying loop guards to MaxPtrDiff can improve results in some cases.
2025-09-02 13:49:22 +01:00
Ramkumar Ramachandra
d8fd511480
[VPlan] Introduce CSE pass (#151872)
Introduce a simple common-subexpression-elimination pass at the
VPlan-level, running late during the execution of the VPlan. The
long-term vision is to get rid of the legacy non-VPlan-based cse routine
in LV, but this patch doesn't yet fully subsume it.
2025-09-02 12:23:29 +01:00
Florian Hahn
cf444ac2ad
[Loads] Check for overflow when adding MaxPtrDiff + Offset.
MaxPtrDiff + Offset may wrap, leading to incorrect results. Use uadd_ov
to check for overflow.
2025-09-02 10:51:32 +01:00
David Sherwood
e867b85118
[LV] Always emit branch weights for vector epilogue (#155437)
We currently only emit the branch weights for the epilogue
iteration count check if there was already branch weight
data for the scalar loop. However, the code makes no use
of the existing branch weight when estimating the
likelihood of taking a particular branch and so we can
just always add the branch weights regardless. These
hints should hopefully improve code generation.
2025-09-02 10:15:21 +01:00
Florian Hahn
ec40830b38
[LV] Add test for wrapping in isDereferenceableAndAlignedInLoop. 2025-09-02 09:37:19 +01:00
Elvis Wang
8fdae0c7da
[Reland] "[RISCV][TTI] Implement getAddressComputationCost() in RISCV TTI. #149955" (#156386)
This patch implements the `getAddressComputationCost()` in RISCV TTI
which
make the gather/scatter with address calculation more expansive that
stride cost.

Note that the only user of `getAddressComputationCost()` with vector
type is in `VPWidenMemoryRecipe::computeCost()`. So this patch make some
LV tests changes.

I've checked the tests changes in LV and seems those changes can be
divided into two groups.
 * gather/scatter with uniform vector ptr, seems can be optimized to
 masked.load.
 * can optimize to stride load/store.

----
After #155739 landed, the assertion (cost mis-aligned) is fixed.
I've tested llvm-test-suite w/ rva23u64 and rva23u64_zvl1024b locally
and no assertion occurred.
2025-09-02 11:43:27 +08:00
Elvis Wang
7997a79be6
[LV] Align legacy cost model to vplan-based model for gather/scatter w/ uniform addr. (#155739)
This patch check if the addr is uniform in legacy cost model to align
vplan-based cost model after #150371.

This patch fixes llvm-test-suite assertion
(https://lab.llvm.org/buildbot/#/builders/210/builds/1935) due to cost
model misaligned after #149955 under RISCV.

I've tested this patch (on top of #149955) on the llvm-test-suite
locally with crashed options `rva23u64`, `rva23u64_zvl1024b` and build
successfully.

Since this fix will change LV, I think would be better to create a PR to
fix this.
2025-09-02 09:11:45 +08:00
Sam Tebbs
37127f74f4
[LV] Bundle sub reductions into VPExpressionRecipe (#147255)
This PR bundles sub reductions into the VPExpressionRecipe class and
adjusts the cost functions to take the negation into account.

Stacked PRs:
1. https://github.com/llvm/llvm-project/pull/147026
2. -> https://github.com/llvm/llvm-project/pull/147255
3. https://github.com/llvm/llvm-project/pull/147302
4. https://github.com/llvm/llvm-project/pull/147513
2025-09-01 17:25:01 +01:00
Florian Hahn
de6a83257c
[Loads] Add tests for proving deref with assumes and loop guards.
Extra test coverage for using loop guards when reasoning about
dereferenceability with assumes.
2025-09-01 17:11:20 +01:00
Mel Chen
13357e8a12
[LV][EVL] Support interleaved access with tail folding by EVL (#152070)
The InterleavedAccess pass already supports transforming
vector-predicated (vp) load/store intrinsics. With this patch, we start
enabling interleaved access under tail folding by EVL.

This patch introduces a new base class, VPInterleaveBase, and a concrete
class, VPInterleaveEVLRecipe. Both the existing VPInterleaveRecipe and
the new VPInterleaveEVLRecipe inherit from and implement
VPInterleaveBase.

Compared to VPInterleaveRecipe, VPInterleaveEVLRecipe adds an EVL
operand to emit vp.load/vp.store intrinsics.

Currently, tail folding by EVL is only supported for scalable
vectorization. Therefore, VPInterleaveEVLRecipe will only emit
interleave/deinterleave intrinsics. Reverse accesses are not yet
implemented, as masked reverse interleaved access under tail folding is
not yet supported.

Fixed #123201
2025-09-01 21:20:06 +08:00
Luke Lau
eb7f6a5f8a
[VPlan] Simplify (x && y) || (x && z) -> x && (y || z) (#156308)
Split off from #155383, since it turns out this has a diff on its own.
2025-09-01 21:12:23 +08:00
Florian Hahn
fb7c0d70a7
[SCEV] Rewrite some SCEVAdd sub-expressions using loop guards. (#156013)
Trip count expressions sometimes consist of adding 3 operands, i.e.
(Const + A + B). There may be guard info for A + B, and if so, apply it.

We can probably more generally apply this, but need to be careful w.r.t
compile-time.

Alive2 Proof for changes in miniters.ll:
https://alive2.llvm.org/ce/z/HFfXOx

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

PR: https://github.com/llvm/llvm-project/pull/156013
2025-09-01 14:01:15 +01:00
Kerry McLaughlin
f0e9bba024
[LoopVectorize] Generate wide active lane masks (#147535)
This patch adds a new flag (-enable-wide-lane-mask) which allows
LoopVectorize to generate wider-than-VF active lane masks when it
is safe to do so (i.e. the mask is used for data and control flow).

The transform in extractFromWideActiveLaneMask creates vector
extracts from the first active lane mask in the header & loop body,
modifying the active lane mask phi operands to use the extracts.

An additional operand is passed to the ActiveLaneMask instruction,
the value of which is used as a multiplier of VF when generating the
mask.
By default this is 1, and is updated to UF by
extractFromWideActiveLaneMask.

The motivation for this change is to improve interleaved loops when
SVE2.1 is available, where we can make use of the whilelo instruction
which returns a predicate pair.

This is based on a PR that was created by @momchil-velikov (#81140)
and contains tests which were added there.
2025-09-01 13:53:30 +01:00
Florian Hahn
82245fc11d
[LV] Update make-follow-up-loop-id.ll to actually check metadata.
Update make-follow-up-loop-id.ll to make it independent of loop-unroll
by just checking if the correct metadata gets emitted for the scalar and
vector loops.

Also added a test to check for the case when the scalar loop is not
known to be dead.
2025-09-01 12:31:16 +01:00
Florian Hahn
a3dfedf09e
[LV] Check both cases in hints-trans.ll: live and dead scalar loop.
Update hints-trans.ll to check both cases: 1) live scalar loop after
vectorization, 2) dead scalar loop after vectorization.
2025-09-01 11:53:40 +01:00
Nikita Popov
055bfc0271
[InstCombine] Strip leading zero indices from GEP (#155415)
GEPs are often in the form `gep [N x %T], ptr %p, i64 0, i64 %idx`.
Canonicalize these to `gep %T, ptr %p, i64 %idx`.

This enables transforms that only support one GEP index to work and
improves CSE.

Various transforms were recently hardened to make sure they still work
without the leading index.
2025-09-01 09:58:11 +02:00
Luke Lau
c9faedd760
[VPlan] Fold common edges away in convertPhisToBlends (#150368)
If a phi is widened with tail folding, all of its predecessors will have
a mask of the form

    %x = logical-and %active-lane-mask, %foo
    %y = logical-and %active-lane-mask, %bar
    %z = logical-and %active-lane-mask, %baz
    ...

We can remove the common %active-lane-mask from all of these edge masks,
which in turn allows us to simplify a lot of VPBlendRecipes.

In particular, it allows the header mask to be removed in selects with
EVL tail folding, improving RISC-V codegen on SPEC CPU 2017 for
525.x264_r, and supersedes #147243.

This also allows us to remove VPBlendRecipe and directly emit
VPInstruction::Select in another patch.
2025-09-01 07:03:33 +00:00
Florian Hahn
465b17c450
[VPlan] Support scalable VFs in narrowInterleaveGroups. (#154842)
Update narrowInterleaveGroups to support scalable VFs. After the
transform, the vector loop will process a single iteration of the
original vector loop for fixed-width vectors and vscale iterations for
scalable vectors.
2025-08-31 20:45:07 +01:00
Florian Hahn
13aff91e7c
Revert "[VPlan] Support plans with vector pointers in narrowInterleaveGroups."
This reverts commit 806a797c52d8018639f5cdcce5eb375b17c87f5e as it
introduced a miscompile.
2025-08-31 19:37:24 +01:00
Florian Hahn
0aac22758a
[LV] Correctly cost chains of replicating calls in legacy CM.
Check for scalarized calls in needsExtract to fix a divergence between
legacy and VPlan-based cost model.

The legacy cost model was missing a check for scalarized calls in
needsExtract, which meant if incorrectly assumed the result of a
scalarized call needs extracting.

Exposed by https://github.com/llvm/llvm-project/pull/154617.

Fixes https://github.com/llvm/llvm-project/issues/156091.
2025-08-31 15:13:47 +01:00
Florian Hahn
806a797c52
[VPlan] Support plans with vector pointers in narrowInterleaveGroups.
After narrowing interleave groups and related memory operations, all
vector pointers should be removed. Remove the check.

In preparation for https://github.com/llvm/llvm-project/pull/149706.
2025-08-29 20:55:40 +01:00
Florian Hahn
3a9f80372b
[SCEV] Add tests for applying guards to SCEVAddExpr sub-expressions.
Adds a test case for computing the backedge-taken-count for
https://github.com/llvm/llvm-project/issues/155941
2025-08-29 13:14:58 +01:00
Florian Hahn
5ebd59806b
[VPlan] Fold BinaryAnd x, 0 -> 0 in simplifyRecipe.
This also fixes a cost-model divergence in the newly added
tests in constant-fold.ll
2025-08-27 22:35:08 +01:00
Florian Hahn
c7d1425016
[LV] Auto-generated some check lines of tests. 2025-08-27 17:49:11 +01:00
Florian Hahn
876a2a9287
[LV] Add early-exit test needing loop guards to prove dereferenceable. 2025-08-27 13:33:15 +01:00
annamthomas
00926a6db6
[SCEV][LAA] Support multiplication overflow computation (#155236)
Add support for identifying multiplication overflow in SCEV.
This is needed in LoopAccessAnalysis and that limitation was worked
around by 484417a.
This allows early-exit vectorization to work as expected in
vect.stats.ll test without needing the workaround.
2025-08-27 12:11:32 +00:00
Sam Parker
7b3e77f8d9
[WebAssembly] Implement getInterleavedMemoryOpCost (#146864)
First pass where we calculate the cost of the memory operation, as well
as the shuffles required. Interleaving by a factor of two should be
relatively cheap, as many ISAs have dedicated instructions to perform
the (de)interleaving. Several of these permutations can be combined for
an interleave stride of 4 and this is the highest stride we allow.

I've costed larger vectors, and more lanes, as more expensive because
not only is more work is needed but the risk of codegen going 'wrong'
rises dramatically. I also filled in a bit of cost modelling for vector
stores.

It appears the main vector plan to avoid is an interleave factor of 4
with v16i8. I've used libyuv and ncnn for benchmarking, using V8 on
AArch64, and observe geomean improvement of ~3% with some kernels
improving 40-60%.

I know there is still significant performance being left on the table,
so this will need more development along with the rest of the cost
model.
2025-08-27 12:43:52 +01:00
Elvis Wang
69db050839
Revert "[RISCV][TTI] Implement getAddressComputationCost() in RISCV TTI." (#155535)
Reverts llvm/llvm-project#149955
2025-08-27 01:54:19 +00:00
Elvis Wang
dfd3833674
[RISCV][TTI] Implement getAddressComputationCost() in RISCV TTI. (#149955)
This patch implements the `getAddressComputationCost()` in RISCV TTI
which
make the gather/scatter with address calculation more expansive that
stride cost.

Note that the only user of `getAddressComputationCost()` with vector
type is in `VPWidenMemoryRecipe::computeCost()`. So this patch make some
LV tests changes.

I've checked the tests changes in LV and seems those changes can be
divided into two groups.
 * gather/scatter with uniform vector ptr, seems can be optimized to
 masked.load.
 * can optimize to stride load/store.
2025-08-27 08:40:40 +08:00
Florian Hahn
914374624f
[SCEV] Try to push op into ZExt: C * zext (A + B) -> zext (A*C + B*C) (#155300)
Try to push constant multiply operand into a ZExt containing an add, if
possible. In general we are trying to push down ops through ZExt if
possible. This is similar to
https://github.com/llvm/llvm-project/pull/151227 which did the same for
additions.

For now this is restricted to adds with a constant operand, which is
similar to some of the logic above.

This enables some additional simplifications.

Alive2 Proof: https://alive2.llvm.org/ce/z/97pbSL

PR: https://github.com/llvm/llvm-project/pull/155300
2025-08-26 19:31:50 +01:00
Florian Hahn
5faed1ad84
[VPlan] Add VPlan-based addMinIterCheck, replace ILV for non-epilogue. (#153643)
This patch adds a new VPlan-based addMinimumIterationCheck, which
replaced the ILV version for the non-epilogue case.

The VPlan-based version constructs a SCEV expression to compute the
minimum iterations, use that to check if the check is known true or
false. Otherwise it creates a VPExpandSCEV recipe and emits a
compare-and-branch.

When using epilogue vectorization, we still need to create the minimum
trip-count-check during the legacy skeleton creation. The patch moves
the definitions out of ILV.

PR: https://github.com/llvm/llvm-project/pull/153643
2025-08-26 15:52:31 +01:00
Mircea Trofin
3af4597ac9
[NFC][SimplifyCFG] Simplify operators for the combined predicate in mergeConditionalStoreToAddress (#155058)
This is about code readability. The operands in the disjunction forming the combined predicate in `mergeConditionalStoreToAddress` could sometimes be negated twice. This patch addresses that.

2 tests needed updating because they exposed the double negation and now they don’t.
2025-08-26 07:07:59 -07:00
Luke Lau
f3520c538d
[VPlan] Replace EVL branch condition with (branch-on-count AVLNext, 0) (#152167)
This changes the branch condition to use the AVL's backedge value
instead of the EVL-based IV.

This allows us to emit bnez on RISC-V and removes a use of the trip
count, which should reduce register pressure.

To match phis with VPlanPatternMatch I've had to relax the assert that
the number of operands must exactly match the pattern for the Phi
opcode, and I've copied over m_ZExtOrSelf from the LLVM IR
PatternMatch.h.

Fixes #151459
2025-08-26 11:19:19 +00:00
Florian Hahn
0abc8b07e5
[LV] Add early-exit test where the inner loop IV depends on outer loop. 2025-08-26 10:52:53 +01:00
Luke Lau
a12d012c87 [VPlan][RISC-V] Add test case for #154103
This has now been fixed by #152707
2025-08-26 17:31:29 +08:00