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

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 9 14:13:40 PST 2025


================
@@ -2565,6 +2600,136 @@ class VPBranchOnMaskRecipe : public VPRecipeBase {
   }
 };
 
+class VPConditionalScalarAssignmentHeaderPHIRecipe final
+    : public VPHeaderPHIRecipe {
+public:
+  VPConditionalScalarAssignmentHeaderPHIRecipe(PHINode *Phi,
+                                               VPValue &VPInitData)
+      : VPHeaderPHIRecipe(VPDef::VPConditionalScalarAssignmentHeaderPHISC, Phi,
+                          &VPInitData) {}
+
+  ~VPConditionalScalarAssignmentHeaderPHIRecipe() override = default;
+
+  VPConditionalScalarAssignmentHeaderPHIRecipe *clone() override {
+    return new VPConditionalScalarAssignmentHeaderPHIRecipe(
+        cast<PHINode>(getUnderlyingInstr()), *getOperand(0));
+  }
+
+  VPValue *NewData = nullptr;
+
+  void execute(VPTransformState &State) override;
+
+  InstructionCost computeCost(ElementCount VF,
+                              VPCostContext &Ctx) const override;
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+  /// Print the recipe.
+  void print(raw_ostream &O, const Twine &Indent,
+             VPSlotTracker &SlotTracker) const override;
+#endif
+
+  VP_CLASSOF_IMPL(VPDef::VPConditionalScalarAssignmentHeaderPHISC)
+
+  static inline bool classof(const VPHeaderPHIRecipe *R) {
+    return R->getVPDefID() == VPDef::VPConditionalScalarAssignmentHeaderPHISC;
+  }
+
+  VPValue *getVPInitData() { return getOperand(0); }
+
+  void setDataUpdate(VPValue *V) { NewData = V; }
+
+  VPValue *getVPNewData() { return NewData; }
+};
+
+class VPConditionalScalarAssignmentDataUpdateRecipe final
+    : public VPSingleDefRecipe {
+public:
+  VPConditionalScalarAssignmentDataUpdateRecipe(SelectInst *SI,
+                                                ArrayRef<VPValue *> Operands)
+      : VPSingleDefRecipe(VPDef::VPConditionalScalarAssignmentDataUpdateSC,
+                          Operands, SI) {}
+
+  ~VPConditionalScalarAssignmentDataUpdateRecipe() override = default;
+
+  VPConditionalScalarAssignmentDataUpdateRecipe *clone() override {
+    SmallVector<VPValue *> Ops(operands());
+    return new VPConditionalScalarAssignmentDataUpdateRecipe(
+        cast<SelectInst>(getUnderlyingInstr()), Ops);
+  }
+
+  void execute(VPTransformState &State) override;
+
+  InstructionCost computeCost(ElementCount VF,
+                              VPCostContext &Ctx) const override;
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+  /// Print the recipe.
+  void print(raw_ostream &O, const Twine &Indent,
+             VPSlotTracker &SlotTracker) const override;
+#endif
+
+  VP_CLASSOF_IMPL(VPDef::VPConditionalScalarAssignmentDataUpdateSC)
+
+  VPValue *getVPDataPhi() const { return getOperand(0); }
+
+  // The condition from the original select statement
+  VPValue *getVPCond() const { return getOperand(1); }
+
+  // The true value from the original select statement
+  VPValue *getVPTrue() const { return getOperand(2); }
+
+  // The false value from the original select statement
+  VPValue *getVPFalse() const { return getOperand(3); }
+
+  // We combine the setters so we can be sure NewMask is before AnyOf
+  // in the operands list, so the getters can be sure which operand numbers
+  // to get.
+  void setVPNewMaskAndVPAnyOf(VPValue *NewMask, VPValue *AnyOf) {
+    addOperand(NewMask);
+    addOperand(AnyOf);
+  }
+
+  VPValue *getVPNewMask() const { return getOperand(4); }
+
+  VPValue *getVPAnyOf() const { return getOperand(5); }
+};
+
+class VPConditionalScalarAssignmentExtractScalarRecipe final
+    : public VPSingleDefRecipe {
+  SmallVector<PHINode *> PhisToFix;
----------------
fhahn wrote:

Does the recipe need to hold references to IR Phis? Can it instead be an operand of the phis that need updating? 

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


More information about the llvm-commits mailing list