summaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
AgeCommit message (Collapse)Author
2025-06-30[InstCombine] Pull unary shuffles through fneg/fabs (#144933)Luke Lau
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-03[ValueTracking] Make Depth last default arg (NFC) (#142384)Ramkumar Ramachandra
Having a finite Depth (or recursion limit) for computeKnownBits is very limiting, but is currently a load-bearing necessity, as all KnownBits are recomputed on each call and there is no caching. As a prerequisite for an effort to remove the recursion limit altogether, either using a clever caching technique, or writing a easily-invalidable KnownBits analysis, make the Depth argument in APIs in ValueTracking uniformly the last argument with a default value. This would aid in removing the argument when the time comes, as many callers that currently pass 0 explicitly are now updated to omit the argument altogether.
2025-05-26[llvm] Value-initialize values with *Map::try_emplace (NFC) (#141522)Kazu Hirata
try_emplace value-initializes values, so we do not need to pass nullptr to try_emplace when the value types are raw pointers or std::unique_ptr<T>.
2025-05-22[InstCombine] Preserve GEP no-wrap flags (#141113)Ramkumar Ramachandra
2025-04-30[InstCombine] Do not combine shuffle+bitcast if the bitcast is eliminable. ↵Ricardo Jesus
(#135769) If we are attempting to combine shuffle+bitcast but the bitcast is pairable with a subsequent bitcast, we should not fold the shuffle as doing so can block further simplifications. The motivation for this is a long-standing regression affecting SIMDe on AArch64, introduced indirectly by the AlwaysInliner (1a2e77cf). Some reproducers: * https://godbolt.org/z/53qx18s6M * https://godbolt.org/z/o5e43h5M7
2025-03-23[InstCombine] Use MapVector for SourceAggregates. (#132564)Florian Hahn
foldAggregateConstructionIntoAggregateReuse iterates over the entries of SourceAggregates and the order of inserted instructions depends on the order of the iterator. Using a regular DenseMap can lead to non-deterministic value naming/numbering. I don't think it can actually impact the generated binary, but it makes diffing IR more difficult. PR: https://github.com/llvm/llvm-project/pull/132564
2025-01-24[InstCombine] Avoid repeated hash lookups (NFC) (#124243)Kazu Hirata
2025-01-24[NFC][DebugInfo] Use iterator moveBefore at many call-sites (#123583)Jeremy Morse
As part of the "RemoveDIs" project, BasicBlock::iterator now carries a debug-info bit that's needed when getFirstNonPHI and similar feed into instruction insertion positions. Call-sites where that's necessary were updated a year ago; but to ensure some type safety however, we'd like to have all calls to moveBefore use iterators. This patch adds a (guaranteed dereferenceable) iterator-taking moveBefore, and changes a bunch of call-sites where it's obviously safe to change to use it by just calling getIterator() on an instruction pointer. A follow-up patch will contain less-obviously-safe changes. We'll eventually deprecate and remove the instruction-pointer insertBefore, but not before adding concise documentation of what considerations are needed (very few).
2024-12-13PatternMatch: migrate to CmpPredicate (#118534)Ramkumar Ramachandra
With the introduction of CmpPredicate in 51a895a (IR: introduce struct with CmpInst::Predicate and samesign), PatternMatch is one of the first key pieces of infrastructure that must be updated to match a CmpInst respecting samesign information. Implement this change to Cmp-matchers. This is a preparatory step in migrating the codebase over to CmpPredicate. Since we no functional changes are desired at this stage, we have chosen not to migrate CmpPredicate::operator==(CmpPredicate) calls to use CmpPredicate::getMatching(), as that would have visible impact on tests that are not yet written: instead, we call CmpPredicate::operator==(Predicate), preserving the old behavior, while also inserting a few FIXME comments for follow-ups.
2024-12-12[InstCombine] Optimistically allow multiple shufflevector uses in foldOpPhi ↵Matthias Braun
(#114278) We would like to optimize situations of the form that happen after loop vectorization+SROA: ``` loop: %phi = phi zeroinitializer, %interleaved %deinterleave_a = shufflevector %phi, poison ; pick half of the lanes %deinterleave_b = shufflevector %phi, posion ; pick remaining lanes ... %a = ... %b = ... %interleaved = shufflevector %a, %b ; interleave lanes of a+b ``` where the interleave and de-interleave shuffle operations cancel each other out. This could be handled by `foldOpPhi` but does not currently work because it does not proceed when there are multiple uses of the `Phi` operation. This extends `foldOpPhi` to allow multiple `shufflevector` uses when they are shown to simplify for all `Phi` input values.
2024-11-21[InstCombine] Extend folding of aggregate construction to cases when source ↵weiguozhi
aggregates are partially available (#100828) Function foldAggregateConstructionIntoAggregateReuse can fold insertvalue(phi(extractvalue(src1), extractvalue(src2))) into phi(src1, src2) when we can find source aggregates in all predecessors. This patch extends it to handle following case insertvalue(phi(extractvalue(src1), elm2)) into phi(src1, insertvalue(elm2)) with the condition that the predecessor without source aggregate has only one successor.
2024-11-20[InstCombine] Only fold extract element to trunc if vector `hasOneUse` (#115627)peterbell10
This fixes a missed optimization caused by the `foldBitcastExtElt` pattern interfering with other combine patterns. In the case I was hitting, we have IR that combines two vectors into a new larger vector by extracting elements and inserting them into the new vector. ```llvm define <4 x half> @bitcast_extract_insert_to_shuffle(i32 %a, i32 %b) { %avec = bitcast i32 %a to <2 x half> %a0 = extractelement <2 x half> %avec, i32 0 %a1 = extractelement <2 x half> %avec, i32 1 %bvec = bitcast i32 %b to <2 x half> %b0 = extractelement <2 x half> %bvec, i32 0 %b1 = extractelement <2 x half> %bvec, i32 1 %ins0 = insertelement <4 x half> undef, half %a0, i32 0 %ins1 = insertelement <4 x half> %ins0, half %a1, i32 1 %ins2 = insertelement <4 x half> %ins1, half %b0, i32 2 %ins3 = insertelement <4 x half> %ins2, half %b1, i32 3 ret <4 x half> %ins3 } ``` With the current behavior, `InstCombine` converts each vector extract sequence to ```llvm %tmp = trunc i32 %a to i16 %a0 = bitcast i16 %tmp to half %a1 = extractelement <2 x half> %avec, i32 1 ``` where the extraction of `%a0` is now done by truncating the original integer. While on it's own this is fairly reasonable, in this case it also blocks the pattern which converts `extractelement` - `insertelement` into shuffles which gives the overall simpler result: ```llvm define <4 x half> @bitcast_extract_insert_to_shuffle(i32 %a, i32 %b) { %avec = bitcast i32 %a to <2 x half> %bvec = bitcast i32 %b to <2 x half> %ins3 = shufflevector <2 x half> %avec, <2 x half> %bvec, <4 x i32> <i32 0, i32 1, i32 2, i32 3> ret <4 x half> %ins3 } ``` In this PR I fix the conflict by obeying the `hasOneUse` check even if there is no shift instruction required. In these cases we can't remove the vector completely, so the pattern has less benefit anyway. Also fwiw, I think dropping the `hasOneUse` check for the 0th element might have been a mistake in the first place. Looking at https://github.com/llvm/llvm-project/commit/535c5d56a7bc9966036a11362d8984983a4bf090 the commit message only mentions loosening the `isDesirableIntType` requirement and doesn't mention changing the `hasOneUse` check at all.
2024-11-10[InstCombine] Fix poison safety of folding shufflevector into select (#115483)Yingwei Zheng
We are allowed to fold shufflevector into select iff the condition is guaranteed not to be poison or the RHS is a poison. Alive2: https://alive2.llvm.org/ce/z/28zEWR Closes https://github.com/llvm/llvm-project/issues/115465.
2024-10-29[InstCombine] Do not fold `shufflevector(select)` if the select condition is ↵Yingwei Zheng
a vector (#113993) Since `shufflevector` is not element-wise, we cannot do fold it into select when the select condition is a vector. For shufflevector that doesn't change the length, it doesn't crash, but it is still a miscompilation: https://alive2.llvm.org/ce/z/s8saCx Fixes https://github.com/llvm/llvm-project/issues/113986.
2024-10-28InstCombine: Fold shufflevector(select) and shufflevector(phi) (#113746)Matthias Braun
- Transform `shufflevector(select(c, x, y), C)` to `select(c, shufflevector(x, C), shufflevector(y, C))` by re-using the `FoldOpIntoSelect` helper. - Transform `shufflevector(phi(x, y), C)` to `phi(shufflevector(x, C), shufflevector(y, C))` by re-using the `foldOpInotPhi` helper.
2024-10-11[NFC] Rename `Intrinsic::getDeclaration` to `getOrInsertDeclaration` (#111752)Rahul Joshi
Rename the function to reflect its correct behavior and to be consistent with `Module::getOrInsertFunction`. This is also in preparation of adding a new `Intrinsic::getDeclaration` that will have behavior similar to `Module::getFunction` (i.e, just lookup, no creation).
2024-09-19[ValueTracking] Use isSafeToSpeculativelyExecuteWithVariableReplaced() in ↵Nikita Popov
more places (#109149) This replaces some uses of isSafeToSpeculativelyExecute() with isSafeToSpeculativelyExecuteWithVariableReplaced(), in cases where we are guarding against operand changes rather plain speculation. I believe that this is NFC with the current implementation of the function (as it only does something different from loads), but this makes us more defensive against future generalizations.
2024-08-28Move stepvector intrinsic out of experimental namespace (#98043)Maciej Gabka
This patch is moving out stepvector intrinsic from the experimental namespace. This intrinsic exists in LLVM for several years now, and is widely used.
2024-07-03[InstCombine] Fix invalid scalarization of divNikita Popov
If the binop is not speculatable, and the extract index is out of range, then scalarizing will perform the operation on a poison operand, resulting in immediate UB, instead of the previous poison result. Fixes https://github.com/llvm/llvm-project/issues/97053.
2024-06-26[VectorUtils] Add llvm::scaleShuffleMaskElts wrapper for ↵Simon Pilgrim
narrowShuffleMaskElts/widenShuffleMaskElts, NFC. (#96646) Using the target number of vector elements, scaleShuffleMaskElts will try to use narrowShuffleMaskElts/widenShuffleMaskElts to scale the shuffle mask accordingly. Working on #58895 I didn't want to create yet another case where we have to handle both re-scaling cases.
2024-06-24Revert "[IR][NFC] Update IRBuilder to use InsertPosition (#96497)"Stephen Tozer
Reverts the above commit, as it updates a common header function and did not update all callsites: https://lab.llvm.org/buildbot/#/builders/29/builds/382 This reverts commit 6481dc57612671ebe77fe9c34214fba94e1b3b27.
2024-06-24[IR][NFC] Update IRBuilder to use InsertPosition (#96497)Stephen Tozer
Uses the new InsertPosition class (added in #94226) to simplify some of the IRBuilder interface, and removes the need to pass a BasicBlock alongside a BasicBlock::iterator, using the fact that we can now get the parent basic block from the iterator even if it points to the sentinel. This patch removes the BasicBlock argument from each constructor or call to setInsertPoint. This has no functional effect, but later on as we look to remove the `Instruction *InsertBefore` argument from instruction-creation (discussed [here](https://discourse.llvm.org/t/psa-instruction-constructors-changing-to-iterator-only-insertion/77845)), this will simplify the process by allowing us to deprecate the InsertPosition constructor directly and catch all the cases where we use instructions rather than iterators.
2024-06-18[InstCombine] Use disjoint flag for alternate binopsNikita Popov
Check the or disjoint flag instead of the weaker MaskedValueIsZero query.
2024-06-18[InstCombine] Avoid use of ConstantExpr::getShl()Nikita Popov
Use the constant folding API instead. Use ImmConstant to make sure it actually folds.
2024-05-21[InstCombine] Use m_Poison() instead of m_Undef() (NFCI)Nikita Popov
In this case the shuffle mask checks should already guarantee a single-source shuffle, so this is just for clarity.
2024-05-21[InstCombine] Use m_Poison() instead of m_Undef() (NFCI)Nikita Popov
In this case, the isIdentityWithExtract() checks should already guarantee that these are single-source shuffles, so this is just for clarity.
2024-05-21[InstCombine] Check for poison instead of undef in single shuffle foldNikita Popov
Otherwise we'll convert undef to poison. Alive2 was already flagging the existing test8 test as a miscompile.
2024-05-21[InstCombine] Use m_Poison instead of m_Undef (NFCI)Nikita Popov
In this case, isIdentityWithExtract() should already ensure that this is a single-source shuffle. This just makes things more explicit.
2024-05-21[InstCombine] Check for poison instead of undef in shuffle of unop transformNikita Popov
Otherwise this may not actually be a single-source shuffle.
2024-05-21[InstCombine] Use m_Poison instead of m_Undef in some places (NFCI)Nikita Popov
I believe that in these cases other conditions already ensure that the second operand is not used, this is mostly for clarity.
2024-05-21[InstCombine] Check for poison instead of undef in splat shuffle foldNikita Popov
We can't canonicalize these to a splat shuffle, as doing so would convert undef -> poison.
2024-05-21[InstCombine] Require poison operand in canEvaluateShuffled transformNikita Popov
This transform works on single-source shuffles, which require that the second operand is poison, not undef. Otherwise we may convert undef to poison. Fixes https://github.com/llvm/llvm-project/issues/92887.
2024-03-24[InstCombine] Copy flags of extractelement for extelt -> icmp combine (#86366)Marc Auberer
Fixes #86164
2024-03-21[InstCombine] Fix for folding select-like `shufflevector` into floating ↵Michele Scandale
point binary operators. (#85452) Folding a select-like `shufflevector` into a floating point binary operators can only be done if the result is preserved for both case. In particular, if the common operand of the `shufflevector` and the floating point binary operator can be a NaN, then the transformation won't preserve the result value.
2024-03-05[NFC][RemoveDIs] Insert instruction using iterators in Transforms/Jeremy Morse
As part of the RemoveDIs project we need LLVM to insert instructions using iterators wherever possible, so that the iterators can carry a bit of debug-info. This commit implements some of that by updating the contents of llvm/lib/Transforms/Utils to always use iterator-versions of instruction constructors. There are two general flavours of update: * Almost all call-sites just call getIterator on an instruction * Several make use of an existing iterator (scenarios where the code is actually significant for debug-info) The underlying logic is that any call to getFirstInsertionPt or similar APIs that identify the start of a block need to have that iterator passed directly to the insertion function, without being converted to a bare Instruction pointer along the way. Noteworthy changes: * FindInsertedValue now takes an optional iterator rather than an instruction pointer, as we need to always insert with iterators, * I've added a few iterator-taking versions of some value-tracking and DomTree methods -- they just unwrap the iterator. These are purely convenience methods to avoid extra syntax in some passes. * A few calls to getNextNode become std::next instead (to keep in the theme of using iterators for positions), * SeparateConstOffsetFromGEP has it's insertion-position field changed. Noteworthy because it's not a purely localised spelling change. All this should be NFC.
2023-12-19[InstCombine] Preserve poison in bitcast of insertelement foldNikita Popov
If the base was poison, retain the poison value.
2023-12-19[InstCombine] Check for poison instead of undef in shuffle transformNikita Popov
This one doesn't seem to make a practical difference because we'd canonicalize undef -> poison in the relevant cases anywy.
2023-12-18[InstCombine] Explicitly canonicalize splat shuffles to use poison RHSNikita Popov
This is usually handled by demanded elements simplification. However, as that is not supported for scalable vectors, also handle it explicitly here.
2023-12-18[InstCombine] Preserve poison in evaluateInDifferentElementOrder()Nikita Popov
Don't unnecessarily replace poison with undef.
2023-12-18[InstCombine] Check for poison instead of undef in shuffle combineNikita Popov
Otherwise we may replace undef with poison. Note that a lot of tests regressing here already have variants that use poison instead of undef (often in a separate inseltpoison file), which is why I'm not adjusting them to the new pattern.
2023-12-18[LLVM][IR] Replace ConstantInt's specialisation of getType() with ↵Paul Walker
getIntegerType(). (#75217) The specialisation will not be valid when ConstantInt gains native support for vector types. This is largely a mechanical change but with extra attention paid to constant folding, InstCombineVectorOps.cpp, LoopFlatten.cpp and Verifier.cpp to remove the need to call `getIntegerType()`. Co-authored-by: Nikita Popov <github@npopov.com>
2023-12-18[InstCombine] Rename UndefElts -> PoisonElts (NFC)Nikita Popov
In line with updated shufflevector semantics, this represents the poison elements rather than undef elements now. This commit is a pure rename, without any logic changes.
2023-10-05[IR]Add NumSrcElts param to is..Mask static function in ShuffleVectorInst.Alexey Bataev
Need to add NumSrcElts param to is..Mask functions in ShuffleVectorInstruction class for better mask analysis. Mask.size() not always matches the sizes of the permuted vector(s). Allows to better estimate the cost in SLP and fix uses of the functions in other cases. Differential Revision: https://reviews.llvm.org/D158449
2023-10-04Revert "[IR]Add NumSrcElts param to is..Mask static function in ↵Arthur Eubanks
ShuffleVectorInst." This reverts commit b186f1f68be11630355afb0c08b80374a6d31782. Causes crashes, see https://reviews.llvm.org/D158449.
2023-10-04[IR]Add NumSrcElts param to is..Mask static function in ShuffleVectorInst.Alexey Bataev
Need to add NumSrcElts param to is..Mask functions in ShuffleVectorInstruction class for better mask analysis. Mask.size() not always matches the sizes of the permuted vector(s). Allows to better estimate the cost in SLP and fix uses of the functions in other cases. Differential Revision: https://reviews.llvm.org/D158449
2023-10-03Revert "[IR]Add NumSrcElts param to is..Mask static function in ↵Alexey Bataev
ShuffleVectorInst." This reverts commit 6f43d28f3452b3ef598bc12b761cfc2dbd0f34c9 to fix a crash reported in https://reviews.llvm.org/D158449.
2023-10-03[IR]Add NumSrcElts param to is..Mask static function in ShuffleVectorInst.Alexey Bataev
Need to add NumSrcElts param to is..Mask functions in ShuffleVectorInstruction class for better mask analysis. Mask.size() not always matches the sizes of the permuted vector(s). Allows to better estimate the cost in SLP and fix uses of the functions in other cases. Differential Revision: https://reviews.llvm.org/D158449
2023-09-29Revert "[IR]Add NumSrcElts param to is..Mask static function in ↵Alexey Bataev
ShuffleVectorInst." This reverts commit 9f5960e004ff54082ccfa9396522e07358f5b66b to fix buildbots reported here https://lab.llvm.org/buildbot/#/builders/230/builds/19412.
2023-09-29[IR]Add NumSrcElts param to is..Mask static function in ShuffleVectorInst.Alexey Bataev
Need to add NumSrcElts param to is..Mask functions in ShuffleVectorInstruction class for better mask analysis. Mask.size() not always matches the sizes of the permuted vector(s). Allows to better estimate the cost in SLP and fix uses of the functions in other cases. Differential Revision: https://reviews.llvm.org/D158449
2023-09-28Revert "[IR]Add NumSrcElts param to is..Mask static function in ↵Alexey Bataev
ShuffleVectorInst." This reverts commit c88c281cf1ac1a01c55231b93826d7c8ae83985b to fix the crash revealed by https://lab.llvm.org/buildbot/#/builders/230/builds/19353.