[llvm] [GlobalISel][AMDGPU] LLT changes for FPInfo (PR #130651)

via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 11 04:57:08 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-globalisel

Author: Tim Gymnich (tgymnich)

<details>
<summary>Changes</summary>

- adds new floating point and integer LLT kinds for both scalars and vectors.

makes progress on https://github.com/llvm/llvm-project/issues/119667

---

Patch is 63.32 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/130651.diff


41 Files Affected:

- (modified) llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h (+1-1) 
- (modified) llvm/include/llvm/CodeGen/LowLevelTypeUtils.h (+1-1) 
- (modified) llvm/include/llvm/CodeGenTypes/LowLevelType.h (+270-94) 
- (modified) llvm/lib/CodeGen/GlobalISel/LegalizeMutations.cpp (+2-4) 
- (modified) llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp (+2-1) 
- (modified) llvm/lib/CodeGen/LowLevelTypeUtils.cpp (+61-13) 
- (modified) llvm/lib/CodeGen/MIRParser/MIParser.cpp (+71-31) 
- (modified) llvm/lib/CodeGenTypes/LowLevelType.cpp (+47-13) 
- (modified) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid0.mir (+1-1) 
- (modified) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid1.mir (+1-1) 
- (added) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid11.mir (+10) 
- (added) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid12.mir (+10) 
- (added) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid13.mir (+10) 
- (added) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid14.mir (+10) 
- (added) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid15.mir (+10) 
- (added) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid16.mir (+10) 
- (added) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid17.mir (+10) 
- (added) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid18.mir (+10) 
- (added) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid19.mir (+10) 
- (modified) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid2.mir (+1-1) 
- (added) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid20.mir (+10) 
- (added) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid21.mir (+10) 
- (added) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid22.mir (+10) 
- (added) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid23.mir (+10) 
- (added) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid24.mir (+10) 
- (added) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid25.mir (+10) 
- (added) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid26.mir (+10) 
- (added) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid27.mir (+10) 
- (added) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid28.mir (+10) 
- (modified) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid3.mir (+1-1) 
- (modified) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid5.mir (+1-1) 
- (modified) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid6.mir (+1-1) 
- (modified) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid7.mir (+1-1) 
- (modified) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid8.mir (+1-1) 
- (modified) llvm/test/CodeGen/MIR/Generic/scalable-vector-type-err10.mir (+1-1) 
- (modified) llvm/test/CodeGen/MIR/Generic/scalable-vector-type-err8.mir (+1-1) 
- (modified) llvm/test/CodeGen/MIR/Generic/scalable-vector-type-err9.mir (+1-1) 
- (modified) llvm/test/CodeGen/MIR/WebAssembly/typed-immediate-operand-invalid0.mir (+1-1) 
- (modified) llvm/test/CodeGen/MIR/WebAssembly/typed-immediate-operand-invalid1.mir (+2-2) 
- (modified) llvm/unittests/CodeGen/GlobalISel/LegalizerInfoTest.cpp (+8-6) 
- (modified) llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp (+66-39) 


``````````diff
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
index 9472aa196f9b4..f8819d9efd833 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
@@ -374,7 +374,7 @@ LegalizeMutation changeElementCountTo(unsigned TypeIdx, unsigned FromTypeIdx);
 
 /// Keep the same scalar or element type as \p TypeIdx, but take the number of
 /// elements from \p Ty.
-LegalizeMutation changeElementCountTo(unsigned TypeIdx, LLT Ty);
+LegalizeMutation changeElementCountTo(unsigned TypeIdx, ElementCount EC);
 
 /// Change the scalar size or element size to have the same scalar size as type
 /// index \p FromIndex. Unlike changeElementTo, this discards pointer types and
diff --git a/llvm/include/llvm/CodeGen/LowLevelTypeUtils.h b/llvm/include/llvm/CodeGen/LowLevelTypeUtils.h
index 142e5cd4e7ad1..e9288ce8fdf51 100644
--- a/llvm/include/llvm/CodeGen/LowLevelTypeUtils.h
+++ b/llvm/include/llvm/CodeGen/LowLevelTypeUtils.h
@@ -40,6 +40,6 @@ LLT getLLTForMVT(MVT Ty);
 /// Get the appropriate floating point arithmetic semantic based on the bit size
 /// of the given scalar LLT.
 const llvm::fltSemantics &getFltSemanticForLLT(LLT Ty);
-}
+} // namespace llvm
 
 #endif // LLVM_CODEGEN_LOWLEVELTYPEUTILS_H
