diff --git a/lldb/source/Expression/IRInterpreter.cpp b/lldb/source/Expression/IRInterpreter.cpp --- a/lldb/source/Expression/IRInterpreter.cpp +++ b/lldb/source/Expression/IRInterpreter.cpp @@ -597,7 +597,8 @@ switch (operand_type->getTypeID()) { default: break; - case Type::VectorTyID: { + case Type::FixedVectorTyID: + case Type::ScalableVectorTyID: { LLDB_LOGF(log, "Unsupported operand type: %s", PrintType(operand_type).c_str()); error.SetErrorString(unsupported_operand_error); diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -157,10 +157,11 @@ LLVMStructTypeKind, /**< Structures */ LLVMArrayTypeKind, /**< Arrays */ LLVMPointerTypeKind, /**< Pointers */ - LLVMVectorTypeKind, /**< SIMD 'packed' format, or other vector type */ LLVMMetadataTypeKind, /**< Metadata */ LLVMX86_MMXTypeKind, /**< X86 MMX */ - LLVMTokenTypeKind /**< Tokens */ + LLVMTokenTypeKind, /**< Tokens */ + LLVMFixedVectorTypeKind, /**< Fixed width SIMD vector type */ + LLVMScalableVectorTypeKind /**< Scalable SIMD vector type */ } LLVMTypeKind; typedef enum { diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h --- a/llvm/include/llvm/IR/DataLayout.h +++ b/llvm/include/llvm/IR/DataLayout.h @@ -664,7 +664,8 @@ // only 80 bits contain information. case Type::X86_FP80TyID: return TypeSize::Fixed(80); - case Type::VectorTyID: { + case Type::FixedVectorTyID: + case Type::ScalableVectorTyID: { VectorType *VTy = cast(Ty); auto EltCnt = VTy->getElementCount(); uint64_t MinBits = EltCnt.Min * diff --git a/llvm/include/llvm/IR/DerivedTypes.h b/llvm/include/llvm/IR/DerivedTypes.h --- a/llvm/include/llvm/IR/DerivedTypes.h +++ b/llvm/include/llvm/IR/DerivedTypes.h @@ -386,7 +386,7 @@ return cast(this)->getNumElements(); } -/// Class to represent vector types. +/// Base class of all SIMD vector types class VectorType : public Type { /// A fully specified VectorType is of the form . 'n' is the /// minimum number of elements of type Ty contained within the vector, and @@ -403,24 +403,22 @@ /// The element type of the vector. Type *ContainedType; - /// Minumum number of elements in the vector. - uint64_t NumElements; - VectorType(Type *ElType, unsigned NumEl, bool Scalable = false); - VectorType(Type *ElType, ElementCount EC); + /// The element count of this vector + ElementCount EC; - // If true, the total number of elements is an unknown multiple of the - // minimum 'NumElements'. Otherwise the total number of elements is exactly - // equal to 'NumElements'. - bool Scalable; +protected: + VectorType(Type *ElType, ElementCount EC, Type::TypeID TID); public: VectorType(const VectorType &) = delete; VectorType &operator=(const VectorType &) = delete; - /// For scalable vectors, this will return the minimum number of elements - /// in the vector. - unsigned getNumElements() const { return NumElements; } + /// Get the number of elements in this vector. It does not make sense to call + /// this function on a scalable vector, and this will be moved into + /// FixedVectorType in a future commit + unsigned getNumElements() const { return EC.Min; } + Type *getElementType() const { return ContainedType; } /// This static method is the primary way to construct an VectorType. @@ -430,6 +428,10 @@ return VectorType::get(ElementType, {NumElements, Scalable}); } + static VectorType *get(Type *ElementType, const VectorType *Other) { + return VectorType::get(ElementType, Other->getElementCount()); + } + /// This static method gets a VectorType with the same number of elements as /// the input type, and the element type is an integer type of the same width /// as the input element type. @@ -507,26 +509,53 @@ /// Return an ElementCount instance to represent the (possibly scalable) /// number of elements in the vector. - ElementCount getElementCount() const { - uint64_t MinimumEltCnt = getNumElements(); - assert(MinimumEltCnt <= UINT_MAX && "Too many elements in vector"); - return { (unsigned)MinimumEltCnt, Scalable }; - } + ElementCount getElementCount() const { return EC; } /// Returns whether or not this is a scalable vector (meaning the total /// element count is a multiple of the minimum). - bool isScalable() const { - return Scalable; - } + bool isScalable() const { return EC.Scalable; } /// Methods for support type inquiry through isa, cast, and dyn_cast. static bool classof(const Type *T) { - return T->getTypeID() == VectorTyID; + return T->getTypeID() == FixedVectorTyID || + T->getTypeID() == ScalableVectorTyID; } }; bool Type::isVectorTy() const { return isa(this); } +/// Class to represent fixed width SIMD vectors +class FixedVectorType : public VectorType { +protected: + FixedVectorType(Type *ElTy, unsigned NumElts) + : VectorType(ElTy, {NumElts, false}, FixedVectorTyID) {} + +public: + static FixedVectorType *get(Type *ElementType, unsigned NumElts); + + static bool classof(const Type *T) { + return T->getTypeID() == FixedVectorTyID; + } +}; + +/// Class to represent scalable SIMD vectors +class ScalableVectorType : public VectorType { +protected: + ScalableVectorType(Type *ElTy, unsigned MinNumElts) + : VectorType(ElTy, {MinNumElts, true}, ScalableVectorTyID) {} + +public: + static ScalableVectorType *get(Type *ElementType, unsigned MinNumElts); + + /// Get the minimum number of elements in this vector. The actual number of + /// elements in the vector is an integer multiple of this value. + uint64_t getMinNumElements() const { return getElementCount().Min; } + + static bool classof(const Type *T) { + return T->getTypeID() == ScalableVectorTyID; + } +}; + /// Class to represent pointers. class PointerType : public Type { explicit PointerType(Type *ElType, unsigned AddrSpace); diff --git a/llvm/include/llvm/IR/Type.h b/llvm/include/llvm/IR/Type.h --- a/llvm/include/llvm/IR/Type.h +++ b/llvm/include/llvm/IR/Type.h @@ -54,26 +54,27 @@ /// enum TypeID { // PrimitiveTypes - make sure LastPrimitiveTyID stays up to date. - VoidTyID = 0, ///< 0: type with no size - HalfTyID, ///< 1: 16-bit floating point type - FloatTyID, ///< 2: 32-bit floating point type - DoubleTyID, ///< 3: 64-bit floating point type - X86_FP80TyID, ///< 4: 80-bit floating point type (X87) - FP128TyID, ///< 5: 128-bit floating point type (112-bit mantissa) - PPC_FP128TyID, ///< 6: 128-bit floating point type (two 64-bits, PowerPC) - LabelTyID, ///< 7: Labels - MetadataTyID, ///< 8: Metadata - X86_MMXTyID, ///< 9: MMX vectors (64 bits, X86 specific) - TokenTyID, ///< 10: Tokens + VoidTyID = 0, ///< 0: type with no size + HalfTyID, ///< 1: 16-bit floating point type + FloatTyID, ///< 2: 32-bit floating point type + DoubleTyID, ///< 3: 64-bit floating point type + X86_FP80TyID, ///< 4: 80-bit floating point type (X87) + FP128TyID, ///< 5: 128-bit floating point type (112-bit mantissa) + PPC_FP128TyID, ///< 6: 128-bit floating point type (two 64-bits, PowerPC) + LabelTyID, ///< 7: Labels + MetadataTyID, ///< 8: Metadata + X86_MMXTyID, ///< 9: MMX vectors (64 bits, X86 specific) + TokenTyID, ///< 10: Tokens // Derived types... see DerivedTypes.h file. // Make sure FirstDerivedTyID stays up to date! - IntegerTyID, ///< 11: Arbitrary bit width integers - FunctionTyID, ///< 12: Functions - StructTyID, ///< 13: Structures - ArrayTyID, ///< 14: Arrays - PointerTyID, ///< 15: Pointers - VectorTyID ///< 16: SIMD 'packed' format, or other vector type + IntegerTyID, ///< 11: Arbitrary bit width integers + FunctionTyID, ///< 12: Functions + StructTyID, ///< 13: Structures + ArrayTyID, ///< 14: Arrays + PointerTyID, ///< 15: Pointers + FixedVectorTyID, ///< 16: Fixed width SIMD vector type + ScalableVectorTyID ///< 17: Scalable SIMD vector type }; private: @@ -266,8 +267,7 @@ return true; // If it is not something that can have a size (e.g. a function or label), // it doesn't have a size. - if (getTypeID() != StructTyID && getTypeID() != ArrayTyID && - getTypeID() != VectorTyID) + if (getTypeID() != StructTyID && getTypeID() != ArrayTyID && !isVectorTy()) return false; // Otherwise we have to try harder to decide. return isSizedDerivedType(Visited); diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -949,7 +949,8 @@ AbbrevToUse = ArrayAbbrev; break; } - case Type::VectorTyID: { + case Type::FixedVectorTyID: + case Type::ScalableVectorTyID: { VectorType *VT = cast(T); // VECTOR [numelts, eltty] or // [numelts, eltty, scalable] diff --git a/llvm/lib/CodeGen/ValueTypes.cpp b/llvm/lib/CodeGen/ValueTypes.cpp --- a/llvm/lib/CodeGen/ValueTypes.cpp +++ b/llvm/lib/CodeGen/ValueTypes.cpp @@ -362,7 +362,8 @@ case Type::FP128TyID: return MVT(MVT::f128); case Type::PPC_FP128TyID: return MVT(MVT::ppcf128); case Type::PointerTyID: return MVT(MVT::iPTR); - case Type::VectorTyID: { + case Type::FixedVectorTyID: + case Type::ScalableVectorTyID: { VectorType *VTy = cast(Ty); return getVectorVT( getVT(VTy->getElementType(), /*HandleUnknown=*/ false), @@ -380,7 +381,8 @@ return MVT::getVT(Ty, HandleUnknown); case Type::IntegerTyID: return getIntegerVT(Ty->getContext(), cast(Ty)->getBitWidth()); - case Type::VectorTyID: { + case Type::FixedVectorTyID: + case Type::ScalableVectorTyID: { VectorType *VTy = cast(Ty); return getVectorVT(Ty->getContext(), getEVT(VTy->getElementType(), /*HandleUnknown=*/ false), diff --git a/llvm/lib/ExecutionEngine/ExecutionEngine.cpp b/llvm/lib/ExecutionEngine/ExecutionEngine.cpp --- a/llvm/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/llvm/lib/ExecutionEngine/ExecutionEngine.cpp @@ -624,17 +624,18 @@ } } break; - case Type::VectorTyID: - // if the whole vector is 'undef' just reserve memory for the value. - auto* VTy = cast(C->getType()); - Type *ElemTy = VTy->getElementType(); - unsigned int elemNum = VTy->getNumElements(); - Result.AggregateVal.resize(elemNum); - if (ElemTy->isIntegerTy()) - for (unsigned int i = 0; i < elemNum; ++i) - Result.AggregateVal[i].IntVal = - APInt(ElemTy->getPrimitiveSizeInBits(), 0); - break; + case Type::FixedVectorTyID: + case Type::ScalableVectorTyID: + // if the whole vector is 'undef' just reserve memory for the value. + auto *VTy = cast(C->getType()); + Type *ElemTy = VTy->getElementType(); + unsigned int elemNum = VTy->getNumElements(); + Result.AggregateVal.resize(elemNum); + if (ElemTy->isIntegerTy()) + for (unsigned int i = 0; i < elemNum; ++i) + Result.AggregateVal[i].IntVal = + APInt(ElemTy->getPrimitiveSizeInBits(), 0); + break; } return Result; } @@ -914,7 +915,8 @@ else llvm_unreachable("Unknown constant pointer type!"); break; - case Type::VectorTyID: { + case Type::FixedVectorTyID: + case Type::ScalableVectorTyID: { unsigned elemNum; Type* ElemTy; const ConstantDataVector *CDV = dyn_cast(C); @@ -1006,8 +1008,7 @@ break; } llvm_unreachable("Unknown constant pointer type!"); - } - break; + } break; default: SmallString<256> Msg; @@ -1046,7 +1047,8 @@ *((PointerTy*)Ptr) = Val.PointerVal; break; - case Type::VectorTyID: + case Type::FixedVectorTyID: + case Type::ScalableVectorTyID: for (unsigned i = 0; i < Val.AggregateVal.size(); ++i) { if (cast(Ty)->getElementType()->isDoubleTy()) *(((double*)Ptr)+i) = Val.AggregateVal[i].DoubleVal; @@ -1096,7 +1098,8 @@ Result.IntVal = APInt(80, y); break; } - case Type::VectorTyID: { + case Type::FixedVectorTyID: + case Type::ScalableVectorTyID: { auto *VT = cast(Ty); Type *ElemT = VT->getElementType(); const unsigned numElems = VT->getNumElements(); diff --git a/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp b/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp --- a/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -169,13 +169,14 @@ Dest.IntVal = APInt(1,Src1.IntVal.OP(Src2.IntVal)); \ break; -#define IMPLEMENT_VECTOR_INTEGER_ICMP(OP, TY) \ - case Type::VectorTyID: { \ - assert(Src1.AggregateVal.size() == Src2.AggregateVal.size()); \ - Dest.AggregateVal.resize( Src1.AggregateVal.size() ); \ - for( uint32_t _i=0;_i(Ty)->getElementType()->isFloatTy()) { \ - IMPLEMENT_VECTOR_FCMP_T(OP, Float); \ - } else { \ - IMPLEMENT_VECTOR_FCMP_T(OP, Double); \ +#define IMPLEMENT_VECTOR_FCMP(OP) \ + case Type::FixedVectorTyID: \ + case Type::ScalableVectorTyID: \ + if (cast(Ty)->getElementType()->isFloatTy()) { \ + IMPLEMENT_VECTOR_FCMP_T(OP, Float); \ + } else { \ + IMPLEMENT_VECTOR_FCMP_T(OP, Double); \ } static GenericValue executeFCMP_OEQ(GenericValue Src1, GenericValue Src2, @@ -1327,7 +1329,7 @@ ExecutionContext &SF) { GenericValue Dest, Src = getOperandValue(SrcVal, SF); - if (SrcVal->getType()->getTypeID() == Type::VectorTyID) { + if (isa(SrcVal->getType())) { assert(SrcVal->getType()->getScalarType()->isDoubleTy() && DstTy->getScalarType()->isFloatTy() && "Invalid FPTrunc instruction"); @@ -1350,7 +1352,7 @@ ExecutionContext &SF) { GenericValue Dest, Src = getOperandValue(SrcVal, SF); - if (SrcVal->getType()->getTypeID() == Type::VectorTyID) { + if (isa(SrcVal->getType())) { assert(SrcVal->getType()->getScalarType()->isFloatTy() && DstTy->getScalarType()->isDoubleTy() && "Invalid FPExt instruction"); @@ -1373,7 +1375,7 @@ Type *SrcTy = SrcVal->getType(); GenericValue Dest, Src = getOperandValue(SrcVal, SF); - if (SrcTy->getTypeID() == Type::VectorTyID) { + if (isa(SrcTy)) { Type *DstVecTy = DstTy->getScalarType(); Type *SrcVecTy = SrcTy->getScalarType(); uint32_t DBitWidth = cast(DstVecTy)->getBitWidth(); @@ -1411,7 +1413,7 @@ Type *SrcTy = SrcVal->getType(); GenericValue Dest, Src = getOperandValue(SrcVal, SF); - if (SrcTy->getTypeID() == Type::VectorTyID) { + if (isa(SrcTy)) { Type *DstVecTy = DstTy->getScalarType(); Type *SrcVecTy = SrcTy->getScalarType(); uint32_t DBitWidth = cast(DstVecTy)->getBitWidth(); @@ -1447,7 +1449,7 @@ ExecutionContext &SF) { GenericValue Dest, Src = getOperandValue(SrcVal, SF); - if (SrcVal->getType()->getTypeID() == Type::VectorTyID) { + if (isa(SrcVal->getType())) { Type *DstVecTy = DstTy->getScalarType(); unsigned size = Src.AggregateVal.size(); // the sizes of src and dst vectors must be equal @@ -1479,7 +1481,7 @@ ExecutionContext &SF) { GenericValue Dest, Src = getOperandValue(SrcVal, SF); - if (SrcVal->getType()->getTypeID() == Type::VectorTyID) { + if (isa(SrcVal->getType())) { Type *DstVecTy = DstTy->getScalarType(); unsigned size = Src.AggregateVal.size(); // the sizes of src and dst vectors must be equal @@ -1540,8 +1542,7 @@ Type *SrcTy = SrcVal->getType(); GenericValue Dest, Src = getOperandValue(SrcVal, SF); - if ((SrcTy->getTypeID() == Type::VectorTyID) || - (DstTy->getTypeID() == Type::VectorTyID)) { + if (isa(SrcTy) || isa(DstTy)) { // vector src bitcast to vector dst or vector src bitcast to scalar dst or // scalar src bitcast to vector dst bool isLittleEndian = getDataLayout().isLittleEndian(); @@ -1553,7 +1554,7 @@ unsigned SrcNum; unsigned DstNum; - if (SrcTy->getTypeID() == Type::VectorTyID) { + if (isa(SrcTy)) { SrcElemTy = SrcTy->getScalarType(); SrcBitSize = SrcTy->getScalarSizeInBits(); SrcNum = Src.AggregateVal.size(); @@ -1566,7 +1567,7 @@ SrcVec.AggregateVal.push_back(Src); } - if (DstTy->getTypeID() == Type::VectorTyID) { + if (isa(DstTy)) { DstElemTy = DstTy->getScalarType(); DstBitSize = DstTy->getScalarSizeInBits(); DstNum = (SrcNum * SrcBitSize) / DstBitSize; @@ -1639,7 +1640,7 @@ } // convert result from integer to specified type - if (DstTy->getTypeID() == Type::VectorTyID) { + if (isa(DstTy)) { if (DstElemTy->isDoubleTy()) { Dest.AggregateVal.resize(DstNum); for (unsigned i = 0; i < DstNum; i++) @@ -1662,8 +1663,7 @@ Dest.IntVal = TempDst.AggregateVal[0].IntVal; } } - } else { // if ((SrcTy->getTypeID() == Type::VectorTyID) || - // (DstTy->getTypeID() == Type::VectorTyID)) + } else { // if (isa(SrcTy)) || isa(DstTy)) // scalar src bitcast to scalar dst if (DstTy->isPointerTy()) { @@ -1954,7 +1954,8 @@ break; case Type::ArrayTyID: case Type::StructTyID: - case Type::VectorTyID: + case Type::FixedVectorTyID: + case Type::ScalableVectorTyID: Dest.AggregateVal = pSrc->AggregateVal; break; case Type::PointerTyID: @@ -2001,7 +2002,8 @@ break; case Type::ArrayTyID: case Type::StructTyID: - case Type::VectorTyID: + case Type::FixedVectorTyID: + case Type::ScalableVectorTyID: pDest->AggregateVal = Src2.AggregateVal; break; case Type::PointerTyID: diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -650,7 +650,8 @@ OS << ']'; return; } - case Type::VectorTyID: { + case Type::FixedVectorTyID: + case Type::ScalableVectorTyID: { VectorType *PTy = cast(Ty); OS << "<"; if (PTy->isScalable()) diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -352,7 +352,8 @@ return ConstantPointerNull::get(cast(Ty)); case Type::StructTyID: case Type::ArrayTyID: - case Type::VectorTyID: + case Type::FixedVectorTyID: + case Type::ScalableVectorTyID: return ConstantAggregateZero::get(Ty); case Type::TokenTyID: return ConstantTokenNone::get(Ty->getContext()); @@ -1780,8 +1781,8 @@ Constant *ConstantExpr::getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced) { #ifndef NDEBUG - bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; - bool toVec = Ty->getTypeID() == Type::VectorTyID; + bool fromVec = isa(C->getType()); + bool toVec = isa(Ty); #endif assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); assert(C->getType()->isIntOrIntVectorTy() && "Trunc operand must be integer"); @@ -1794,8 +1795,8 @@ Constant *ConstantExpr::getSExt(Constant *C, Type *Ty, bool OnlyIfReduced) { #ifndef NDEBUG - bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; - bool toVec = Ty->getTypeID() == Type::VectorTyID; + bool fromVec = isa(C->getType()); + bool toVec = isa(Ty); #endif assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); assert(C->getType()->isIntOrIntVectorTy() && "SExt operand must be integral"); @@ -1808,8 +1809,8 @@ Constant *ConstantExpr::getZExt(Constant *C, Type *Ty, bool OnlyIfReduced) { #ifndef NDEBUG - bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; - bool toVec = Ty->getTypeID() == Type::VectorTyID; + bool fromVec = isa(C->getType()); + bool toVec = isa(Ty); #endif assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); assert(C->getType()->isIntOrIntVectorTy() && "ZEXt operand must be integral"); @@ -1822,8 +1823,8 @@ Constant *ConstantExpr::getFPTrunc(Constant *C, Type *Ty, bool OnlyIfReduced) { #ifndef NDEBUG - bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; - bool toVec = Ty->getTypeID() == Type::VectorTyID; + bool fromVec = isa(C->getType()); + bool toVec = isa(Ty); #endif assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() && @@ -1834,8 +1835,8 @@ Constant *ConstantExpr::getFPExtend(Constant *C, Type *Ty, bool OnlyIfReduced) { #ifndef NDEBUG - bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; - bool toVec = Ty->getTypeID() == Type::VectorTyID; + bool fromVec = isa(C->getType()); + bool toVec = isa(Ty); #endif assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() && @@ -1846,8 +1847,8 @@ Constant *ConstantExpr::getUIToFP(Constant *C, Type *Ty, bool OnlyIfReduced) { #ifndef NDEBUG - bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; - bool toVec = Ty->getTypeID() == Type::VectorTyID; + bool fromVec = isa(C->getType()); + bool toVec = isa(Ty); #endif assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); assert(C->getType()->isIntOrIntVectorTy() && Ty->isFPOrFPVectorTy() && @@ -1857,8 +1858,8 @@ Constant *ConstantExpr::getSIToFP(Constant *C, Type *Ty, bool OnlyIfReduced) { #ifndef NDEBUG - bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; - bool toVec = Ty->getTypeID() == Type::VectorTyID; + bool fromVec = isa(C->getType()); + bool toVec = isa(Ty); #endif assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); assert(C->getType()->isIntOrIntVectorTy() && Ty->isFPOrFPVectorTy() && @@ -1868,8 +1869,8 @@ Constant *ConstantExpr::getFPToUI(Constant *C, Type *Ty, bool OnlyIfReduced) { #ifndef NDEBUG - bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; - bool toVec = Ty->getTypeID() == Type::VectorTyID; + bool fromVec = isa(C->getType()); + bool toVec = isa(Ty); #endif assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); assert(C->getType()->isFPOrFPVectorTy() && Ty->isIntOrIntVectorTy() && @@ -1879,8 +1880,8 @@ Constant *ConstantExpr::getFPToSI(Constant *C, Type *Ty, bool OnlyIfReduced) { #ifndef NDEBUG - bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; - bool toVec = Ty->getTypeID() == Type::VectorTyID; + bool fromVec = isa(C->getType()); + bool toVec = isa(Ty); #endif assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); assert(C->getType()->isFPOrFPVectorTy() && Ty->isIntOrIntVectorTy() && diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -501,12 +501,14 @@ return LLVMArrayTypeKind; case Type::PointerTyID: return LLVMPointerTypeKind; - case Type::VectorTyID: - return LLVMVectorTypeKind; case Type::X86_MMXTyID: return LLVMX86_MMXTypeKind; case Type::TokenTyID: return LLVMTokenTypeKind; + case Type::FixedVectorTyID: + return LLVMFixedVectorTypeKind; + case Type::ScalableVectorTyID: + return LLVMScalableVectorTypeKind; } llvm_unreachable("Unhandled TypeID."); } diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp --- a/llvm/lib/IR/DataLayout.cpp +++ b/llvm/lib/IR/DataLayout.cpp @@ -739,7 +739,8 @@ AlignType = FLOAT_ALIGN; break; case Type::X86_MMXTyID: - case Type::VectorTyID: + case Type::FixedVectorTyID: + case Type::ScalableVectorTyID: AlignType = VECTOR_ALIGN; break; default: diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp --- a/llvm/lib/IR/Type.cpp +++ b/llvm/lib/IR/Type.cpp @@ -73,13 +73,10 @@ return getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits(); // 64-bit fixed width vector types can be losslessly converted to x86mmx. - if (((isa(this) && - !cast(this)->getElementCount().Scalable) && - Ty->isX86_MMXTy()) && + if (((isa(this)) && Ty->isX86_MMXTy()) && getPrimitiveSizeInBits().getFixedSize() == 64) return true; - if ((isX86_MMXTy() && (isa(Ty) && - !cast(Ty)->getElementCount().Scalable)) && + if ((isX86_MMXTy() && isa(Ty)) && Ty->getPrimitiveSizeInBits().getFixedSize() == 64) return true; @@ -123,7 +120,8 @@ case Type::X86_MMXTyID: return TypeSize::Fixed(64); case Type::IntegerTyID: return TypeSize::Fixed(cast(this)->getBitWidth()); - case Type::VectorTyID: { + case Type::FixedVectorTyID: + case Type::ScalableVectorTyID: { const VectorType *VTy = cast(this); ElementCount EC = VTy->getElementCount(); TypeSize ETS = VTy->getElementType()->getPrimitiveSizeInBits(); @@ -586,30 +584,65 @@ // VectorType Implementation //===----------------------------------------------------------------------===// -VectorType::VectorType(Type *ElType, ElementCount EC) - : Type(ElType->getContext(), VectorTyID), ContainedType(ElType), - NumElements(EC.Min), Scalable(EC.Scalable) { +VectorType::VectorType(Type *ElType, ElementCount EC, Type::TypeID TID) + : Type(ElType->getContext(), TID), ContainedType(ElType), EC(EC) { ContainedTys = &ContainedType; NumContainedTys = 1; } VectorType *VectorType::get(Type *ElementType, ElementCount EC) { - assert(EC.Min > 0 && "#Elements of a VectorType must be greater than 0"); + if (EC.Scalable) + return ScalableVectorType::get(ElementType, EC.Min); + else + return FixedVectorType::get(ElementType, EC.Min); +} + +bool VectorType::isValidElementType(Type *ElemTy) { + return ElemTy->isIntegerTy() || ElemTy->isFloatingPointTy() || + ElemTy->isPointerTy(); +} + +//===----------------------------------------------------------------------===// +// FixedVectorType Implementation +//===----------------------------------------------------------------------===// + +FixedVectorType *FixedVectorType::get(Type *ElementType, unsigned NumElts) { + assert(NumElts > 0 && "#Elements of a VectorType must be greater than 0"); assert(isValidElementType(ElementType) && "Element type of a VectorType must " "be an integer, floating point, or " "pointer type."); + ElementCount EC(NumElts, false); + LLVMContextImpl *pImpl = ElementType->getContext().pImpl; - VectorType *&Entry = ElementType->getContext().pImpl - ->VectorTypes[std::make_pair(ElementType, EC)]; + VectorType *&Entry = ElementType->getContext() + .pImpl->VectorTypes[std::make_pair(ElementType, EC)]; + if (!Entry) - Entry = new (pImpl->Alloc) VectorType(ElementType, EC); - return Entry; + Entry = new (pImpl->Alloc) FixedVectorType(ElementType, NumElts); + return cast(Entry); } -bool VectorType::isValidElementType(Type *ElemTy) { - return ElemTy->isIntegerTy() || ElemTy->isFloatingPointTy() || - ElemTy->isPointerTy(); +//===----------------------------------------------------------------------===// +// ScalableVectorType Implementation +//===----------------------------------------------------------------------===// + +ScalableVectorType *ScalableVectorType::get(Type *ElementType, + unsigned MinNumElts) { + assert(MinNumElts > 0 && "#Elements of a VectorType must be greater than 0"); + assert(isValidElementType(ElementType) && "Element type of a VectorType must " + "be an integer, floating point, or " + "pointer type."); + + ElementCount EC(MinNumElts, true); + + LLVMContextImpl *pImpl = ElementType->getContext().pImpl; + VectorType *&Entry = ElementType->getContext() + .pImpl->VectorTypes[std::make_pair(ElementType, EC)]; + + if (!Entry) + Entry = new (pImpl->Alloc) ScalableVectorType(ElementType, MinNumElts); + return cast(Entry); } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp --- a/llvm/lib/Linker/IRMover.cpp +++ b/llvm/lib/Linker/IRMover.cpp @@ -305,7 +305,8 @@ case Type::ArrayTyID: return *Entry = ArrayType::get(ElementTypes[0], cast(Ty)->getNumElements()); - case Type::VectorTyID: + case Type::FixedVectorTyID: + case Type::ScalableVectorTyID: return *Entry = VectorType::get(ElementTypes[0], cast(Ty)->getNumElements()); case Type::PointerTyID: diff --git a/llvm/lib/Target/AMDGPU/AMDGPUHSAMetadataStreamer.cpp b/llvm/lib/Target/AMDGPU/AMDGPUHSAMetadataStreamer.cpp --- a/llvm/lib/Target/AMDGPU/AMDGPUHSAMetadataStreamer.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUHSAMetadataStreamer.cpp @@ -152,7 +152,7 @@ return ValueType::F64; case Type::PointerTyID: return getValueType(Ty->getPointerElementType(), TypeName); - case Type::VectorTyID: + case Type::FixedVectorTyID: return getValueType(cast(Ty)->getElementType(), TypeName); default: return ValueType::Struct; @@ -185,7 +185,7 @@ return "float"; case Type::DoubleTyID: return "double"; - case Type::VectorTyID: { + case Type::FixedVectorTyID: { auto VecTy = cast(Ty); auto ElTy = VecTy->getElementType(); auto NumElements = VecTy->getNumElements(); @@ -599,7 +599,7 @@ return "f64"; case Type::PointerTyID: return getValueType(Ty->getPointerElementType(), TypeName); - case Type::VectorTyID: + case Type::FixedVectorTyID: return getValueType(cast(Ty)->getElementType(), TypeName); default: return "struct"; @@ -632,7 +632,7 @@ return "float"; case Type::DoubleTyID: return "double"; - case Type::VectorTyID: { + case Type::FixedVectorTyID: { auto VecTy = cast(Ty); auto ElTy = VecTy->getElementType(); auto NumElements = VecTy->getNumElements(); diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPrintfRuntimeBinding.cpp b/llvm/lib/Target/AMDGPU/AMDGPUPrintfRuntimeBinding.cpp --- a/llvm/lib/Target/AMDGPU/AMDGPUPrintfRuntimeBinding.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUPrintfRuntimeBinding.cpp @@ -408,8 +408,7 @@ Value *Arg = CI->getArgOperand(ArgCount); Type *ArgType = Arg->getType(); SmallVector WhatToStore; - if (ArgType->isFPOrFPVectorTy() && - (ArgType->getTypeID() != Type::VectorTyID)) { + if (ArgType->isFPOrFPVectorTy() && !isa(ArgType)) { Type *IType = (ArgType->isFloatTy()) ? Int32Ty : Int64Ty; if (OpConvSpecifiers[ArgCount - 1] == 'f') { ConstantFP *fpCons = dyn_cast(Arg); @@ -478,7 +477,7 @@ Arg = new PtrToIntInst(Arg, DstType, "PrintArgPtr", Brnch); WhatToStore.push_back(Arg); } - } else if (ArgType->getTypeID() == Type::VectorTyID) { + } else if (isa(ArgType)) { Type *IType = NULL; uint32_t EleCount = cast(ArgType)->getNumElements(); uint32_t EleSize = ArgType->getScalarSizeInBits(); diff --git a/llvm/lib/Target/Hexagon/HexagonTargetObjectFile.cpp b/llvm/lib/Target/Hexagon/HexagonTargetObjectFile.cpp --- a/llvm/lib/Target/Hexagon/HexagonTargetObjectFile.cpp +++ b/llvm/lib/Target/Hexagon/HexagonTargetObjectFile.cpp @@ -307,7 +307,7 @@ const ArrayType *ATy = cast(Ty); return getSmallestAddressableSize(ATy->getElementType(), GV, TM); } - case Type::VectorTyID: { + case Type::FixedVectorTyID: { const VectorType *PTy = cast(Ty); return getSmallestAddressableSize(PTy->getElementType(), GV, TM); } diff --git a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp --- a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp @@ -1184,7 +1184,7 @@ case Type::IntegerTyID: // Integers larger than 64 bits case Type::StructTyID: case Type::ArrayTyID: - case Type::VectorTyID: + case Type::FixedVectorTyID: ElementSize = DL.getTypeStoreSize(ETy); // Ptx allows variable initilization only for constant and // global state spaces. @@ -1358,7 +1358,7 @@ switch (ETy->getTypeID()) { case Type::StructTyID: case Type::ArrayTyID: - case Type::VectorTyID: + case Type::FixedVectorTyID: ElementSize = DL.getTypeStoreSize(ETy); O << " .b8 "; getSymbol(GVar)->print(O, MAI); @@ -1892,7 +1892,7 @@ } case Type::ArrayTyID: - case Type::VectorTyID: + case Type::FixedVectorTyID: case Type::StructTyID: { if (isa(CPV) || isa(CPV)) { int ElementSize = DL.getTypeAllocSize(CPV->getType()); diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp --- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -129,7 +129,8 @@ default: break; case Type::PointerTyID: return true; - case Type::VectorTyID: + case Type::FixedVectorTyID: + case Type::ScalableVectorTyID: if (cast(Ty)->getElementType()->isPointerTy()) return true; break; diff --git a/llvm/lib/Transforms/Utils/FunctionComparator.cpp b/llvm/lib/Transforms/Utils/FunctionComparator.cpp --- a/llvm/lib/Transforms/Utils/FunctionComparator.cpp +++ b/llvm/lib/Transforms/Utils/FunctionComparator.cpp @@ -488,7 +488,8 @@ return cmpNumbers(STyL->getNumElements(), STyR->getNumElements()); return cmpTypes(STyL->getElementType(), STyR->getElementType()); } - case Type::VectorTyID: { + case Type::FixedVectorTyID: + case Type::ScalableVectorTyID: { auto *STyL = cast(TyL); auto *STyR = cast(TyR); if (STyL->getElementCount().Scalable != STyR->getElementCount().Scalable) diff --git a/llvm/tools/llvm-c-test/echo.cpp b/llvm/tools/llvm-c-test/echo.cpp --- a/llvm/tools/llvm-c-test/echo.cpp +++ b/llvm/tools/llvm-c-test/echo.cpp @@ -137,7 +137,10 @@ Clone(LLVMGetElementType(Src)), LLVMGetPointerAddressSpace(Src) ); - case LLVMVectorTypeKind: + case LLVMScalableVectorTypeKind: + // FIXME: scalable vectors unsupported + break; + case LLVMFixedVectorTypeKind: return LLVMVectorType( Clone(LLVMGetElementType(Src)), LLVMGetVectorSize(Src) diff --git a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp --- a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp +++ b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp @@ -168,12 +168,12 @@ return nullptr; return LLVMType::getArrayTy(elementType, type->getArrayNumElements()); } - case llvm::Type::VectorTyID: { - auto *typeVTy = llvm::cast(type); - if (typeVTy->isScalable()) { - emitError(unknownLoc) << "scalable vector types not supported"; - return nullptr; - } + case llvm::Type::ScalableVectorTyID: { + emitError(unknownLoc) << "scalable vector types not supported"; + return nullptr; + } + case llvm::Type::FixedVectorTyID: { + auto *typeVTy = llvm::cast(type); LLVMType elementType = processType(typeVTy->getElementType()); if (!elementType) return nullptr;