Repository: llvm/llvm-project
File: llvm/lib/Transforms/Vectorize/VPlan.h (C/C++)

Code before:
  };
  /// Holds reduction-specific flags: RecurKind, IsOrdered, IsInLoop, and FMFs.
  struct ReductionFlagsTy {
    // RecurKind has ~26 values, needs 5 bits but uses 6 bits to account for
    // additional kinds.
    unsigned char Kind : 6;
    // TODO: Derive order/in-loop from plan and remove here.
    unsigned char IsOrdered : 1;
    unsigned char IsInLoop : 1;
    FastMathFlagsTy FMFs;

    ReductionFlagsTy(RecurKind Kind, bool IsOrdered, bool IsInLoop,
                     FastMathFlags FMFs)
        : Kind(static_cast<unsigned char>(Kind)), IsOrdered(IsOrdered),
          IsInLoop(IsInLoop), FMFs(FMFs) {}
  };

  OperationType OpType;

  union {
    uint8_t CmpPredStorage;
    WrapFlagsTy WrapFlags;
    TruncFlagsTy TruncFlags;
    DisjointFlagsTy DisjointFlags;
    ExactFlagsTy ExactFlags;
    uint8_t GEPFlagsStorage;
    NonNegFlagsTy NonNegFlags;
    FastMathFlagsTy FMFs;
    FCmpFlagsTy FCmpFlags;
    ReductionFlagsTy ReductionFlags;
  };

public:
  VPIRFlags() : OpType(OperationType::Other), CmpPredStorage(0) {}

  VPIRFlags(Instruction &I) {
    if (auto *FCmp = dyn_cast<FCmpInst>(&I)) {
      OpType = OperationType::FCmp;
      Bitfield::set<CmpInst::PredicateField>(FCmpFlags.PredStorage,
                                             FCmp->getPredicate());
      FCmpFlags.FMFs = FCmp->getFastMathFlags();
    } else if (auto *Op = dyn_cast<CmpInst>(&I)) {
      OpType = OperationType::Cmp;
      Bitfield::set<CmpInst::PredicateField>(CmpPredStorage,
                                             Op->getPredicate());
    } else if (auto *Op = dyn_cast<PossiblyDisjointInst>(&I)) {
      OpType = OperationType::DisjointOp;
      DisjointFlags.IsDisjoint = Op->isDisjoint();
    } else if (auto *Op = dyn_cast<OverflowingBinaryOperator>(&I)) {
      OpType = OperationType::OverflowingBinOp;
      WrapFlags = {Op->hasNoUnsignedWrap(), Op->hasNoSignedWrap()};

Review comment (suggestion):
I think you need only 6 bits:

```cpp
  using PredicateField =
      Bitfield::Element<Predicate, 0, 6, LAST_ICMP_PREDICATE>
```

Code after:
  /// Holds both the predicate and fast-math flags for floating-point
  /// comparisons.
  struct FCmpFlagsTy {
    uint8_t CmpPredStorage;
    FastMathFlagsTy FMFs;
  };
  /// Holds reduction-specific flags: RecurKind, IsOrdered, IsInLoop, and FMFs.
  struct ReductionFlagsTy {
    // RecurKind has ~26 values, needs 5 bits but uses 6 bits to account for
    // additional kinds.
    unsigned char Kind : 6;
    // TODO: Derive order/in-loop from plan and remove here.
    unsigned char IsOrdered : 1;
    unsigned char IsInLoop : 1;
    FastMathFlagsTy FMFs;

    ReductionFlagsTy(RecurKind Kind, bool IsOrdered, bool IsInLoop,
                     FastMathFlags FMFs)
        : Kind(static_cast<unsigned char>(Kind)), IsOrdered(IsOrdered),
          IsInLoop(IsInLoop), FMFs(FMFs) {}
  };

  OperationType OpType;

  union {
    uint8_t CmpPredStorage;
    WrapFlagsTy WrapFlags;
    TruncFlagsTy TruncFlags;
    DisjointFlagsTy DisjointFlags;
    ExactFlagsTy ExactFlags;
    uint8_t GEPFlagsStorage;
    NonNegFlagsTy NonNegFlags;
    FastMathFlagsTy FMFs;
    FCmpFlagsTy FCmpFlags;
    ReductionFlagsTy ReductionFlags;
  };

public:
  VPIRFlags() : OpType(OperationType::Other), CmpPredStorage(0) {}

  VPIRFlags(Instruction &I) {
    if (auto *FCmp = dyn_cast<FCmpInst>(&I)) {
      OpType = OperationType::FCmp;
      Bitfield::set<CmpInst::PredicateField>(FCmpFlags.CmpPredStorage,
                                             FCmp->getPredicate());
      assert(getPredicate() == FCmp->getPredicate() && "predicate truncated");
      FCmpFlags.FMFs = FCmp->getFastMathFlags();
    } else if (auto *Op = dyn_cast<CmpInst>(&I)) {
      OpType = OperationType::Cmp;
      Bitfield::set<CmpInst::PredicateField>(CmpPredStorage,
                                             Op->getPredicate());