[llvm] [GlobalISel][LLT] Introduce FPInfo for LLT (PR #155107)

via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 23 09:05:43 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: Denis.G (DenisGZM)

<details>
<summary>Changes</summary>

Added extra information in LLT to support ambiguous fp types during GlobalISel. Original idea by @<!-- -->tgymnich

Main differences from https://github.com/llvm/llvm-project/pull/122503 are:
* Do not deprecate LLT::scalar
* Allow targets to enable/disable IR translation with extenden LLT via `TargetOption::EnableGlobalISelExtendedLLT` (disabled by default)
* `IRTranslator` use `TargetLoweringInfo` for appropriate `LLT` generation.
* For this reason added flag in GlobalISelMatchTable` to allow switch between legacy and new extended LLT names
* Revert using stubs like `LLT::float32` for float types as they are real now. Added `TODO` for such cases.

Also MIRParser now may parse new type indetifiers.


---

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


50 Files Affected:

- (modified) llvm/include/llvm/CodeGen/Analysis.h (+2-1) 
- (modified) llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h (+2) 
- (modified) llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h (+1-1) 
- (modified) llvm/include/llvm/CodeGen/LowLevelTypeUtils.h (+3-3) 
- (modified) llvm/include/llvm/CodeGen/TargetLowering.h (+3) 
- (modified) llvm/include/llvm/CodeGenTypes/LowLevelType.h (+275-99) 
- (modified) llvm/include/llvm/Target/TargetMachine.h (+1) 
- (modified) llvm/include/llvm/Target/TargetOptions.h (+6-1) 
- (modified) llvm/lib/CodeGen/Analysis.cpp (+5-5) 
- (modified) llvm/lib/CodeGen/GlobalISel/CallLowering.cpp (+7-6) 
- (modified) llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp (+46-41) 
- (modified) llvm/lib/CodeGen/GlobalISel/LegalizeMutations.cpp (+2-4) 
- (modified) llvm/lib/CodeGen/GlobalISel/LoadStoreOpt.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp (+2-1) 
- (modified) llvm/lib/CodeGen/LowLevelTypeUtils.cpp (+71-16) 
- (modified) llvm/lib/CodeGen/MIRParser/MIParser.cpp (+78-37) 
- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (+2-2) 
- (modified) llvm/lib/CodeGen/TargetLoweringBase.cpp (+8) 
- (modified) llvm/lib/CodeGenTypes/LowLevelType.cpp (+65-14) 
- (modified) llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp (+2-2) 
- (modified) llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp (+1-1) 
- (modified) llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp (+3-2) 
- (modified) llvm/lib/Target/AMDGPU/AMDGPUCombinerHelper.cpp (+5-3) 
- (modified) llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp (+9-8) 
- (modified) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid0.mir (+2-2) 
- (modified) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid1.mir (+2-2) 
- (modified) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid2.mir (+1-1) 
- (modified) llvm/test/CodeGen/MIR/AArch64/parse-low-level-type-invalid3.mir (+3-3) 
- (modified) llvm/test/CodeGen/MIR/Generic/scalable-vector-type-err0.mir (+1-1) 
- (modified) llvm/test/CodeGen/MIR/Generic/scalable-vector-type-err1.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-err11.mir (+1-1) 
- (modified) llvm/test/CodeGen/MIR/Generic/scalable-vector-type-err12.mir (+1-1) 
- (modified) llvm/test/CodeGen/MIR/Generic/scalable-vector-type-err13.mir (+1-1) 
- (modified) llvm/test/CodeGen/MIR/Generic/scalable-vector-type-err14.mir (+1-1) 
- (modified) llvm/test/CodeGen/MIR/Generic/scalable-vector-type-err15.mir (+1-1) 
- (modified) llvm/test/CodeGen/MIR/Generic/scalable-vector-type-err2.mir (+1-1) 
- (modified) llvm/test/CodeGen/MIR/Generic/scalable-vector-type-err3.mir (+1-1) 
- (modified) llvm/test/CodeGen/MIR/Generic/scalable-vector-type-err4.mir (+1-1) 
- (modified) llvm/test/CodeGen/MIR/Generic/scalable-vector-type-err5.mir (+1-1) 
- (modified) llvm/test/CodeGen/MIR/Generic/scalable-vector-type-err6.mir (+1-1) 
- (modified) llvm/test/CodeGen/MIR/Generic/scalable-vector-type-err7.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 (+2-2) 
- (modified) llvm/test/CodeGen/MIR/WebAssembly/typed-immediate-operand-invalid1.mir (+2-2) 
- (modified) llvm/unittests/CodeGen/GlobalISel/CMakeLists.txt (+1) 
- (added) llvm/unittests/CodeGen/GlobalISel/IRTranslatorBF16Test.cpp (+130) 
- (modified) llvm/unittests/CodeGen/GlobalISel/LegalizerInfoTest.cpp (+8-6) 
- (modified) llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp (+70-9) 


``````````diff
diff --git a/llvm/include/llvm/CodeGen/Analysis.h b/llvm/include/llvm/CodeGen/Analysis.h
index 98b52579d03b7..2aadc27930b7a 100644
--- a/llvm/include/llvm/CodeGen/Analysis.h
+++ b/llvm/include/llvm/CodeGen/Analysis.h
@@ -101,7 +101,8 @@ inline void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL,
 /// If Offsets is non-null, it points to a vector to be filled in
 /// with the in-memory offsets of each of the individual values.
 ///
-void computeValueLLTs(const DataLayout &DL, Type &Ty,
+void computeValueLLTs(const TargetLowering &TLI,
+                      const DataLayout &DL, Type &Ty,
                       SmallVectorImpl<LLT> &ValueTys,
                       SmallVectorImpl<uint64_t> *Offsets = nullptr,
                       uint64_t StartingOffset = 0);
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
index 3d7ccd55ee042..5673fd5168477 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
@@ -642,6 +642,8 @@ class IRTranslator : public MachineFunctionPass {
 
   StackProtectorDescriptor SPDescriptor;
 
+  bool mayTranslateUserTypes(const User &U) const;
+
   /// Switch analysis and optimization.
   class GISelSwitchLowering : public SwitchCG::SwitchLowering {
   public:
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
index fd72a3898562e..8412042a780e8 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
@@ -380,7 +380,7 @@ LLVM_ABI LegalizeMutation changeElementCountTo(unsigned TypeIdx,
 
 /// Keep the same scalar or element type as \p TypeIdx, but take the number of
 /// elements from \p Ty.
-LLVM_ABI LegalizeMutation changeElementCountTo(unsigned TypeIdx, LLT Ty);
+LLVM_ABI 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 51a298eb8b247..1c8f34b1a8518 100644
--- a/llvm/include/llvm/CodeGen/LowLevelTypeUtils.h
+++ b/llvm/include/llvm/CodeGen/LowLevelTypeUtils.h
@@ -27,7 +27,7 @@ class Type;
 struct fltSemantics;
 
 /// Construct a low-level type based on an LLVM type.
-LLVM_ABI LLT getLLTForType(Type &Ty, const DataLayout &DL);
+LLVM_ABI LLT getLLTForType(Type &Ty, const DataLayout &DL, bool AllowExtendedLLT = false);
 
 /// Get a rough equivalent of an MVT for a given LLT. MVT can't distinguish
 /// pointers, so these will convert to a plain integer.
@@ -36,11 +36,11 @@ LLVM_ABI EVT getApproximateEVTForLLT(LLT Ty, LLVMContext &Ctx);
 
 /// Get a rough equivalent of an LLT for a given MVT. LLT does not yet support
 /// scalarable vector types, and will assert if used.
-LLVM_ABI LLT getLLTForMVT(MVT Ty);
+LLVM_ABI LLT getLLTForMVT(MVT Ty, bool AllowExtendedLLT = false);
 
 /// Get the appropriate floating point arithmetic semantic based on the bit size
 /// of the given scalar LLT.
 LLVM_ABI const llvm::fltSemantics &getFltSemanticForLLT(LLT Ty);
-}
+} // namespace llvm
 
 #endif // LLVM_CODEGEN_LOWLEVELTYPEUTILS_H
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 4480ced637456..f4fdd8c69ea9e 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -416,6 +416,9 @@ class LLVM_ABI TargetLoweringBase {
   /// amounts, returns MVT::i32.
   EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const;
 
+  virtual LLT getLLTForType(Type &Ty, const DataLayout &DL) const;
+  virtual LLT getLLTForMVT(MVT Ty) const;
+
   /// Return the preferred type to use for a shift opcode, given the shifted
   /// amount type is \p ShiftValueTy.
   LLVM_READONLY
diff --git a/llvm/include/llvm/CodeGenTypes/LowLevelType.h b/llvm/include/llvm/CodeGenTypes/LowLevelType.h
index d8e0848aff84d..0c217ba1fcf7e 100644
--- a/llvm/include/llvm/CodeGenTypes/LowLevelType.h
+++ b/llvm/include/llvm/CodeGenTypes/LowLevelType.h
@@ -39,68 +39,148 @@ class raw_ostream;
 
 class LLT {
 public:
+  enum class FPVariant {
+    IEEE_FLOAT = 0x0,
+    BRAIN_FLOAT = 0x1,     // BRAIN_FLOAT
+    PPC128_FLOAT = 0x2,    // PPC128_FLOAT
+    EXTENDED_FP80 = 0x3,   // FP80
+    TENSOR_FLOAT32 = 0x4,  // TENSOR_FLOAT32
+    VARIANT_FLOAT_5 = 0x5, // UNASSIGNED
+    VARIANT_FLOAT_6 = 0x6, // UNASSIGNED
+    VARIANT_FLOAT_7 = 0x7, // UNASSIGNED
+  };
+
+  enum class Kind : uint64_t {
+    INVALID = 0b0000,
+    ANY_SCALAR = 0b0001,
+    INTEGER = 0b0010,
+    FLOAT = 0b0011,
+    POINTER = 0b0100,
+    VECTOR_ANY = 0b0101,
+    VECTOR_INTEGER = 0b0110,
+    VECTOR_FLOAT = 0b0111,
+    VECTOR_POINTER = 0b1000,
+  };
+
+  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;
+
+    return Kind::VECTOR_ANY;
+  }
+
+  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;
+
+    return Kind::ANY_SCALAR;
+  }
+
   /// Get a low-level scalar or aggregate "bag of bits".
   static constexpr LLT scalar(unsigned SizeInBits) {
-    return LLT{/*isPointer=*/false, /*isVector=*/false, /*isScalar=*/true,
-               ElementCount::getFixed(0), SizeInBits,
-               /*AddressSpace=*/0};
+    return LLT{Kind::ANY_SCALAR, 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),
+    return LLT{Kind::ANY_SCALAR, ElementCount::getFixed(0),
                /*SizeInBits=*/0,
-               /*AddressSpace=*/0};
+               /*AddressSpace=*/0, static_cast<FPVariant>(0)};
   }
 
   /// 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.
   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_ANY, 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::EXTENDED_FP80);
+  }
+
+  /// 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::PPC128_FLOAT);
   }
 
   /// Get a low-level fixed-width vector of some number of elements and element
   /// width.
-  static constexpr LLT fixed_vector(unsigned NumElements,
-                                    unsigned ScalarSizeInBits) {
-    return vector(ElementCount::getFixed(NumElements), ScalarSizeInBits);
+  static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits) {
+    return vector(ElementCount::getFixed(NumElements),
+                  LLT::scalar(ScalarSizeInBits));
   }
 
   /// Get a low-level fixed-width vector of some number of elements and element
@@ -111,9 +191,9 @@ class LLT {
 
   /// Get a low-level scalable vector of some number of elements and element
   /// width.
-  static constexpr LLT scalable_vector(unsigned MinNumElements,
-                                       unsigned ScalarSizeInBits) {
-    return vector(ElementCount::getScalable(MinNumElements), ScalarSizeInBits);
+  static constexpr LLT scalable_vector(unsigned MinNumElements, unsigned ScalarSizeInBits) {
+    return vector(ElementCount::getScalable(MinNumElements),
+                  LLT::scalar(ScalarSizeInBits));
   }
 
   /// Get a low-level scalable vector of some number of elements and element
@@ -132,27 +212,79 @@ class LLT {
     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) {}
 
-  LLVM_ABI explicit LLT(MVT VT);
+  LLVM_ABI explicit LLT(MVT VT, bool AllowExtendedLLT = false);
+  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 Info == Kind::ANY_SCALAR || Info == Kind::INTEGER || Info == Kind::FLOAT; }
+  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::EXTENDED_FP80);
+  }
+  constexpr bool isPPCF128() const {
+    return isVariantFloat(128, FPVariant::PPC128_FLOAT);
+  }
+  constexpr bool isToken() const {
+    return Info == Kind::ANY_SCALAR && RawData == 0;
+  }
+  constexpr bool isAnyScalar() const {
+    return isValid() && Info == Kind::ANY_SCALAR;
+  }
+  constexpr bool isVectorAny() const {
+    return isVector() && Info == Kind::VECTOR_ANY;
+  }
+  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_ANY || Info == Kind::VECTOR_INTEGER||
+            Info == Kind::VECTOR_FLOAT || Info == Kind::VECTOR_POINTER);
+  }
   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
@@ -177,12 +309,18 @@ class LLT {
   /// if the LLT is not a vector type.
   constexpr bool isFixedVector() const { return isVector() && !isScalable(); }
 
+  constexpr bool isFixedVector(unsigned NumElements,
+                               unsigned ScalarSize) const {
+    return isFixedVector() && getNumElements() == NumElements &&
+           getScalarSizeInBits() == ScalarSize;
+  }
+
   /// Returns true if the LLT is a scalable vector. Returns false otherwise,
   /// even if the LLT is not a vector type.
   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());
   }
@@ -207,6 +345,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 {
@@ -217,10 +364,14 @@ 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(), getElementType().isInteger()
+                                                    ? LLT::integer(NewEltSize)
+                                                    : LLT::scalar(NewEltSize))
+           : isInteger() ? LLT::integer(NewEltSize)
+                         : LLT::scalar(NewEltSize);
   }
 
   /// Return a vector or scalar with the same element type and the new element
@@ -229,6 +380,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.
@@ -243,6 +398,9 @@ class LLT {
     }
 
     assert(getScalarSizeInBits() % Factor == 0);
+    if (isInteger())
+      return integer(getScalarSizeInBits() / Factor);
+
     return scalar(getScalarSizeInBits() / Factor);
   }
 
@@ -277,10 +435,26 @@ 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());
+
+    if (isIntegerVector())
+      return integer(getScalarSizeInBits());
+
+    return scalar(getScalarSizeInBits());
+  }
+
+  constexpr LLT changeToInteger() const {
+    if (isPointer() || isPointerVector())
+      return *this;
+
+    if (isVector())
+      return vector(getElementCount(), LLT::integer(getScalarSizeInBits()));
+
+    return integer(getSizeInBits());
   }
 
   LLVM_ABI void print(raw_ostream &OS) const;
@@ -290,8 +464,14 @@ class LLT {
 #endif
 
   constexpr bool operator==(const LLT &RHS) const {
-    return IsPointer == RHS.IsPointer && IsVector == RHS.IsVector &&
-           IsScalar == RHS.IsScalar && RHS.RawData == RawData;
+    if (isAnyScalar() || RHS.isAnyScalar()) {
+      return isScalar() == RHS.isScalar() && RawData == RHS.RawData;
+    }
+    if (isVector() && RHS.isVector()) {
+      return getElementType() == RHS.getElementType() &&
+             getElementCount() == RHS.getElementCount();
+    }
+    return Info == RHS.Info && RawData == RHS.RawData;
   }
 
   constexpr bool operator!=(const LLT &RHS) const { return !(*this == RHS); }
@@ -301,37 +481,33 @@ 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 : 4
+  /// RawData : 60
+  /// 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 ele...
[truncated]

``````````

</details>


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


More information about the llvm-commits mailing list