[llvm] [VPlan] Create header phi recipes after initial scalar optimizations. (PR #200920)

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 10 05:15:45 PDT 2026


================
@@ -632,19 +632,38 @@ createWidenInductionRecipe(PHINode *Phi, VPPhi *PhiR, VPIRValue *Start,
                            const InductionDescriptor &IndDesc, VPlan &Plan,
                            PredicatedScalarEvolution &PSE, Loop &OrigLoop,
                            DebugLoc DL) {
-  [[maybe_unused]] ScalarEvolution &SE = *PSE.getSE();
+  ScalarEvolution &SE = *PSE.getSE();
   assert(SE.isLoopInvariant(IndDesc.getStep(), &OrigLoop) &&
          "step must be loop invariant");
   assert((Plan.getLiveIn(IndDesc.getStartValue()) == Start ||
           (SE.isSCEVable(IndDesc.getStartValue()->getType()) &&
-           SE.getSCEV(IndDesc.getStartValue()) ==
+           PSE.getSCEV(IndDesc.getStartValue()) ==
                vputils::getSCEVExprForVPValue(Start, PSE))) &&
          "Start VPValue must match IndDesc's start value");
 
-  VPValue *Step =
-      vputils::getOrCreateVPValueForSCEVExpr(Plan, IndDesc.getStep());
-
   VPValue *BackedgeVal = PhiR->getOperand(1);
+  // Try to get the versioned step from the induction increment directly.
+  auto GetStep = [&]() -> VPValue * {
+    VPValue *Step;
+    if (match(BackedgeVal, m_Add(m_Specific(PhiR), m_VPValue(Step))))
+      return Step;
+
+    // Pointer induction: scale the GEP index by the source element size.
+    Type *GEPSrcElemTy;
+    ArrayRef<VPValue *> GEPOps;
+    if (match(BackedgeVal, m_GetElementPtr(GEPSrcElemTy, GEPOps)) &&
+        GEPOps.size() == 2 && GEPOps[0] == PhiR) {
+      Type *StepTy = IndDesc.getStep()->getType();
+      const SCEV *Idx = vputils::getSCEVExprForVPValue(GEPOps[1], PSE);
+      if (!isa<SCEVCouldNotCompute>(Idx))
+        return vputils::getOrCreateVPValueForSCEVExpr(
+            Plan, SE.getMulExpr(SE.getTruncateOrSignExtend(Idx, StepTy),
+                                SE.getSizeOfExpr(StepTy, GEPSrcElemTy)));
+    }
+    return vputils::getOrCreateVPValueForSCEVExpr(Plan, IndDesc.getStep());
+  };
----------------
fhahn wrote:

Yes that also works, updated, thanks

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


More information about the llvm-commits mailing list