[llvm] [VPlan] Use bitfield to store Cmp predicates and GEP wrap flags. (NFC) (PR #181571)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Feb 15 12:36:16 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Florian Hahn (fhahn)
<details>
<summary>Changes</summary>
Instead of storing CmpInst::Predicate/GepNoWrapFlags, only store their raw bitfield values. This reduces the size of VPIRFlags from 12 to 3 bytes.
---
Full diff: https://github.com/llvm/llvm-project/pull/181571.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/Vectorize/VPlan.h (+30-23)
- (modified) llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp (+10-8)
``````````diff
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h
index 07b6c306fa980..dc73b44ae1772 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.h
+++ b/llvm/lib/Transforms/Vectorize/VPlan.h
@@ -25,6 +25,7 @@
#define LLVM_TRANSFORMS_VECTORIZE_VPLAN_H
#include "VPlanValue.h"
+#include "llvm/ADT/Bitfields.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
@@ -721,7 +722,7 @@ class VPIRFlags {
/// Holds both the predicate and fast-math flags for floating-point
/// comparisons.
struct FCmpFlagsTy {
- CmpInst::Predicate Pred;
+ uint8_t PredStorage;
FastMathFlagsTy FMFs;
};
/// Holds reduction-specific flags: RecurKind, IsOrdered, IsInLoop, and FMFs.
@@ -743,30 +744,31 @@ class VPIRFlags {
OperationType OpType;
union {
- CmpInst::Predicate CmpPredicate;
+ uint8_t CmpPredStorage;
WrapFlagsTy WrapFlags;
TruncFlagsTy TruncFlags;
DisjointFlagsTy DisjointFlags;
ExactFlagsTy ExactFlags;
- GEPNoWrapFlags GEPFlags;
+ uint8_t GEPFlagsStorage;
NonNegFlagsTy NonNegFlags;
FastMathFlagsTy FMFs;
FCmpFlagsTy FCmpFlags;
ReductionFlagsTy ReductionFlags;
- unsigned AllFlags;
};
public:
- VPIRFlags() : OpType(OperationType::Other), AllFlags(0) {}
+ VPIRFlags() : OpType(OperationType::Other), CmpPredStorage(0) {}
VPIRFlags(Instruction &I) {
if (auto *FCmp = dyn_cast<FCmpInst>(&I)) {
OpType = OperationType::FCmp;
- FCmpFlags.Pred = FCmp->getPredicate();
+ Bitfield::set<CmpInst::PredicateField>(FCmpFlags.PredStorage,
+ FCmp->getPredicate());
FCmpFlags.FMFs = FCmp->getFastMathFlags();
} else if (auto *Op = dyn_cast<CmpInst>(&I)) {
OpType = OperationType::Cmp;
- CmpPredicate = Op->getPredicate();
+ Bitfield::set<CmpInst::PredicateField>(CmpPredStorage,
+ Op->getPredicate());
} else if (auto *Op = dyn_cast<PossiblyDisjointInst>(&I)) {
OpType = OperationType::DisjointOp;
DisjointFlags.IsDisjoint = Op->isDisjoint();
@@ -781,7 +783,7 @@ class VPIRFlags {
ExactFlags.IsExact = Op->isExact();
} else if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
OpType = OperationType::GEPOp;
- GEPFlags = GEP->getNoWrapFlags();
+ GEPFlagsStorage = GEP->getNoWrapFlags().getRaw();
} else if (auto *PNNI = dyn_cast<PossiblyNonNegInst>(&I)) {
OpType = OperationType::NonNegOp;
NonNegFlags.NonNeg = PNNI->hasNonNeg();
@@ -790,16 +792,17 @@ class VPIRFlags {
FMFs = Op->getFastMathFlags();
} else {
OpType = OperationType::Other;
- AllFlags = 0;
+ CmpPredStorage = 0;
}
}
- VPIRFlags(CmpInst::Predicate Pred)
- : OpType(OperationType::Cmp), CmpPredicate(Pred) {}
+ VPIRFlags(CmpInst::Predicate Pred) : OpType(OperationType::Cmp) {
+ Bitfield::set<CmpInst::PredicateField>(CmpPredStorage, Pred);
+ }
VPIRFlags(CmpInst::Predicate Pred, FastMathFlags FMFs)
: OpType(OperationType::FCmp) {
- FCmpFlags.Pred = Pred;
+ Bitfield::set<CmpInst::PredicateField>(FCmpFlags.PredStorage, Pred);
FCmpFlags.FMFs = FMFs;
}
@@ -821,16 +824,13 @@ class VPIRFlags {
: OpType(OperationType::PossiblyExactOp), ExactFlags(ExactFlags) {}
VPIRFlags(GEPNoWrapFlags GEPFlags)
- : OpType(OperationType::GEPOp), GEPFlags(GEPFlags) {}
+ : OpType(OperationType::GEPOp), GEPFlagsStorage(GEPFlags.getRaw()) {}
VPIRFlags(RecurKind Kind, bool IsOrdered, bool IsInLoop, FastMathFlags FMFs)
: OpType(OperationType::ReductionOp),
ReductionFlags(Kind, IsOrdered, IsInLoop, FMFs) {}
- void transferFlags(VPIRFlags &Other) {
- OpType = Other.OpType;
- AllFlags = Other.AllFlags;
- }
+ void transferFlags(VPIRFlags &Other) { *this = Other; }
/// Only keep flags also present in \p Other. \p Other must have the same
/// OpType as the current object.
@@ -856,7 +856,7 @@ class VPIRFlags {
ExactFlags.IsExact = false;
break;
case OperationType::GEPOp:
- GEPFlags = GEPNoWrapFlags::none();
+ GEPFlagsStorage = 0;
break;
case OperationType::FPMathOp:
case OperationType::FCmp:
@@ -891,7 +891,8 @@ class VPIRFlags {
I.setIsExact(ExactFlags.IsExact);
break;
case OperationType::GEPOp:
- cast<GetElementPtrInst>(&I)->setNoWrapFlags(GEPFlags);
+ cast<GetElementPtrInst>(&I)->setNoWrapFlags(
+ GEPNoWrapFlags::fromRaw(GEPFlagsStorage));
break;
case OperationType::FPMathOp:
case OperationType::FCmp: {
@@ -919,19 +920,23 @@ class VPIRFlags {
CmpInst::Predicate getPredicate() const {
assert((OpType == OperationType::Cmp || OpType == OperationType::FCmp) &&
"recipe doesn't have a compare predicate");
- return OpType == OperationType::FCmp ? FCmpFlags.Pred : CmpPredicate;
+ uint8_t Storage =
+ OpType == OperationType::FCmp ? FCmpFlags.PredStorage : CmpPredStorage;
+ return Bitfield::get<CmpInst::PredicateField>(Storage);
}
void setPredicate(CmpInst::Predicate Pred) {
assert((OpType == OperationType::Cmp || OpType == OperationType::FCmp) &&
"recipe doesn't have a compare predicate");
if (OpType == OperationType::FCmp)
- FCmpFlags.Pred = Pred;
+ Bitfield::set<CmpInst::PredicateField>(FCmpFlags.PredStorage, Pred);
else
- CmpPredicate = Pred;
+ Bitfield::set<CmpInst::PredicateField>(CmpPredStorage, Pred);
}
- GEPNoWrapFlags getGEPNoWrapFlags() const { return GEPFlags; }
+ GEPNoWrapFlags getGEPNoWrapFlags() const {
+ return GEPNoWrapFlags::fromRaw(GEPFlagsStorage);
+ }
/// Returns true if the recipe has a comparison predicate.
bool hasPredicate() const {
@@ -1037,6 +1042,8 @@ class VPIRFlags {
#endif
};
+static_assert(sizeof(VPIRFlags) <= 3, "VPIRFlags should not grow");
+
/// A pure-virtual common base class for recipes defining a single VPValue and
/// using IR flags.
struct VPRecipeWithIRFlags : public VPSingleDefRecipe, public VPIRFlags {
diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
index c15b9fb23060a..d2a11f988b0d5 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
@@ -333,12 +333,12 @@ void VPIRFlags::intersectFlags(const VPIRFlags &Other) {
ExactFlags.IsExact &= Other.ExactFlags.IsExact;
break;
case OperationType::GEPOp:
- GEPFlags &= Other.GEPFlags;
+ GEPFlagsStorage &= Other.GEPFlagsStorage;
break;
case OperationType::FPMathOp:
case OperationType::FCmp:
assert((OpType != OperationType::FCmp ||
- FCmpFlags.Pred == Other.FCmpFlags.Pred) &&
+ FCmpFlags.PredStorage == Other.FCmpFlags.PredStorage) &&
"Cannot drop CmpPredicate");
getFMFsRef().NoNaNs &= Other.getFMFsRef().NoNaNs;
getFMFsRef().NoInfs &= Other.getFMFsRef().NoInfs;
@@ -347,7 +347,8 @@ void VPIRFlags::intersectFlags(const VPIRFlags &Other) {
NonNegFlags.NonNeg &= Other.NonNegFlags.NonNeg;
break;
case OperationType::Cmp:
- assert(CmpPredicate == Other.CmpPredicate && "Cannot drop CmpPredicate");
+ assert(CmpPredStorage == Other.CmpPredStorage &&
+ "Cannot drop CmpPredicate");
break;
case OperationType::ReductionOp:
assert(ReductionFlags.Kind == Other.ReductionFlags.Kind &&
@@ -360,7 +361,6 @@ void VPIRFlags::intersectFlags(const VPIRFlags &Other) {
getFMFsRef().NoInfs &= Other.getFMFsRef().NoInfs;
break;
case OperationType::Other:
- assert(AllFlags == Other.AllFlags && "Cannot drop other flags");
break;
}
}
@@ -2220,14 +2220,16 @@ void VPIRFlags::printFlags(raw_ostream &O) const {
case OperationType::FPMathOp:
getFastMathFlags().print(O);
break;
- case OperationType::GEPOp:
- if (GEPFlags.isInBounds())
+ case OperationType::GEPOp: {
+ GEPNoWrapFlags Flags = getGEPNoWrapFlags();
+ if (Flags.isInBounds())
O << " inbounds";
- else if (GEPFlags.hasNoUnsignedSignedWrap())
+ else if (Flags.hasNoUnsignedSignedWrap())
O << " nusw";
- if (GEPFlags.hasNoUnsignedWrap())
+ if (Flags.hasNoUnsignedWrap())
O << " nuw";
break;
+ }
case OperationType::NonNegOp:
if (NonNegFlags.NonNeg)
O << " nneg";
``````````
</details>
https://github.com/llvm/llvm-project/pull/181571
More information about the llvm-commits
mailing list