diff --git a/llvm/include/llvm/CodeGenTypes/LowLevelType.h b/llvm/include/llvm/CodeGenTypes/LowLevelType.h
index 06879e1f8d15b..27692b2c9f1b3 100644
--- a/llvm/include/llvm/CodeGenTypes/LowLevelType.h
+++ b/llvm/include/llvm/CodeGenTypes/LowLevelType.h
@@ -29,6 +29,7 @@
 #include "llvm/ADT/DenseMapInfo.h"
 #include "llvm/CodeGenTypes/MachineValueType.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
 #include <cassert>
 
 namespace llvm {
@@ -38,68 +39,159 @@ class raw_ostream;
 
 class LLT {
 public:
+  enum class FPVariant {
+    IEEE_FLOAT = 0x0,
+    BRAIN_FLOAT = 0x1,     // BRAIN_FLOAT
+    VARIANT_FLOAT_2 = 0x2, // PPC_FLOAT
+    VARIANT_FLOAT_3 = 0x3, // FP80
+    VARIANT_FLOAT_4 = 0x4, // TENSOR_FLOAT
+    VARIANT_FLOAT_5 = 0x5, // UNASSIGNED
+    VARIANT_FLOAT_6 = 0x6, // UNASSIGNED
+    VARIANT_FLOAT_7 = 0x7, // UNASSIGNED
+  };
+
+  enum class Kind : uint64_t {
+    SCALAR = 0b000,
+    INTEGER = 0b001,
+    FLOAT = 0b010,
+    POINTER = 0b011,
+    VECTOR_SCALAR = 0b100,
+    VECTOR_INTEGER = 0b101,
+    VECTOR_FLOAT = 0b110,
+    VECTOR_POINTER = 0b111,
+  };
+
+  constexpr static Kind toVector(Kind Ty) {
+    if (Ty == Kind::POINTER)
+      return Kind::VECTOR_POINTER;
+
+    if (Ty == Kind::INTEGER)
+      return Kind::VECTOR_INTEGER;
+
+    if (Ty == Kind::FLOAT)
+      return Kind::VECTOR_FLOAT;
+
+    if (Ty == Kind::SCALAR)
+      return Kind::VECTOR_SCALAR;
+
+    llvm_unreachable("Type is already a vector type");
+  }
+
+  constexpr static Kind toScalar(Kind Ty) {
+    if (Ty == Kind::VECTOR_POINTER)
+      return Kind::POINTER;
+
+    if (Ty == Kind::VECTOR_INTEGER)
+      return Kind::INTEGER;
+
+    if (Ty == Kind::VECTOR_FLOAT)
+      return Kind::FLOAT;
+
+    if (Ty == Kind::VECTOR_SCALAR)
+      return Kind::SCALAR;
+
+    llvm_unreachable("Type is already a scalar type");
+  }
+
   /// Get a low-level scalar or aggregate "bag of bits".
+  // TODO: deperecate this: [[deprecated("Use LLT::integer(unsigned)
+  // instead.")]]
   static constexpr LLT scalar(unsigned SizeInBits) {
-    return LLT{/*isPointer=*/false, /*isVector=*/false, /*isScalar=*/true,
-               ElementCount::getFixed(0), SizeInBits,
-               /*AddressSpace=*/0};
+    return LLT{Kind::INTEGER, ElementCount::getFixed(0), SizeInBits,
+               /*AddressSpace=*/0, static_cast<FPVariant>(0)};
+  }
+
+  static constexpr LLT integer(unsigned SizeInBits) {
+    return LLT{Kind::INTEGER, ElementCount::getFixed(0), SizeInBits,
+               /*AddressSpace=*/0, static_cast<FPVariant>(0)};
+  }
+
+  static constexpr LLT floatingPoint(unsigned SizeInBits, FPVariant FP) {
+    return LLT{Kind::FLOAT, ElementCount::getFixed(0), SizeInBits,
+               /*AddressSpace=*/0, FP};
   }
 
   /// Get a low-level token; just a scalar with zero bits (or no size).
   static constexpr LLT token() {
-    return LLT{/*isPointer=*/false, /*isVector=*/false,
-               /*isScalar=*/true,   ElementCount::getFixed(0),
-               /*SizeInBits=*/0,
-               /*AddressSpace=*/0};
+    LLT Token;
+    Token.Info = Kind::INTEGER;
+    return Token;
   }
 
   /// Get a low-level pointer in the given address space.
   static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits) {
     assert(SizeInBits > 0 && "invalid pointer size");
-    return LLT{/*isPointer=*/true, /*isVector=*/false, /*isScalar=*/false,
-               ElementCount::getFixed(0), SizeInBits, AddressSpace};
+    return LLT{Kind::POINTER, ElementCount::getFixed(0), SizeInBits,
+               AddressSpace, static_cast<FPVariant>(0)};
   }
 
   /// Get a low-level vector of some number of elements and element width.
+  // TODO: deprecate this: [[deprecated("Use LLT::vector(EC, LLT) instead.")]]
   static constexpr LLT vector(ElementCount EC, unsigned ScalarSizeInBits) {
     assert(!EC.isScalar() && "invalid number of vector elements");
-    return LLT{/*isPointer=*/false, /*isVector=*/true, /*isScalar=*/false,
-               EC, ScalarSizeInBits, /*AddressSpace=*/0};
+    return LLT{Kind::VECTOR_INTEGER, EC, ScalarSizeInBits,
+               /*AddressSpace=*/0, static_cast<FPVariant>(0)};
   }
 
   /// Get a low-level vector of some number of elements and element type.
   static constexpr LLT vector(ElementCount EC, LLT ScalarTy) {
     assert(!EC.isScalar() && "invalid number of vector elements");
     assert(!ScalarTy.isVector() && "invalid vector element type");
-    return LLT{ScalarTy.isPointer(),
-               /*isVector=*/true,
-               /*isScalar=*/false,
-               EC,
-               ScalarTy.getSizeInBits().getFixedValue(),
-               ScalarTy.isPointer() ? ScalarTy.getAddressSpace() : 0};
+
+    Kind Info = toVector(ScalarTy.Info);
+    return LLT{Info, EC, ScalarTy.getSizeInBits().getFixedValue(),
+               ScalarTy.isPointer() ? ScalarTy.getAddressSpace() : 0,
+               ScalarTy.isFloat() ? ScalarTy.getFPVariant()
+                                  : static_cast<FPVariant>(0)};
+  }
+  // Get a 8-bit brain float value.
+  static constexpr LLT bfloat8() {
+    return floatingPoint(8, FPVariant::BRAIN_FLOAT);
+  }
+
+  // Get a 16-bit brain float value.
+  static constexpr LLT bfloat16() {
+    return floatingPoint(16, FPVariant::BRAIN_FLOAT);
   }
 
   /// Get a 16-bit IEEE half value.
-  /// TODO: Add IEEE semantics to type - This currently returns a simple `scalar(16)`.
   static constexpr LLT float16() {
-    return scalar(16);
+    return floatingPoint(16, FPVariant::IEEE_FLOAT);
   }
 
   /// Get a 32-bit IEEE float value.
   static constexpr LLT float32() {
-    return scalar(32);
+    return floatingPoint(32, FPVariant::IEEE_FLOAT);
   }
 
   /// Get a 64-bit IEEE double value.
   static constexpr LLT float64() {
-    return scalar(64);
+    return floatingPoint(64, FPVariant::IEEE_FLOAT);
+  }
+
+  /// Get a 80-bit X86 floating point value.
+  static constexpr LLT x86fp80() {
+    return floatingPoint(80, FPVariant::VARIANT_FLOAT_3);
+  }
+
+  /// Get a 128-bit IEEE quad value.
+  static constexpr LLT float128() {
+    return floatingPoint(128, FPVariant::IEEE_FLOAT);
+  }
+
+  /// Get a 128-bit PowerPC double double value.
+  static constexpr LLT ppcf128() {
+    return floatingPoint(128, FPVariant::VARIANT_FLOAT_2);
   }
 
   /// Get a low-level fixed-width vector of some number of elements and element
   /// width.
+  // TODO: deprecate this: [[deprecated("Use LLT::fixed_vector(unsigned, LLT)
+  // instead.")]]
   static constexpr LLT fixed_vector(unsigned NumElements,
                                     unsigned ScalarSizeInBits) {
-    return vector(ElementCount::getFixed(NumElements), ScalarSizeInBits);
+    return vector(ElementCount::getFixed(NumElements),
+                  LLT::integer(ScalarSizeInBits));
   }
 
   /// Get a low-level fixed-width vector of some number of elements and element
@@ -110,9 +202,12 @@ class LLT {
 
   /// Get a low-level scalable vector of some number of elements and element
   /// width.
+  // TODO: deprecate this: [[deprecated("Use LLT::scalable_vector(unsigned, LLT)
+  // instead.")]]
   static constexpr LLT scalable_vector(unsigned MinNumElements,
                                        unsigned ScalarSizeInBits) {
-    return vector(ElementCount::getScalable(MinNumElements), ScalarSizeInBits);
+    return vector(ElementCount::getScalable(MinNumElements),
+                  LLT::integer(ScalarSizeInBits));
   }
 
   /// Get a low-level scalable vector of some number of elements and element
@@ -125,33 +220,84 @@ class LLT {
     return EC.isScalar() ? ScalarTy : LLT::vector(EC, ScalarTy);
   }
 
+  // TODO: deprecate this:  [[deprecated("Use LLT::scalarOrVector(EC, LLT)
+  // instead.")]]
   static constexpr LLT scalarOrVector(ElementCount EC, uint64_t ScalarSize) {
     assert(ScalarSize <= std::numeric_limits<unsigned>::max() &&
            "Not enough bits in LLT to represent size");
     return scalarOrVector(EC, LLT::scalar(static_cast<unsigned>(ScalarSize)));
   }
 
-  explicit constexpr LLT(bool isPointer, bool isVector, bool isScalar,
-                         ElementCount EC, uint64_t SizeInBits,
-                         unsigned AddressSpace)
+  explicit constexpr LLT(Kind Info, ElementCount EC, uint64_t SizeInBits,
+                         unsigned AddressSpace, FPVariant FP)
       : LLT() {
-    init(isPointer, isVector, isScalar, EC, SizeInBits, AddressSpace);
+    init(Info, EC, SizeInBits, AddressSpace, FP);
   }
-  explicit constexpr LLT()
-      : IsScalar(false), IsPointer(false), IsVector(false), RawData(0) {}
 
   explicit LLT(MVT VT);
+  explicit constexpr LLT() : Info(static_cast<Kind>(0)), RawData(0) {}
 
-  constexpr bool isValid() const { return IsScalar || RawData != 0; }
-  constexpr bool isScalar() const { return IsScalar; }
-  constexpr bool isToken() const { return IsScalar && RawData == 0; };
-  constexpr bool isVector() const { return isValid() && IsVector; }
+  constexpr bool isValid() const { return isToken() || RawData != 0; }
+  constexpr bool isScalar() const {
+    return isValid() && (Info == Kind::INTEGER || Info == Kind::FLOAT ||
+                         Info == Kind::SCALAR);
+  }
+  constexpr bool isScalar(unsigned Size) const {
+    return isScalar() && getScalarSizeInBits() == Size;
+  }
+  constexpr bool isFloat() const { return isValid() && Info == Kind::FLOAT; }
+  constexpr bool isFloat(unsigned Size) const {
+    return isFloat() && getScalarSizeInBits() == Size;
+  }
+  constexpr bool isVariantFloat() const {
+    return isFloat() && getFPVariant() != FPVariant::IEEE_FLOAT;
+  }
+  constexpr bool isVariantFloat(FPVariant Variant) const {
+    return isFloat() && getFPVariant() == Variant;
+  }
+  constexpr bool isVariantFloat(unsigned Size, FPVariant Variant) const {
+    return isVariantFloat(Variant) && getScalarSizeInBits() == Size;
+  }
+  constexpr bool isFloatVector() const {
+    return isVector() && Info == Kind::VECTOR_FLOAT;
+  }
+  constexpr bool isIEEEFloat(unsigned Size) const {
+    return isVariantFloat(Size, FPVariant::IEEE_FLOAT);
+  }
+  constexpr bool isBFloat(unsigned Size) const {
+    return isVariantFloat(Size, FPVariant::BRAIN_FLOAT);
+  }
+  constexpr bool isX86FP80() const {
+    return isVariantFloat(80, FPVariant::VARIANT_FLOAT_3);
+  }
+  constexpr bool isPPCF128() const {
+    return isVariantFloat(128, FPVariant::VARIANT_FLOAT_2);
+  }
+  constexpr bool isToken() const {
+    return Info == Kind::INTEGER && RawData == 0;
+  }
+  constexpr bool isInteger() const {
+    return isValid() && Info == Kind::INTEGER;
+  }
+  constexpr bool isInteger(unsigned Size) const {
+    return isInteger() && getScalarSizeInBits() == Size;
+  }
+  constexpr bool isIntegerVector() const {
+    return isVector() && Info == Kind::VECTOR_INTEGER;
+  }
+  constexpr bool isVector() const {
+    return isValid() &&
+           (Info == Kind::VECTOR_INTEGER || Info == Kind::VECTOR_FLOAT ||
+            Info == Kind::VECTOR_POINTER || Info == Kind::VECTOR_SCALAR);
+  }
   constexpr bool isPointer() const {
-    return isValid() && IsPointer && !IsVector;
+    return isValid() && Info == Kind::POINTER;
+  }
+  constexpr bool isPointerVector() const {
+    return isVector() && Info == Kind::VECTOR_POINTER;
   }
-  constexpr bool isPointerVector() const { return IsPointer && isVector(); }
   constexpr bool isPointerOrPointerVector() const {
-    return IsPointer && isValid();
+    return isPointer() || isPointerVector();
   }
 
   /// Returns the number of elements in a vector LLT. Must only be called on
@@ -181,7 +327,7 @@ class LLT {
   constexpr bool isScalableVector() const { return isVector() && isScalable(); }
 
   constexpr ElementCount getElementCount() const {
-    assert(IsVector && "cannot get number of elements on scalar/aggregate");
+    assert(isVector() && "cannot get number of elements on scalar/aggregate");
     return ElementCount::get(getFieldValue(VectorElementsFieldInfo),
                              isScalable());
   }
@@ -206,6 +352,15 @@ class LLT {
     return isVector() ? getElementType() : *this;
   }
 
+  constexpr FPVariant getFPVariant() const {
+    assert((isFloat() || isFloatVector()) &&
+           "cannot get FP info for non float type");
+
+    return FPVariant(getFieldValue(FPFieldInfo));
+  }
+
+  constexpr Kind getKind() const { return Info; }
+
   /// If this type is a vector, return a vector with the same number of elements
   /// but the new element type. Otherwise, return the new element type.
   constexpr LLT changeElementType(LLT NewEltTy) const {
@@ -216,10 +371,10 @@ class LLT {
   /// but the new element size. Otherwise, return the new element type. Invalid
   /// for pointer types. For pointer types, use changeElementType.
   constexpr LLT changeElementSize(unsigned NewEltSize) const {
-    assert(!isPointerOrPointerVector() &&
+    assert(!isPointerOrPointerVector() && !(isFloat() || isFloatVector()) &&
            "invalid to directly change element size for pointers");
-    return isVector() ? LLT::vector(getElementCount(), NewEltSize)
-                      : LLT::scalar(NewEltSize);
+    return isVector() ? LLT::vector(getElementCount(), LLT::integer(NewEltSize))
+                      : LLT::integer(NewEltSize);
   }
 
   /// Return a vector or scalar with the same element type and the new element
@@ -228,6 +383,10 @@ class LLT {
     return LLT::scalarOrVector(EC, getScalarType());
   }
 
+  constexpr LLT changeElementCount(unsigned NumElements) const {
+    return changeElementCount(ElementCount::getFixed(NumElements));
+  }
+
   /// Return a type that is \p Factor times smaller. Reduces the number of
   /// elements if this is a vector, or the bitwidth for scalar/pointers. Does
   /// not attempt to handle cases that aren't evenly divisible.
@@ -242,7 +401,7 @@ class LLT {
     }
 
     assert(getScalarSizeInBits() % Factor == 0);
-    return scalar(getScalarSizeInBits() / Factor);
+    return integer(getScalarSizeInBits() / Factor);
   }
 
   /// Produce a vector type that is \p Factor times bigger, preserving the
@@ -276,10 +435,23 @@ class LLT {
   /// Returns the vector's element type. Only valid for vector types.
   constexpr LLT getElementType() const {
     assert(isVector() && "cannot get element type of scalar/aggregate");
-    if (IsPointer)
+    if (isPointerVector())
       return pointer(getAddressSpace(), getScalarSizeInBits());
-    else
-      return scalar(getScalarSizeInBits());
+
+    if (isFloatVector())
+      return floatingPoint(getScalarSizeInBits(), getFPVariant());
+
+    return integer(getScalarSizeInBits());
+  }
+
+  constexpr LLT changeToInteger() const {
+    if (isPointer() || isPointerVector())
+      return *this;
+
+    if (isVector())
+      return vector(getElementCount(), LLT::integer(getScalarSizeInBits()));
+
+    return integer(getSizeInBits());
   }
 
   void print(raw_ostream &OS) const;
@@ -289,8 +461,7 @@ class LLT {
 #endif
 
   constexpr bool operator==(const LLT &RHS) const {
-    return IsPointer == RHS.IsPointer && IsVector == RHS.IsVector &&
-           IsScalar == RHS.IsScalar && RHS.RawData == RawData;
+    return Info == RHS.Info && RawData == RHS.RawData;
   }
 
   constexpr bool operator!=(const LLT &RHS) const { return !(*this == RHS); }
@@ -300,37 +471,38 @@ class LLT {
 
 private:
   /// LLT is packed into 64 bits as follows:
-  /// isScalar : 1
-  /// isPointer : 1
-  /// isVector  : 1
-  /// with 61 bits remaining for Kind-specific data, packed in bitfields
-  /// as described below. As there isn't a simple portable way to pack bits
-  /// into bitfields, here the different fields in the packed structure is
+  /// Info : 3
+  /// RawData : 61
+  /// with 61 bits of RawData remaining for Kind-specific data, packed in
+  /// bitfields as described below. As there isn't a simple portable way to pack
+  /// bits into bitfields, here the different fields in the packed structure is
   /// described in static const *Field variables. Each of these variables
   /// is a 2-element array, with the first element describing the bitfield size
   /// and the second element describing the bitfield offset.
+  /// There are 3 special LLT instances:
+  /// - invalid: Info == SCALAR, RawData == 0
+  /// - token: Info == INTEGER, RawData == 0
+  /// - empty: Info == FLOAT, RawData == 0
+  /// - tombstone: Info == POINTER, RawData == 0
   ///
-  /// +--------+---------+--------+----------+----------------------+
-  /// |isScalar|isPointer|isVector| RawData  |Notes                 |
-  /// +--------+---------+--------+----------+----------------------+
-  /// |   0    |    0    |   0    |    0     |Invalid               |
-  /// +--------+---------+--------+----------+----------------------+
-  /// |   0    |    0    |   1    |    0     |Tombstone Key         |
-  /// +--------+---------+--------+----------+----------------------+
-  /// |   0    |    1    |   0    |    0     |Empty Key             |
-  /// +--------+---------+--------+----------+----------------------+
-  /// |   1    |    0    |   0    |    0     |Token                 |
-  /// +--------+---------+--------+----------+----------------------+
-  /// |   1    |    0    |   0    | non-zero |Scalar                |
-  /// +--------+---------+--------+----------+----------------------+
-  /// |   0    |    1    |   0    | non-zero |Pointer               |
-  /// +--------+---------+--------+----------+----------------------+
-  /// |   0    |    0    |   1    | non-zero |Vector of non-pointer |
-  /// +--------+---------+--------+----------+----------------------+
-  /// |   0    |    1    |   1    | non-zero |Vector of pointer     |
-  /// +--------+---------+--------+----------+----------------------+
-  ///
-  /// Everything else is reserved.
+  /*
+                                --- LLT ---
+
+   63       56       47       39       31       23       15       7      0
+   |        |        |        |        |        |        |        |      |
+  |xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|
+   ...................................                                      (1)
+   *****************                                                        (2)
+                     ~~~~~~~~~~~~~~~~~~~~~~~~~~                             (3)
+                                                ^^^^^^^^^^^^^^^^^           (4)
+                                                                      @     (5)
+                                            ###                             (6)
+                                                                       %%%  (7)
+
+  (1) ScalarSize  (2) PointerSize  (3) PointerAddressSpace
+  (4) VectorElements  (5) VectorScalable  (6) FPVariant  (7) Kind
+
+  */
   typedef int BitFieldInfo[2];
   ///
   /// This is how the bitfields are packed per Kind:
@@ -340,6 +512,7 @@ class LLT {
   /// * Non-pointer scalar (isPointer == 0 && isVector == 0):
   ///   SizeInBits: 32;
   static const constexpr BitFieldInfo ScalarSizeFieldInfo{32, 29};
+  static const constexpr BitFieldInfo FPFieldInfo{3, 21};
   /// * Pointer (isPoint...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/130651


More information about the llvm-commits mailing list