36 Commits

Author SHA1 Message Date
Florian Hahn
06fd0f9d65
[VPlan] Move initial skeleton construction earlier (NFC). (#150848)
Split up the not clearly named prepareForVectorization transform into
buildVPlan0, which adds the vector preheader, middle and scalar
preheader blocks, as well as the canonical induction recipes and sets
the trip count. The new transform is run directly after building the
plain CFG VPlan initially.

The remaining code handling early exits and adding the branch in the
middle block is renamed to handleEarlyExitsAndAddMiddleCheck and still
runs at the original position.

With the code movement, we only have to add the skeleton once to the
initial VPlan, and cloning will take care of the rest. It will also
enable moving other construction steps to work directly on VPlan0, like
adding resume phis.

PR: https://github.com/llvm/llvm-project/pull/150848
2025-08-09 20:54:42 +01:00
Florian Hahn
e80e7e717e
[VPlan] Use scalar VPPhi instead of VPWidenPHIRecipe in createPlainCFG. (#150847)
The initial VPlan closely reflects the original scalar loop, so unsing
VPWidenPHIRecipe here is premature. Widened phi recipes should only be
introduced together with other widened recipes.

PR: https://github.com/llvm/llvm-project/pull/150847
2025-08-06 14:43:03 +01:00
Florian Hahn
0433e1e15f
[VPlan] Add VPlan::getTrue/getFalse convenience helpers (NFC).
Makes it slightly more convenient to create true/false constants.
2025-08-04 21:04:55 +01:00
Simon Pilgrim
b983ce8145 [VPlan] handleMaxMinNumReductions - fix gcc Wparentheses warning. NFC. 2025-08-03 11:50:31 +01:00
Florian Hahn
f8b1c7333f
[VPlan] Add getContext helper to VPlan (NFC). 2025-07-27 18:53:53 +01:00
Florian Hahn
c9a87b45a3
[VPlan] Retrieve latch terminator from VPlan. (NFC)
Remove an unnecessary lookup via original IR loop.
2025-07-27 09:48:59 +01:00
Florian Hahn
bc7487d8ed
[VPlan] Cast header and latch to VPBasicBlock early (NFC).
There are only VPBasicBlocks when prepareForVectorization is called.
Cast them early instead of having multiple casts later on.
2025-07-27 09:47:50 +01:00
Florian Hahn
82e4b83328
[VPlan] Use terminator debug loc for latch BranchOnCond.
Update VPlan to consistently use the latch branch debug location for the
latch branch in the vector loop, if there is one.
2025-07-26 21:45:25 +01:00
Florian Hahn
3813567e08
[VPlan] Clarify transform name to handlMaxNumNumReductions. (NFC)
Clarify name as suggested in https://github.com/llvm/llvm-project/pull/149736,
as only FMaxNum and FMinNum are handled.
2025-07-21 07:14:46 +01:00
Florian Hahn
e3af202fd2
[VPlan] Remove unused IsReplicator arg from createVPRegionBlock (NFC).
The argument is always true, remove it.
2025-07-20 20:58:25 +01:00
Kazu Hirata
28c1433cf3 [Vectorize] Fix a warning
This patch fixes:

  llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp:726:13: error:
  unused variable 'RedPhiRK' [-Werror,-Wunused-variable]
2025-07-18 14:58:52 -07:00
Florian Hahn
004c67ea25
[LV] Vectorize maxnum/minnum w/o fast-math flags. (#148239)
Update LV to vectorize maxnum/minnum reductions without fast-math flags,
by adding an extra check in the loop if any inputs to maxnum/minnum are
NaN, due to maxnum/minnum behavior w.r.t to signaling NaNs. Signed-zeros 
are already handled consistently by maxnum/minnum.

If any input is NaN,
 *exit the vector loop,
 *compute the reduction result up to the vector iteration that contained
   NaN inputs and
 * resume in the scalar loop


New recurrence kinds are added for reductions using maxnum/minnum
without fast-math flags.

PR: https://github.com/llvm/llvm-project/pull/148239
2025-07-18 21:58:19 +01:00
Florian Hahn
afe8150780
[VPlan] Simplify exituser handling by generating all extracts first(NFCI)
Simplify the handling of exit users by generating all extracts first
(safe option), and have FOR handling optimize the extracts, similar to
already done for reductions and inductions.

NFC modulo first-order recurrence extract order in middle block.
2025-07-16 08:14:12 +01:00
Florian Hahn
f168175d01
[VPlan] Move using namespace VPlanPatternMatch to top level (NFC).
VPlanConstruction.cpp doesn't use IR pattern matching, so using
VPlanPatternMatch can be moved to the top-level, to slightly reduce the
diff in follow-up changes.
2025-07-13 19:22:13 +01:00
Florian Hahn
64686c59c3
[VPlan] Connect (MemRuntime|SCEV)Check blocks as VPlan transform (NFC). (#143879)
Connect SCEV and memory runtime check block directly in VPlan as
VPIRBasicBlocks, removing ILV::emitSCEVChecks and
ILV::emitMemRuntimeChecks.

The new logic is currently split across
LoopVectorizationPlanner::addRuntimeChecks which collects a list of
{Condition, CheckBlock} pairs and performs some checks and emits remarks
if needed. The list of checks is then added to VPlan in
VPlanTransforms::connectCheckBlocks.

PR: https://github.com/llvm/llvm-project/pull/143879
2025-07-09 14:03:25 +02:00
Florian Hahn
0f00a96fed
[VPlan] Simplify branch on False in VPlan transform (NFC). (#140409)
Simplify branch on false, starting with the branch from the middle block
to the scalar preheader. Initially this helps simplifying the initial
VPlan construction.

Depends on https://github.com/llvm/llvm-project/pull/140405.

PR: https://github.com/llvm/llvm-project/pull/140409
2025-05-31 20:32:45 +01:00
Florian Hahn
d56deea1e4
[VPlan] Connect Entry to scalar preheader during initial construction. (#140132)
Update initial construction to connect the Plan's entry to the scalar
preheader during initial construction. This moves a small part of the
 skeleton creation out of ILV and will also enable replacing
 VPInstruction::ResumePhi with regular VPPhi recipes.

Resume phis need 2 incoming values to start with, the second being the
bypass value from the scalar ph (and used to replicate the incoming
value for other bypass blocks). Adding the extra edge ensures we
incoming values for resume phis match the incoming blocks.

PR: https://github.com/llvm/llvm-project/pull/140132
2025-05-27 16:07:56 +01:00
Florian Hahn
95ba5508e5
Reapply "[VPlan] Move predication to VPlanTransform (NFC). (#128420)"
This reverts commit 793bb6b257fa4d9f4af169a4366cab3da01f2e1f.

The recommitted version contains a fix to make sure only the original
phis are processed in convertPhisToBlends nu collecting them in a vector
first. This fixes a crash when no mask is needed, because there is only
a single incoming value.

Original message:
This patch moves the logic to predicate and linearize a VPlan to a
dedicated VPlan transform. It mostly ports the existing logic directly.

There are a number of follow-ups planned in the near future to
further improve on the implementation:
* Edge and block masks are cached in VPPredicator, but the block masks
are still made available to VPRecipeBuilder, so they can be accessed
during recipe construction. As a follow-up, this should be replaced by
adding mask operands to all VPInstructions that need them and use that
during recipe construction.
* The mask caching in a map also means that this map needs updating each
time a new recipe replaces a VPInstruction; this would also be handled
by adding mask operands.

PR: https://github.com/llvm/llvm-project/pull/128420
2025-05-22 08:16:15 +01:00
Florian Hahn
793bb6b257
Revert "[VPlan] Move predication to VPlanTransform (NFC). (#128420)"
This reverts commit b263c08e1a0b54a871915930aa9a1a6ba205b099.

Looks like this triggers a crash in one of the Fortran tests. Reverting
while I investigate
    https://lab.llvm.org/buildbot/#/builders/41/builds/6825
2025-05-21 19:24:21 +01:00
Florian Hahn
b263c08e1a
[VPlan] Move predication to VPlanTransform (NFC). (#128420)
This patch moves the logic to predicate and linearize a VPlan to a
dedicated VPlan transform. It mostly ports the existing logic directly.

There are a number of follow-ups planned in the near future to
further improve on the implementation:
* Edge and block masks are cached in VPPredicator, but the block masks
are still made available to VPRecipeBuilder, so they can be accessed
during recipe construction. As a follow-up, this should be replaced by
adding mask operands to all VPInstructions that need them and use that
during recipe construction.
* The mask caching in a map also means that this map needs updating each
time a new recipe replaces a VPInstruction; this would also be handled
by adding mask operands.


PR: https://github.com/llvm/llvm-project/pull/128420
2025-05-21 15:47:33 +01:00
Florian Hahn
2f55123cbb
[VPlan] Handle early exit before forming regions. (NFC) (#138393)
Move early-exit handling up front to original VPlan construction, before
introducing early exits.

This builds on https://github.com/llvm/llvm-project/pull/137709, which
adds exiting edges to the original VPlan, instead of adding exit blocks
later.

This retains the exit conditions early, and means we can handle early
exits before forming regions, without the reliance on VPRecipeBuilder.

Once we retain all exits initially, handling early exits before region
construction ensures the regions are valid; otherwise we would leave
edges exiting the region from elsewhere than the latch.

Removing the reliance on VPRecipeBuilder removes the dependence on
mapping IR BBs to VPBBs and unblocks predication as VPlan transform:
https://github.com/llvm/llvm-project/pull/128420.

Depends on https://github.com/llvm/llvm-project/pull/137709 (included in
PR).

PR: https://github.com/llvm/llvm-project/pull/138393
2025-05-12 12:53:20 +01:00
Florian Hahn
cfde685e22
[VPlan] Sink VPB2IRBB lookups to VPRecipeBuilder (NFC).
This allows migrating some more code to be based on VPBBs in
VPRecipeBuilder, in preparation for
https://github.com/llvm/llvm-project/pull/128420.
2025-05-10 22:00:58 +01:00
Florian Hahn
339dc9500b
[VPlan] Retain exit conditions and edges in initial VPlan (NFC). (#137709)
Update initial VPlan construction to include exit conditions and edges.

The loop region is now first constructed without entry/exiting. Those
are set after inserting the region in the CFG, to preserve the original
predecessor/successor order of blocks.

For now, all early exits are disconnected before forming the regions,
but a follow-up will update uncountable exit handling to also happen
here. This is required to enable VPlan predication and remove the
dependence any IR BBs
(https://github.com/llvm/llvm-project/pull/128420).

PR: https://github.com/llvm/llvm-project/pull/137709
2025-05-08 18:10:52 +01:00
Florian Hahn
32928a0784
[VPlan] Construct regions from innermost to outermost (NFC).
Flip the region construction order to innermost first from outermost
first. This ensures we only set the final parent region for VPBBs once.

Split off from https://github.com/llvm/llvm-project/pull/137709.
2025-05-06 20:49:24 +01:00
Florian Hahn
282af2ddfc
[VPlan] Remove unneeded checks from PlanCFGBuilder::isExternalDef (NFC).
Remove checking if the instruction is in the preheader or exit blocks.
Those checks are redundant and handled by checking if the instruction is
outside the loop below.

Split off as suggested from https://github.com/llvm/llvm-project/pull/137709.
2025-05-06 19:04:22 +01:00
Florian Hahn
edb690dc5b
Reapply "[VPlan] Add canonical IV during construction (NFC)."
This reverts commit d431921677ae923d189ff2d6f188f676a2964ed8.

Missing gtests have been updated.

Original message:

This addresses an existing TODO and simply moves the current code to add
canonical IV recipes to the initial skeleton construction, at the same
place where the corresponding region will be introduced.
2025-05-03 10:54:59 +01:00
Florian Hahn
d431921677
Revert "[VPlan] Add canonical IV during construction (NFC)."
This reverts commit e17122fffa8d233fcf9f717354ecda46173f1b8d.

Revert as this seems to break some unit tests on some bots.
2025-04-29 22:55:11 +01:00
Florian Hahn
e17122fffa
[VPlan] Add canonical IV during construction (NFC).
This addresses an existing TODO and simply moves the current code to add
canonical IV recipes to the initial skeleton construction, at the same
place where the corresponding region will be introduced.
2025-04-29 22:38:59 +01:00
Florian Hahn
d2ce88a939
[VPlan] Create initial skeleton before creating regions. (NFC)
Move out the logic to prepare for vectorization to a separate transform,
before creating loop regions. This was discussed as follow-up
in https://github.com/llvm/llvm-project/pull/136455.

This just moves the existing code around slightly  and will simplify
follow-up patches to include the exiting edges during initial VPlan
construction.
2025-04-28 21:51:32 +01:00
Florian Hahn
92bfbbc4e5
[VPlan] Invert condition if needed when creating inner regions. (#132292)
As pointed out by @iamlouk in
https://github.com/llvm/llvm-project/pull/129402, the current code
doesn't handle latches with different successor orders correctly.
Introduce a `NOT`, if needed.

Depends on  https://github.com/llvm/llvm-project/pull/129402

PR: https://github.com/llvm/llvm-project/pull/132292
2025-04-28 09:40:43 +01:00
Florian Hahn
826f237cb4
[VPlan] Don't added separate vector latch block (NFC).
Simplify initial VPlan construction by not creating a separate
vector.latch block, which isn't needed and will get folded away later.
This has been suggested as independent clean-up multiple times.
2025-04-26 22:03:18 +01:00
Florian Hahn
ff36508d21
[VPlan] Remove redundant setting of parent in createLoopRegion (NFC).
The regions parents will be set when the parents are set after creating
the parent region.
2025-04-23 21:45:15 +01:00
Florian Hahn
3fbbe9b8d0
[VPlan] Add exit phi operands during initial construction (NFC). (#136455)
Add incoming exit phi operands during the initial VPlan construction.
This ensures all users are added to the initial VPlan and is also needed
in preparation to retaining exiting edges during initial construction.

PR: https://github.com/llvm/llvm-project/pull/136455
2025-04-23 20:40:42 +01:00
Florian Hahn
e232d28eff
[VPlan] Move plain CFG construction to VPlanConstruction. (NFC)
Follow-up as discussed in https://github.com/llvm/llvm-project/pull/129402.

After bc03d6cce257, the VPlanHCFGBuilder doesn't actually build a HCFG
any longer. Move what remains directly into VPlanConstruction.cpp.
2025-04-18 21:52:05 +01:00
Florian Hahn
bc03d6cce2
[VPlan] Introduce all loop regions as VPlan transform. (NFC) (#129402)
Further simplify VPlan CFG builder by moving introduction of inner
regions to a VPlan transform, building on
https://github.com/llvm/llvm-project/pull/128419.

The HCFG builder now only constructs plain CFGs. I will move it to
VPlanConstruction as follow-up.

Depends on https://github.com/llvm/llvm-project/pull/128419.

PR: https://github.com/llvm/llvm-project/pull/129402
2025-04-16 13:30:45 +02:00
Florian Hahn
fd267082ee
[VPlan] Refactor VPlan creation, add transform introducing region (NFC). (#128419)
Create an empty VPlan first, then let the HCFG builder create a plain
CFG for the top-level loop (w/o a top-level region). The top-level
region is introduced by a separate VPlan-transform. This is instead of
creating the vector loop region before building the VPlan CFG for the
input loop.

This simplifies the HCFG builder (which should probably be renamed) and
moves along the roadmap ('buildLoop') outlined in [1].

As follow-up, I plan to also preserve the exit branches in the initial
VPlan out of the CFG builder, including connections to the exit blocks.

The conversion from plain CFG with potentially multiple exits to a
single entry/exit region will be done as VPlan transform in a follow-up.

This is needed to enable VPlan-based predication. Currently early exit
support relies on building the block-in masks on the original CFG,
because exiting branches and conditions aren't preserved in the VPlan.
So in order to switch to VPlan-based predication, we will have to
preserve them in the initial plain CFG, so the exit conditions are
available explicitly when we convert to single entry/exit regions.

Another follow-up is updating the outer loop handling to also introduce
VPRegionBlocks for nested loops as transform. Currently the existing
logic in the builder will take care of creating VPRegionBlocks for
nested loops, but not the top-level loop.

[1]
https://llvm.org/devmtg/2023-10/slides/techtalks/Hahn-VPlan-StatusUpdateAndRoadmap.pdf

PR: https://github.com/llvm/llvm-project/pull/128419
2025-03-09 15:05:35 +00:00