diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/AsmParser/LLLexer.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 13 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLToken.h | 1 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/IR/LLVMContextImpl.h | 2 | ||||
-rw-r--r-- | llvm/lib/IR/Type.cpp | 13 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 35 |
9 files changed, 68 insertions, 13 deletions
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index dc8ff7f1315..a9099711be4 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -707,6 +707,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(xchg); KEYWORD(nand); KEYWORD(max); KEYWORD(min); KEYWORD(umax); KEYWORD(umin); + KEYWORD(vscale); KEYWORD(x); KEYWORD(blockaddress); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index b6f982bc3fb..0a9a09e644d 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -2743,7 +2743,18 @@ bool LLParser::ParseStructBody(SmallVectorImpl<Type*> &Body) { /// Type /// ::= '[' APSINTVAL 'x' Types ']' /// ::= '<' APSINTVAL 'x' Types '>' +/// ::= '<' 'vscale' 'x' APSINTVAL 'x' Types '>' bool LLParser::ParseArrayVectorType(Type *&Result, bool isVector) { + bool Scalable = false; + + if (isVector && Lex.getKind() == lltok::kw_vscale) { + Lex.Lex(); // consume the 'vscale' + if (ParseToken(lltok::kw_x, "expected 'x' after vscale")) + return true; + + Scalable = true; + } + if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned() || Lex.getAPSIntVal().getBitWidth() > 64) return TokError("expected number in address space"); @@ -2770,7 +2781,7 @@ bool LLParser::ParseArrayVectorType(Type *&Result, bool isVector) { return Error(SizeLoc, "size too large for vector"); if (!VectorType::isValidElementType(EltTy)) return Error(TypeLoc, "invalid vector element type"); - Result = VectorType::get(EltTy, unsigned(Size)); + Result = VectorType::get(EltTy, unsigned(Size), Scalable); } else { if (!ArrayType::isValidElementType(EltTy)) return Error(TypeLoc, "invalid array element type"); diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h index a1e70932178..6256c14b9d6 100644 --- a/llvm/lib/AsmParser/LLToken.h +++ b/llvm/lib/AsmParser/LLToken.h @@ -37,6 +37,7 @@ enum Kind { bar, // | colon, // : + kw_vscale, kw_x, kw_true, kw_false, diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 49de70e26de..c33fc568abe 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1775,7 +1775,8 @@ Error BitcodeReader::parseTypeTableBody() { return error("Invalid type"); ResultTy = ArrayType::get(ResultTy, Record[0]); break; - case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty] + case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty] or + // [numelts, eltty, scalable] if (Record.size() < 2) return error("Invalid record"); if (Record[0] == 0) @@ -1783,7 +1784,8 @@ Error BitcodeReader::parseTypeTableBody() { ResultTy = getTypeByID(Record[1]); if (!ResultTy || !StructType::isValidElementType(ResultTy)) return error("Invalid type"); - ResultTy = VectorType::get(ResultTy, Record[0]); + bool Scalable = Record.size() > 2 ? Record[2] : false; + ResultTy = VectorType::get(ResultTy, Record[0], Scalable); break; } diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 1f39fa34a8b..1cf55ba813a 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -938,10 +938,13 @@ void ModuleBitcodeWriter::writeTypeTable() { } case Type::VectorTyID: { VectorType *VT = cast<VectorType>(T); - // VECTOR [numelts, eltty] + // VECTOR [numelts, eltty] or + // [numelts, eltty, scalable] Code = bitc::TYPE_CODE_VECTOR; TypeVals.push_back(VT->getNumElements()); TypeVals.push_back(VE.getTypeID(VT->getElementType())); + if (VT->isScalable()) + TypeVals.push_back(VT->isScalable()); break; } } diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index ca7afd0d81a..402a1bd9df5 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -620,7 +620,10 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) { } case Type::VectorTyID: { VectorType *PTy = cast<VectorType>(Ty); - OS << "<" << PTy->getNumElements() << " x "; + OS << "<"; + if (PTy->isScalable()) + OS << "vscale x "; + OS << PTy->getNumElements() << " x "; print(PTy->getElementType(), OS); OS << '>'; return; diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 4560617624e..78cf707e0e7 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -1334,7 +1334,7 @@ public: unsigned NamedStructTypesUniqueID = 0; DenseMap<std::pair<Type *, uint64_t>, ArrayType*> ArrayTypes; - DenseMap<std::pair<Type *, unsigned>, VectorType*> VectorTypes; + DenseMap<std::pair<Type *, ElementCount>, VectorType*> VectorTypes; DenseMap<Type*, PointerType*> PointerTypes; // Pointers in AddrSpace = 0 DenseMap<std::pair<Type*, unsigned>, PointerType*> ASPointerTypes; diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp index 4016bb10ba3..3d53134ca6d 100644 --- a/llvm/lib/IR/Type.cpp +++ b/llvm/lib/IR/Type.cpp @@ -599,21 +599,20 @@ bool ArrayType::isValidElementType(Type *ElemTy) { // VectorType Implementation //===----------------------------------------------------------------------===// -VectorType::VectorType(Type *ElType, unsigned NumEl) - : SequentialType(VectorTyID, ElType, NumEl) {} +VectorType::VectorType(Type *ElType, ElementCount EC) + : SequentialType(VectorTyID, ElType, EC.Min), Scalable(EC.Scalable) {} -VectorType *VectorType::get(Type *ElementType, unsigned NumElements) { - assert(NumElements > 0 && "#Elements of a VectorType must be greater than 0"); +VectorType *VectorType::get(Type *ElementType, ElementCount EC) { + assert(EC.Min > 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."); LLVMContextImpl *pImpl = ElementType->getContext().pImpl; VectorType *&Entry = ElementType->getContext().pImpl - ->VectorTypes[std::make_pair(ElementType, NumElements)]; - + ->VectorTypes[std::make_pair(ElementType, EC)]; if (!Entry) - Entry = new (pImpl->Alloc) VectorType(ElementType, NumElements); + Entry = new (pImpl->Alloc) VectorType(ElementType, EC); return Entry; } diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 7369aa88abe..10bac6df3a5 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -43,6 +43,7 @@ // //===----------------------------------------------------------------------===// +#include "LLVMContextImpl.h" #include "llvm/IR/Verifier.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" @@ -318,6 +319,31 @@ public: bool hasBrokenDebugInfo() const { return BrokenDebugInfo; } + void verifyTypes() { + LLVMContext &Ctx = M.getContext(); + for (auto &Entry : Ctx.pImpl->ArrayTypes) { + Type *EltTy = Entry.second->getElementType(); + if (auto *VTy = dyn_cast<VectorType>(EltTy)) + if (VTy->isScalable()) + CheckFailed("Arrays cannot contain scalable vectors", + Entry.second, &M); + } + + for (StructType* STy : Ctx.pImpl->AnonStructTypes) + for (Type *EltTy : STy->elements()) + if (auto *VTy = dyn_cast<VectorType>(EltTy)) + if (VTy->isScalable()) + CheckFailed("Structs cannot contain scalable vectors", STy, &M); + + for (auto &Entry : Ctx.pImpl->NamedStructTypes) { + StructType *STy = Entry.second; + for (Type *EltTy : STy->elements()) + if (auto *VTy = dyn_cast<VectorType>(EltTy)) + if (VTy->isScalable()) + CheckFailed("Structs cannot contain scalable vectors", STy, &M); + } + } + bool verify(const Function &F) { assert(F.getParent() == &M && "An instance of this class only works with a specific module!"); @@ -387,6 +413,8 @@ public: verifyCompileUnits(); + verifyTypes(); + verifyDeoptimizeCallingConvs(); DISubprogramAttachments.clear(); return !Broken; @@ -691,6 +719,13 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) { "DIGlobalVariableExpression"); } + // Scalable vectors cannot be global variables, since we don't know + // the runtime size. If the global is a struct or an array containing + // scalable vectors, that will be caught be verifyTypes instead. + if (auto *VTy = dyn_cast<VectorType>(GV.getValueType())) + if (VTy->isScalable()) + CheckFailed("Globals cannot contain scalable vectors", &GV); + if (!GV.hasInitializer()) { visitGlobalValue(GV); return; |