[llvm] [LV][VPlan] Add initial support for CSA vectorization (PR #121222)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 13 12:02:13 PST 2025


================
@@ -8969,6 +9017,77 @@ VPRecipeBuilder::tryToCreatePartialReduction(Instruction *Reduction,
                                       Reduction);
 }
 
+/// Add ConditionalScalarAssignment Recipes that must occur after each
+/// instruction in the input IR is processed and introduced into VPlan.
+static void addConditionalScalarAssignmentPostprocessRecipes(
+    VPRecipeBuilder &RecipeBuilder,
+    const LoopVectorizationLegality::ConditionalScalarAssignmentList &CSAs,
+    VPBasicBlock *MiddleVPBB, DebugLoc DL, VFRange &Range, VPlan &Plan,
+    Loop *OrigLoop) {
+  // Don't vectorize conditional scalar assignment for
+  // VF=ElementCount::getFixed(1)
+  if (LoopVectorizationPlanner::getDecisionAndClampRange(
+          [&](ElementCount VF) { return VF.isScalar(); }, Range))
+    return;
+
+  VPBasicBlock *Header = Plan.getVectorLoopRegion()->getEntryBasicBlock();
+  for (const auto &CSA : CSAs) {
+    // Build the MaskPhi recipe.
+    auto *VPInitMask = RecipeBuilder.getVPValueOrAddLiveIn(
+        ConstantInt::getFalse(Type::getInt1Ty(CSA.first->getContext())));
+    VPBuilder B;
+    B.setInsertPoint(Header, Header->getFirstNonPhi());
+    auto *VPMaskPhi = B.createConditionalScalarAssignmentMaskPhi(
+        VPInitMask, DL, "csa.mask.phi");
+    B.clearInsertionPoint();
+
+    auto GetVPValue = [&](Value *I) {
+      return RecipeBuilder.getRecipe(cast<Instruction>(I))->getVPSingleValue();
+    };
+    VPConditionalScalarAssignmentDataUpdateRecipe *VPDataUpdate =
+        cast<VPConditionalScalarAssignmentDataUpdateRecipe>(
+            cast<VPConditionalScalarAssignmentHeaderPHIRecipe>(
+                GetVPValue(CSA.first))
+                ->getVPNewData());
+
+    // The CSA optimization wants to use a condition such that when it is
+    // true, a new value is assigned. However, it is possible that a true lane
+    // in WidenedCond corresponds to selection of the initial value instead.
+    // In that case, we must use the negation of WidenedCond.
+    // i.e. select cond new_val old_val versus select cond.not old_val new_val
+    assert(CSA.second.getCond() &&
+           "CSADescriptor must know how to describe the condition");
+    VPValue *WidenedCond = GetVPValue(CSA.second.getCond());
+    VPValue *CondToUse = WidenedCond;
+    if (cast<SelectInst>(CSA.second.getAssignment())->getTrueValue() ==
----------------
artagnon wrote:

Redundant cast?

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


More information about the llvm-commits mailing list