summaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms
AgeCommit message (Collapse)Author
2025-07-03[LSR] Strip dead code (NFC) (#146109)Ramkumar Ramachandra
Nested AddRec is already rejected by the handling in pushSCEV().
2025-07-03[VPlan] Don't convert VPWidenSelectRecipes to vp.select in EVL transform ↵Luke Lau
(#146695) createEVLRecipe tries to optimise recipes that use the header mask by replacing them with their VP equivalents and setting the EVL, allowing the mask to be removed. However we currently also convert widened selects to vp.select even though they don't necessarily use the header mask. Unlike vp.merge a vp.select only makes the "unused" lanes past EVL poison, so it's not needed for correctness. In the same vein as #127180, this patch removes the transform for VPWidenSelectRecipes and keeps them as plain select instructions to allow for more optimisations. RISCVVLOptimizer will still be able to optimise away any VL toggles and we end up with better code generation across llvm-test-suite and SPEC CPU 2017.
2025-07-03[VPlan] Remove redundant debug location setting in ↵Mel Chen
VPInterleaveRecipe::execute. nfc (#146670) Remove it since we already set debug loc in VPBasicBlock::executeRecipes.
2025-07-03[VectorCombine] Scalarize extracts of ZExt if profitable. (#142976)Florian Hahn
Add a new scalarization transform that tries to convert extracts of a vector ZExt to a set of scalar shift and mask operations. This can be profitable if the cost of extracting is the same or higher than the cost of 2 scalar ops. This is the case on AArch64 for example. For AArch64,this shows up in a number of workloads, including av1aom, gmsh, minizinc and astc-encoder. PR: https://github.com/llvm/llvm-project/pull/142976
2025-07-03[VPlan] Early assert for unsupported interleaved access features. nfc (#146669)Mel Chen
2025-07-02[msan] Fix "Add optional flag to improve instrumentation of disjoint OR ↵Thurston Dang
(#145990)" (#146799) The "V1" and "V2" values were already NOT'ed, hence the calculation of disjoint OR in #145990 was incorrect. This patch fixes the issue, with some refactoring and renaming of variables.
2025-07-02[NFC] [MSAN] replace (void) with [[maybe_unused]] (#146617)Florian Mayer
The latter is preferred in the LLVM style guide.
2025-07-02[SimplifyCFG] Transform switch to select when common bits uniquely identify ↵Gábor Spaits
one case (#145233) Fix #141753 . This patch introduces a new check, that tries to decide if the conjunction of all the values uniquely identify the accepted values by the switch.
2025-07-02[VectorCombine] Scalarize vector intrinsics with scalar arguments (#146530)Luke Lau
Some intrinsics like llvm.abs or llvm.powi have a scalar argument even when the overloaded type is a vector. This patch handles these in scalarizeOpOrCmp to allow scalarizing them. In the test the leftover vector powi isn't folded away to poison, this should be fixed in a separate patch.
2025-07-02[InstCombine] Fix multi-use handling for multi-GEP rewrite (#146689)Nikita Popov
If we're expanding offsets for a chain of GEPs in RewriteGEPs mode, we should also rewrite GEPs that have one-use themselves, but are kept alive by a multi-use GEP later in the chain. For the sake of simplicity, I've changed this to just skip the one-use condition entirely (which will perform an unnecessary rewrite of a no longer used GEP, but shouldn't otherwise matter).
2025-07-02[LV] Add support for partial reductions without a binary op (#133922)David Sherwood
Consider IR such as this: for.body: %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ] %accum = phi i32 [ 0, %entry ], [ %add, %for.body ] %gep.a = getelementptr i8, ptr %a, i64 %iv %load.a = load i8, ptr %gep.a, align 1 %ext.a = zext i8 %load.a to i32 %add = add i32 %ext.a, %accum %iv.next = add i64 %iv, 1 %exitcond.not = icmp eq i64 %iv.next, 1025 br i1 %exitcond.not, label %for.exit, label %for.body Conceptually we can vectorise this using partial reductions too, although the current loop vectoriser implementation requires the accumulation of a multiply. For AArch64 this is easily done with a udot or sdot with an identity operand, i.e. a vector of (i16 1). In order to do this I had to teach getScaledReductions that the accumulated value may come from a unary op, hence there is only one extension to consider. Similarly, I updated the vplan and AArch64 TTI cost model to understand the possible unary op. --------- Co-authored-by: Matt Devereau <matthew.devereau@arm.com>
2025-07-02[VPlan] Emit VPVectorEndPointerRecipe for reverse interleave pointer ↵Mel Chen
adjustment (#144864) A reverse interleave access is essentially composed of multiple load/store operations with same negative stride, and their addresses are based on the last lane address of member 0 in the interleaved group. Currently, we already have VPVectorEndPointerRecipe for computing the last lane address of consecutive reverse memory accesses. This patch extends VPVectorEndPointerRecipe to support constant stride and extracts the reverse interleave group address adjustment from VPInterleaveRecipe::execute, replacing it with a VPVectorEndPointerRecipe. The final goal is to support interleaved accesses with EVL tail folding. Given that VPInterleaveRecipe is large and tightly coupled — combining both load and store, and embedding operations like reverse pointer adjustion (GEP), widen load/store, deinterleave/interleave, and reversal — breaking it down into smaller, dedicated recipes may allow VPlanTransforms::tryAddExplicitVectorLength to lower them into EVL-aware form more effectively. One foreseeable challenge is that VPlanTransforms::convertToConcreteRecipes currently runs after tryAddExplicitVectorLength, so decomposing VPInterleaveRecipe will likely need to happen earlier in the pipeline to be effective.
2025-07-02VPlanRecipes.cpp - fix "'llvm::VPExpressionRecipe::computeCost': not all ↵Simon Pilgrim
control paths return a value" MSVC warning. NFC.
2025-07-02[IR] Introduce `dead_on_return` attributeAntonio Frighetto
Add `dead_on_return` attribute, which is meant to be taken advantage by the frontend, and states that the memory pointed to by the argument is dead upon function return. As with `byval`, it is supposed to be used for passing aggregates by value. The difference lies in the ABI: `byval` implies that the pointer is explicitly passed as argument to the callee (during codegen the copy is emitted as per byval contract), whereas a `dead_on_return`-marked argument implies that the copy already exists in the IR, is located at a specific stack offset within the caller, and this memory will not be read further by the caller upon callee return – or otherwise poison, if read before being written. RFC: https://discourse.llvm.org/t/rfc-add-dead-on-return-attribute/86871.
2025-07-02[InstCombine] Fold icmp of gep chain with base (#144065)Nikita Popov
Fold icmp between a chain of geps and its base pointer. Previously only a single gep was supported. This will be extended to handle the case of two gep chains with a common base in a followup. This helps to avoid regressions after #137297.
2025-07-01[VPlan] Make Phi operand for VPReductionPHIRecipe optional (NFC).Florian Hahn
VPReductionPHIRecipe doesn't rely on the underlying phi any longer, allow empty underlying values when cloning. NFC at the moment but will enable follow-up patches.
2025-07-01[Reland][IPO] Added attributor for identifying invariant loads (#146584)zGoldthorpe
Patched and tested the `AAInvariantLoadPointer` attributor from #141800, which identifies pointers whose loads are eligible to be marked as `!invariant.load`. The bug in the attributor was due to `AAMemoryBehavior` always identifying pointers obtained from `alloca`s as having no writes. I'm not entirely sure why `AAMemoryBehavior` behaves this way, but it seems to be beceause it identifies the scope of an `alloca` to be limited to only that instruction (and, certainly, no memory writes occur within the `alloca` instructin). This patch just adds a check to disallow all loads from `alloca` pointers from being marked `!invariant.load` (since any well-defined program will have to write to stack pointers at some point).
2025-07-01[VPlan] Add missing VPWidenSelectto VPRecipeWithIRFlags::classof (NFC).Florian Hahn
Add missing entry to VPRecipeWithIRFlags. NFC currently as it is never called on VPWidenSelectRecipes currently.
2025-07-01[VectorCombine] Mark function as changed if shuffle is created.Florian Hahn
777d6b5de90b7e0 exposed a code path where a function is modified but not marked accordingly. Make sure we return true from foldShuffleFromReductions if only a shuffle has been inserted/replaced. Should fix https://lab.llvm.org/buildbot/#/builders/187/builds/7578.
2025-07-01[VectorCombine] Use InstSimplifyFolder to simplify instrs on creation. (#146350)Florian Hahn
Update VectorCombine to use InstSimplifyFolder to simplify redundant instructions on creation. PR: https://github.com/llvm/llvm-project/pull/146350
2025-07-01[VPlan] Add VPExpressionRecipe, replacing extended reduction recipes. (#144281)Florian Hahn
This patch adds a new recipe to combine multiple recipes into an 'expression' recipe, which should be considered as single entity for cost-modeling and transforms. The recipe needs to be 'decomposed', i.e. replaced by its individual recipes before execute. This subsumes VPExtendedReductionRecipe and VPMulAccumulateReductionRecipe and should make it easier to extend to include more types of bundled patterns, like e.g. extends folded into loads or various arithmetic instructions, if supported by the target. It allows avoiding re-creating the original recipes when converting to concrete recipes, together with removing the need to record various information. The current version of the patch still retains the original printing matching VPExtendedReductionRecipe and VPMulAccumulateReductionRecipe, but this specialized print could be replaced with printing the bundled recipes directly. PR: https://github.com/llvm/llvm-project/pull/144281
2025-07-01[InstCombine] Pull vector reverse through intrinsics (#146384)Luke Lau
This is the intrinsic version of #146349, and handles fabs as well as other intrinsics. It's largely a copy of InstCombinerImpl::foldShuffledIntrinsicOperands but a bit simpler since we don't need to find a common mask. Creating a separate function seems to be cleaner than trying to shoehorn it into the existing one.
2025-07-01[InstCombine] Fix use after freeNikita Popov
Load the nowrap flags before calling EmitGEPOffset(), as this may free the instruction.
2025-07-01[FunctionAttrs] Handle ConstantRange overflow in memset initializes ↵Shivam Gupta
inference (#145739) Avoid constructing invalid ConstantRange when Offset + Length in memset overflows signed 64-bit integer space. This prevents assertion failures when inferring the initializes attribute. Fixes #140345
2025-07-01[InstCombine] Rewrite multi-use GEPs when simplifying comparison (#146100)Nikita Popov
We already do this when both sides are a GEP, but not if only one is. This ensures that the offset arithmetic is not duplicated.
2025-07-01[LV] Use vscale for tuning to improve branch weight estimates (#144733)David Sherwood
In addBranchWeightToMiddleTerminator we attempt to add branch weights to the middle block terminator. We pessimistically assume vscale=1, whereas we can improve the estimate by using the value of vscale used for tuning.
2025-07-01[VPlan] Support VPWidenIntOrFpInductionRecipes with EVL tail folding (#144666)Luke Lau
Following on from #118638, this handles widened induction variables with EVL tail folding by setting the VF operand to be EVL, calculated in the vector body. We need to do this for correctness since with EVL tail folding the number of elements processed in the penultimate iteration may not be VF, but the runtime EVL, and we need take this into account when updating the backedge value. - Because the VF may now not be a live-in we need to move the insertion point to just after the VFs definition - We also need to avoid truncating it when it's the same size as the step type, previously this wasn't a problem for live-ins. - Also because the VF may be smaller than the IV type, since the EVL is always i32, we may need to zext it. On -march=rva23u64 -O3 we get 87.1% more loops vectorized on TSVC, and 42.8% more loops vectorized on SPEC CPU 2017
2025-07-01[InstCombine] Combine interleaved recurrences. (#143878)Ricardo Jesus
Combine sequences such as: ```llvm %pn1 = phi [init1, %BB1], [%op1, %BB2] %pn2 = phi [init2, %BB1], [%op2, %BB2] %op1 = binop %pn1, constant1 %op2 = binop %pn2, constant2 %rdx = binop %op1, %op2 ``` Into: ```llvm %phi_combined = phi [init_combined, %BB1], [%op_combined, %BB2] %rdx_combined = binop %phi_combined, constant_combined ``` This allows us to simplify interleaved reductions, for example as introduced by the loop vectorizer. The anecdotal example for this is the loop below: ```c float foo() { float q = 1.f; for (int i = 0; i < 1000; ++i) q *= .99f; return q; } ``` Which currently gets lowered explicitly such as (on AArch64, interleaved by four): ```gas .LBB0_1: fmul v0.4s, v0.4s, v1.4s fmul v2.4s, v2.4s, v1.4s fmul v3.4s, v3.4s, v1.4s fmul v4.4s, v4.4s, v1.4s subs w8, w8, #32 b.ne .LBB0_1 ``` But with this patch lowers trivially: ```gas foo: mov w8, #5028 movk w8, #14389, lsl #16 fmov s0, w8 ret ```
2025-07-01[Coroutines] Work on intrinsic IDs instead of names (NFCI) (#145518)Nikita Popov
For the checks whether certain intrinsics are used, work with intrinsic IDs instead of intrinsic names. This also exposes that some of the checks were incorrect, because the intrinsics were overloaded. There is no efficient way to determine whether these are used. This change explicitly documents which intrinsics are not checked for this reason.
2025-06-30[VPlan] Truncate/Extend ComputeReductionResult at construction (NFC). (#141860)Florian Hahn
Instead of looking up the narrower reduction type via getRecurrenceType we can generate the needed extend directly at constructiond re-use the truncated value from the loop. PR: https://github.com/llvm/llvm-project/pull/141860
2025-06-30[VPlan] Infer reduction result types w/o accessing underlying phis.(NFC)Florian Hahn
Remove another use of the underlying IR phi.
2025-06-30[SCCP] Improve worklist management (#146321)Nikita Popov
SCCP currently stores instructions whose lattice value has changed in a worklist, and then updates their users in the main loop. This may result in instructions unnecessarily being visited multiple times (as an instruction will often use multiple other instructions). Additionally, we'd often redundantly visit instructions that were already visited when the containing block first became executable. Instead, change the worklist to directly store the instructions that need to be revisited. Additionally, do not add instructions to the worklist that will already be covered by the main basic block walk. This change is conceptually NFC, but is expected to produce minor differences in practice, because the visitation order interacts with the range widening limit.
2025-06-30[InstCombine] Pull vector reverse through fneg (#146349)Luke Lau
This follows on from https://github.com/llvm/llvm-project/pull/144933#issuecomment-2992372627, and allows us to remove the reverse (fneg (reverse x)) combine. A separate patch will handle the case for fabs. I haven't checked if we perform this canonicalization for either unops or binops for vp.reverse
2025-06-30[InstCombine] smin(smax(X, -1), 1) -> scmp(X, 0) and smax(smin(X, 1), -1) -> ↵AZero13
scmp(X, 0) (#145736) Motivating case: https://godbolt.org/z/Wxcc51jcj Alive2: https://alive2.llvm.org/ce/z/-bPPAg
2025-06-30[GlobalOpt] Revert global widening transform (#144652)Nikita Popov
Partially reverts e37d736def5b95a2710f92881b5fc8b0494d8a05. The transform has a number of correctness and code quality issues, and will benefit from a from-scratch re-review more than incremental fixes. The correctness issues are hinted at in https://github.com/llvm/llvm-project/pull/144641, but I think it needs a larger rework to stop working on ArrayTypes and the implementation could use some other improvements (like callInstIsMemcpy should just be `dyn_cast<MemCpyInst>`). I can comment in more detail on a resubmission of the patch.
2025-06-30[VPlan] Replace all uses of VF when EVL tail folding. NFCI (#146339)Luke Lau
With EVL tail folding, any use of the VF live in should be replaced by the EVL. Otherwise, it should likely be directly emitted as a constant via VPTransformState::VF. This strengthens the EVL transformation by replacing all uses of VF with EVL and asserting that the only users are VPVectorEndPointerRecipe and VPScalarIVStepsRecipe, the latter of which is new. This should be NFC because even though we didn't previously replace the EVL of VPScalarIVStepsRecipe, it's only used when unrolling which we don't allow with EVL tail folding yet.
2025-06-30[EarlyCSE] Add support for writeonly call CSE (#145474)Nikita Popov
Add support for CSE of writeonly calls, similar to the existing support for readonly calls.
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-30[KeyInstr] Add DISubprogram::keyInstructions bit (#144107)Orlando Cazalet-Hyams
Patch 1/4 adding bitcode support. Store whether or not a function is using Key Instructions in its DISubprogram so that we don't need to rely on the -mllvm flag -dwarf-use-key-instructions to determine whether or not to interpret Key Instructions metadata to decide is_stmt placement at DWARF emission time. This makes bitcode support simple and enables well defined mixing of non-key-instructions and key-instructions functions in an LTO context. This patch adds the bit (using DISubprogram::SubclassData1). PR 144104 and 144103 use it during DWARF emission. PR 44102 adds bitcode support. See pull request for overview of alternative attempts.
2025-06-29[VPlan] Fix crash when trying to narrow interleave group storing const.Florian Hahn
Use dyn_cast_null to handle the case where an interleave groups stores a constant in any of its lanes.
2025-06-29Revert "[VPlan] Allow derived IVs and scalar-steps in narrowing interleave."Florian Hahn
This reverts commit 2787759ef2e41b19f8bfde06fe9a26b25d1f5834. This exposed a crash on some build bots. Revert to investigate.
2025-06-29[InstCombine] Create Icmp in canonical form (NFC) (#146266)Andreas Jonson
2025-06-29[VPlan] Allow derived IVs and scalar-steps in narrowing interleave.Florian Hahn
Both VPDerivedIVRecipe and VPScalarIVSteps recipe should be supported in narrowInterleaveGroups: * VPDerivedIVRecipe is based on the canonical IV and independent of VF, * VPScalarIVSteps takes the VF as operand, so it will be updated by narrowInterleaveGroup.
2025-06-29[LV] Add support for cmp reductions with decreasing IVs. (#140451)Florian Hahn
Similar to FindLastIV, add FindFirstIVSMin to support select (icmp(), x, y) reductions where one of x or y is a decreasing induction, producing a SMin reduction. It uses signed max as sentinel value. PR: https://github.com/llvm/llvm-project/pull/140451
2025-06-28[VPlan] Simplify code in single scalar transform code (NFC).Florian Hahn
Adjust code as suggested post-commit 3b7b95f78e2. https://github.com/llvm/llvm-project/commit/3b7b95f78e24aca5175b8f864bfea2953a2dd34f#r160997427
2025-06-28[SimplifyCFG] Use indexType from data layout in switch to table conversion ↵Andreas Jonson
(#146207) Generate the GEP with the index type that InstCombine will cast it to but use the knowledge that the index is unsigned.
2025-06-28[VPlan] Also visit VPBBs outside loop region when unrolling by VF.Florian Hahn
Make sure all VPBBs outside the top-level loop region and directly inside the region are visited; all those blocks may contain VPReplicateRecipes that need unrolling. This makes sure we unroll VPRepicateRecipes by VF if they are hoisted out of the loop, but cannot be converted to single scalar recipes yet.
2025-06-28[LSR] Clean up code using SCEVPatternMatch (NFC) (#145556)Ramkumar Ramachandra
2025-06-28[LoopInterchange] Modernize loops (NFC) (#146105)Ramkumar Ramachandra
2025-06-28[RelLookupTableConverter] Drop unnamed_addr for GVs in entries to avoid ↵dianqk
generating GOTPCREL relocations (#146068) The entry in a relative lookup table is a global variable with a constant offset, such as `@gv`, `GEP @gv, 1`, and so on. We cannot only consider the case of a trivial global variable. This PR handles all cases using the existing `IsConstantOffsetFromGlobal` function.