Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
e72140a
[LV] Expand VPWidenIntOrFpInductionRecipe into separate recipes
lukel97 Dec 4, 2024
6fc4a7c
Remove initial and backedge recipes, expand out to regular VPInstruct…
lukel97 Dec 12, 2024
e7f5a4e
Only truncate the IV step, don't widen it
lukel97 Dec 12, 2024
31bdc7c
Use recipe debugloc after 734a204fbd4b790048c57f79351ad8beeb1000ce
lukel97 Dec 16, 2024
42dc912
Mark splat and step vector recipes as free from side effects/reads/wr…
lukel97 Dec 16, 2024
6839647
Fix crash when pointer IV comes after intorfp IV
lukel97 Dec 17, 2024
6c659ca
Remove VPWidenIntOrFpInductionPHIRecipe, use VPWidenPHIRecipe instead
lukel97 Dec 4, 2024
1cd6c81
Use dyn_cast
lukel97 Jan 6, 2025
dcc6640
Remove VPSplatRecipe, replace with VPInstruction::Splat
lukel97 Jan 6, 2025
ca81015
Update comment
lukel97 Jan 6, 2025
8b77af4
Pass Name when generating VPInstruction::Splat
lukel97 Jan 8, 2025
5ad4cc1
Allow splatting VPScalarCastRecipe directly, remove VPInstruction::splat
lukel97 Feb 3, 2025
d183c91
Remove VPStepVectorRecipe, replace with VPInstruction
lukel97 Feb 3, 2025
79b9700
Add VPlan debug output test
lukel97 Feb 18, 2025
d3d85f6
Undo stray whitespace change
lukel97 Feb 18, 2025
8f94610
Fix ARM test
lukel97 Feb 18, 2025
dff84ec
Remove unnecessary assert
lukel97 Mar 3, 2025
5457030
Merge remote-tracking branch 'origin/main' into loop-vectorize/split-…
lukel97 Mar 3, 2025
68b6b66
Update vplan test to include preheader, remove references to old reci…
lukel97 Mar 3, 2025
8257a57
Merge branch 'main' of github.com:llvm/llvm-project into loop-vectori…
lukel97 May 8, 2025
0f8b4f6
Update now that #129508 is landed
lukel97 May 8, 2025
7fc4859
clang-format
lukel97 May 8, 2025
61bd641
Fix typo, use TypeInfo in assert
lukel97 May 14, 2025
ec5fe59
Don't move VPWidenPointerInductionRecipe, instead fixup location of p…
lukel97 May 14, 2025
466ed14
Merge branch 'main' of github.com:llvm/llvm-project into loop-vectori…
lukel97 May 21, 2025
b315afb
Fix comments
lukel97 May 21, 2025
993ba23
Remove VPWidenPHIRecipe change
lukel97 May 21, 2025
894bde0
Merge branch 'main' of github.com:llvm/llvm-project into loop-vectori…
lukel97 May 29, 2025
8037a19
Merge branch 'main' of github.com:llvm/llvm-project into loop-vectori…
lukel97 Jun 2, 2025
ddca9b9
Merge branch 'main' of github.com:llvm/llvm-project into loop-vectori…
lukel97 Jun 3, 2025
27c724e
Merge branch 'main' of github.com:llvm/llvm-project into loop-vectori…
lukel97 Jun 11, 2025
b83af78
Merge branch 'main' of github.com:llvm/llvm-project into loop-vectori…
lukel97 Jun 13, 2025
55deb1c
Merge branch 'main' of github.com:llvm/llvm-project into loop-vectori…
lukel97 Jun 17, 2025
7cf85b9
Infer and check types instead of peeking through underlying value for…
lukel97 Jun 17, 2025
4f3acf0
Move comment to flags
lukel97 Jun 17, 2025
e8d64a4
Use ToRemove
lukel97 Jun 17, 2025
f34b569
Remove null ptr in test, update variable names
lukel97 Jun 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,12 @@ class VPBuilder {
FPBinOp ? FPBinOp->getFastMathFlags() : FastMathFlags()));
}

VPInstruction *createStepVector(Type *Ty) {
VPValue *TyVal = BB->getPlan()->getOrAddLiveIn(Constant::getNullValue(Ty));
return tryInsertInstruction(
new VPInstruction(VPInstruction::StepVector, {TyVal}));
}

