[llvm] [VPlan] Extend tryToFoldLiveIns to fold binary intrinsics (PR #161703)

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 24 02:32:28 PDT 2025


================
@@ -943,56 +943,98 @@ static void recursivelyDeleteDeadRecipes(VPValue *V) {
   }
 }
 
+/// Get any instruction opcode or intrinsic ID data embedded in recipe \p R.
+/// Returns an optional pair, where the first element indicates whether it is
+/// an intrinsic ID.
+static std::optional<std::pair<bool, unsigned>>
+getOpcodeOrIntrinsicID(const VPSingleDefRecipe *R) {
+  return TypeSwitch<const VPSingleDefRecipe *,
+                    std::optional<std::pair<bool, unsigned>>>(R)
+      .Case<VPInstruction, VPWidenRecipe, VPWidenCastRecipe,
+            VPWidenSelectRecipe, VPWidenGEPRecipe, VPReplicateRecipe>(
+          [](auto *I) { return std::make_pair(false, I->getOpcode()); })
+      .Case<VPWidenIntrinsicRecipe>([](auto *I) {
+        return std::make_pair(true, I->getVectorIntrinsicID());
+      })
+      .Case<VPVectorPointerRecipe, VPPredInstPHIRecipe>([](auto *I) {
+        // For recipes that do not directly map to LLVM IR instructions,
+        // assign opcodes after the last VPInstruction opcode (which is also
+        // after the last IR Instruction opcode), based on the VPDefID.
+        return std::make_pair(false,
+                              VPInstruction::OpsEnd + 1 + I->getVPDefID());
+      })
+      .Default([](auto *) { return std::nullopt; });
+}
+
 /// Try to fold \p R using InstSimplifyFolder. Will succeed and return a
-/// non-nullptr Value for a handled \p Opcode if corresponding \p Operands are
-/// foldable live-ins.
-static Value *tryToFoldLiveIns(const VPRecipeBase &R, unsigned Opcode,
-                               ArrayRef<VPValue *> Operands,
-                               const DataLayout &DL, VPTypeAnalysis &TypeInfo) {
-  SmallVector<Value *, 4> Ops;
-  for (VPValue *Op : Operands) {
-    if (!Op->isLiveIn() || !Op->getLiveInIRValue())
+/// non-nullptr Value for a handled opcode or intrinsic ID if corresponding \p
+/// Operands are foldable live-ins.
+static VPValue *tryToFoldLiveIns(VPSingleDefRecipe &R,
+                                 ArrayRef<VPValue *> Operands,
+                                 const DataLayout &DL,
+                                 VPTypeAnalysis &TypeInfo) {
+  auto FoldToIRValue = [&]() -> Value * {
+    auto OpcodeOrIID = getOpcodeOrIntrinsicID(&R);
+    if (!OpcodeOrIID)
       return nullptr;
----------------
fhahn wrote:

```suggestion
  auto OpcodeOrIID = getOpcodeOrIntrinsicID(&R);
  if (!OpcodeOrIID)
    return nullptr;
 
  SmallVector<Value *, 4> Ops;
  for (VPValue *Op : Operands) {
    if (!Op->isLiveIn() || !Op->getLiveInIRValue())
      return nullptr;
      Ops.push_back(Op->getLiveInIRValue());
  }
  auto FoldToIRValue = [&]() -> Value * {

```

Could move out early legality checks to make early exits clearer & reduce indent level.

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


More information about the llvm-commits mailing list