[llvm] [VPlan] Introduce vputils::getSingleScalarClone (PR #161667)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 21 09:59:11 PDT 2025


https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/161667

>From c08940d9290eaa2dd6bf5bac92a0eaab56ce2f48 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Thu, 2 Oct 2025 14:21:01 +0100
Subject: [PATCH 1/2] [VPlan] Introduce vputils::getSingleScalarClone

---
 .../Transforms/Vectorize/VPlanTransforms.cpp  | 28 ++++---------------
 llvm/lib/Transforms/Vectorize/VPlanUtils.cpp  | 21 ++++++++++++++
 llvm/lib/Transforms/Vectorize/VPlanUtils.h    |  4 +++
 3 files changed, 31 insertions(+), 22 deletions(-)

diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index e060e7081042a..dbd6da7a25da3 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -189,19 +189,7 @@ static bool sinkScalarOperands(VPlan &Plan) {
     if (NeedsDuplicating) {
       if (ScalarVFOnly)
         continue;
-      VPSingleDefRecipe *Clone;
-      if (auto *SinkCandidateRepR =
-              dyn_cast<VPReplicateRecipe>(SinkCandidate)) {
-        // TODO: Handle converting to uniform recipes as separate transform,
-        // then cloning should be sufficient here.
-        Instruction *I = SinkCandidate->getUnderlyingInstr();
-        Clone = new VPReplicateRecipe(I, SinkCandidate->operands(), true,
-                                      nullptr /*Mask*/, *SinkCandidateRepR);
-        // TODO: add ".cloned" suffix to name of Clone's VPValue.
-      } else {
-        Clone = SinkCandidate->clone();
-      }
-
+      VPSingleDefRecipe *Clone = vputils::getSingleScalarClone(SinkCandidate);
       Clone->insertBefore(SinkCandidate);
       SinkCandidate->replaceUsesWithIf(Clone, [SinkTo](VPUser &U, unsigned) {
         return cast<VPRecipeBase>(&U)->getParent() != SinkTo;
@@ -667,8 +655,7 @@ static void legalizeAndOptimizeInductions(VPlan &Plan) {
       if (!vputils::isSingleScalar(Def) && !vputils::onlyFirstLaneUsed(Def))
         continue;
 
-      auto *Clone = new VPReplicateRecipe(Def->getUnderlyingInstr(),
-                                          Def->operands(), /*IsUniform*/ true);
+      VPSingleDefRecipe *Clone = vputils::getSingleScalarClone(Def);
       Clone->insertAfter(Def);
       Def->replaceAllUsesWith(Clone);
     }
@@ -1335,9 +1322,8 @@ static void narrowToSingleScalarRecipes(VPlan &Plan) {
       auto *RepOrWidenR = cast<VPSingleDefRecipe>(&R);
       if (RepR && isa<StoreInst>(RepR->getUnderlyingInstr()) &&
           vputils::isSingleScalar(RepR->getOperand(1))) {
-        auto *Clone = new VPReplicateRecipe(
-            RepOrWidenR->getUnderlyingInstr(), RepOrWidenR->operands(),
-            true /*IsSingleScalar*/, nullptr /*Mask*/, *RepR /*Metadata*/);
+        auto *Clone =
+            cast<VPReplicateRecipe>(vputils::getSingleScalarClone(RepOrWidenR));
         Clone->insertBefore(RepOrWidenR);
         unsigned ExtractOpc =
             vputils::isUniformAcrossVFsAndUFs(RepR->getOperand(1))
@@ -1346,7 +1332,7 @@ static void narrowToSingleScalarRecipes(VPlan &Plan) {
         auto *Ext = new VPInstruction(ExtractOpc, {Clone->getOperand(0)});
         Ext->insertBefore(Clone);
         Clone->setOperand(0, Ext);
-        RepR->eraseFromParent();
+        RepOrWidenR->eraseFromParent();
         continue;
       }
 
@@ -1362,9 +1348,7 @@ static void narrowToSingleScalarRecipes(VPlan &Plan) {
           }))
         continue;
 
-      auto *Clone = new VPReplicateRecipe(RepOrWidenR->getUnderlyingInstr(),
-                                          RepOrWidenR->operands(),
-                                          true /*IsSingleScalar*/);
+      VPSingleDefRecipe *Clone = vputils::getSingleScalarClone(RepOrWidenR);
       Clone->insertBefore(RepOrWidenR);
       RepOrWidenR->replaceAllUsesWith(Clone);
     }
diff --git a/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp b/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
index 10801c0119e62..a76615316354a 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
@@ -253,3 +253,24 @@ vputils::getRecipesForUncountableExit(VPlan &Plan,
 
   return UncountableCondition;
 }
+
+VPSingleDefRecipe *vputils::getSingleScalarClone(VPSingleDefRecipe *R) {
+  return TypeSwitch<VPSingleDefRecipe *, VPSingleDefRecipe *>(R)
+      .Case<VPInstruction, VPWidenRecipe, VPWidenSelectRecipe,
+            VPWidenCallRecipe, VPReplicateRecipe>([](auto *I) {
+        return new VPReplicateRecipe(I->getUnderlyingInstr(), I->operands(),
+                                     /*IsSingleScalar*/ true,
+                                     /*Mask*/ nullptr,
+                                     /*Metadata*/ *I);
+      })
+      .Case<VPWidenGEPRecipe>([](auto *I) {
+        // WidenGEP does not have metadata.
+        return new VPReplicateRecipe(I->getUnderlyingInstr(), I->operands(),
+                                     /*IsSingleScalar*/ true, /*Mask*/ nullptr);
+      })
+      .Case<VPScalarIVStepsRecipe>([](auto *I) { return I->clone(); })
+      .Default([](auto *I) {
+        llvm_unreachable("Recipe not convertible to single-scalar");
+        return nullptr;
+      });
+}
diff --git a/llvm/lib/Transforms/Vectorize/VPlanUtils.h b/llvm/lib/Transforms/Vectorize/VPlanUtils.h
index 840a5b9e12a01..1b6ea3951c534 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanUtils.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanUtils.h
@@ -122,6 +122,10 @@ std::optional<VPValue *>
 getRecipesForUncountableExit(VPlan &Plan,
                              SmallVectorImpl<VPRecipeBase *> &Recipes,
                              SmallVectorImpl<VPRecipeBase *> &GEPs);
+
+/// Returns a single-scalar version of \p R, creating a fresh single-scalar
+/// VPReplicateRecipe or just cloning the recipe.
+VPSingleDefRecipe *getSingleScalarClone(VPSingleDefRecipe *R);
 } // namespace vputils
 
 //===----------------------------------------------------------------------===//

>From 7d71949e37c54533725c4a6bfeaf30c62cfaf39e Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Tue, 21 Oct 2025 17:58:19 +0100
Subject: [PATCH 2/2] [VPlan] Address review

---
 llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp | 2 +-
 llvm/lib/Transforms/Vectorize/VPlanUtils.cpp      | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index dbd6da7a25da3..0a5dd2d0ccc66 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -1332,7 +1332,7 @@ static void narrowToSingleScalarRecipes(VPlan &Plan) {
         auto *Ext = new VPInstruction(ExtractOpc, {Clone->getOperand(0)});
         Ext->insertBefore(Clone);
         Clone->setOperand(0, Ext);
-        RepOrWidenR->eraseFromParent();
+        RepR->eraseFromParent();
         continue;
       }
 
diff --git a/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp b/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
index a76615316354a..7d45b124bee4a 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
@@ -255,6 +255,7 @@ vputils::getRecipesForUncountableExit(VPlan &Plan,
 }
 
 VPSingleDefRecipe *vputils::getSingleScalarClone(VPSingleDefRecipe *R) {
+  // TODO: add ".cloned" suffix to name of Clone's VPValue.
   return TypeSwitch<VPSingleDefRecipe *, VPSingleDefRecipe *>(R)
       .Case<VPInstruction, VPWidenRecipe, VPWidenSelectRecipe,
             VPWidenCallRecipe, VPReplicateRecipe>([](auto *I) {
@@ -270,7 +271,7 @@ VPSingleDefRecipe *vputils::getSingleScalarClone(VPSingleDefRecipe *R) {
       })
       .Case<VPScalarIVStepsRecipe>([](auto *I) { return I->clone(); })
       .Default([](auto *I) {
-        llvm_unreachable("Recipe not convertible to single-scalar");
+        llvm_unreachable("Don't know how to convert to single-scalar");
         return nullptr;
       });
 }



More information about the llvm-commits mailing list