[llvm] [SCEV] Introduce PSE::getAddRecExpr, use in VPlan (NFC) (PR #195818)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Thu May 7 06:09:29 PDT 2026


================
@@ -281,43 +277,37 @@ const SCEV *vputils::getSCEVExprForVPValue(const VPValue *V,
   ArrayRef<VPValue *> Ops;
   Type *SourceElementType;
   if (match(V, m_GetElementPtr(SourceElementType, Ops))) {
-    const SCEV *GEPExpr = CreateSCEV(Ops, [&](ArrayRef<SCEVUse> Ops) {
+    return CreateSCEV(Ops, [&](ArrayRef<SCEVUse> 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)
-          .Case([](const VPExpandSCEVRecipe *R) { return R->getSCEV(); })
-          .Case([&SE, &PSE, L](const VPWidenIntOrFpInductionRecipe *R) {
-            const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
-            if (!L || isa<SCEVCouldNotCompute>(Step))
-              return SE.getCouldNotCompute();
-            const SCEV *Start =
-                getSCEVExprForVPValue(R->getStartValue(), PSE, L);
-            const SCEV *AddRec =
-                SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
-            if (R->getTruncInst())
-              return SE.getTruncateExpr(AddRec, R->getScalarType());
-            return AddRec;
-          })
-          .Case([&SE, &PSE, L](const VPWidenPointerInductionRecipe *R) {
-            const SCEV *Start =
-                getSCEVExprForVPValue(R->getStartValue(), PSE, L);
-            if (!L || isa<SCEVCouldNotCompute>(Start))
-              return SE.getCouldNotCompute();
-            const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
-            if (isa<SCEVCouldNotCompute>(Step))
-              return SE.getCouldNotCompute();
-            return SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
-          })
-          .Case([&SE, &PSE, L](const VPDerivedIVRecipe *R) {
-            const SCEV *Start = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
-            const SCEV *IV = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
-            const SCEV *Scale = getSCEVExprForVPValue(R->getOperand(2), PSE, L);
+  return TypeSwitch<const VPRecipeBase *, const SCEV *>(V->getDefiningRecipe())
+      .Case([](const VPExpandSCEVRecipe *R) { return R->getSCEV(); })
+      .Case([&SE, &PSE](const VPWidenIntOrFpInductionRecipe *R) {
+        const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE);
+        if (isa<SCEVCouldNotCompute>(Step))
+          return SE.getCouldNotCompute();
+        const SCEV *Start = getSCEVExprForVPValue(R->getStartValue(), PSE);
+        const SCEV *AddRec = PSE.getAddRecExpr(Start, Step, SCEV::FlagAnyWrap);
----------------
artagnon wrote:

My initial patch did indeed have a PSE::getLoop(), but I'm leaning towards this solution now, as it might be not be the best idea to expose the Loop in the PSE, which could lead to incorrect usages that drop the Predicates? I think it might be better to directly use PSE when Loop or Predicates are present?

https://github.com/llvm/llvm-project/pull/195818


More information about the llvm-commits mailing list