[llvm] [VPlan] Introduce distillation of widening semantics (NFC) (PR #196181)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 13 03:19:31 PDT 2026
================
@@ -361,27 +361,146 @@ bool vputils::isAddressSCEVForCost(const SCEV *Addr, ScalarEvolution &SE,
match(Addr, m_scev_AffineAddRec(m_SCEV(), m_SCEV()));
}
-/// Returns true if \p Opcode preserves uniformity, i.e., if all operands are
-/// uniform, the result will also be uniform.
-static bool preservesUniformity(unsigned Opcode) {
+/// A class keeping track of widening information of various recipes.
+/// A recipe necessarily produces a single scalar value if only the SingleScalar
+/// bit is set, a wide value if only the Wide bit is set, and scalar values for
+/// all VF lanes only the GenPerAllLanes bit is set. The SingleScalar bit can be
+/// set on Wide or GenPerAllLanes recipes, which indicates that the recipe could
+/// be narrowed to single-scalar if legal and profitable. For instructions not
+/// producing values, like an assume or store, the bits talk about the
+/// appropriate operands. Finally, there is a class of instructions that
+/// necessarily take vector operands and produce a scalar result, like
+/// (Insert|Extract)Element, or necessarily take a scalar values and produce a
+/// vector, like Build(Struct)Vector, or could be interepreted as either a wide
+/// or narrow recipe like Broadcasts and non-constant live-ins: these are marked
+/// with the Agnostic bit.
+class VPWideningInfo {
+ unsigned char Info : 4;
+
+public:
+ using VPWideningTy = enum {
+ SingleScalar = 1 << 0,
+ Wide = 1 << 1,
+ GenPerAllLanes = 1 << 2,
+ Agnostic = 1 << 3
+ };
+
+ VPWideningInfo(unsigned char Info) : Info(Info) {}
+ operator unsigned char() const { return Info; }
+ bool producesSingleScalarResult() const {
+ return Info == SingleScalar || Info == (SingleScalar | Agnostic);
+ }
+ bool couldProduceSingleScalarResult() const { return Info & SingleScalar; }
+};
+
+static VPWideningInfo getNarrowableWideningInfo(unsigned Opcode,
+ VPWideningInfo WideOrRep) {
if (Instruction::isBinaryOp(Opcode) || Instruction::isCast(Opcode))
- return true;
+ return WideOrRep | VPWideningInfo::SingleScalar;
switch (Opcode) {
case Instruction::Freeze:
case Instruction::GetElementPtr:
case Instruction::ICmp:
case Instruction::FCmp:
case Instruction::Select:
case VPInstruction::Not:
- case VPInstruction::Broadcast:
case VPInstruction::MaskedCond:
case VPInstruction::PtrAdd:
- return true;
+ return WideOrRep | VPWideningInfo::SingleScalar;
default:
- return false;
+ return WideOrRep;
}
}
+static VPWideningInfo getWideningInfo(const VPRecipeBase &R) {
+ switch (R.getVPRecipeID()) {
+ case VPRecipeBase::VPVectorPointerSC:
----------------
artagnon wrote:
Yes, would be good to improve independently: I'll put up a PR; thanks for brining it up.
https://github.com/llvm/llvm-project/pull/196181
More information about the llvm-commits
mailing list