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

Code before:
    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()};
    } else if (auto *Op = dyn_cast<TruncInst>(&I)) {
      OpType = OperationType::Trunc;
      TruncFlags = {Op->hasNoUnsignedWrap(), Op->hasNoSignedWrap()};
    } else if (auto *Op = dyn_cast<PossiblyExactOperator>(&I)) {
      OpType = OperationType::PossiblyExactOp;

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

```cpp
  enum : unsigned {
    InBoundsFlag = (1 << 0),
    NUSWFlag = (1 << 1),
    NUWFlag = (1 << 2),
  };
```

Code after:
  };
  /// 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());
      assert(getPredicate() == Op->getPredicate() && "predicate truncated");
    } else if (auto *Op = dyn_cast<PossiblyDisjointInst>(&I)) {
      OpType = OperationType::DisjointOp;
      DisjointFlags.IsDisjoint = Op->isDisjoint();
    } else if (auto *Op = dyn_cast<OverflowingBinaryOperator>(&I)) {