[llvm] [GlobalISel][LLT] Introduce FPInfo for LLT (PR #155107)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 23 09:05:44 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-globalisel
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