2277 Commits

Author SHA1 Message Date
Simon Pilgrim
0fa0ce1f3a
[CostModel][X86] Update SK_Broadcast based on cost kinds (#150620)
When these were converted to CostKindTblEntry the throughput was mainly copied to all cost kinds

Regenerated with my check_cost_tables.py helper script
2025-07-26 13:52:47 +01:00
Alexey Bataev
ef98e248c7 [SLP]Initial support for copyable elements (non-schedulable only)
Adds initial support for copyable elements. This patch only models adds
and model copyable elements as add <element>, 0, i.e. uses identity
constants for missing lanes.
Only support for elements, which do not require scheduling, is added to
reduce size of the patch.

Fixed compile time regressions, reported crashes, updated release notes

Reviewers: RKSimon, hiraditya

Reviewed By: RKSimon

Pull Request: https://github.com/llvm/llvm-project/pull/140279
2025-07-25 10:55:07 -07:00
Martin Storsjö
936ee35dcc Revert "[SLP]Initial support for copyable elements (non-schedulable only)"
This reverts commit 898bba311f180ed54de33dc09e7071c279a4942a.

This change caused hangs and crashes, see
https://github.com/llvm/llvm-project/pull/140279#issuecomment-3115051063.
2025-07-25 01:22:20 +03:00
Martin Storsjö
bd170b78bb Revert "[SLP] Check if the user node has state before trying getting main instruction/opcode"
This reverts commit c9cea24fe68e24750b2d479144f839e1c2ec9d2b.

This is being reverted as it is intermixed with another commit
(898bba311f180ed54de33dc09e7071c279a4942a) that needs to be reverted.
2025-07-25 01:22:19 +03:00
Alexey Bataev
c9cea24fe6 [SLP] Check if the user node has state before trying getting main instruction/opcode
Need to check if the parent node has state to prevent compiler crashes.
Fixes #150479
2025-07-24 12:00:43 -07:00
Alexey Bataev
898bba311f [SLP]Initial support for copyable elements (non-schedulable only)
Adds initial support for copyable elements. This patch only models adds
and model copyable elements as add <element>, 0, i.e. uses identity
constants for missing lanes.
Only support for elements, which do not require scheduling, is added to
reduce size of the patch.

Fixed compile time regressions, updated release notes

Reviewers: RKSimon, hiraditya

Reviewed By: RKSimon

Pull Request: https://github.com/llvm/llvm-project/pull/140279
2025-07-23 13:38:34 -07:00
Alexey Bataev
a415d68e48 Revert "[SLP]Initial support for copyable elements (non-schedulable only)"
This reverts commit e202dba288edd47f1b370cc43aa8cd36a924e7c1 to try to
resolve compile time issues, reported in https://llvm-compile-time-tracker.com/compare.php?from=36089e5d983fe9ae00f497c2d500f37227f82db1&to=e202dba288edd47f1b370cc43aa8cd36a924e7c1&stat=instructions%3Au&details=on
2025-07-22 07:39:32 -07:00
Alexey Bataev
e202dba288
[SLP]Initial support for copyable elements (non-schedulable only)
Adds initial support for copyable elements. This patch only models adds
and model copyable elements as add <element>, 0, i.e. uses identity
constants for missing lanes.
Only support for elements, which do not require scheduling, is added to
reduce size of the patch.

Reviewers: RKSimon, hiraditya

Reviewed By: RKSimon

Pull Request: https://github.com/llvm/llvm-project/pull/140279
2025-07-21 14:07:28 -04:00
Alexey Bataev
ff225b5d88 [SLP][NFC]Add a run line for the test, NFC 2025-07-18 10:14:18 -07:00
Nikita Popov
369f749dc4 [SLP] Remove lifetime.start on null pointer in test (NFC) 2025-07-18 12:47:49 +02:00
Alexey Bataev
60ae9c9c63
[SLP]Do not consider non-profitable loads slices
If all slices are small and end up with strided or even vectorization
states, better to not consider these candidates for the vectorization
and try to vectorize the whole bunch as gathered loads.

Reviewers: hiraditya, RKSimon, HanKuanChen

Reviewed By: RKSimon, HanKuanChen

Pull Request: https://github.com/llvm/llvm-project/pull/149209
2025-07-17 08:00:02 -04:00
Florian Hahn
02d3738be9
[AArch64,TTI] Remove RealUse check for vector insert/extract costs. (#146526)
getVectorInstrCostHelper would return costs of zero for vector
inserts/extracts that move data between GPR and vector registers, if
there was no 'real' use, i.e. there was no corresponding existing
instruction.

This meant that passes like LoopVectorize and SLPVectorizer, which
likely are the main users of the interface, would understimate the cost
of insert/extracts that move data between GPR and vector registers,
which has non-trivial costs.

The patch removes the special case and only returns costs of zero for
lane 0 if it there is no need to transfer between integer and vector
registers.

This impacts a number of SLP test, and most of them look like general
improvements.I think the change should make things more accurate for any
AArch64 target, but if not it could also just be Apple CPU specific.

I am seeing +2% end-to-end improvements on SLP-heavy workloads.

PR: https://github.com/llvm/llvm-project/pull/146526
2025-07-15 15:19:27 +01:00
Gaëtan Bossu
adb6efeac9
[SLP] Fix cost estimation of external uses with wrong VF (#148185)
It assumed that the VF remains constant throughout the tree. That's not
always true. This meant that we could query the extraction cost for a
lane that is out of bounds.

While experimenting with re-vectorisation for AArch64, we ran into this
issue. We cannot add a proper AArch64 test as more changes would need to
be brought in.

This commit is only fixing the computation of VF and adding an assert.
Some tests were failing after adding the assert:
 - foo() in llvm/test/Transforms/SLPVectorizer/X86/horizontal.ll
- test() in
llvm/test/Transforms/SLPVectorizer/X86/reduction-with-removed-extracts.ll
- test_with_extract() in
llvm/test/Transforms/SLPVectorizer/RISCV/segmented-loads.ll
2025-07-15 11:39:09 +01:00
Florian Hahn
eb4de577da
[SLP,AArch64] Update build-vector test to actually build vectors.
Update test with all zero constant input values which get folded during
IR construction to actually use different input values, which require
materializing build vectors.
2025-07-14 13:47:44 +01:00
Alexey Bataev
a999a1b88c
[SLP]Remove emission of vector_insert/vector_extract intrinsics
Replaced by the regular shuffles.

Fixes #145512

Reviewers: RKSimon

Reviewed By: RKSimon

Pull Request: https://github.com/llvm/llvm-project/pull/148007
2025-07-11 15:26:45 -04:00
Alexey Bataev
dd60663b9b [SLP] Emit reduction instead of 2 extracts + scalar op, when vectorizing operands (#147583)
Added emission of the 2-element reduction instead of 2 extracts + scalar
op, when trying to vectorize operands of the instruction, if it is more
profitable.
2025-07-10 12:50:52 -07:00
Alex Bradbury
18627e995c Revert "[SLP] Emit reduction instead of 2 extracts + scalar op, when vectorizing operands (#147583)"
This reverts commit ac4a38e9bd573a173432b89cbef7cce7a48e7907.

This breaks the RVV builders
(MicroBenchmarks/ImageProcessing/Blur/blur.test and
MultiSource/Benchmarks/tramp3d-v4/tramp3d-v4.test from llvm-test-suite)
and reportedly SPEC Accel2023
<https://github.com/llvm/llvm-project/pull/147583#issuecomment-3057183138>.
2025-07-10 14:55:22 +01:00
Simon Pilgrim
59a99c6f2c [SLP] Drop unnecessary '' from around -passes=... arg lists to appease update_test_checks.py when run on DOS. NFC. 2025-07-10 12:18:41 +01:00
Alexey Bataev
ac4a38e9bd
[SLP] Emit reduction instead of 2 extracts + scalar op, when vectorizing operands (#147583)
Added emission of the 2-element reduction instead of 2 extracts + scalar
op, when trying to vectorize operands of the instruction, if it is more
profitable.
2025-07-09 19:52:09 -04:00
Gaëtan Bossu
50facad7fc
[SLP][REVEC] Fix insertelement legality checks (#146921)
The current code assumes that all the values in VL are valid
instructions, while it is possible to get poison.
2025-07-09 10:28:50 +01:00
David Spickett
651c994feb [llvm][test] Fix REQUIRES in extractelement-insertpoint.ll
The target is called "x86" not "x86_64".
2025-07-03 13:14:42 +00:00
Hanyang (Eric) Xu
6e1e89ee38
[SLP] Avoid -passes=instcombine stages in SLP tests (#146257)
Fixes #145511

Note that there are still two instances of
--passes=slp-vectorizer,instcombine left unchanged because it seems that
the tests are meant to run in conjunction with instcombine and removing
instcombine would invalidate their original objective:


[llvm/test/Transforms/SLPVectorizer/arith-div-undef.ll](https://github.com/llvm/llvm-project/blob/main/llvm/test/Transforms/SLPVectorizer/arith-div-undef.ll)

[llvm/test/Transforms/SLPVectorizer/slp-hr-with-reuse.ll](https://github.com/llvm/llvm-project/blob/main/llvm/test/Transforms/SLPVectorizer/slp-hr-with-reuse.ll)
2025-07-02 06:14:41 -04:00
Luke Lau
d0c1ea928c
[InstCombine] Pull unary shuffles through fneg/fabs (#144933)
This canonicalizes fneg/fabs (shuffle X, poison, mask) -> shuffle
(fneg/fabs X), posion, mask

This undoes part of b331a7ebc1e02f9939d1a4a1509e7eb6cdda3d38 and
a8f13dbdeb31be37ee15b5febb7cc2137bbece67, but keeps the binary shuffle
case i.e. shuffle fneg, fneg, mask.

By pulling out the shuffle we bring it inline with the same
canonicalisation we perform on binary ops and intrinsics, which the
original commit acknowledges it goes in the opposite direction.

However nowadays VectorCombine is more powerful and can do more
optimisations when the shuffle is pulled out, so I think we should
revisit this. In particular we get more shuffles folded and can perform
scalarization.
2025-06-30 10:40:12 +01:00
Gheorghe-Teodor Bercea
3df36a2b18
[AMDGPU] Enable vectorization of i8 values. (#134934)
This patch adjusts the cost model to account for the ability of the
AMDGPU optimizer to group together i8 values into i32 values.

Co-authored-by: Erich Keane <ekeane@nvidia.com>
2025-06-26 19:15:31 -04:00
Simon Pilgrim
1a60c74c13
[CostModel][X86] SK_InsertSubvector inserted into the lowest subvector should be treated as SK_Select blend (#145892)
X86 uses implicit widening and BLEND/MOV shuffles in these cases - otherwise we still treat it as a SK_PermuteTwoSrc
2025-06-26 16:00:51 +01:00
Simon Pilgrim
8202c94cec
[CostModel][X86] getMaskedMemoryOpCost - widening masks must compute the cost of the full width insert_subvector across multiple legal vectors (#145693)
The memory value and mask value types might legalise differently - e.g. a v64i32 might split into 4 x v16i32 / 8 x v8i32 but the mask might legalize as 1 x v64i8 / 2 x v32i8 etc.

If the legalised value type has been split, then we must ensure we compute the cost for the entire mask value type and let getShuffleCost handle any legalisation, not assume that only a single trailing split mask will require widening.
2025-06-25 16:30:35 +01:00
Simon Pilgrim
bf4afb08fe
[CostModel] improveShuffleKindFromMask - recognise a SK_PermuteSingleSrc incorrectly tagged as SK_PermuteTwoSrc (#145352)
If a SK_PermuteTwoSrc shuffle kind's mask only references the first
operand, then treat this as SK_PermuteSingleSrc

Part of #145335
2025-06-23 20:20:47 +01:00
Matt Arsenault
54015f36c6
AMDGPU: Cost model for minimumnum/maximumnum (#141946) 2025-06-18 08:19:06 +09:00
Matt Arsenault
c9b2816388
AMDGPU: Fix cost model for 16-bit operations on gfx8 (#141943)
We should only divide the number of pieces to fit the packed instructions
if we actually have pk instructions. This increases the cost of copysign,
but is closer to the current codegen output. It could be much cheaper
than it is now.
2025-06-18 08:07:03 +09:00
Alexey Bataev
0108a5908c [SLP]Fix a crash on an subvector size calculation for non-power-of-2 vector
Patch fixes cost estimation for the extractelements from non-power-of-2
vectors, defined as subvector extracts. In this case the subvector size
might be not adjusted to a whole register size, need to get the minimum
between whole vector size and the actual difference to prevent compiler
crash.

Fixes #143513
2025-06-17 08:58:07 -07:00
Jeffrey Byrnes
c9a87a50ae
[SLPVectorizer] Use accurate cost for external users of resize shuffles (#137419)
When implementing the vectorization, we potentially need to add shuffles
for external users. In such cases, we may be shuffling a smaller vector
into a larger vector. When this happens `ResizeToVF` will just build a
poison padded identity vector. Then the to build the final shuffle, we
just use the `SK_InsertSubvector` mask.

This is possibly clearer by looking at the included test in
SLPVectorizer/AMDGPU/external-shuffle.ll

In the exit block we have a bunch of shuffles to glue the vectorized
tree match the `InsertElement` users. `TMP25` holds the result of
resizing the v2i16 vectorized sequence to match the `InsertElement` size
v16i16. Then `TMP26` is the final shuffle which replaces the
`InsertElement` sequence. This is just an insertsubvector.

However, when calculating the cost for these shuffles, we aren't
modelling this correctly. `ResizeToVF` will indicate to
`performExtractsShuffleAction` that we cannot use the original mask due
to the resize shuffle. The consequence is that the cost calculation uses
a different shuffle mask than what is ultimately used.

Going back to the included test, we can consider again `TMP26`. Clearly
we can see the shuffle uses a mask {0, 1, 2, 3, 16, 17, poison ..}.
However, we will currently calculate the cost with a mask {0, 1, 2, 3,
20, 21, ...} we have replaced 16 and 17 with 20 and 21 (Index + Vector
Size). Queries like BasicTTImpl::improveShuffleKindFromMask will not
recognize this as an `SK_InsertSubvector` mask, and targets which have
reduced costs for `SK_InsertSubvector` will not accurately calculate the
cost.
2025-06-17 08:14:05 -07:00
Han-Kuan Chen
414710c753
[SLP] Fix isCommutative to check uses of the original instruction instead of the converted instruction. (#143094) 2025-06-17 22:03:14 +08:00
Luke Lau
b81d5e06c7
[InstCombine] Fold shuffles through all trivially vectorizable intrinsics (#141979)
This addresses a TODO in foldShuffledIntrinsicOperands to use
isTriviallyVectorizable instead of a hardcoded list of intrinsics, which
in turn allows more intriniscs to be scalarized by VectorCombine.

From what I can tell every intrinsic here should be speculatable so an
assertion was added.

Because this enables intrinsics like abs which have a scalar operand, we
need to also check isVectorIntrinsicWithScalarOpAtArg.
2025-06-13 18:25:07 +01:00
Jeffrey Byrnes
cc17f68e56
[SLP] NFC: Precommit test for pull/137419 (#137730)
Precommit for https://github.com/llvm/llvm-project/pull/137419
2025-06-12 07:23:07 -07:00
Alexey Bataev
cb648ba970 [SLP]Check if the user node has instructions, used only outside
Gather nodes with parents, which scalar instructions are used only
outside, are generated before the whole tree vectorization. Need to
teach isGatherShuffledSingleRegisterEntry to check that such nodes are
emitted first and they cannot depend on other nodes, which are emitted
later.

Fixes #141628
2025-05-29 10:09:49 -07:00
Alexey Bataev
aa452b65fc [SLP]Restore insertion points after gathers vectorization
Restore insertion points after gathers vectorization to avoid a crash in
a root node vectorization.

Fixes #141265
2025-05-24 07:25:20 -07:00
Alexey Bataev
3918ef3688
[SLP]Fix the analysis for masked compress loads
Need to remove the check for Orders in interleaved loads analysis and
estimate shuffle cost without the reordering to correctly handle the
costs of masked compress loads.

Reviewers: hiraditya, HanKuanChen, RKSimon

Reviewed By: HanKuanChen, RKSimon

Pull Request: https://github.com/llvm/llvm-project/pull/140647
2025-05-20 07:31:16 -04:00
Alexey Bataev
bb8e2a8937 [SLP]Relax assertion to avoid compiler crash
Need to relax the assertion to fix a compiler crash in case if the
reordered compress loads are more profitable than the ordered ones.

Fixes #140334
2025-05-18 14:26:36 -07:00
Alexey Bataev
fb86b3d96b [SLP]Change the insertion point for outside-block-used nodes and prevec phi operand gathers
Need to set the insertion point for (non-schedulable) vector node after
the last instruction in the node to avoid def-use breakage. But it also
causes miscompilation with gather/buildvector operands of the phi nodes,
used in the same phi only in the block.
These nodes supposed to be inserted at the end of the block and after
changing the insertion point for the non-schedulable vec block, it also
may break def-use dependencies. Need to prevector such nodes, to emit
them as early as possible, so the vectorized nodes are inserted before
these nodes.

Fixes #139728

Recommit after revert 60fb92179291e848eb7b04913bdc818d081db296

Reviewers: hiraditya, HanKuanChen, RKSimon

Reviewed By: RKSimon

Pull Request: https://github.com/llvm/llvm-project/pull/139917
2025-05-18 12:59:36 -07:00
Alexey Bataev
60fb921792 Revert "[SLP]Change the insertion point for outside-block-used nodes and prevec phi operand gathers"
This reverts commit d79d9b8fbfc7e8411aeaf2f5e1be9d4247594fee to fix
a bug reported in https://github.com/llvm/llvm-project/pull/139917#issuecomment-2888216404
2025-05-17 11:06:37 -07:00
Alexey Bataev
d79d9b8fbf
[SLP]Change the insertion point for outside-block-used nodes and prevec phi operand gathers
Need to set the insertion point for (non-schedulable) vector node after
the last instruction in the node to avoid def-use breakage. But it also
causes miscompilation with gather/buildvector operands of the phi nodes,
used in the same phi only in the block.
These nodes supposed to be inserted at the end of the block and after
changing the insertion point for the non-schedulable vec block, it also
may break def-use dependencies. Need to prevector such nodes, to emit
them as early as possible, so the vectorized nodes are inserted before
these nodes.

Fixes #139728

Reviewers: hiraditya, HanKuanChen, RKSimon

Reviewed By: RKSimon

Pull Request: https://github.com/llvm/llvm-project/pull/139917
2025-05-16 12:52:27 -04:00
Ramkumar Ramachandra
c807395011
[LAA/SLP] Don't truncate APInt in getPointersDiff (#139941)
Change getPointersDiff to return an std::optional<int64_t>, and fill
this value with using APInt::trySExtValue. This simple change requires
changes to other functions in LAA, and major changes in SLPVectorizer
changing types from 32-bit to 64-bit.

Fixes #139202.
2025-05-15 10:08:05 +01:00
Alexey Bataev
c632ac3506 [SLP][NFC]Add a test with the gather operand in phi node in gathered loads 2025-05-14 08:18:23 -07:00
Alexey Bataev
e1ea86e849 [SLP]Do not try to use interleaved loads, if reordering is required
If the interleaved loads require reordering, better to avoid generate
load + shuffle sequence, which in this case cannot be recognized as
interleaved load. Also, it fixes the issue with the incorrect codegen.

Fixes #138923
2025-05-12 14:12:51 -07:00
Alexey Bataev
fa985b5f1e [SLP][NFC]Add a test with missed reordering of the interleaved loads 2025-05-12 13:48:11 -07:00
Alexey Bataev
2e13f7ab01 [SLP][NFC]Add a test with the incorrect vectorization for the pointers with distance difference > 2^32 2025-05-12 06:30:05 -07:00
Han-Kuan Chen
53df6400af
[SLP] Fix incorrect operand order in interchangeable instruction. (#139225) 2025-05-12 20:03:45 +08:00
Alexey Bataev
49042f2bee [SLP][NFC]Add a test with ordering of the operands of unordered loads 2025-05-11 08:09:51 -07:00
David Green
3b4d5638b3 [AArch64] Limit vector splitting to vectors of size larger than 128bit
The intent of this code is to split larger vectors into smaller shuffles, but
it currently triggering on some small vector types. Limit it to vectors of size
>128bit.
2025-05-09 22:17:28 +01:00
Gheorghe-Teodor Bercea
25a031947a
[AMDGPU][NFC] Add tests in preparation for i8 vectorization (#138801)
Precommit tests for PR: https://github.com/llvm/llvm-project/pull/134934
2025-05-09 10:32:49 -04:00