//===--------------------------------------------------------------------===//
// RAII helpers.
//===--------------------------------------------------------------------===//
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2935,8 +2935,7 @@ LoopVectorizationCostModel::getVectorIntrinsicCost(CallInst *CI,

void InnerLoopVectorizer::fixVectorizedLoop(VPTransformState &State) {
// Fix widened non-induction PHIs by setting up the PHI operands.
if (EnableVPlanNativePath)
fixNonInductionPHIs(State);
fixNonInductionPHIs(State);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needed because we're now using VPWidenPHI on the non-vplan-native path. Happy to split this off into an NFC as well if wanted


// After vectorization, the exit blocks of the original loop will have
// additional predecessors. Invalidate SCEVs for the exit phis in case SE
Expand Down Expand Up @@ -7716,7 +7715,8 @@ DenseMap<const SCEV *, Value *> LoopVectorizationPlanner::executePlan(
VPlanTransforms::optimizeForVFAndUF(BestVPlan, BestVF, BestUF, PSE);
VPlanTransforms::simplifyRecipes(BestVPlan, *Legal->getWidestInductionType());
VPlanTransforms::removeDeadRecipes(BestVPlan);
VPlanTransforms::convertToConcreteRecipes(BestVPlan);
VPlanTransforms::convertToConcreteRecipes(BestVPlan,
Legal->getWidestInductionType());

// Perform the actual loop transformation.
VPTransformState State(&TTI, BestVF, BestUF, LI, DT, ILV.Builder, &ILV,
Expand Down
40 changes: 16 additions & 24 deletions llvm/lib/Transforms/Vectorize/VPlan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,15 +313,17 @@ Value *VPTransformState::get(const VPValue *Def, bool NeedsScalar) {
LastLane = 0;
}

auto *LastInst = cast<Instruction>(get(Def, LastLane));
// Set the insert point after the last scalarized instruction or after the
// last PHI, if LastInst is a PHI. This ensures the insertelement sequence
// will directly follow the scalar definitions.
auto OldIP = Builder.saveIP();
auto NewIP = isa<PHINode>(LastInst)
? LastInst->getParent()->getFirstNonPHIIt()
: std::next(BasicBlock::iterator(LastInst));
Builder.SetInsertPoint(&*NewIP);
auto *LastVal = get(Def, LastLane);
if (auto *LastInst = dyn_cast<Instruction>(LastVal)) {
// Set the insert point after the last scalarized instruction or after the
// last PHI, if LastInst is a PHI. This ensures the insertelement sequence
// will directly follow the scalar definitions.
auto NewIP = isa<PHINode>(LastInst)
? LastInst->getParent()->getFirstNonPHIIt()
: std::next(BasicBlock::iterator(LastInst));
Builder.SetInsertPoint(&*NewIP);
}

// However, if we are vectorizing, we need to construct the vector values.
// If the value is known to be uniform after vectorization, we can just
Expand All @@ -336,7 +338,7 @@ Value *VPTransformState::get(const VPValue *Def, bool NeedsScalar) {
} else {
// Initialize packing with insertelements to start from undef.
assert(!VF.isScalable() && "VF is assumed to be non scalable.");
Value *Undef = PoisonValue::get(toVectorizedTy(LastInst->getType(), VF));
Value *Undef = PoisonValue::get(toVectorizedTy(LastVal->getType(), VF));
set(Def, Undef);
for (unsigned Lane = 0; Lane < VF.getKnownMinValue(); ++Lane)
packScalarIntoVectorizedValue(Def, Lane);
Expand Down Expand Up @@ -1050,28 +1052,18 @@ void VPlan::execute(VPTransformState *State) {
if (isa<VPWidenPHIRecipe>(&R))
continue;

if (isa<VPWidenInductionRecipe>(&R)) {
PHINode *Phi = nullptr;
if (isa<VPWidenIntOrFpInductionRecipe>(&R)) {
Phi = cast<PHINode>(State->get(R.getVPSingleValue()));
} else {
auto *WidenPhi = cast<VPWidenPointerInductionRecipe>(&R);
assert(!WidenPhi->onlyScalarsGenerated(State->VF.isScalable()) &&
"recipe generating only scalars should have been replaced");
auto *GEP = cast<GetElementPtrInst>(State->get(WidenPhi));
Phi = cast<PHINode>(GEP->getPointerOperand());
}
if (auto *WidenPhi = dyn_cast<VPWidenPointerInductionRecipe>(&R)) {
assert(!WidenPhi->onlyScalarsGenerated(State->VF.isScalable()) &&
"recipe generating only scalars should have been replaced");
auto *GEP = cast<GetElementPtrInst>(State->get(WidenPhi));
PHINode *Phi = cast<PHINode>(GEP->getPointerOperand());

Phi->setIncomingBlock(1, VectorLatchBB);

// Move the last step to the end of the latch block. This ensures
// consistent placement of all induction updates.
Instruction *Inc = cast<Instruction>(Phi->getIncomingValue(1));
Inc->moveBefore(std::prev(VectorLatchBB->getTerminator()->getIterator()));

// Use the steps for the last part as backedge value for the induction.
if (auto *IV = dyn_cast<VPWidenIntOrFpInductionRecipe>(&R))
Inc->setOperand(0, State->get(IV->getLastUnrolledPartOperand()));
continue;
}

Expand Down
25 changes: 18 additions & 7 deletions llvm/lib/Transforms/Vectorize/VPlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,9 @@ class VPInstruction : public VPRecipeWithIRFlags,
// Extracts the first active lane of a vector, where the first operand is
// the predicate, and the second operand is the vector to extract.
ExtractFirstActive,
// Creates a step vector starting from 0 with a step of 1. The first operand
// is a dummy constant that should be used to specify the element type.
StepVector,
};

private:
Expand Down Expand Up @@ -1757,7 +1760,9 @@ class VPWidenInductionRecipe : public VPHeaderPHIRecipe {
};

/// A recipe for handling phi nodes of integer and floating-point inductions,
/// producing their vector values.
/// producing their vector values. This won't execute any LLVM IR and will get
/// expanded later into VPWidenIntOrFpInitialRecipe, VPWidenIntOrFpPHIRecipe and
/// VPWidenIntOrFpBackedgeRecipe.
class VPWidenIntOrFpInductionRecipe : public VPWidenInductionRecipe {
TruncInst *Trunc;

Expand Down Expand Up @@ -1790,9 +1795,10 @@ class VPWidenIntOrFpInductionRecipe : public VPWidenInductionRecipe {

VP_CLASSOF_IMPL(VPDef::VPWidenIntOrFpInductionSC)

/// Generate the vectorized and scalarized versions of the phi node as
/// needed by their users.
void execute(VPTransformState &State) override;
void execute(VPTransformState &State) override {
llvm_unreachable("cannot execute this recipe, should be expanded via "
"expandVPWidenIntOrFpInductionRecipe");
}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
/// Print the recipe.
Expand Down Expand Up @@ -1938,11 +1944,16 @@ class VPScalarPHIRecipe : public VPHeaderPHIRecipe {
/// exactly 2 incoming values, the first from the predecessor of the region and
/// the second from the exiting block of the region.
class VPWidenPHIRecipe : public VPSingleDefRecipe {
/// Name to use for the generated IR instruction for the widened phi.
std::string Name;

public:
/// Create a new VPWidenPHIRecipe for \p Phi with start value \p Start and
/// debug location \p DL.
VPWidenPHIRecipe(PHINode *Phi, VPValue *Start = nullptr, DebugLoc DL = {})
: VPSingleDefRecipe(VPDef::VPWidenPHISC, ArrayRef<VPValue *>(), Phi, DL) {
/// debug location \p DL..
VPWidenPHIRecipe(Instruction *Phi, VPValue *Start = nullptr, DebugLoc DL = {},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A VPWidenIntOrFpInduction's underlying value can be a trunc instruction too, but now that you mention it I think it's ok if we just pass WidenIVR->getPHINode() in here. I've removed it in 993ba23

const Twine &Name = "vec.phi")
: VPSingleDefRecipe(VPDef::VPWidenPHISC, ArrayRef<VPValue *>(), Phi, DL),
Name(Name.str()) {
if (Start)
addOperand(Start);
}
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPInstruction *R) {
case VPInstruction::CalculateTripCountMinusVF:
case VPInstruction::CanonicalIVIncrementForPart:
case VPInstruction::AnyOf:
case VPInstruction::StepVector:
return SetResultTyFromOp();
case VPInstruction::ExtractFirstActive:
case VPInstruction::ExtractFromEnd: {
Expand Down
Loading
Loading