[llvm] 6cc18a8 - [VPlan] Support more GEP-like recipes in getSCEVExprForVPValue (NFCI)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 18 14:21:48 PST 2026
Author: Florian Hahn
Date: 2026-01-18T22:20:25Z
New Revision: 6cc18a8e4338dbbeb29b4a57af89e0cc0aca7be9
URL: https://github.com/llvm/llvm-project/commit/6cc18a8e4338dbbeb29b4a57af89e0cc0aca7be9
DIFF: https://github.com/llvm/llvm-project/commit/6cc18a8e4338dbbeb29b4a57af89e0cc0aca7be9.diff
LOG: [VPlan] Support more GEP-like recipes in getSCEVExprForVPValue (NFCI)
Support VPWidenGEPRecipe, VPInstructions and VPRelpicateRecipe with
GEP-like opcodes in getSCEVExprForVPValue via a new matcher binding
source element type and operands.
This is used in code paths when computing SCEV expressions in the
VPlan-based cost model, which should produce costs matching the legacy
cost model.
Added:
Modified:
llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h
llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h b/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h
index 148ee4119f372..09c3722961246 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h
@@ -963,6 +963,56 @@ struct live_in_vpvalue {
inline live_in_vpvalue m_LiveIn() { return live_in_vpvalue(); }
+/// Match a GEP recipe (VPWidenGEPRecipe, VPInstruction, or VPReplicateRecipe)
+/// and bind the source element type and operands.
+struct GetElementPtr_match {
+ Type *&SourceElementType;
+ ArrayRef<VPValue *> &Operands;
+
+ GetElementPtr_match(Type *&SourceElementType, ArrayRef<VPValue *> &Operands)
+ : SourceElementType(SourceElementType), Operands(Operands) {}
+
+ template <typename ITy> bool match(ITy *V) const {
+ return matchRecipeAndBind<VPWidenGEPRecipe>(V) ||
+ matchRecipeAndBind<VPInstruction>(V) ||
+ matchRecipeAndBind<VPReplicateRecipe>(V);
+ }
+
+private:
+ template <typename RecipeTy> bool matchRecipeAndBind(const VPValue *V) const {
+ auto *DefR = dyn_cast<RecipeTy>(V);
+ if (!DefR)
+ return false;
+
+ if constexpr (std::is_same_v<RecipeTy, VPWidenGEPRecipe>) {
+ SourceElementType = DefR->getSourceElementType();
+ } else if (DefR->getOpcode() == Instruction::GetElementPtr) {
+ SourceElementType = cast<GetElementPtrInst>(DefR->getUnderlyingInstr())
+ ->getSourceElementType();
+ } else if constexpr (std::is_same_v<RecipeTy, VPInstruction>) {
+ if (DefR->getOpcode() == VPInstruction::PtrAdd) {
+ // PtrAdd is a byte-offset GEP with i8 element type.
+ LLVMContext &Ctx = DefR->getParent()->getPlan()->getContext();
+ SourceElementType = Type::getInt8Ty(Ctx);
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+
+ Operands = ArrayRef<VPValue *>(DefR->op_begin(), DefR->op_end());
+ return true;
+ }
+};
+
+/// Match a GEP recipe with any number of operands and bind source element type
+/// and operands.
+inline GetElementPtr_match m_GetElementPtr(Type *&SourceElementType,
+ ArrayRef<VPValue *> &Operands) {
+ return GetElementPtr_match(SourceElementType, Operands);
+}
+
template <typename SubPattern_t> struct OneUse_match {
SubPattern_t SubPattern;
diff --git a/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp b/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
index 795d137a3f47c..4873075a771c4 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
@@ -234,6 +234,15 @@ const SCEV *vputils::getSCEVExprForVPValue(const VPValue *V,
return SE.getSMinExpr(Ops[0], Ops[1]);
});
+ ArrayRef<VPValue *> Ops;
+ Type *SourceElementType;
+ if (match(V, m_GetElementPtr(SourceElementType, Ops))) {
+ const SCEV *GEPExpr = CreateSCEV(Ops, [&](ArrayRef<const SCEV *> Ops) {
+ return SE.getGEPExpr(Ops.front(), Ops.drop_front(), SourceElementType);
+ });
+ return PSE.getPredicatedSCEV(GEPExpr);
+ }
+
// TODO: Support constructing SCEVs for more recipes as needed.
const VPRecipeBase *DefR = V->getDefiningRecipe();
const SCEV *Expr = TypeSwitch<const VPRecipeBase *, const SCEV *>(DefR)
@@ -279,26 +288,6 @@ const SCEV *vputils::getSCEVExprForVPValue(const VPValue *V,
return SE.getCouldNotCompute();
return SE.getTruncateOrSignExtend(IV, Step->getType());
})
- .Case<VPReplicateRecipe>([&SE, &PSE, L](const VPReplicateRecipe *R) {
- if (R->getOpcode() != Instruction::GetElementPtr)
- return SE.getCouldNotCompute();
-
- const SCEV *Base = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
- if (isa<SCEVCouldNotCompute>(Base))
- return SE.getCouldNotCompute();
-
- SmallVector<const SCEV *> IndexExprs;
- for (VPValue *Index : drop_begin(R->operands())) {
- const SCEV *IndexExpr = getSCEVExprForVPValue(Index, PSE, L);
- if (isa<SCEVCouldNotCompute>(IndexExpr))
- return SE.getCouldNotCompute();
- IndexExprs.push_back(IndexExpr);
- }
-
- Type *SrcElementTy = cast<GetElementPtrInst>(R->getUnderlyingInstr())
- ->getSourceElementType();
- return SE.getGEPExpr(Base, IndexExprs, SrcElementTy);
- })
.Default(
[&SE](const VPRecipeBase *) { return SE.getCouldNotCompute(); });
More information about the llvm-commits
mailing list