[llvm] [VPlan] Fix missing onlyFirstLaneUsed(). NFC (PR #145449)

Elvis Wang via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 2 18:02:23 PDT 2025


https://github.com/ElvisWang123 updated https://github.com/llvm/llvm-project/pull/145449

>From 2091c206f3394267fa2acf6f384966ecfe7904bd Mon Sep 17 00:00:00 2001
From: Elvis Wang <elvis.wang at sifive.com>
Date: Mon, 23 Jun 2025 19:12:34 -0700
Subject: [PATCH] [VPlan] Fixup missing onlyFirstLaneUsed(). NFC

This patch fixup missing onlyFirstLaneUsed() implementaions for
following recipes.

- VPWidenRecipe with `extractValue` , the index of the extract value must
be scalar.

- VPWidenCallRecipe, the last operand of this recipes is the function
name/pointer of the scalar function, which should be scalar type.

- VPInstruction::ExtractValue, the index of the extract value must be
scalar.

- VPInstruction::ComputeFindIVResult, the operand(2) is the
sentinel value, which should be scalar.
---
 llvm/lib/Transforms/Vectorize/VPlan.h         | 21 +++++++++++++++++++
 .../lib/Transforms/Vectorize/VPlanRecipes.cpp |  4 +++-
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h
index d460573f5bec6..6df7c97dd6c00 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.h
+++ b/llvm/lib/Transforms/Vectorize/VPlan.h
@@ -1357,6 +1357,18 @@ class VPWidenRecipe : public VPRecipeWithIRFlags, public VPIRMetadata {
   void print(raw_ostream &O, const Twine &Indent,
              VPSlotTracker &SlotTracker) const override;
 #endif
+
+  bool onlyFirstLaneUsed(const VPValue *Op) const override {
+    assert(is_contained(operands(), Op) &&
+           "Op must be an operand of the recipe");
+
+    // The operand(1) of the extract value is the index to extract, which should
+    // be scalar.
+    if (Opcode == Instruction::ExtractValue)
+      return Op == getOperand(1);
+
+    return false;
+  }
 };
 
 /// VPWidenCastRecipe is a recipe to create vector cast instructions.
@@ -1551,6 +1563,15 @@ class VPWidenCallRecipe : public VPRecipeWithIRFlags, public VPIRMetadata {
   void print(raw_ostream &O, const Twine &Indent,
              VPSlotTracker &SlotTracker) const override;
 #endif
+
+  /// Returns true if the recipe only uses the first lane of operand \p Op.
+  bool onlyFirstLaneUsed(const VPValue *Op) const override {
+    assert(is_contained(operands(), Op) &&
+           "Op must be an operand of the recipe");
+    // The last operand is the function pointer of the underlying scalar
+    // function, which should be scalar.
+    return Op == getOperand(getNumOperands() - 1);
+  }
 };
 
 /// A recipe representing a sequence of load -> update -> store as part of
diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
index 318e8171e098d..e26a1495ed762 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
@@ -1069,6 +1069,7 @@ bool VPInstruction::onlyFirstLaneUsed(const VPValue *Op) const {
   default:
     return false;
   case Instruction::ExtractElement:
+  case Instruction::ExtractValue:
     return Op == getOperand(1);
   case Instruction::PHI:
     return true;
@@ -1090,8 +1091,9 @@ bool VPInstruction::onlyFirstLaneUsed(const VPValue *Op) const {
   case VPInstruction::PtrAdd:
     return Op == getOperand(0) || vputils::onlyFirstLaneUsed(this);
   case VPInstruction::ComputeAnyOfResult:
-  case VPInstruction::ComputeFindIVResult:
     return Op == getOperand(1);
+  case VPInstruction::ComputeFindIVResult:
+    return Op == getOperand(1) || Op == getOperand(2);
   };
   llvm_unreachable("switch should return");
 }



More information about the llvm-commits mailing list