[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