[llvm] c2d51a2 - [VPlan] Add Type* and getType() to VPSymbolicValue (NFC) (#195183)
via llvm-commits
llvm-commits at lists.llvm.org
Tue May 12 04:22:09 PDT 2026
Author: Florian Hahn
Date: 2026-05-12T12:22:04+01:00
New Revision: c2d51a2719026acd30d505cf11d7f33bc27adafd
URL: https://github.com/llvm/llvm-project/commit/c2d51a2719026acd30d505cf11d7f33bc27adafd
DIFF: https://github.com/llvm/llvm-project/commit/c2d51a2719026acd30d505cf11d7f33bc27adafd.diff
LOG: [VPlan] Add Type* and getType() to VPSymbolicValue (NFC) (#195183)
Add a Type* field to VPSymbolicValue, along with a getType() methods to
query the stored scalar type.
This makes it easier to retrieve the type of various symbolic values,
and also simplifies VPTypeAnalysis construction.
PR: https://github.com/llvm/llvm-project/pull/195183
Added:
Modified:
llvm/lib/Transforms/Vectorize/VPlan.cpp
llvm/lib/Transforms/Vectorize/VPlan.h
llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp
llvm/lib/Transforms/Vectorize/VPlanAnalysis.h
llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp
llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp
llvm/lib/Transforms/Vectorize/VPlanValue.h
llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
llvm/unittests/Transforms/Vectorize/VPlanTestBase.h
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp
index 3c8f3362ae93a..2ec1b002f56f8 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp
@@ -862,7 +862,8 @@ VPInstruction *VPRegionBlock::getOrCreateCanonicalIVIncrement() {
CanIV->getDebugLoc(), "index.next");
}
-VPlan::VPlan(Loop *L) {
+VPlan::VPlan(Loop *L, Type *IdxTy)
+ : VectorTripCount(IdxTy), VF(IdxTy), UF(IdxTy), VFxUF(IdxTy) {
setEntry(createVPIRBasicBlock(L->getLoopPreheader()));
ScalarHeader = createVPIRBasicBlock(L->getHeader());
@@ -873,7 +874,7 @@ VPlan::VPlan(Loop *L) {
}
VPlan::~VPlan() {
- VPSymbolicValue DummyValue;
+ VPSymbolicValue DummyValue(nullptr);
for (auto *VPB : CreatedBlocks) {
if (auto *VPBB = dyn_cast<VPBasicBlock>(VPB)) {
@@ -1236,7 +1237,8 @@ VPlan *VPlan::duplicate() {
NewScalarHeader = createVPIRBasicBlock(ScalarHeaderIRBB);
}
// Create VPlan, clone live-ins and remap operands in the cloned blocks.
- auto *NewPlan = new VPlan(cast<VPBasicBlock>(NewEntry), NewScalarHeader);
+ auto *NewPlan =
+ new VPlan(cast<VPBasicBlock>(NewEntry), NewScalarHeader, getIndexType());
DenseMap<VPValue *, VPValue *> Old2NewVPValues;
for (VPIRValue *OldLiveIn : getLiveIns())
Old2NewVPValues[OldLiveIn] = NewPlan->getOrAddLiveIn(OldLiveIn);
@@ -1258,7 +1260,8 @@ VPlan *VPlan::duplicate() {
"All VPSymbolicValues must be handled below");
if (BackedgeTakenCount)
- NewPlan->BackedgeTakenCount = new VPSymbolicValue();
+ NewPlan->BackedgeTakenCount =
+ new VPSymbolicValue(BackedgeTakenCount->getType());
// Map and propagate materialized state for symbolic values.
for (auto [OldSV, NewSV] :
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h
index 63436c79e9a98..f6e77092e016c 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.h
+++ b/llvm/lib/Transforms/Vectorize/VPlan.h
@@ -4559,9 +4559,11 @@ class VPlan {
SmallVector<VPBlockBase *> CreatedBlocks;
/// Construct a VPlan with \p Entry to the plan and with \p ScalarHeader
- /// wrapping the original header of the scalar loop.
- VPlan(VPBasicBlock *Entry, VPIRBasicBlock *ScalarHeader)
- : Entry(Entry), ScalarHeader(ScalarHeader) {
+ /// wrapping the original header of the scalar loop. The vector loop will have
+ /// index type \p IdxTy.
+ VPlan(VPBasicBlock *Entry, VPIRBasicBlock *ScalarHeader, Type *IdxTy)
+ : Entry(Entry), ScalarHeader(ScalarHeader), VectorTripCount(IdxTy),
+ VF(IdxTy), UF(IdxTy), VFxUF(IdxTy) {
Entry->setPlan(this);
assert(ScalarHeader->getNumSuccessors() == 0 &&
"scalar header must be a leaf node");
@@ -4570,12 +4572,14 @@ class VPlan {
public:
/// Construct a VPlan for \p L. This will create VPIRBasicBlocks wrapping the
/// original preheader and scalar header of \p L, to be used as entry and
- /// scalar header blocks of the new VPlan.
- VPlan(Loop *L);
+ /// scalar header blocks of the new VPlan. The vector loop will have index
+ /// type \p IdxTy.
+ VPlan(Loop *L, Type *IdxTy);
/// Construct a VPlan with a new VPBasicBlock as entry, a VPIRBasicBlock
- /// wrapping \p ScalarHeaderBB and a trip count of \p TC.
- VPlan(BasicBlock *ScalarHeaderBB) {
+ /// wrapping \p ScalarHeaderBB and vector loop index of type \p IdxTy.
+ VPlan(BasicBlock *ScalarHeaderBB, Type *IdxTy)
+ : VectorTripCount(IdxTy), VF(IdxTy), UF(IdxTy), VFxUF(IdxTy) {
setEntry(createVPBasicBlock("preheader"));
ScalarHeader = createVPIRBasicBlock(ScalarHeaderBB);
}
@@ -4678,8 +4682,9 @@ class VPlan {
/// The backedge taken count of the original loop.
VPValue *getOrCreateBackedgeTakenCount() {
+ // BTC shares the canonical IV type with VectorTripCount.
if (!BackedgeTakenCount)
- BackedgeTakenCount = new VPSymbolicValue();
+ BackedgeTakenCount = new VPSymbolicValue(VectorTripCount.getType());
return BackedgeTakenCount;
}
VPValue *getBackedgeTakenCount() const { return BackedgeTakenCount; }
@@ -4907,6 +4912,9 @@ class VPlan {
return ScalarPH &&
is_contained(ScalarPH->getPredecessors(), getMiddleBlock());
}
+
+ /// The type of the canonical induction variable of the vector loop.
+ Type *getIndexType() const { return VF.getType(); }
};
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
diff --git a/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp b/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp
index a42b631cd3304..ddfd528d42217 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp
@@ -24,23 +24,6 @@ using namespace VPlanPatternMatch;
#define DEBUG_TYPE "vplan"
-VPTypeAnalysis::VPTypeAnalysis(const VPlan &Plan)
- : Ctx(Plan.getContext()), DL(Plan.getDataLayout()) {
- if (auto LoopRegion = Plan.getVectorLoopRegion()) {
- CanonicalIVTy = LoopRegion->getCanonicalIVType();
- return;
- }
-
- // If there's no loop region, retrieve the type from the trip count
- // expression.
- auto *TC = Plan.getTripCount();
- if (auto *TCIRV = dyn_cast<VPIRValue>(TC)) {
- CanonicalIVTy = TCIRV->getType();
- return;
- }
- CanonicalIVTy = cast<VPExpandSCEVRecipe>(TC)->getSCEV()->getType();
-}
-
Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPBlendRecipe *R) {
Type *ResTy = inferScalarType(R->getIncomingValue(0));
for (unsigned I = 1, E = R->getNumIncomingValues(); I != E; ++I) {
@@ -128,7 +111,7 @@ Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPInstruction *R) {
case VPInstruction::LastActiveLane:
// Assume that the maximum possible number of elements in a vector fits
// within the index type for the default address space.
- return DL.getIndexType(Ctx, 0);
+ return R->getParent()->getPlan()->getDataLayout().getIndexType(Ctx, 0);
case VPInstruction::LogicalAnd:
case VPInstruction::LogicalOr:
assert(inferScalarType(R->getOperand(0))->isIntegerTy(1) &&
@@ -286,11 +269,8 @@ Type *VPTypeAnalysis::inferScalarType(const VPValue *V) {
if (auto *IRV = dyn_cast<VPIRValue>(V))
return IRV->getType();
- if (isa<VPSymbolicValue>(V)) {
- // All VPValues without any underlying IR value (like the vector trip count
- // or the backedge-taken count) have the same type as the canonical IV.
- return CanonicalIVTy;
- }
+ if (auto *SymbolicV = dyn_cast<VPSymbolicValue>(V))
+ return SymbolicV->getType();
if (auto *RegionV = dyn_cast<VPRegionValue>(V))
return RegionV->getType();
diff --git a/llvm/lib/Transforms/Vectorize/VPlanAnalysis.h b/llvm/lib/Transforms/Vectorize/VPlanAnalysis.h
index c1c9075420d1c..b73636c31f0a7 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanAnalysis.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanAnalysis.h
@@ -9,6 +9,7 @@
#ifndef LLVM_TRANSFORMS_VECTORIZE_VPLANANALYSIS_H
#define LLVM_TRANSFORMS_VECTORIZE_VPLANANALYSIS_H
+#include "VPlan.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
@@ -45,12 +46,7 @@ struct VPCostContext;
/// of the previously inferred types.
class VPTypeAnalysis {
DenseMap<const VPValue *, Type *> CachedTypes;
- /// Type of the canonical induction variable. Used for all VPValues without
- /// any underlying IR value (like the vector trip count or the backedge-taken
- /// count).
- Type *CanonicalIVTy;
LLVMContext &Ctx;
- const DataLayout &DL;
Type *inferScalarTypeForRecipe(const VPBlendRecipe *R);
Type *inferScalarTypeForRecipe(const VPInstruction *R);
@@ -60,7 +56,7 @@ class VPTypeAnalysis {
Type *inferScalarTypeForRecipe(const VPReplicateRecipe *R);
public:
- VPTypeAnalysis(const VPlan &Plan);
+ VPTypeAnalysis(const VPlan &Plan) : Ctx(Plan.getContext()) {}
/// Infer the type of \p V. Returns the scalar type of \p V.
Type *inferScalarType(const VPValue *V);
diff --git a/llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp b/llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp
index e20d5d947ac54..c2b05984db272 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp
@@ -78,8 +78,9 @@ class PlainCFGBuilder {
void createVPInstructionsForVPBB(VPBasicBlock *VPBB, BasicBlock *BB);
public:
- PlainCFGBuilder(Loop *Lp, LoopInfo *LI, LoopVersioning *LVer)
- : TheLoop(Lp), LI(LI), LVer(LVer), Plan(std::make_unique<VPlan>(Lp)) {}
+ PlainCFGBuilder(Loop *Lp, LoopInfo *LI, LoopVersioning *LVer, Type *IdxTy)
+ : TheLoop(Lp), LI(LI), LVer(LVer),
+ Plan(std::make_unique<VPlan>(Lp, IdxTy)) {}
/// Build plain CFG for TheLoop and connect it to Plan's entry.
std::unique_ptr<VPlan> buildPlainCFG();
@@ -635,7 +636,7 @@ std::unique_ptr<VPlan>
VPlanTransforms::buildVPlan0(Loop *TheLoop, LoopInfo &LI, Type *InductionTy,
DebugLoc IVDL, PredicatedScalarEvolution &PSE,
LoopVersioning *LVer) {
- PlainCFGBuilder Builder(TheLoop, &LI, LVer);
+ PlainCFGBuilder Builder(TheLoop, &LI, LVer, InductionTy);
std::unique_ptr<VPlan> VPlan0 = Builder.buildPlainCFG();
addInitialSkeleton(*VPlan0, InductionTy, IVDL, PSE, TheLoop);
simplifyLiveInsWithSCEV(*VPlan0, PSE);
diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
index 11a91dcd46867..6d5db90436c79 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
@@ -3017,7 +3017,7 @@ VPExpressionRecipe::VPExpressionRecipe(
if (Def && ExpressionRecipesAsSetOfUsers.contains(Def))
continue;
addOperand(Op);
- LiveInPlaceholders.push_back(new VPSymbolicValue());
+ LiveInPlaceholders.push_back(new VPSymbolicValue(nullptr));
}
}
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index 32d89a34105a4..c836a280eac19 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -2678,7 +2678,7 @@ void VPlanTransforms::removeBranchOnConst(VPlan &Plan, bool OnlyLatches) {
// Detach all unreachable blocks from their successors, removing their recipes
// and incoming values from phi recipes.
- VPSymbolicValue Tmp;
+ VPSymbolicValue Tmp(nullptr);
for (VPBlockBase *B : AllBlocks) {
if (Reachable.contains(B))
continue;
diff --git a/llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp b/llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp
index f1b9efae08377..30dd61ba5b232 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp
@@ -345,7 +345,7 @@ void UnrollState::unrollRecipeByUF(VPRecipeBase &R) {
VPBuilder Builder(VPR);
const DataLayout &DL = Plan.getDataLayout();
Type *IndexTy = DL.getIndexType(TypeInfo.inferScalarType(VPR));
- Type *VFTy = TypeInfo.inferScalarType(&Plan.getVF());
+ Type *VFTy = Plan.getVF().getType();
VPValue *VF = Builder.createScalarZExtOrTrunc(
&Plan.getVF(), IndexTy, VFTy, DebugLoc::getUnknown());
// VFxUF does not wrap, so VF * Part also cannot wrap.
diff --git a/llvm/lib/Transforms/Vectorize/VPlanValue.h b/llvm/lib/Transforms/Vectorize/VPlanValue.h
index 8f9806adf774e..777da17c904f3 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanValue.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanValue.h
@@ -278,12 +278,15 @@ struct VPConstantInt : public VPIRValue {
/// A symbolic live-in VPValue, used for values like vector trip count, VF, and
/// VFxUF.
struct VPSymbolicValue : public VPValue {
- VPSymbolicValue() : VPValue(VPVSymbolicSC, nullptr) {}
+ VPSymbolicValue(Type *Ty) : VPValue(VPVSymbolicSC, nullptr), Ty(Ty) {}
static bool classof(const VPValue *V) {
return V->getVPValueID() == VPVSymbolicSC;
}
+ /// Returns the scalar type of this symbolic value.
+ Type *getType() const { return Ty; }
+
/// Returns true if this symbolic value has been materialized.
bool isMaterialized() const { return Materialized; }
@@ -294,6 +297,9 @@ struct VPSymbolicValue : public VPValue {
}
private:
+ /// The scalar type of this symbolic value.
+ Type *Ty;
+
/// Track whether this symbolic value has been materialized (replaced).
/// After materialization, accessing users should trigger an assertion.
bool Materialized = false;
diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
index 61acb5846a9cb..1dceed39b2d03 100644
--- a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
+++ b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
@@ -53,7 +53,7 @@ define void @f(i32 %x) {
Loop *L = LI->getLoopFor(LoopHeader);
PredicatedScalarEvolution PSE(*SE, *L);
- VPlan Plan(LoopHeader);
+ VPlan Plan(LoopHeader, IntegerType::get(*Ctx, 32));
Argument *X = F->getArg(0);
VPValue *Op = Plan.getOrAddLiveIn(X);
diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h b/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h
index 2c1797a5a724e..4f8f3581afa8c 100644
--- a/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h
+++ b/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h
@@ -133,7 +133,8 @@ class VPlanTestBase : public testing::Test {
}
VPlan &getPlan() {
- Plans.push_back(std::make_unique<VPlan>(ScalarHeader));
+ Plans.push_back(
+ std::make_unique<VPlan>(ScalarHeader, IntegerType::get(C, 64)));
VPlan &Plan = *Plans.back();
VPValue *DefaultTC = Plan.getConstantInt(32, 1024);
Plan.setTripCount(DefaultTC);
More information about the llvm-commits
mailing list