[GlobalISel][LLT] Introduce FPInfo for LLT (Enable bfloat, ppc128float and others in GlobalISel)#155107
Conversation
…ble extended types for llvm-ir lowering in TargetLoweringBase. Added flag for GISel emitter to enable/disable extended types in matcher tables
|
@llvm/pr-subscribers-llvm-selectiondag @llvm/pr-subscribers-backend-amdgpu Author: Denis.G (DenisGZM) ChangesAdded extra information in LLT to support ambiguous fp types during GlobalISel. Original idea by @tgymnich Main differences from #122503 are:
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:
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]
|
|
@llvm/pr-subscribers-llvm-globalisel Author: Denis.G (DenisGZM) ChangesAdded extra information in LLT to support ambiguous fp types during GlobalISel. Original idea by @tgymnich Main differences from #122503 are:
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:
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]
|
|
@llvm/pr-subscribers-backend-aarch64 Author: Denis.G (DenisGZM) ChangesAdded extra information in LLT to support ambiguous fp types during GlobalISel. Original idea by @tgymnich Main differences from #122503 are:
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:
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]
|
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/154/builds/29467 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/23/builds/18809 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/13/builds/12352 Here is the relevant piece of the build log for the reference |
|
Hi, anybody looking at fixing this issue or should we revert? |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/38/builds/8344 Here is the relevant piece of the build log for the reference |
Probably is #188273 |
|
FWIW, this has some compile-time performance impact, stage1-aarch64-O0g +0.22%. https://llvm-compile-time-tracker.com/compare.php?from=46205ff9b4cbe2bc18cc6600f0acf76bb4810053&to=b1aa6a45060bb9f89efded9e694503d6b4626a4a&stat=instructions:u |
|
There are compile-time failure here: |
…c128float and others in GlobalISel) (llvm#155107)" This reverts commit b1aa6a4 and commit ce44d63. This fails the build with some older gcc: llvm/include/llvm/CodeGenTypes/LowLevelType.h:501:35: error: call to non-constexpr function ‘static llvm::LLT llvm::LLT::integer(unsigned int)’ return integer(getSizeInBits()); ^
|
Reverting in #188344 |
…c128float and others in GlobalISel) (#155107)" (#188344) This reverts commit b1aa6a4 and commit ce44d63. This fails the build with some older gcc: llvm/include/llvm/CodeGenTypes/LowLevelType.h:501:35: error: call to non-constexpr function ‘static llvm::LLT llvm::LLT::integer(unsigned int)’ return integer(getSizeInBits()); ^
…c128float and others in GlobalISel) (llvm#155107)" (llvm#188344) This reverts commit b1aa6a4 and commit ce44d63. This fails the build with some older gcc: llvm/include/llvm/CodeGenTypes/LowLevelType.h:501:35: error: call to non-constexpr function ‘static llvm::LLT llvm::LLT::integer(unsigned int)’ return integer(getSizeInBits()); ^
Duh, this is something that can easily get missed. GCC 7 and 8 would fail the compilation, GCC 9+ works. |
…calling non-constexpr integer()/floatingPoint() PR llvm#155107 introduced LLT::integer() and LLT::floatingPoint() which are non-constexpr (they call getUseExtended() which reads a mutable static). Several constexpr member functions now transitively call these, which GCC 7/8 eagerly rejects even if the non-constexpr path is never taken at compile time. GCC 9+ defers this check and accepts the code. Remove constexpr from: getScalarType, changeElementSize, changeVectorElementCount, changeElementCount, divide, multiplyElements, getElementType, changeToInteger, operator==, operator!=. Convert affected static_asserts in LowLevelTypeTest.cpp to runtime EXPECT_EQ checks.
…t and others in GlobalISel) (llvm#155107) Added extra information in LLT to support ambiguous fp types during GlobalISel. Original idea by @tgymnich Main differences from llvm#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 indentifiers. --------- Co-authored-by: Tim Gymnich <tim@gymni.ch> Co-authored-by: Ryan Cowan <ryan.cowan@arm.com>
…c128float and others in GlobalISel) (llvm#155107)" (llvm#188344) This reverts commit b1aa6a4 and commit ce44d63. This fails the build with some older gcc: llvm/include/llvm/CodeGenTypes/LowLevelType.h:501:35: error: call to non-constexpr function ‘static llvm::LLT llvm::LLT::integer(unsigned int)’ return integer(getSizeInBits()); ^
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/114/builds/239 Here is the relevant piece of the build log for the reference |
…c128float and others in GlobalISel) (#155107)" (#188502) This is a reland of #155107 along with a fix for old gcc builds. This patch is reverted in #188344 due to compilation failures described in #155107 (comment) The fix to old gcc builds is to remove `constexpr` modifiers in the original patch in 0721d8e
… bfloat, ppc128float and others in GlobalISel) (#155107)" (#188502) This is a reland of llvm/llvm-project#155107 along with a fix for old gcc builds. This patch is reverted in llvm/llvm-project#188344 due to compilation failures described in llvm/llvm-project#155107 (comment) The fix to old gcc builds is to remove `constexpr` modifiers in the original patch in 0721d8e7768c011b8cf2d4d223ca6eca3392b1f9
|
Been experimenting with this (after reland), and it's pretty sweet. Really helps clean up RegBankSelect (at least for Wasm). Am I correct in my understanding that while this introduces extended LLT, it doesn't actually migrate much (or any of) of the core GISel infastructure to use I noticed that for instance, |
|
I've found an issue while trying this out (related to match table). Details at #190873 |
… bfloat, ppc128float and others in GlobalISel) (#155107)" (#188502) This is a reland of llvm/llvm-project#155107 along with a fix for old gcc builds. This patch is reverted in llvm/llvm-project#188344 due to compilation failures described in llvm/llvm-project#155107 (comment) The fix to old gcc builds is to remove `constexpr` modifiers in the original patch in 0721d8e7768c011b8cf2d4d223ca6eca3392b1f9
Added extra information in LLT to support ambiguous fp types during GlobalISel. Original idea by @tgymnich
Main differences from #122503 are:
TargetOption::EnableGlobalISelExtendedLLT(disabled by default)IRTranslatoruseTargetLoweringInfofor appropriateLLTgeneration.LLT::float32for float types as they are real now. AddedTODOfor such cases.Also MIRParser now may parse new type indentifiers.