================
@@ -7484,6 +7505,221 @@ void VPlanTransforms::makeMemOpWideningDecisions(VPlan 
&Plan, VFRange &Range,
                            });
 }
 
+void VPlanTransforms::multiversionForUnitStridedMemOps(
+    VPlan &Plan, VPCostContext &CostCtx, VFSelectionContext &Config,
+    VPRecipeBuilder &RecipeBuilder, VFRange &Range,
+    SmallVectorImpl<VPInstruction *> &MemOps) {
+  if (CostCtx.L->getHeader()->getParent()->hasOptSize())
+    return;
+  SmallVector<VPInstruction *> RemainingOps;
+
+  ScalarEvolution *SE = CostCtx.PSE.getSE();
+
+  PredicatedScalarEvolution StrideMVPSE(*SE, const_cast<Loop &>(*CostCtx.L));
+
+  SCEVUnionPredicate StridePredicates({}, *SE);
+
+  // Use `for_each` so that we could do `return Skip();`.
+  for_each(MemOps, [&](VPInstruction *VPI) {
+    auto Skip = [&]() { RemainingOps.push_back(VPI); };
+    if (RecipeBuilder.isConsecutiveWithoutVPlanBasedStrideSpeculation(VPI))
+      return Skip();
+    auto *PtrOp = VPI->getOpcode() == Instruction::Load ? VPI->getOperand(0)
+                                                        : VPI->getOperand(1);
+
+    const SCEV *PtrSCEV =
+        vputils::getSCEVExprForVPValue(PtrOp, CostCtx.PSE, CostCtx.L);
+    const SCEV *Start, *Stride;
+
+    if (!match(PtrSCEV, m_scev_AffineAddRec(m_SCEV(Start), m_SCEV(Stride),
+                                            m_SpecificLoop(CostCtx.L))))
+      return Skip();
+
+    Type *ScalarTy = VPI->getOpcode() == Instruction::Load
+                         ? VPI->getScalarType()
+                         : VPI->getOperand(0)->getScalarType();
+
+    if (VPI->getMask()) {
+      Instruction *I = VPI->getUnderlyingInstr();
+      if (!LoopVectorizationPlanner::getDecisionAndClampRange(
+              [&](ElementCount VF) -> bool {
+                return Config.isLegalMaskedLoadOrStore(I, VF);
+              },
+              Range))
+        return Skip();
+    }
+
+    const auto *TypeSize = cast<SCEVConstant>(SE->getSizeOfExpr(
+        Stride->getType(), SE->getDataLayout().getTypeAllocSize(ScalarTy)));
+
+    auto ReplaceWithUnitStrided = [&]() {
+      VPBuilder Builder(VPI);
+      VPValue *StrideInBytes = Plan.getOrAddLiveIn(TypeSize->getValue());
+      auto *VecPtr =
+          new VPVectorPointerRecipe(PtrOp, ScalarTy, StrideInBytes,
+                                    GEPNoWrapFlags::none(), 
VPI->getDebugLoc());
+      Builder.insert(VecPtr);
+      if (VPI->getOpcode() == Instruction::Load) {
+        auto *WideLoad = new VPWidenLoadRecipe(
+            cast<LoadInst>(*VPI->getUnderlyingInstr()), VecPtr, VPI->getMask(),
+            true, *VPI, VPI->getDebugLoc());
+        Builder.insert(WideLoad);
+        VPI->replaceAllUsesWith(WideLoad);
+      } else {
+        auto *WideStore = new VPWidenStoreRecipe(
+            cast<StoreInst>(*VPI->getUnderlyingInstr()), VecPtr,
+            VPI->getOperand(0), VPI->getMask(), true, *VPI, 
VPI->getDebugLoc());
+        Builder.insert(WideStore);
+      }
+      VPI->eraseFromParent();
+    };
+
+    if (isa<SCEVConstant>(Stride)) {
+      if (Stride != TypeSize)
+        return Skip();
+
+      // Earlier MV helped with this memory operation too.
+      ReplaceWithUnitStrided();
+      return;
+    }
+
+    const SCEVConstant *StrideConstantMultiplier;
+    const SCEV *StrideNonConstantMultiplier;
+
+    const SCEV *ToMultiVersion = Stride;
+    const SCEV *MVConst = TypeSize;
+    if (match(Stride, m_scev_c_Mul(m_SCEVConstant(StrideConstantMultiplier),
+                                   m_SCEV(StrideNonConstantMultiplier)))) {
+      if (TypeSize != StrideConstantMultiplier) {
+        // TODO: Support `TypeSize = N * StrideCosntantMultiplier`,
+        // including negative `N`. For now, only process when they're equal,
+        // which matches the usefull part of the legacy behavior that
----------------
artagnon wrote:

```suggestion
        // which matches the useful part of the legacy behavior that
```

https://github.com/llvm/llvm-project/pull/182595
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to