diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-04 19:20:19 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-08 19:02:26 +0000 |
commit | 81ad626541db97eb356e2c1d4a20eb2a26a766ab (patch) | |
tree | 311b6a8987c32b1e1dcbab65c54cfac3fdb56175 /contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp | |
parent | 5fff09660e06a66bed6482da9c70df328e16bbb6 (diff) | |
parent | 145449b1e420787bb99721a429341fa6be3adfb6 (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 1774 |
1 files changed, 1267 insertions, 507 deletions
diff --git a/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 720ab560f988..93b07fc0db30 100644 --- a/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -39,6 +39,7 @@ #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/GVMaterializer.h" +#include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/GlobalAlias.h" #include "llvm/IR/GlobalIFunc.h" #include "llvm/IR/GlobalObject.h" @@ -50,6 +51,8 @@ #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IntrinsicsAArch64.h" +#include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" @@ -91,6 +94,11 @@ static cl::opt<bool> PrintSummaryGUIDs( cl::desc( "Print the global id for each value when reading the module summary")); +static cl::opt<bool> ExpandConstantExprs( + "expand-constant-exprs", cl::Hidden, + cl::desc( + "Expand constant expressions to instructions for testing purposes")); + namespace { enum { @@ -282,7 +290,7 @@ static Expected<bool> hasObjCCategoryInModule(BitstreamCursor &Stream) { case bitc::MODULE_CODE_SECTIONNAME: { // SECTIONNAME: [strchr x N] std::string S; if (convertToString(Record, 0, S)) - return error("Invalid record"); + return error("Invalid section name record"); // Check for the i386 and other (x86_64, ARM) conventions if (S.find("__DATA,__objc_catlist") != std::string::npos || S.find("__OBJC,__category") != std::string::npos) @@ -361,7 +369,7 @@ static Expected<std::string> readModuleTriple(BitstreamCursor &Stream) { case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N] std::string S; if (convertToString(Record, 0, S)) - return error("Invalid record"); + return error("Invalid triple record"); Triple = S; break; } @@ -429,7 +437,7 @@ protected: std::pair<StringRef, ArrayRef<uint64_t>> readNameFromStrtab(ArrayRef<uint64_t> Record); - bool readBlockInfo(); + Error readBlockInfo(); // Contains an arbitrary and optional string identifying the bitcode producer std::string ProducerIdentification; @@ -450,7 +458,7 @@ Error BitcodeReaderBase::error(const Twine &Message) { Expected<unsigned> BitcodeReaderBase::parseVersionRecord(ArrayRef<uint64_t> Record) { if (Record.empty()) - return error("Invalid record"); + return error("Invalid version record"); unsigned ModuleVersion = Record[0]; if (ModuleVersion > 2) return error("Invalid value"); @@ -470,6 +478,90 @@ BitcodeReaderBase::readNameFromStrtab(ArrayRef<uint64_t> Record) { namespace { +/// This represents a constant expression or constant aggregate using a custom +/// structure internal to the bitcode reader. Later, this structure will be +/// expanded by materializeValue() either into a constant expression/aggregate, +/// or into an instruction sequence at the point of use. This allows us to +/// upgrade bitcode using constant expressions even if this kind of constant +/// expression is no longer supported. +class BitcodeConstant final : public Value, + TrailingObjects<BitcodeConstant, unsigned> { + friend TrailingObjects; + + // Value subclass ID: Pick largest possible value to avoid any clashes. + static constexpr uint8_t SubclassID = 255; + +public: + // Opcodes used for non-expressions. This includes constant aggregates + // (struct, array, vector) that might need expansion, as well as non-leaf + // constants that don't need expansion (no_cfi, dso_local, blockaddress), + // but still go through BitcodeConstant to avoid different uselist orders + // between the two cases. + static constexpr uint8_t ConstantStructOpcode = 255; + static constexpr uint8_t ConstantArrayOpcode = 254; + static constexpr uint8_t ConstantVectorOpcode = 253; + static constexpr uint8_t NoCFIOpcode = 252; + static constexpr uint8_t DSOLocalEquivalentOpcode = 251; + static constexpr uint8_t BlockAddressOpcode = 250; + static constexpr uint8_t FirstSpecialOpcode = BlockAddressOpcode; + + // Separate struct to make passing different number of parameters to + // BitcodeConstant::create() more convenient. + struct ExtraInfo { + uint8_t Opcode; + uint8_t Flags; + unsigned Extra; + Type *SrcElemTy; + + ExtraInfo(uint8_t Opcode, uint8_t Flags = 0, unsigned Extra = 0, + Type *SrcElemTy = nullptr) + : Opcode(Opcode), Flags(Flags), Extra(Extra), SrcElemTy(SrcElemTy) {} + }; + + uint8_t Opcode; + uint8_t Flags; + unsigned NumOperands; + unsigned Extra; // GEP inrange index or blockaddress BB id. + Type *SrcElemTy; // GEP source element type. + +private: + BitcodeConstant(Type *Ty, const ExtraInfo &Info, ArrayRef<unsigned> OpIDs) + : Value(Ty, SubclassID), Opcode(Info.Opcode), Flags(Info.Flags), + NumOperands(OpIDs.size()), Extra(Info.Extra), + SrcElemTy(Info.SrcElemTy) { + std::uninitialized_copy(OpIDs.begin(), OpIDs.end(), + getTrailingObjects<unsigned>()); + } + + BitcodeConstant &operator=(const BitcodeConstant &) = delete; + +public: + static BitcodeConstant *create(BumpPtrAllocator &A, Type *Ty, + const ExtraInfo &Info, + ArrayRef<unsigned> OpIDs) { + void *Mem = A.Allocate(totalSizeToAlloc<unsigned>(OpIDs.size()), + alignof(BitcodeConstant)); + return new (Mem) BitcodeConstant(Ty, Info, OpIDs); + } + + static bool classof(const Value *V) { return V->getValueID() == SubclassID; } + + ArrayRef<unsigned> getOperandIDs() const { + return makeArrayRef(getTrailingObjects<unsigned>(), NumOperands); + } + + Optional<unsigned> getInRangeIndex() const { + assert(Opcode == Instruction::GetElementPtr); + if (Extra == (unsigned)-1) + return None; + return Extra; + } + + const char *getOpcodeName() const { + return Instruction::getOpcodeName(Opcode); + } +}; + class BitcodeReader : public BitcodeReaderBase, public GVMaterializer { LLVMContext &Context; Module *TheModule = nullptr; @@ -483,8 +575,23 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer { std::vector<std::string> SectionTable; std::vector<std::string> GCTable; - std::vector<Type*> TypeList; - DenseMap<Function *, FunctionType *> FunctionTypes; + std::vector<Type *> TypeList; + /// Track type IDs of contained types. Order is the same as the contained + /// types of a Type*. This is used during upgrades of typed pointer IR in + /// opaque pointer mode. + DenseMap<unsigned, SmallVector<unsigned, 1>> ContainedTypeIDs; + /// In some cases, we need to create a type ID for a type that was not + /// explicitly encoded in the bitcode, or we don't know about at the current + /// point. For example, a global may explicitly encode the value type ID, but + /// not have a type ID for the pointer to value type, for which we create a + /// virtual type ID instead. This map stores the new type ID that was created + /// for the given pair of Type and contained type ID. + DenseMap<std::pair<Type *, unsigned>, unsigned> VirtualTypeIDs; + DenseMap<Function *, unsigned> FunctionTypeIDs; + /// Allocator for BitcodeConstants. This should come before ValueList, + /// because the ValueList might hold ValueHandles to these constants, so + /// ValueList must be destroyed before Alloc. + BumpPtrAllocator Alloc; BitcodeReaderValueList ValueList; Optional<MetadataLoader> MDLoader; std::vector<Comdat *> ComdatList; @@ -544,6 +651,13 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer { DenseMap<Function *, std::vector<BasicBlock *>> BasicBlockFwdRefs; std::deque<Function *> BasicBlockFwdRefQueue; + /// These are Functions that contain BlockAddresses which refer a different + /// Function. When parsing the different Function, queue Functions that refer + /// to the different Function. Those Functions must be materialized in order + /// to resolve their BlockAddress constants before the different Function + /// gets moved into another Module. + std::vector<Function *> BackwardRefFunctions; + /// Indicates that we are using a new encoding for instruction operands where /// most operands in the current FUNCTION_BLOCK are encoded relative to the /// instruction number, for a more compact encoding. Some instruction @@ -575,8 +689,8 @@ public: /// Main interface to parsing a bitcode buffer. /// \returns true if an error occurred. Error parseBitcodeInto( - Module *M, bool ShouldLazyLoadMetadata = false, bool IsImporting = false, - DataLayoutCallbackTy DataLayoutCallback = [](StringRef) { return None; }); + Module *M, bool ShouldLazyLoadMetadata, bool IsImporting, + DataLayoutCallbackTy DataLayoutCallback); static uint64_t decodeSignRotatedValue(uint64_t V); @@ -590,12 +704,21 @@ private: StructType *createIdentifiedStructType(LLVMContext &Context, StringRef Name); StructType *createIdentifiedStructType(LLVMContext &Context); + static constexpr unsigned InvalidTypeID = ~0u; + Type *getTypeByID(unsigned ID); + Type *getPtrElementTypeByID(unsigned ID); + unsigned getContainedTypeID(unsigned ID, unsigned Idx = 0); + unsigned getVirtualTypeID(Type *Ty, ArrayRef<unsigned> ContainedTypeIDs = {}); + + Expected<Value *> materializeValue(unsigned ValID, BasicBlock *InsertBB); + Expected<Constant *> getValueForInitializer(unsigned ID); - Value *getFnValueByID(unsigned ID, Type *Ty) { + Value *getFnValueByID(unsigned ID, Type *Ty, unsigned TyID, + BasicBlock *ConstExprInsertBB) { if (Ty && Ty->isMetadataTy()) return MetadataAsValue::get(Ty->getContext(), getFnMetadataByID(ID)); - return ValueList.getValueFwdRef(ID, Ty); + return ValueList.getValueFwdRef(ID, Ty, TyID, ConstExprInsertBB); } Metadata *getFnMetadataByID(unsigned ID) { @@ -617,7 +740,8 @@ private: /// Increment Slot past the number of slots used in the record. Return true on /// failure. bool getValueTypePair(const SmallVectorImpl<uint64_t> &Record, unsigned &Slot, - unsigned InstNum, Value *&ResVal) { + unsigned InstNum, Value *&ResVal, unsigned &TypeID, + BasicBlock *ConstExprInsertBB) { if (Slot == Record.size()) return true; unsigned ValNo = (unsigned)Record[Slot++]; // Adjust the ValNo, if it was encoded relative to the InstNum. @@ -626,14 +750,18 @@ private: if (ValNo < InstNum) { // If this is not a forward reference, just return the value we already // have. - ResVal = getFnValueByID(ValNo, nullptr); + TypeID = ValueList.getTypeID(ValNo); + ResVal = getFnValueByID(ValNo, nullptr, TypeID, ConstExprInsertBB); + assert((!ResVal || ResVal->getType() == getTypeByID(TypeID)) && + "Incorrect type ID stored for value"); return ResVal == nullptr; } if (Slot == Record.size()) return true; - unsigned TypeNo = (unsigned)Record[Slot++]; - ResVal = getFnValueByID(ValNo, getTypeByID(TypeNo)); + TypeID = (unsigned)Record[Slot++]; + ResVal = getFnValueByID(ValNo, getTypeByID(TypeID), TypeID, + ConstExprInsertBB); return ResVal == nullptr; } @@ -641,8 +769,9 @@ private: /// past the number of slots used by the value in the record. Return true if /// there is an error. bool popValue(const SmallVectorImpl<uint64_t> &Record, unsigned &Slot, - unsigned InstNum, Type *Ty, Value *&ResVal) { - if (getValue(Record, Slot, InstNum, Ty, ResVal)) + unsigned InstNum, Type *Ty, unsigned TyID, Value *&ResVal, + BasicBlock *ConstExprInsertBB) { + if (getValue(Record, Slot, InstNum, Ty, TyID, ResVal, ConstExprInsertBB)) return true; // All values currently take a single record slot. ++Slot; @@ -651,38 +780,41 @@ private: /// Like popValue, but does not increment the Slot number. bool getValue(const SmallVectorImpl<uint64_t> &Record, unsigned Slot, - unsigned InstNum, Type *Ty, Value *&ResVal) { - ResVal = getValue(Record, Slot, InstNum, Ty); + unsigned InstNum, Type *Ty, unsigned TyID, Value *&ResVal, + BasicBlock *ConstExprInsertBB) { + ResVal = getValue(Record, Slot, InstNum, Ty, TyID, ConstExprInsertBB); return ResVal == nullptr; } /// Version of getValue that returns ResVal directly, or 0 if there is an /// error. Value *getValue(const SmallVectorImpl<uint64_t> &Record, unsigned Slot, - unsigned InstNum, Type *Ty) { + unsigned InstNum, Type *Ty, unsigned TyID, + BasicBlock *ConstExprInsertBB) { if (Slot == Record.size()) return nullptr; unsigned ValNo = (unsigned)Record[Slot]; // Adjust the ValNo, if it was encoded relative to the InstNum. if (UseRelativeIDs) ValNo = InstNum - ValNo; - return getFnValueByID(ValNo, Ty); + return getFnValueByID(ValNo, Ty, TyID, ConstExprInsertBB); } /// Like getValue, but decodes signed VBRs. Value *getValueSigned(const SmallVectorImpl<uint64_t> &Record, unsigned Slot, - unsigned InstNum, Type *Ty) { + unsigned InstNum, Type *Ty, unsigned TyID, + BasicBlock *ConstExprInsertBB) { if (Slot == Record.size()) return nullptr; unsigned ValNo = (unsigned)decodeSignRotatedValue(Record[Slot]); // Adjust the ValNo, if it was encoded relative to the InstNum. if (UseRelativeIDs) ValNo = InstNum - ValNo; - return getFnValueByID(ValNo, Ty); + return getFnValueByID(ValNo, Ty, TyID, ConstExprInsertBB); } /// Upgrades old-style typeless byval/sret/inalloca attributes by adding the /// corresponding argument's pointee type. Also upgrades intrinsics that now /// require an elementtype attribute. - void propagateAttributeTypes(CallBase *CB, ArrayRef<Type *> ArgsTys); + Error propagateAttributeTypes(CallBase *CB, ArrayRef<unsigned> ArgsTys); /// Converts alignment exponent (i.e. power of two (or zero)) to the /// corresponding alignment to use. If alignment is too large, returns @@ -827,7 +959,10 @@ BitcodeReader::BitcodeReader(BitstreamCursor Stream, StringRef Strtab, StringRef ProducerIdentification, LLVMContext &Context) : BitcodeReaderBase(std::move(Stream), Strtab), Context(Context), - ValueList(Context, Stream.SizeInBytes()) { + ValueList(this->Stream.SizeInBytes(), + [this](unsigned ValID, BasicBlock *InsertBB) { + return materializeValue(ValID, InsertBB); + }) { this->ProducerIdentification = std::string(ProducerIdentification); } @@ -859,6 +994,11 @@ Error BitcodeReader::materializeForwardReferencedFunctions() { } assert(BasicBlockFwdRefs.empty() && "Function missing from queue"); + for (Function *F : BackwardRefFunctions) + if (Error Err = materialize(F)) + return Err; + BackwardRefFunctions.clear(); + // Reset state. WillMaterializeAllForwardRefs = false; return Error::success(); @@ -1176,6 +1316,324 @@ Type *BitcodeReader::getTypeByID(unsigned ID) { return TypeList[ID] = createIdentifiedStructType(Context); } +unsigned BitcodeReader::getContainedTypeID(unsigned ID, unsigned Idx) { + auto It = ContainedTypeIDs.find(ID); + if (It == ContainedTypeIDs.end()) + return InvalidTypeID; + + if (Idx >= It->second.size()) + return InvalidTypeID; + + return It->second[Idx]; +} + +Type *BitcodeReader::getPtrElementTypeByID(unsigned ID) { + if (ID >= TypeList.size()) + return nullptr; + + Type *Ty = TypeList[ID]; + if (!Ty->isPointerTy()) + return nullptr; + + Type *ElemTy = getTypeByID(getContainedTypeID(ID, 0)); + if (!ElemTy) + return nullptr; + + assert(cast<PointerType>(Ty)->isOpaqueOrPointeeTypeMatches(ElemTy) && + "Incorrect element type"); + return ElemTy; +} + +unsigned BitcodeReader::getVirtualTypeID(Type *Ty, + ArrayRef<unsigned> ChildTypeIDs) { + unsigned ChildTypeID = ChildTypeIDs.empty() ? InvalidTypeID : ChildTypeIDs[0]; + auto CacheKey = std::make_pair(Ty, ChildTypeID); + auto It = VirtualTypeIDs.find(CacheKey); + if (It != VirtualTypeIDs.end()) { + // The cmpxchg return value is the only place we need more than one + // contained type ID, however the second one will always be the same (i1), + // so we don't need to include it in the cache key. This asserts that the + // contained types are indeed as expected and there are no collisions. + assert((ChildTypeIDs.empty() || + ContainedTypeIDs[It->second] == ChildTypeIDs) && + "Incorrect cached contained type IDs"); + return It->second; + } + +#ifndef NDEBUG + if (!Ty->isOpaquePointerTy()) { + assert(Ty->getNumContainedTypes() == ChildTypeIDs.size() && + "Wrong number of contained types"); + for (auto Pair : zip(Ty->subtypes(), ChildTypeIDs)) { + assert(std::get<0>(Pair) == getTypeByID(std::get<1>(Pair)) && + "Incorrect contained type ID"); + } + } +#endif + + unsigned TypeID = TypeList.size(); + TypeList.push_back(Ty); + if (!ChildTypeIDs.empty()) + append_range(ContainedTypeIDs[TypeID], ChildTypeIDs); + VirtualTypeIDs.insert({CacheKey, TypeID}); + return TypeID; +} + +static bool isConstExprSupported(uint8_t Opcode) { + // These are not real constant expressions, always consider them supported. + if (Opcode >= BitcodeConstant::FirstSpecialOpcode) + return true; + + return !ExpandConstantExprs; +} + +Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID, + BasicBlock *InsertBB) { + // Quickly handle the case where there is no BitcodeConstant to resolve. + if (StartValID < ValueList.size() && ValueList[StartValID] && + !isa<BitcodeConstant>(ValueList[StartValID])) + return ValueList[StartValID]; + + SmallDenseMap<unsigned, Value *> MaterializedValues; + SmallVector<unsigned> Worklist; + Worklist.push_back(StartValID); + while (!Worklist.empty()) { + unsigned ValID = Worklist.back(); + if (MaterializedValues.count(ValID)) { + // Duplicate expression that was already handled. + Worklist.pop_back(); + continue; + } + + if (ValID >= ValueList.size() || !ValueList[ValID]) + return error("Invalid value ID"); + + Value *V = ValueList[ValID]; + auto *BC = dyn_cast<BitcodeConstant>(V); + if (!BC) { + MaterializedValues.insert({ValID, V}); + Worklist.pop_back(); + continue; + } + + // Iterate in reverse, so values will get popped from the worklist in + // expected order. + SmallVector<Value *> Ops; + for (unsigned OpID : reverse(BC->getOperandIDs())) { + auto It = MaterializedValues.find(OpID); + if (It != MaterializedValues.end()) + Ops.push_back(It->second); + else + Worklist.push_back(OpID); + } + + // Some expressions have not been resolved yet, handle them first and then + // revisit this one. + if (Ops.size() != BC->getOperandIDs().size()) + continue; + std::reverse(Ops.begin(), Ops.end()); + + SmallVector<Constant *> ConstOps; + for (Value *Op : Ops) + if (auto *C = dyn_cast<Constant>(Op)) + ConstOps.push_back(C); + + // Materialize as constant expression if possible. + if (isConstExprSupported(BC->Opcode) && ConstOps.size() == Ops.size()) { + Constant *C; + if (Instruction::isCast(BC->Opcode)) { + C = UpgradeBitCastExpr(BC->Opcode, ConstOps[0], BC->getType()); + if (!C) + C = ConstantExpr::getCast(BC->Opcode, ConstOps[0], BC->getType()); + } else if (Instruction::isUnaryOp(BC->Opcode)) { + C = ConstantExpr::get(BC->Opcode, ConstOps[0], BC->Flags); + } else if (Instruction::isBinaryOp(BC->Opcode)) { + C = ConstantExpr::get(BC->Opcode, ConstOps[0], ConstOps[1], BC->Flags); + } else { + switch (BC->Opcode) { + case BitcodeConstant::NoCFIOpcode: { + auto *GV = dyn_cast<GlobalValue>(ConstOps[0]); + if (!GV) + return error("no_cfi operand must be GlobalValue"); + C = NoCFIValue::get(GV); + break; + } + case BitcodeConstant::DSOLocalEquivalentOpcode: { + auto *GV = dyn_cast<GlobalValue>(ConstOps[0]); + if (!GV) + return error("dso_local operand must be GlobalValue"); + C = DSOLocalEquivalent::get(GV); + break; + } + case BitcodeConstant::BlockAddressOpcode: { + Function *Fn = dyn_cast<Function>(ConstOps[0]); + if (!Fn) + return error("blockaddress operand must be a function"); + + // If the function is already parsed we can insert the block address + // right away. + BasicBlock *BB; + unsigned BBID = BC->Extra; + if (!BBID) + // Invalid reference to entry block. + return error("Invalid ID"); + if (!Fn->empty()) { + Function::iterator BBI = Fn->begin(), BBE = Fn->end(); + for (size_t I = 0, E = BBID; I != E; ++I) { + if (BBI == BBE) + return error("Invalid ID"); + ++BBI; + } + BB = &*BBI; + } else { + // Otherwise insert a placeholder and remember it so it can be + // inserted when the function is parsed. + auto &FwdBBs = BasicBlockFwdRefs[Fn]; + if (FwdBBs.empty()) + BasicBlockFwdRefQueue.push_back(Fn); + if (FwdBBs.size() < BBID + 1) + FwdBBs.resize(BBID + 1); + if (!FwdBBs[BBID]) + FwdBBs[BBID] = BasicBlock::Create(Context); + BB = FwdBBs[BBID]; + } + C = BlockAddress::get(Fn, BB); + break; + } + case BitcodeConstant::ConstantStructOpcode: + C = ConstantStruct::get(cast<StructType>(BC->getType()), ConstOps); + break; + case BitcodeConstant::ConstantArrayOpcode: + C = ConstantArray::get(cast<ArrayType>(BC->getType()), ConstOps); + break; + case BitcodeConstant::ConstantVectorOpcode: + C = ConstantVector::get(ConstOps); + break; + case Instruction::ICmp: + case Instruction::FCmp: + C = ConstantExpr::getCompare(BC->Flags, ConstOps[0], ConstOps[1]); + break; + case Instruction::GetElementPtr: + C = ConstantExpr::getGetElementPtr( + BC->SrcElemTy, ConstOps[0], makeArrayRef(ConstOps).drop_front(), + BC->Flags, BC->getInRangeIndex()); + break; + case Instruction::Select: + C = ConstantExpr::getSelect(ConstOps[0], ConstOps[1], ConstOps[2]); + break; + case Instruction::ExtractElement: + C = ConstantExpr::getExtractElement(ConstOps[0], ConstOps[1]); + break; + case Instruction::InsertElement: + C = ConstantExpr::getInsertElement(ConstOps[0], ConstOps[1], + ConstOps[2]); + break; + case Instruction::ShuffleVector: { + SmallVector<int, 16> Mask; + ShuffleVectorInst::getShuffleMask(ConstOps[2], Mask); + C = ConstantExpr::getShuffleVector(ConstOps[0], ConstOps[1], Mask); + break; + } + default: + llvm_unreachable("Unhandled bitcode constant"); + } + } + + // Cache resolved constant. + ValueList.replaceValueWithoutRAUW(ValID, C); + MaterializedValues.insert({ValID, C}); + Worklist.pop_back(); + continue; + } + + if (!InsertBB) + return error(Twine("Value referenced by initializer is an unsupported " + "constant expression of type ") + + BC->getOpcodeName()); + + // Materialize as instructions if necessary. + Instruction *I; + if (Instruction::isCast(BC->Opcode)) { + I = CastInst::Create((Instruction::CastOps)BC->Opcode, Ops[0], + BC->getType(), "constexpr", InsertBB); + } else if (Instruction::isUnaryOp(BC->Opcode)) { + I = UnaryOperator::Create((Instruction::UnaryOps)BC->Opcode, Ops[0], + "constexpr", InsertBB); + } else if (Instruction::isBinaryOp(BC->Opcode)) { + I = BinaryOperator::Create((Instruction::BinaryOps)BC->Opcode, Ops[0], + Ops[1], "constexpr", InsertBB); + if (isa<OverflowingBinaryOperator>(I)) { + if (BC->Flags & OverflowingBinaryOperator::NoSignedWrap) + I->setHasNoSignedWrap(); + if (BC->Flags & OverflowingBinaryOperator::NoUnsignedWrap) + I->setHasNoUnsignedWrap(); + } + if (isa<PossiblyExactOperator>(I) && + (BC->Flags & PossiblyExactOperator::IsExact)) + I->setIsExact(); + } else { + switch (BC->Opcode) { + case BitcodeConstant::ConstantStructOpcode: + case BitcodeConstant::ConstantArrayOpcode: + case BitcodeConstant::ConstantVectorOpcode: { + Type *IdxTy = Type::getInt32Ty(BC->getContext()); + Value *V = PoisonValue::get(BC->getType()); + for (auto Pair : enumerate(Ops)) { + Value *Idx = ConstantInt::get(IdxTy, Pair.index()); + V = InsertElementInst::Create(V, Pair.value(), Idx, "constexpr.ins", + InsertBB); + } + I = cast<Instruction>(V); + break; + } + case Instruction::ICmp: + case Instruction::FCmp: + I = CmpInst::Create((Instruction::OtherOps)BC->Opcode, + (CmpInst::Predicate)BC->Flags, Ops[0], Ops[1], + "constexpr", InsertBB); + break; + case Instruction::GetElementPtr: + I = GetElementPtrInst::Create(BC->SrcElemTy, Ops[0], + makeArrayRef(Ops).drop_front(), + "constexpr", InsertBB); + if (BC->Flags) + cast<GetElementPtrInst>(I)->setIsInBounds(); + break; + case Instruction::Select: + I = SelectInst::Create(Ops[0], Ops[1], Ops[2], "constexpr", InsertBB); + break; + case Instruction::ExtractElement: + I = ExtractElementInst::Create(Ops[0], Ops[1], "constexpr", InsertBB); + break; + case Instruction::InsertElement: + I = InsertElementInst::Create(Ops[0], Ops[1], Ops[2], "constexpr", + InsertBB); + break; + case Instruction::ShuffleVector: + I = new ShuffleVectorInst(Ops[0], Ops[1], Ops[2], "constexpr", + InsertBB); + break; + default: + llvm_unreachable("Unhandled bitcode constant"); + } + } + + MaterializedValues.insert({ValID, I}); + Worklist.pop_back(); + } + + return MaterializedValues[StartValID]; +} + +Expected<Constant *> BitcodeReader::getValueForInitializer(unsigned ID) { + Expected<Value *> MaybeV = materializeValue(ID, /* InsertBB */ nullptr); + if (!MaybeV) + return MaybeV.takeError(); + + // Result must be Constant if InsertBB is nullptr. + return cast<Constant>(MaybeV.get()); +} + StructType *BitcodeReader::createIdentifiedStructType(LLVMContext &Context, StringRef Name) { auto *Ret = StructType::create(Context, Name); @@ -1346,7 +1804,7 @@ Error BitcodeReader::parseAttributeBlock() { case bitc::PARAMATTR_CODE_ENTRY_OLD: // ENTRY: [paramidx0, attr0, ...] // Deprecated, but still needed to read old bitcode files. if (Record.size() & 1) - return error("Invalid record"); + return error("Invalid parameter attribute record"); for (unsigned i = 0, e = Record.size(); i != e; i += 2) { AttrBuilder B(Context); @@ -1437,8 +1895,14 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::Dereferenceable; case bitc::ATTR_KIND_DEREFERENCEABLE_OR_NULL: return Attribute::DereferenceableOrNull; + case bitc::ATTR_KIND_ALLOC_ALIGN: + return Attribute::AllocAlign; + case bitc::ATTR_KIND_ALLOC_KIND: + return Attribute::AllocKind; case bitc::ATTR_KIND_ALLOC_SIZE: return Attribute::AllocSize; + case bitc::ATTR_KIND_ALLOCATED_POINTER: + return Attribute::AllocatedPointer; case bitc::ATTR_KIND_NO_RED_ZONE: return Attribute::NoRedZone; case bitc::ATTR_KIND_NO_RETURN: @@ -1451,6 +1915,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::NoProfile; case bitc::ATTR_KIND_NO_UNWIND: return Attribute::NoUnwind; + case bitc::ATTR_KIND_NO_SANITIZE_BOUNDS: + return Attribute::NoSanitizeBounds; case bitc::ATTR_KIND_NO_SANITIZE_COVERAGE: return Attribute::NoSanitizeCoverage; case bitc::ATTR_KIND_NULL_POINTER_IS_VALID: @@ -1529,6 +1995,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::MustProgress; case bitc::ATTR_KIND_HOT: return Attribute::Hot; + case bitc::ATTR_KIND_PRESPLIT_COROUTINE: + return Attribute::PresplitCoroutine; } } @@ -1586,7 +2054,7 @@ Error BitcodeReader::parseAttributeGroupBlock() { break; case bitc::PARAMATTR_GRP_CODE_ENTRY: { // ENTRY: [grpid, idx, a0, a1, ...] if (Record.size() < 3) - return error("Invalid record"); + return error("Invalid grp record"); uint64_t GrpID = Record[0]; uint64_t Idx = Record[1]; // Index of the object this attribute refers to. @@ -1607,6 +2075,8 @@ Error BitcodeReader::parseAttributeGroupBlock() { B.addStructRetAttr(nullptr); else if (Kind == Attribute::InAlloca) B.addInAllocaAttr(nullptr); + else if (Kind == Attribute::UWTable) + B.addUWTableAttr(UWTableKind::Default); else if (Attribute::isEnumAttrKind(Kind)) B.addAttribute(Kind); else @@ -1629,6 +2099,10 @@ Error BitcodeReader::parseAttributeGroupBlock() { B.addAllocSizeAttrFromRawRepr(Record[++i]); else if (Kind == Attribute::VScaleRange) B.addVScaleRangeAttrFromRawRepr(Record[++i]); + else if (Kind == Attribute::UWTable) + B.addUWTableAttr(UWTableKind(Record[++i])); + else if (Kind == Attribute::AllocKind) + B.addAllocKindAttr(static_cast<AllocFnKind>(Record[++i])); } else if (Record[i] == 3 || Record[i] == 4) { // String attribute bool HasValue = (Record[i++] == 4); SmallString<64> KindStr; @@ -1647,9 +2121,7 @@ Error BitcodeReader::parseAttributeGroupBlock() { } B.addAttribute(KindStr.str(), ValStr.str()); - } else { - assert((Record[i] == 5 || Record[i] == 6) && - "Invalid attribute group entry"); + } else if (Record[i] == 5 || Record[i] == 6) { bool HasType = Record[i] == 6; Attribute::AttrKind Kind; if (Error Err = parseAttrKind(Record[++i], &Kind)) @@ -1658,6 +2130,8 @@ Error BitcodeReader::parseAttributeGroupBlock() { return error("Not a type attribute"); B.addTypeAttr(Kind, HasType ? getTypeByID(Record[++i]) : nullptr); + } else { + return error("Invalid attribute group entry"); } } @@ -1708,6 +2182,7 @@ Error BitcodeReader::parseTypeTableBody() { // Read a record. Record.clear(); Type *ResultTy = nullptr; + SmallVector<unsigned> ContainedIDs; Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); if (!MaybeRecord) return MaybeRecord.takeError(); @@ -1718,7 +2193,7 @@ Error BitcodeReader::parseTypeTableBody() { // TYPE_CODE_NUMENTRY contains a count of the number of types in the // type list. This allows us to reserve space. if (Record.empty()) - return error("Invalid record"); + return error("Invalid numentry record"); TypeList.resize(Record[0]); continue; case bitc::TYPE_CODE_VOID: // VOID @@ -1762,7 +2237,7 @@ Error BitcodeReader::parseTypeTableBody() { break; case bitc::TYPE_CODE_INTEGER: { // INTEGER: [width] if (Record.empty()) - return error("Invalid record"); + return error("Invalid integer record"); uint64_t NumBits = Record[0]; if (NumBits < IntegerType::MIN_INT_BITS || @@ -1774,7 +2249,7 @@ Error BitcodeReader::parseTypeTableBody() { case bitc::TYPE_CODE_POINTER: { // POINTER: [pointee type] or // [pointee type, address space] if (Record.empty()) - return error("Invalid record"); + return error("Invalid pointer record"); unsigned AddressSpace = 0; if (Record.size() == 2) AddressSpace = Record[1]; @@ -1782,13 +2257,18 @@ Error BitcodeReader::parseTypeTableBody() { if (!ResultTy || !PointerType::isValidElementType(ResultTy)) return error("Invalid type"); + if (LLVM_UNLIKELY(!Context.hasSetOpaquePointersValue())) + Context.setOpaquePointers(false); + ContainedIDs.push_back(Record[0]); ResultTy = PointerType::get(ResultTy, AddressSpace); break; } case bitc::TYPE_CODE_OPAQUE_POINTER: { // OPAQUE_POINTER: [addrspace] if (Record.size() != 1) - return error("Invalid record"); - if (Context.supportsTypedPointers()) + return error("Invalid opaque pointer record"); + if (LLVM_UNLIKELY(!Context.hasSetOpaquePointersValue())) { + Context.setOpaquePointers(true); + } else if (Context.supportsTypedPointers()) return error( "Opaque pointers are only supported in -opaque-pointers mode"); unsigned AddressSpace = Record[0]; @@ -1799,7 +2279,7 @@ Error BitcodeReader::parseTypeTableBody() { // Deprecated, but still needed to read old bitcode files. // FUNCTION: [vararg, attrid, retty, paramty x N] if (Record.size() < 3) - return error("Invalid record"); + return error("Invalid function record"); SmallVector<Type*, 8> ArgTys; for (unsigned i = 3, e = Record.size(); i != e; ++i) { if (Type *T = getTypeByID(Record[i])) @@ -1812,13 +2292,14 @@ Error BitcodeReader::parseTypeTableBody() { if (!ResultTy || ArgTys.size() < Record.size()-3) return error("Invalid type"); + ContainedIDs.append(Record.begin() + 2, Record.end()); ResultTy = FunctionType::get(ResultTy, ArgTys, Record[0]); break; } case bitc::TYPE_CODE_FUNCTION: { // FUNCTION: [vararg, retty, paramty x N] if (Record.size() < 2) - return error("Invalid record"); + return error("Invalid function record"); SmallVector<Type*, 8> ArgTys; for (unsigned i = 2, e = Record.size(); i != e; ++i) { if (Type *T = getTypeByID(Record[i])) { @@ -1834,12 +2315,13 @@ Error BitcodeReader::parseTypeTableBody() { if (!ResultTy || ArgTys.size() < Record.size()-2) return error("Invalid type"); + ContainedIDs.append(Record.begin() + 1, Record.end()); ResultTy = FunctionType::get(ResultTy, ArgTys, Record[0]); break; } case bitc::TYPE_CODE_STRUCT_ANON: { // STRUCT: [ispacked, eltty x N] if (Record.empty()) - return error("Invalid record"); + return error("Invalid anon struct record"); SmallVector<Type*, 8> EltTys; for (unsigned i = 1, e = Record.size(); i != e; ++i) { if (Type *T = getTypeByID(Record[i])) @@ -1849,17 +2331,18 @@ Error BitcodeReader::parseTypeTableBody() { } if (EltTys.size() != Record.size()-1) return error("Invalid type"); + ContainedIDs.append(Record.begin() + 1, Record.end()); ResultTy = StructType::get(Context, EltTys, Record[0]); break; } case bitc::TYPE_CODE_STRUCT_NAME: // STRUCT_NAME: [strchr x N] if (convertToString(Record, 0, TypeName)) - return error("Invalid record"); + return error("Invalid struct name record"); continue; case bitc::TYPE_CODE_STRUCT_NAMED: { // STRUCT: [ispacked, eltty x N] if (Record.empty()) - return error("Invalid record"); + return error("Invalid named struct record"); if (NumRecords >= TypeList.size()) return error("Invalid TYPE table"); @@ -1881,14 +2364,15 @@ Error BitcodeReader::parseTypeTableBody() { break; } if (EltTys.size() != Record.size()-1) - return error("Invalid record"); + return error("Invalid named struct record"); Res->setBody(EltTys, Record[0]); + ContainedIDs.append(Record.begin() + 1, Record.end()); ResultTy = Res; break; } case bitc::TYPE_CODE_OPAQUE: { // OPAQUE: [] if (Record.size() != 1) - return error("Invalid record"); + return error("Invalid opaque type record"); if (NumRecords >= TypeList.size()) return error("Invalid TYPE table"); @@ -1906,22 +2390,24 @@ Error BitcodeReader::parseTypeTableBody() { } case bitc::TYPE_CODE_ARRAY: // ARRAY: [numelts, eltty] if (Record.size() < 2) - return error("Invalid record"); + return error("Invalid array type record"); ResultTy = getTypeByID(Record[1]); if (!ResultTy || !ArrayType::isValidElementType(ResultTy)) return error("Invalid type"); + ContainedIDs.push_back(Record[1]); ResultTy = ArrayType::get(ResultTy, Record[0]); break; case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty] or // [numelts, eltty, scalable] if (Record.size() < 2) - return error("Invalid record"); + return error("Invalid vector type record"); if (Record[0] == 0) return error("Invalid vector length"); ResultTy = getTypeByID(Record[1]); if (!ResultTy || !VectorType::isValidElementType(ResultTy)) return error("Invalid type"); bool Scalable = Record.size() > 2 ? Record[2] : false; + ContainedIDs.push_back(Record[1]); ResultTy = VectorType::get(ResultTy, Record[0], Scalable); break; } @@ -1932,7 +2418,10 @@ Error BitcodeReader::parseTypeTableBody() { return error( "Invalid TYPE table: Only named structs can be forward referenced"); assert(ResultTy && "Didn't read a type?"); - TypeList[NumRecords++] = ResultTy; + TypeList[NumRecords] = ResultTy; + if (!ContainedIDs.empty()) + ContainedTypeIDs[NumRecords] = std::move(ContainedIDs); + ++NumRecords; } } @@ -1968,12 +2457,12 @@ Error BitcodeReader::parseOperandBundleTags() { if (!MaybeRecord) return MaybeRecord.takeError(); if (MaybeRecord.get() != bitc::OPERAND_BUNDLE_TAG) - return error("Invalid record"); + return error("Invalid operand bundle record"); // OPERAND_BUNDLE_TAG: [strchr x N] BundleTags.emplace_back(); if (convertToString(Record, 0, BundleTags.back())) - return error("Invalid record"); + return error("Invalid operand bundle record"); Record.clear(); } } @@ -2012,11 +2501,11 @@ Error BitcodeReader::parseSyncScopeNames() { if (!MaybeRecord) return MaybeRecord.takeError(); if (MaybeRecord.get() != bitc::SYNC_SCOPE_NAME) - return error("Invalid record"); + return error("Invalid sync scope record"); SmallString<16> SSN; if (convertToString(Record, 0, SSN)) - return error("Invalid record"); + return error("Invalid sync scope record"); SSIDs.push_back(Context.getOrInsertSyncScopeID(SSN)); Record.clear(); @@ -2056,8 +2545,9 @@ static Expected<uint64_t> jumpToValueSymbolTable(uint64_t Offset, Expected<BitstreamEntry> MaybeEntry = Stream.advance(); if (!MaybeEntry) return MaybeEntry.takeError(); - assert(MaybeEntry.get().Kind == BitstreamEntry::SubBlock); - assert(MaybeEntry.get().ID == bitc::VALUE_SYMTAB_BLOCK_ID); + if (MaybeEntry.get().Kind != BitstreamEntry::SubBlock || + MaybeEntry.get().ID != bitc::VALUE_SYMTAB_BLOCK_ID) + return error("Expected value symbol table subblock"); return CurrentBit; } @@ -2107,11 +2597,15 @@ Error BitcodeReader::parseGlobalValueSymbolTable() { if (!MaybeRecord) return MaybeRecord.takeError(); switch (MaybeRecord.get()) { - case bitc::VST_CODE_FNENTRY: // [valueid, offset] + case bitc::VST_CODE_FNENTRY: { // [valueid, offset] + unsigned ValueID = Record[0]; + if (ValueID >= ValueList.size() || !ValueList[ValueID]) + return error("Invalid value reference in symbol table"); setDeferredFunctionInfo(FuncBitcodeOffsetDelta, - cast<Function>(ValueList[Record[0]]), Record); + cast<Function>(ValueList[ValueID]), Record); break; } + } } } @@ -2213,10 +2707,10 @@ Error BitcodeReader::parseValueSymbolTable(uint64_t Offset) { } case bitc::VST_CODE_BBENTRY: { if (convertToString(Record, 1, ValueName)) - return error("Invalid record"); + return error("Invalid bbentry record"); BasicBlock *BB = getBasicBlock(Record[0]); if (!BB) - return error("Invalid record"); + return error("Invalid bbentry record"); BB->setName(StringRef(ValueName.data(), ValueName.size())); ValueName.clear(); @@ -2253,10 +2747,10 @@ Error BitcodeReader::resolveGlobalAndIndirectSymbolInits() { // Not ready to resolve this yet, it requires something later in the file. GlobalInits.push_back(GlobalInitWorklist.back()); } else { - if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID])) - GlobalInitWorklist.back().first->setInitializer(C); - else - return error("Expected a constant"); + Expected<Constant *> MaybeC = getValueForInitializer(ValID); + if (!MaybeC) + return MaybeC.takeError(); + GlobalInitWorklist.back().first->setInitializer(MaybeC.get()); } GlobalInitWorklist.pop_back(); } @@ -2266,9 +2760,10 @@ Error BitcodeReader::resolveGlobalAndIndirectSymbolInits() { if (ValID >= ValueList.size()) { IndirectSymbolInits.push_back(IndirectSymbolInitWorklist.back()); } else { - Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]); - if (!C) - return error("Expected a constant"); + Expected<Constant *> MaybeC = getValueForInitializer(ValID); + if (!MaybeC) + return MaybeC.takeError(); + Constant *C = MaybeC.get(); GlobalValue *GV = IndirectSymbolInitWorklist.back().first; if (auto *GA = dyn_cast<GlobalAlias>(GV)) { if (C->getType() != GV->getType()) @@ -2292,30 +2787,30 @@ Error BitcodeReader::resolveGlobalAndIndirectSymbolInits() { if (Info.PersonalityFn) { unsigned ValID = Info.PersonalityFn - 1; if (ValID < ValueList.size()) { - if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID])) - Info.F->setPersonalityFn(C); - else - return error("Expected a constant"); + Expected<Constant *> MaybeC = getValueForInitializer(ValID); + if (!MaybeC) + return MaybeC.takeError(); + Info.F->setPersonalityFn(MaybeC.get()); Info.PersonalityFn = 0; } } if (Info.Prefix) { unsigned ValID = Info.Prefix - 1; if (ValID < ValueList.size()) { - if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID])) - Info.F->setPrefixData(C); - else - return error("Expected a constant"); + Expected<Constant *> MaybeC = getValueForInitializer(ValID); + if (!MaybeC) + return MaybeC.takeError(); + Info.F->setPrefixData(MaybeC.get()); Info.Prefix = 0; } } if (Info.Prologue) { unsigned ValID = Info.Prologue - 1; if (ValID < ValueList.size()) { - if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID])) - Info.F->setPrologueData(C); - else - return error("Expected a constant"); + Expected<Constant *> MaybeC = getValueForInitializer(ValID); + if (!MaybeC) + return MaybeC.takeError(); + Info.F->setPrologueData(MaybeC.get()); Info.Prologue = 0; } } @@ -2343,26 +2838,11 @@ Error BitcodeReader::parseConstants() { // Read all the records for this value table. Type *CurTy = Type::getInt32Ty(Context); + unsigned Int32TyID = getVirtualTypeID(CurTy); + unsigned CurTyID = Int32TyID; + Type *CurElemTy = nullptr; unsigned NextCstNo = ValueList.size(); - struct DelayedShufTy { - VectorType *OpTy; - VectorType *RTy; - uint64_t Op0Idx; - uint64_t Op1Idx; - uint64_t Op2Idx; - unsigned CstNo; - }; - std::vector<DelayedShufTy> DelayedShuffles; - struct DelayedSelTy { - Type *OpTy; - uint64_t Op0Idx; - uint64_t Op1Idx; - uint64_t Op2Idx; - unsigned CstNo; - }; - std::vector<DelayedSelTy> DelayedSelectors; - while (true) { Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); if (!MaybeEntry) @@ -2374,57 +2854,8 @@ Error BitcodeReader::parseConstants() { case BitstreamEntry::Error: return error("Malformed block"); case BitstreamEntry::EndBlock: - // Once all the constants have been read, go through and resolve forward - // references. - // - // We have to treat shuffles specially because they don't have three - // operands anymore. We need to convert the shuffle mask into an array, - // and we can't convert a forward reference. - for (auto &DelayedShuffle : DelayedShuffles) { - VectorType *OpTy = DelayedShuffle.OpTy; - VectorType *RTy = DelayedShuffle.RTy; - uint64_t Op0Idx = DelayedShuffle.Op0Idx; - uint64_t Op1Idx = DelayedShuffle.Op1Idx; - uint64_t Op2Idx = DelayedShuffle.Op2Idx; - uint64_t CstNo = DelayedShuffle.CstNo; - Constant *Op0 = ValueList.getConstantFwdRef(Op0Idx, OpTy); - Constant *Op1 = ValueList.getConstantFwdRef(Op1Idx, OpTy); - Type *ShufTy = - VectorType::get(Type::getInt32Ty(Context), RTy->getElementCount()); - Constant *Op2 = ValueList.getConstantFwdRef(Op2Idx, ShufTy); - if (!ShuffleVectorInst::isValidOperands(Op0, Op1, Op2)) - return error("Invalid shufflevector operands"); - SmallVector<int, 16> Mask; - ShuffleVectorInst::getShuffleMask(Op2, Mask); - Value *V = ConstantExpr::getShuffleVector(Op0, Op1, Mask); - ValueList.assignValue(V, CstNo); - } - for (auto &DelayedSelector : DelayedSelectors) { - Type *OpTy = DelayedSelector.OpTy; - Type *SelectorTy = Type::getInt1Ty(Context); - uint64_t Op0Idx = DelayedSelector.Op0Idx; - uint64_t Op1Idx = DelayedSelector.Op1Idx; - uint64_t Op2Idx = DelayedSelector.Op2Idx; - uint64_t CstNo = DelayedSelector.CstNo; - Constant *Op1 = ValueList.getConstantFwdRef(Op1Idx, OpTy); - Constant *Op2 = ValueList.getConstantFwdRef(Op2Idx, OpTy); - // The selector might be an i1 or an <n x i1> - // Get the type from the ValueList before getting a forward ref. - if (VectorType *VTy = dyn_cast<VectorType>(OpTy)) { - Value *V = ValueList[Op0Idx]; - assert(V); - if (SelectorTy != V->getType()) - SelectorTy = VectorType::get(SelectorTy, VTy->getElementCount()); - } - Constant *Op0 = ValueList.getConstantFwdRef(Op0Idx, SelectorTy); - Value *V = ConstantExpr::getSelect(Op0, Op1, Op2); - ValueList.assignValue(V, CstNo); - } - if (NextCstNo != ValueList.size()) return error("Invalid constant reference"); - - ValueList.resolveConstantForwardRefs(); return Error::success(); case BitstreamEntry::Record: // The interesting case. @@ -2448,12 +2879,14 @@ Error BitcodeReader::parseConstants() { break; case bitc::CST_CODE_SETTYPE: // SETTYPE: [typeid] if (Record.empty()) - return error("Invalid record"); + return error("Invalid settype record"); if (Record[0] >= TypeList.size() || !TypeList[Record[0]]) - return error("Invalid record"); + return error("Invalid settype record"); if (TypeList[Record[0]] == VoidType) return error("Invalid constant type"); - CurTy = TypeList[Record[0]]; + CurTyID = Record[0]; + CurTy = TypeList[CurTyID]; + CurElemTy = getPtrElementTypeByID(CurTyID); continue; // Skip the ValueList manipulation. case bitc::CST_CODE_NULL: // NULL if (CurTy->isVoidTy() || CurTy->isFunctionTy() || CurTy->isLabelTy()) @@ -2462,12 +2895,12 @@ Error BitcodeReader::parseConstants() { break; case bitc::CST_CODE_INTEGER: // INTEGER: [intval] if (!CurTy->isIntegerTy() || Record.empty()) - return error("Invalid record"); + return error("Invalid integer const record"); V = ConstantInt::get(CurTy, decodeSignRotatedValue(Record[0])); break; case bitc::CST_CODE_WIDE_INTEGER: {// WIDE_INTEGER: [n x intval] if (!CurTy->isIntegerTy() || Record.empty()) - return error("Invalid record"); + return error("Invalid wide integer const record"); APInt VInt = readWideAPInt(Record, cast<IntegerType>(CurTy)->getBitWidth()); @@ -2477,7 +2910,7 @@ Error BitcodeReader::parseConstants() { } case bitc::CST_CODE_FLOAT: { // FLOAT: [fpval] if (Record.empty()) - return error("Invalid record"); + return error("Invalid float const record"); if (CurTy->isHalfTy()) V = ConstantFP::get(Context, APFloat(APFloat::IEEEhalf(), APInt(16, (uint16_t)Record[0]))); @@ -2510,26 +2943,22 @@ Error BitcodeReader::parseConstants() { case bitc::CST_CODE_AGGREGATE: {// AGGREGATE: [n x value number] if (Record.empty()) - return error("Invalid record"); + return error("Invalid aggregate record"); unsigned Size = Record.size(); - SmallVector<Constant*, 16> Elts; - - if (StructType *STy = dyn_cast<StructType>(CurTy)) { - for (unsigned i = 0; i != Size; ++i) - Elts.push_back(ValueList.getConstantFwdRef(Record[i], - STy->getElementType(i))); - V = ConstantStruct::get(STy, Elts); - } else if (ArrayType *ATy = dyn_cast<ArrayType>(CurTy)) { - Type *EltTy = ATy->getElementType(); - for (unsigned i = 0; i != Size; ++i) - Elts.push_back(ValueList.getConstantFwdRef(Record[i], EltTy)); - V = ConstantArray::get(ATy, Elts); - } else if (VectorType *VTy = dyn_cast<VectorType>(CurTy)) { - Type *EltTy = VTy->getElementType(); - for (unsigned i = 0; i != Size; ++i) - Elts.push_back(ValueList.getConstantFwdRef(Record[i], EltTy)); - V = ConstantVector::get(Elts); + SmallVector<unsigned, 16> Elts; + for (unsigned i = 0; i != Size; ++i) + Elts.push_back(Record[i]); + + if (isa<StructType>(CurTy)) { + V = BitcodeConstant::create( + Alloc, CurTy, BitcodeConstant::ConstantStructOpcode, Elts); + } else if (isa<ArrayType>(CurTy)) { + V = BitcodeConstant::create(Alloc, CurTy, + BitcodeConstant::ConstantArrayOpcode, Elts); + } else if (isa<VectorType>(CurTy)) { + V = BitcodeConstant::create( + Alloc, CurTy, BitcodeConstant::ConstantVectorOpcode, Elts); } else { V = UndefValue::get(CurTy); } @@ -2538,7 +2967,7 @@ Error BitcodeReader::parseConstants() { case bitc::CST_CODE_STRING: // STRING: [values] case bitc::CST_CODE_CSTRING: { // CSTRING: [values] if (Record.empty()) - return error("Invalid record"); + return error("Invalid string record"); SmallString<16> Elts(Record.begin(), Record.end()); V = ConstantDataArray::getString(Context, Elts, @@ -2547,7 +2976,7 @@ Error BitcodeReader::parseConstants() { } case bitc::CST_CODE_DATA: {// DATA: [n x value] if (Record.empty()) - return error("Invalid record"); + return error("Invalid data record"); Type *EltTy; if (auto *Array = dyn_cast<ArrayType>(CurTy)) @@ -2609,27 +3038,23 @@ Error BitcodeReader::parseConstants() { } case bitc::CST_CODE_CE_UNOP: { // CE_UNOP: [opcode, opval] if (Record.size() < 2) - return error("Invalid record"); + return error("Invalid unary op constexpr record"); int Opc = getDecodedUnaryOpcode(Record[0], CurTy); if (Opc < 0) { V = UndefValue::get(CurTy); // Unknown unop. } else { - Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy); - unsigned Flags = 0; - V = ConstantExpr::get(Opc, LHS, Flags); + V = BitcodeConstant::create(Alloc, CurTy, Opc, (unsigned)Record[1]); } break; } case bitc::CST_CODE_CE_BINOP: { // CE_BINOP: [opcode, opval, opval] if (Record.size() < 3) - return error("Invalid record"); + return error("Invalid binary op constexpr record"); int Opc = getDecodedBinaryOpcode(Record[0], CurTy); if (Opc < 0) { V = UndefValue::get(CurTy); // Unknown binop. } else { - Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy); - Constant *RHS = ValueList.getConstantFwdRef(Record[2], CurTy); - unsigned Flags = 0; + uint8_t Flags = 0; if (Record.size() >= 4) { if (Opc == Instruction::Add || Opc == Instruction::Sub || @@ -2647,23 +3072,23 @@ Error BitcodeReader::parseConstants() { Flags |= SDivOperator::IsExact; } } - V = ConstantExpr::get(Opc, LHS, RHS, Flags); + V = BitcodeConstant::create(Alloc, CurTy, {(uint8_t)Opc, Flags}, + {(unsigned)Record[1], (unsigned)Record[2]}); } break; } case bitc::CST_CODE_CE_CAST: { // CE_CAST: [opcode, opty, opval] if (Record.size() < 3) - return error("Invalid record"); + return error("Invalid cast constexpr record"); int Opc = getDecodedCastOpcode(Record[0]); if (Opc < 0) { V = UndefValue::get(CurTy); // Unknown cast. } else { - Type *OpTy = getTypeByID(Record[1]); + unsigned OpTyID = Record[1]; + Type *OpTy = getTypeByID(OpTyID); if (!OpTy) - return error("Invalid record"); - Constant *Op = ValueList.getConstantFwdRef(Record[2], OpTy); - V = UpgradeBitCastExpr(Opc, Op, CurTy); - if (!V) V = ConstantExpr::getCast(Opc, Op, CurTy); + return error("Invalid cast constexpr record"); + V = BitcodeConstant::create(Alloc, CurTy, Opc, (unsigned)Record[2]); } break; } @@ -2671,6 +3096,8 @@ Error BitcodeReader::parseConstants() { case bitc::CST_CODE_CE_GEP: // [ty, n x operands] case bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX: { // [ty, flags, n x // operands] + if (Record.size() < 2) + return error("Constant GEP record must have at least two elements"); unsigned OpNum = 0; Type *PointeeType = nullptr; if (BitCode == bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX || @@ -2686,180 +3113,190 @@ Error BitcodeReader::parseConstants() { } else if (BitCode == bitc::CST_CODE_CE_INBOUNDS_GEP) InBounds = true; - SmallVector<Constant*, 16> Elts; - Type *Elt0FullTy = nullptr; + SmallVector<unsigned, 16> Elts; + unsigned BaseTypeID = Record[OpNum]; while (OpNum != Record.size()) { - if (!Elt0FullTy) - Elt0FullTy = getTypeByID(Record[OpNum]); - Type *ElTy = getTypeByID(Record[OpNum++]); + unsigned ElTyID = Record[OpNum++]; + Type *ElTy = getTypeByID(ElTyID); if (!ElTy) - return error("Invalid record"); - Elts.push_back(ValueList.getConstantFwdRef(Record[OpNum++], ElTy)); + return error("Invalid getelementptr constexpr record"); + Elts.push_back(Record[OpNum++]); } if (Elts.size() < 1) return error("Invalid gep with no operands"); - PointerType *OrigPtrTy = cast<PointerType>(Elt0FullTy->getScalarType()); - if (!PointeeType) - PointeeType = OrigPtrTy->getPointerElementType(); - else if (!OrigPtrTy->isOpaqueOrPointeeTypeMatches(PointeeType)) + Type *BaseType = getTypeByID(BaseTypeID); + if (isa<VectorType>(BaseType)) { + BaseTypeID = getContainedTypeID(BaseTypeID, 0); + BaseType = getTypeByID(BaseTypeID); + } + + PointerType *OrigPtrTy = dyn_cast_or_null<PointerType>(BaseType); + if (!OrigPtrTy) + return error("GEP base operand must be pointer or vector of pointer"); + + if (!PointeeType) { + PointeeType = getPtrElementTypeByID(BaseTypeID); + if (!PointeeType) + return error("Missing element type for old-style constant GEP"); + } else if (!OrigPtrTy->isOpaqueOrPointeeTypeMatches(PointeeType)) return error("Explicit gep operator type does not match pointee type " "of pointer operand"); - ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end()); - V = ConstantExpr::getGetElementPtr(PointeeType, Elts[0], Indices, - InBounds, InRangeIndex); + V = BitcodeConstant::create(Alloc, CurTy, + {Instruction::GetElementPtr, InBounds, + InRangeIndex.value_or(-1), PointeeType}, + Elts); break; } case bitc::CST_CODE_CE_SELECT: { // CE_SELECT: [opval#, opval#, opval#] if (Record.size() < 3) - return error("Invalid record"); + return error("Invalid select constexpr record"); - DelayedSelectors.push_back( - {CurTy, Record[0], Record[1], Record[2], NextCstNo}); - (void)ValueList.getConstantFwdRef(NextCstNo, CurTy); - ++NextCstNo; - continue; + V = BitcodeConstant::create( + Alloc, CurTy, Instruction::Select, + {(unsigned)Record[0], (unsigned)Record[1], (unsigned)Record[2]}); + break; } case bitc::CST_CODE_CE_EXTRACTELT : { // CE_EXTRACTELT: [opty, opval, opty, opval] if (Record.size() < 3) - return error("Invalid record"); + return error("Invalid extractelement constexpr record"); + unsigned OpTyID = Record[0]; VectorType *OpTy = - dyn_cast_or_null<VectorType>(getTypeByID(Record[0])); + dyn_cast_or_null<VectorType>(getTypeByID(OpTyID)); if (!OpTy) - return error("Invalid record"); - Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy); - Constant *Op1 = nullptr; + return error("Invalid extractelement constexpr record"); + unsigned IdxRecord; if (Record.size() == 4) { - Type *IdxTy = getTypeByID(Record[2]); + unsigned IdxTyID = Record[2]; + Type *IdxTy = getTypeByID(IdxTyID); if (!IdxTy) - return error("Invalid record"); - Op1 = ValueList.getConstantFwdRef(Record[3], IdxTy); + return error("Invalid extractelement constexpr record"); + IdxRecord = Record[3]; } else { // Deprecated, but still needed to read old bitcode files. - Op1 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context)); + IdxRecord = Record[2]; } - if (!Op1) - return error("Invalid record"); - V = ConstantExpr::getExtractElement(Op0, Op1); + V = BitcodeConstant::create(Alloc, CurTy, Instruction::ExtractElement, + {(unsigned)Record[1], IdxRecord}); break; } case bitc::CST_CODE_CE_INSERTELT : { // CE_INSERTELT: [opval, opval, opty, opval] VectorType *OpTy = dyn_cast<VectorType>(CurTy); if (Record.size() < 3 || !OpTy) - return error("Invalid record"); - Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy); - Constant *Op1 = ValueList.getConstantFwdRef(Record[1], - OpTy->getElementType()); - Constant *Op2 = nullptr; + return error("Invalid insertelement constexpr record"); + unsigned IdxRecord; if (Record.size() == 4) { - Type *IdxTy = getTypeByID(Record[2]); + unsigned IdxTyID = Record[2]; + Type *IdxTy = getTypeByID(IdxTyID); if (!IdxTy) - return error("Invalid record"); - Op2 = ValueList.getConstantFwdRef(Record[3], IdxTy); + return error("Invalid insertelement constexpr record"); + IdxRecord = Record[3]; } else { // Deprecated, but still needed to read old bitcode files. - Op2 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context)); + IdxRecord = Record[2]; } - if (!Op2) - return error("Invalid record"); - V = ConstantExpr::getInsertElement(Op0, Op1, Op2); + V = BitcodeConstant::create( + Alloc, CurTy, Instruction::InsertElement, + {(unsigned)Record[0], (unsigned)Record[1], IdxRecord}); break; } case bitc::CST_CODE_CE_SHUFFLEVEC: { // CE_SHUFFLEVEC: [opval, opval, opval] VectorType *OpTy = dyn_cast<VectorType>(CurTy); if (Record.size() < 3 || !OpTy) - return error("Invalid record"); - DelayedShuffles.push_back( - {OpTy, OpTy, Record[0], Record[1], Record[2], NextCstNo}); - ++NextCstNo; - continue; + return error("Invalid shufflevector constexpr record"); + V = BitcodeConstant::create( + Alloc, CurTy, Instruction::ShuffleVector, + {(unsigned)Record[0], (unsigned)Record[1], (unsigned)Record[2]}); + break; } case bitc::CST_CODE_CE_SHUFVEC_EX: { // [opty, opval, opval, opval] VectorType *RTy = dyn_cast<VectorType>(CurTy); VectorType *OpTy = dyn_cast_or_null<VectorType>(getTypeByID(Record[0])); if (Record.size() < 4 || !RTy || !OpTy) - return error("Invalid record"); - DelayedShuffles.push_back( - {OpTy, RTy, Record[1], Record[2], Record[3], NextCstNo}); - ++NextCstNo; - continue; + return error("Invalid shufflevector constexpr record"); + V = BitcodeConstant::create( + Alloc, CurTy, Instruction::ShuffleVector, + {(unsigned)Record[1], (unsigned)Record[2], (unsigned)Record[3]}); + break; } case bitc::CST_CODE_CE_CMP: { // CE_CMP: [opty, opval, opval, pred] if (Record.size() < 4) - return error("Invalid record"); - Type *OpTy = getTypeByID(Record[0]); + return error("Invalid cmp constexpt record"); + unsigned OpTyID = Record[0]; + Type *OpTy = getTypeByID(OpTyID); if (!OpTy) - return error("Invalid record"); - Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy); - Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy); - - if (OpTy->isFPOrFPVectorTy()) - V = ConstantExpr::getFCmp(Record[3], Op0, Op1); - else - V = ConstantExpr::getICmp(Record[3], Op0, Op1); + return error("Invalid cmp constexpr record"); + V = BitcodeConstant::create( + Alloc, CurTy, + {(uint8_t)(OpTy->isFPOrFPVectorTy() ? Instruction::FCmp + : Instruction::ICmp), + (uint8_t)Record[3]}, + {(unsigned)Record[1], (unsigned)Record[2]}); break; } // This maintains backward compatibility, pre-asm dialect keywords. // Deprecated, but still needed to read old bitcode files. case bitc::CST_CODE_INLINEASM_OLD: { if (Record.size() < 2) - return error("Invalid record"); + return error("Invalid inlineasm record"); std::string AsmStr, ConstrStr; bool HasSideEffects = Record[0] & 1; bool IsAlignStack = Record[0] >> 1; unsigned AsmStrSize = Record[1]; if (2+AsmStrSize >= Record.size()) - return error("Invalid record"); + return error("Invalid inlineasm record"); unsigned ConstStrSize = Record[2+AsmStrSize]; if (3+AsmStrSize+ConstStrSize > Record.size()) - return error("Invalid record"); + return error("Invalid inlineasm record"); for (unsigned i = 0; i != AsmStrSize; ++i) AsmStr += (char)Record[2+i]; for (unsigned i = 0; i != ConstStrSize; ++i) ConstrStr += (char)Record[3+AsmStrSize+i]; UpgradeInlineAsmString(&AsmStr); - // FIXME: support upgrading in opaque pointers mode. - V = InlineAsm::get(cast<FunctionType>(CurTy->getPointerElementType()), - AsmStr, ConstrStr, HasSideEffects, IsAlignStack); + if (!CurElemTy) + return error("Missing element type for old-style inlineasm"); + V = InlineAsm::get(cast<FunctionType>(CurElemTy), AsmStr, ConstrStr, + HasSideEffects, IsAlignStack); break; } // This version adds support for the asm dialect keywords (e.g., // inteldialect). case bitc::CST_CODE_INLINEASM_OLD2: { if (Record.size() < 2) - return error("Invalid record"); + return error("Invalid inlineasm record"); std::string AsmStr, ConstrStr; bool HasSideEffects = Record[0] & 1; bool IsAlignStack = (Record[0] >> 1) & 1; unsigned AsmDialect = Record[0] >> 2; unsigned AsmStrSize = Record[1]; if (2+AsmStrSize >= Record.size()) - return error("Invalid record"); + return error("Invalid inlineasm record"); unsigned ConstStrSize = Record[2+AsmStrSize]; if (3+AsmStrSize+ConstStrSize > Record.size()) - return error("Invalid record"); + return error("Invalid inlineasm record"); for (unsigned i = 0; i != AsmStrSize; ++i) AsmStr += (char)Record[2+i]; for (unsigned i = 0; i != ConstStrSize; ++i) ConstrStr += (char)Record[3+AsmStrSize+i]; UpgradeInlineAsmString(&AsmStr); - // FIXME: support upgrading in opaque pointers mode. - V = InlineAsm::get(cast<FunctionType>(CurTy->getPointerElementType()), - AsmStr, ConstrStr, HasSideEffects, IsAlignStack, + if (!CurElemTy) + return error("Missing element type for old-style inlineasm"); + V = InlineAsm::get(cast<FunctionType>(CurElemTy), AsmStr, ConstrStr, + HasSideEffects, IsAlignStack, InlineAsm::AsmDialect(AsmDialect)); break; } // This version adds support for the unwind keyword. case bitc::CST_CODE_INLINEASM_OLD3: { if (Record.size() < 2) - return error("Invalid record"); + return error("Invalid inlineasm record"); unsigned OpNum = 0; std::string AsmStr, ConstrStr; bool HasSideEffects = Record[OpNum] & 1; @@ -2870,10 +3307,10 @@ Error BitcodeReader::parseConstants() { unsigned AsmStrSize = Record[OpNum]; ++OpNum; if (OpNum + AsmStrSize >= Record.size()) - return error("Invalid record"); + return error("Invalid inlineasm record"); unsigned ConstStrSize = Record[OpNum + AsmStrSize]; if (OpNum + 1 + AsmStrSize + ConstStrSize > Record.size()) - return error("Invalid record"); + return error("Invalid inlineasm record"); for (unsigned i = 0; i != AsmStrSize; ++i) AsmStr += (char)Record[OpNum + i]; @@ -2881,21 +3318,22 @@ Error BitcodeReader::parseConstants() { for (unsigned i = 0; i != ConstStrSize; ++i) ConstrStr += (char)Record[OpNum + AsmStrSize + i]; UpgradeInlineAsmString(&AsmStr); - // FIXME: support upgrading in opaque pointers mode. - V = InlineAsm::get(cast<FunctionType>(CurTy->getPointerElementType()), - AsmStr, ConstrStr, HasSideEffects, IsAlignStack, + if (!CurElemTy) + return error("Missing element type for old-style inlineasm"); + V = InlineAsm::get(cast<FunctionType>(CurElemTy), AsmStr, ConstrStr, + HasSideEffects, IsAlignStack, InlineAsm::AsmDialect(AsmDialect), CanThrow); break; } // This version adds explicit function type. case bitc::CST_CODE_INLINEASM: { if (Record.size() < 3) - return error("Invalid record"); + return error("Invalid inlineasm record"); unsigned OpNum = 0; auto *FnTy = dyn_cast_or_null<FunctionType>(getTypeByID(Record[OpNum])); ++OpNum; if (!FnTy) - return error("Invalid record"); + return error("Invalid inlineasm record"); std::string AsmStr, ConstrStr; bool HasSideEffects = Record[OpNum] & 1; bool IsAlignStack = (Record[OpNum] >> 1) & 1; @@ -2905,10 +3343,10 @@ Error BitcodeReader::parseConstants() { unsigned AsmStrSize = Record[OpNum]; ++OpNum; if (OpNum + AsmStrSize >= Record.size()) - return error("Invalid record"); + return error("Invalid inlineasm record"); unsigned ConstStrSize = Record[OpNum + AsmStrSize]; if (OpNum + 1 + AsmStrSize + ConstStrSize > Record.size()) - return error("Invalid record"); + return error("Invalid inlineasm record"); for (unsigned i = 0; i != AsmStrSize; ++i) AsmStr += (char)Record[OpNum + i]; @@ -2922,75 +3360,44 @@ Error BitcodeReader::parseConstants() { } case bitc::CST_CODE_BLOCKADDRESS:{ if (Record.size() < 3) - return error("Invalid record"); - Type *FnTy = getTypeByID(Record[0]); + return error("Invalid blockaddress record"); + unsigned FnTyID = Record[0]; + Type *FnTy = getTypeByID(FnTyID); if (!FnTy) - return error("Invalid record"); - Function *Fn = - dyn_cast_or_null<Function>(ValueList.getConstantFwdRef(Record[1],FnTy)); - if (!Fn) - return error("Invalid record"); - - // If the function is already parsed we can insert the block address right - // away. - BasicBlock *BB; - unsigned BBID = Record[2]; - if (!BBID) - // Invalid reference to entry block. - return error("Invalid ID"); - if (!Fn->empty()) { - Function::iterator BBI = Fn->begin(), BBE = Fn->end(); - for (size_t I = 0, E = BBID; I != E; ++I) { - if (BBI == BBE) - return error("Invalid ID"); - ++BBI; - } - BB = &*BBI; - } else { - // Otherwise insert a placeholder and remember it so it can be inserted - // when the function is parsed. - auto &FwdBBs = BasicBlockFwdRefs[Fn]; - if (FwdBBs.empty()) - BasicBlockFwdRefQueue.push_back(Fn); - if (FwdBBs.size() < BBID + 1) - FwdBBs.resize(BBID + 1); - if (!FwdBBs[BBID]) - FwdBBs[BBID] = BasicBlock::Create(Context); - BB = FwdBBs[BBID]; - } - V = BlockAddress::get(Fn, BB); + return error("Invalid blockaddress record"); + V = BitcodeConstant::create( + Alloc, CurTy, + {BitcodeConstant::BlockAddressOpcode, 0, (unsigned)Record[2]}, + Record[1]); break; } case bitc::CST_CODE_DSO_LOCAL_EQUIVALENT: { if (Record.size() < 2) - return error("Invalid record"); - Type *GVTy = getTypeByID(Record[0]); + return error("Invalid dso_local record"); + unsigned GVTyID = Record[0]; + Type *GVTy = getTypeByID(GVTyID); if (!GVTy) - return error("Invalid record"); - GlobalValue *GV = dyn_cast_or_null<GlobalValue>( - ValueList.getConstantFwdRef(Record[1], GVTy)); - if (!GV) - return error("Invalid record"); - - V = DSOLocalEquivalent::get(GV); + return error("Invalid dso_local record"); + V = BitcodeConstant::create( + Alloc, CurTy, BitcodeConstant::DSOLocalEquivalentOpcode, Record[1]); break; } case bitc::CST_CODE_NO_CFI_VALUE: { if (Record.size() < 2) - return error("Invalid record"); - Type *GVTy = getTypeByID(Record[0]); + return error("Invalid no_cfi record"); + unsigned GVTyID = Record[0]; + Type *GVTy = getTypeByID(GVTyID); if (!GVTy) - return error("Invalid record"); - GlobalValue *GV = dyn_cast_or_null<GlobalValue>( - ValueList.getConstantFwdRef(Record[1], GVTy)); - if (!GV) - return error("Invalid record"); - V = NoCFIValue::get(GV); + return error("Invalid no_cfi record"); + V = BitcodeConstant::create(Alloc, CurTy, BitcodeConstant::NoCFIOpcode, + Record[1]); break; } } - ValueList.assignValue(V, NextCstNo); + assert(V->getType() == getTypeByID(CurTyID) && "Incorrect result type ID"); + if (Error Err = ValueList.assignValue(NextCstNo, V, CurTyID)) + return Err; ++NextCstNo; } } @@ -3146,7 +3553,7 @@ Error BitcodeReader::globalCleanup() { // Some types could be renamed during loading if several modules are // loaded in the same LLVMContext (LTO scenario). In this case we should // remangle intrinsics names as well. - RemangledIntrinsics[&F] = Remangled.getValue(); + RemangledIntrinsics[&F] = *Remangled; // Look for functions that rely on old function attribute behavior. UpgradeFunctionAttributes(F); } @@ -3211,17 +3618,17 @@ Error BitcodeReader::rememberAndSkipFunctionBodies() { } } -bool BitcodeReaderBase::readBlockInfo() { +Error BitcodeReaderBase::readBlockInfo() { Expected<Optional<BitstreamBlockInfo>> MaybeNewBlockInfo = Stream.ReadBlockInfoBlock(); if (!MaybeNewBlockInfo) - return true; // FIXME Handle the error. + return MaybeNewBlockInfo.takeError(); Optional<BitstreamBlockInfo> NewBlockInfo = std::move(MaybeNewBlockInfo.get()); if (!NewBlockInfo) - return true; + return error("Malformed block"); BlockInfo = std::move(*NewBlockInfo); - return false; + return Error::success(); } Error BitcodeReader::parseComdatRecord(ArrayRef<uint64_t> Record) { @@ -3238,6 +3645,8 @@ Error BitcodeReader::parseComdatRecord(ArrayRef<uint64_t> Record) { if (Record.size() < 2) return error("Invalid record"); unsigned ComdatNameSize = Record[1]; + if (ComdatNameSize > Record.size() - 2) + return error("Comdat name size too large"); OldFormatName.reserve(ComdatNameSize); for (unsigned i = 0; i != ComdatNameSize; ++i) OldFormatName += (char)Record[2 + i]; @@ -3256,6 +3665,19 @@ static void inferDSOLocal(GlobalValue *GV) { GV->setDSOLocal(true); } +GlobalValue::SanitizerMetadata deserializeSanitizerMetadata(unsigned V) { + GlobalValue::SanitizerMetadata Meta; + if (V & (1 << 0)) + Meta.NoAddress = true; + if (V & (1 << 1)) + Meta.NoHWAddress = true; + if (V & (1 << 2)) + Meta.NoMemtag = true; + if (V & (1 << 3)) + Meta.IsDynInit = true; + return Meta; +} + Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) { // v1: [pointer type, isconst, initid, linkage, alignment, section, // visibility, threadlocal, unnamed_addr, externally_initialized, @@ -3267,7 +3689,8 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) { if (Record.size() < 6) return error("Invalid record"); - Type *Ty = getTypeByID(Record[0]); + unsigned TyID = Record[0]; + Type *Ty = getTypeByID(TyID); if (!Ty) return error("Invalid record"); bool isConstant = Record[1] & 1; @@ -3279,7 +3702,10 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) { if (!Ty->isPointerTy()) return error("Invalid type for value"); AddressSpace = cast<PointerType>(Ty)->getAddressSpace(); - Ty = Ty->getPointerElementType(); + TyID = getContainedTypeID(TyID); + Ty = getTypeByID(TyID); + if (!Ty) + return error("Missing element type for old-style global"); } uint64_t RawLinkage = Record[3]; @@ -3325,7 +3751,7 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) { else upgradeDLLImportExportLinkage(NewGV, RawLinkage); - ValueList.push_back(NewGV); + ValueList.push_back(NewGV, getVirtualTypeID(NewGV->getType(), TyID)); // Remember which value to use for the global initializer. if (unsigned InitID = Record[2]) @@ -3355,6 +3781,12 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) { if (Record.size() > 15) NewGV->setPartition(StringRef(Strtab.data() + Record[14], Record[15])); + if (Record.size() > 16 && Record[16]) { + llvm::GlobalValue::SanitizerMetadata Meta = + deserializeSanitizerMetadata(Record[16]); + NewGV->setSanitizerMetadata(Meta); + } + return Error::success(); } @@ -3368,11 +3800,16 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { if (Record.size() < 8) return error("Invalid record"); - Type *FTy = getTypeByID(Record[0]); + unsigned FTyID = Record[0]; + Type *FTy = getTypeByID(FTyID); if (!FTy) return error("Invalid record"); - if (auto *PTy = dyn_cast<PointerType>(FTy)) - FTy = PTy->getPointerElementType(); + if (isa<PointerType>(FTy)) { + FTyID = getContainedTypeID(FTyID, 0); + FTy = getTypeByID(FTyID); + if (!FTy) + return error("Missing element type for old-style function"); + } if (!isa<FunctionType>(FTy)) return error("Invalid type for value"); @@ -3390,7 +3827,7 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { assert(Func->getFunctionType() == FTy && "Incorrect fully specified type provided for function"); - FunctionTypes[Func] = cast<FunctionType>(FTy); + FunctionTypeIDs[Func] = FTyID; Func->setCallingConv(CC); bool isProto = Record[2]; @@ -3412,8 +3849,11 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { Func->removeParamAttr(i, Kind); - Type *PTy = cast<FunctionType>(FTy)->getParamType(i); - Type *PtrEltTy = PTy->getPointerElementType(); + unsigned ParamTypeID = getContainedTypeID(FTyID, i + 1); + Type *PtrEltTy = getPtrElementTypeByID(ParamTypeID); + if (!PtrEltTy) + return error("Missing param element type for attribute upgrade"); + Attribute NewAttr; switch (Kind) { case Attribute::ByVal: @@ -3433,6 +3873,16 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { } } + if (Func->getCallingConv() == CallingConv::X86_INTR && + !Func->arg_empty() && !Func->hasParamAttribute(0, Attribute::ByVal)) { + unsigned ParamTypeID = getContainedTypeID(FTyID, 1); + Type *ByValTy = getPtrElementTypeByID(ParamTypeID); + if (!ByValTy) + return error("Missing param element type for x86_intrcc upgrade"); + Attribute NewAttr = Attribute::getWithByValType(Context, ByValTy); + Func->addParamAttr(0, NewAttr); + } + MaybeAlign Alignment; if (Error Err = parseAlignmentValue(Record[5], Alignment)) return Err; @@ -3495,7 +3945,7 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { Func->setPartition(StringRef(Strtab.data() + Record[17], Record[18])); } - ValueList.push_back(Func); + ValueList.push_back(Func, getVirtualTypeID(Func->getType(), FTyID)); if (OperandInfo.PersonalityFn || OperandInfo.Prefix || OperandInfo.Prologue) FunctionOperands.push_back(OperandInfo); @@ -3527,7 +3977,8 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord( if (Record.size() < (3 + (unsigned)NewRecord)) return error("Invalid record"); unsigned OpNum = 0; - Type *Ty = getTypeByID(Record[OpNum++]); + unsigned TypeID = Record[OpNum++]; + Type *Ty = getTypeByID(TypeID); if (!Ty) return error("Invalid record"); @@ -3536,8 +3987,11 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord( auto *PTy = dyn_cast<PointerType>(Ty); if (!PTy) return error("Invalid type for value"); - Ty = PTy->getPointerElementType(); AddrSpace = PTy->getAddressSpace(); + TypeID = getContainedTypeID(TypeID); + Ty = getTypeByID(TypeID); + if (!Ty) + return error("Missing element type for old-style indirect symbol"); } else { AddrSpace = Record[OpNum++]; } @@ -3582,7 +4036,7 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord( OpNum += 2; } - ValueList.push_back(NewGA); + ValueList.push_back(NewGA, getVirtualTypeID(NewGA->getType(), TypeID)); IndirectSymbolInits.push_back(std::make_pair(NewGA, Val)); return Error::success(); } @@ -3639,8 +4093,8 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, return Err; break; case bitc::BLOCKINFO_BLOCK_ID: - if (readBlockInfo()) - return error("Malformed block"); + if (Error Err = readBlockInfo()) + return Err; break; case bitc::PARAMATTR_BLOCK_ID: if (Error Err = parseAttributeBlock()) @@ -3796,7 +4250,10 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, std::string S; if (convertToString(Record, 0, S)) return error("Invalid record"); - TheModule->setDataLayout(S); + Expected<DataLayout> MaybeDL = DataLayout::parse(S); + if (!MaybeDL) + return MaybeDL.takeError(); + TheModule->setDataLayout(MaybeDL.get()); break; } case bitc::MODULE_CODE_ASM: { // ASM: [strchr x N] @@ -3894,18 +4351,20 @@ Error BitcodeReader::typeCheckLoadStoreInst(Type *ValType, Type *PtrType) { return Error::success(); } -void BitcodeReader::propagateAttributeTypes(CallBase *CB, - ArrayRef<Type *> ArgsTys) { +Error BitcodeReader::propagateAttributeTypes(CallBase *CB, + ArrayRef<unsigned> ArgTyIDs) { + AttributeList Attrs = CB->getAttributes(); for (unsigned i = 0; i != CB->arg_size(); ++i) { for (Attribute::AttrKind Kind : {Attribute::ByVal, Attribute::StructRet, Attribute::InAlloca}) { - if (!CB->paramHasAttr(i, Kind) || - CB->getParamAttr(i, Kind).getValueAsType()) + if (!Attrs.hasParamAttr(i, Kind) || + Attrs.getParamAttr(i, Kind).getValueAsType()) continue; - CB->removeParamAttr(i, Kind); + Type *PtrEltTy = getPtrElementTypeByID(ArgTyIDs[i]); + if (!PtrEltTy) + return error("Missing element type for typed attribute upgrade"); - Type *PtrEltTy = ArgsTys[i]->getPointerElementType(); Attribute NewAttr; switch (Kind) { case Attribute::ByVal: @@ -3921,7 +4380,7 @@ void BitcodeReader::propagateAttributeTypes(CallBase *CB, llvm_unreachable("not an upgraded type attribute"); } - CB->addParamAttr(i, NewAttr); + Attrs = Attrs.addParamAttribute(Context, i, NewAttr); } } @@ -3932,10 +4391,13 @@ void BitcodeReader::propagateAttributeTypes(CallBase *CB, if (!CI.hasArg()) continue; - if (CI.isIndirect && !CB->getAttributes().getParamElementType(ArgNo)) { - Type *ElemTy = ArgsTys[ArgNo]->getPointerElementType(); - CB->addParamAttr( - ArgNo, Attribute::get(Context, Attribute::ElementType, ElemTy)); + if (CI.isIndirect && !Attrs.getParamElementType(ArgNo)) { + Type *ElemTy = getPtrElementTypeByID(ArgTyIDs[ArgNo]); + if (!ElemTy) + return error("Missing element type for inline asm upgrade"); + Attrs = Attrs.addParamAttribute( + Context, ArgNo, + Attribute::get(Context, Attribute::ElementType, ElemTy)); } ArgNo++; @@ -3945,15 +4407,41 @@ void BitcodeReader::propagateAttributeTypes(CallBase *CB, switch (CB->getIntrinsicID()) { case Intrinsic::preserve_array_access_index: case Intrinsic::preserve_struct_access_index: - if (!CB->getAttributes().getParamElementType(0)) { - Type *ElTy = ArgsTys[0]->getPointerElementType(); + case Intrinsic::aarch64_ldaxr: + case Intrinsic::aarch64_ldxr: + case Intrinsic::aarch64_stlxr: + case Intrinsic::aarch64_stxr: + case Intrinsic::arm_ldaex: + case Intrinsic::arm_ldrex: + case Intrinsic::arm_stlex: + case Intrinsic::arm_strex: { + unsigned ArgNo; + switch (CB->getIntrinsicID()) { + case Intrinsic::aarch64_stlxr: + case Intrinsic::aarch64_stxr: + case Intrinsic::arm_stlex: + case Intrinsic::arm_strex: + ArgNo = 1; + break; + default: + ArgNo = 0; + break; + } + if (!Attrs.getParamElementType(ArgNo)) { + Type *ElTy = getPtrElementTypeByID(ArgTyIDs[ArgNo]); + if (!ElTy) + return error("Missing element type for elementtype upgrade"); Attribute NewAttr = Attribute::get(Context, Attribute::ElementType, ElTy); - CB->addParamAttr(0, NewAttr); + Attrs = Attrs.addParamAttribute(Context, ArgNo, NewAttr); } break; + } default: break; } + + CB->setAttributes(Attrs); + return Error::success(); } /// Lazily parse the specified function body block. @@ -3970,18 +4458,24 @@ Error BitcodeReader::parseFunctionBody(Function *F) { unsigned ModuleMDLoaderSize = MDLoader->size(); // Add all the function arguments to the value table. -#ifndef NDEBUG unsigned ArgNo = 0; - FunctionType *FTy = FunctionTypes[F]; -#endif + unsigned FTyID = FunctionTypeIDs[F]; for (Argument &I : F->args()) { - assert(I.getType() == FTy->getParamType(ArgNo++) && + unsigned ArgTyID = getContainedTypeID(FTyID, ArgNo + 1); + assert(I.getType() == getTypeByID(ArgTyID) && "Incorrect fully specified type for Function Argument"); - ValueList.push_back(&I); + ValueList.push_back(&I, ArgTyID); + ++ArgNo; } unsigned NextValueNo = ValueList.size(); BasicBlock *CurBB = nullptr; unsigned CurBBNo = 0; + // Block into which constant expressions from phi nodes are materialized. + BasicBlock *PhiConstExprBB = nullptr; + // Edge blocks for phi nodes into which constant expressions have been + // expanded. + SmallMapVector<std::pair<BasicBlock *, BasicBlock *>, BasicBlock *, 4> + ConstExprEdgeBBs; DebugLoc LastLoc; auto getLastInstruction = [&]() -> Instruction * { @@ -4050,6 +4544,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // Read a record. Record.clear(); Instruction *I = nullptr; + unsigned ResTypeID = InvalidTypeID; Expected<unsigned> MaybeBitCode = Stream.readRecord(Entry.ID, Record); if (!MaybeBitCode) return MaybeBitCode.takeError(); @@ -4091,6 +4586,31 @@ Error BitcodeReader::parseFunctionBody(Function *F) { continue; } + case bitc::FUNC_CODE_BLOCKADDR_USERS: // BLOCKADDR_USERS: [vals...] + // The record should not be emitted if it's an empty list. + if (Record.empty()) + return error("Invalid record"); + // When we have the RARE case of a BlockAddress Constant that is not + // scoped to the Function it refers to, we need to conservatively + // materialize the referred to Function, regardless of whether or not + // that Function will ultimately be linked, otherwise users of + // BitcodeReader might start splicing out Function bodies such that we + // might no longer be able to materialize the BlockAddress since the + // BasicBlock (and entire body of the Function) the BlockAddress refers + // to may have been moved. In the case that the user of BitcodeReader + // decides ultimately not to link the Function body, materializing here + // could be considered wasteful, but it's better than a deserialization + // failure as described. This keeps BitcodeReader unaware of complex + // linkage policy decisions such as those use by LTO, leaving those + // decisions "one layer up." + for (uint64_t ValID : Record) + if (auto *F = dyn_cast<Function>(ValueList[ValID])) + BackwardRefFunctions.push_back(F); + else + return error("Invalid record"); + + continue; + case bitc::FUNC_CODE_DEBUG_LOC_AGAIN: // DEBUG_LOC_AGAIN // This record indicates that the last instruction is at the same // location as the previous instruction with a location. @@ -4133,7 +4653,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_UNOP: { // UNOP: [opval, ty, opcode] unsigned OpNum = 0; Value *LHS; - if (getValueTypePair(Record, OpNum, NextValueNo, LHS) || + unsigned TypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, LHS, TypeID, CurBB) || OpNum+1 > Record.size()) return error("Invalid record"); @@ -4141,6 +4662,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { if (Opc == -1) return error("Invalid record"); I = UnaryOperator::Create((Instruction::UnaryOps)Opc, LHS); + ResTypeID = TypeID; InstructionList.push_back(I); if (OpNum < Record.size()) { if (isa<FPMathOperator>(I)) { @@ -4154,8 +4676,10 @@ Error BitcodeReader::parseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_BINOP: { // BINOP: [opval, ty, opval, opcode] unsigned OpNum = 0; Value *LHS, *RHS; - if (getValueTypePair(Record, OpNum, NextValueNo, LHS) || - popValue(Record, OpNum, NextValueNo, LHS->getType(), RHS) || + unsigned TypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, LHS, TypeID, CurBB) || + popValue(Record, OpNum, NextValueNo, LHS->getType(), TypeID, RHS, + CurBB) || OpNum+1 > Record.size()) return error("Invalid record"); @@ -4163,6 +4687,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { if (Opc == -1) return error("Invalid record"); I = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS); + ResTypeID = TypeID; InstructionList.push_back(I); if (OpNum < Record.size()) { if (Opc == Instruction::Add || @@ -4191,11 +4716,13 @@ Error BitcodeReader::parseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_CAST: { // CAST: [opval, opty, destty, castopc] unsigned OpNum = 0; Value *Op; - if (getValueTypePair(Record, OpNum, NextValueNo, Op) || + unsigned OpTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID, CurBB) || OpNum+2 != Record.size()) return error("Invalid record"); - Type *ResTy = getTypeByID(Record[OpNum]); + ResTypeID = Record[OpNum]; + Type *ResTy = getTypeByID(ResTypeID); int Opc = getDecodedCastOpcode(Record[OpNum + 1]); if (Opc == -1 || !ResTy) return error("Invalid record"); @@ -4220,23 +4747,31 @@ Error BitcodeReader::parseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_GEP: { // GEP: type, [n x operands] unsigned OpNum = 0; + unsigned TyID; Type *Ty; bool InBounds; if (BitCode == bitc::FUNC_CODE_INST_GEP) { InBounds = Record[OpNum++]; - Ty = getTypeByID(Record[OpNum++]); + TyID = Record[OpNum++]; + Ty = getTypeByID(TyID); } else { InBounds = BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD; + TyID = InvalidTypeID; Ty = nullptr; } Value *BasePtr; - if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr)) + unsigned BasePtrTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr, BasePtrTypeID, + CurBB)) return error("Invalid record"); if (!Ty) { - Ty = BasePtr->getType()->getScalarType()->getPointerElementType(); + TyID = getContainedTypeID(BasePtrTypeID); + if (BasePtr->getType()->isVectorTy()) + TyID = getContainedTypeID(TyID); + Ty = getTypeByID(TyID); } else if (!cast<PointerType>(BasePtr->getType()->getScalarType()) ->isOpaqueOrPointeeTypeMatches(Ty)) { return error( @@ -4246,13 +4781,37 @@ Error BitcodeReader::parseFunctionBody(Function *F) { SmallVector<Value*, 16> GEPIdx; while (OpNum != Record.size()) { Value *Op; - if (getValueTypePair(Record, OpNum, NextValueNo, Op)) + unsigned OpTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID, CurBB)) return error("Invalid record"); GEPIdx.push_back(Op); } I = GetElementPtrInst::Create(Ty, BasePtr, GEPIdx); + ResTypeID = TyID; + if (cast<GEPOperator>(I)->getNumIndices() != 0) { + auto GTI = std::next(gep_type_begin(I)); + for (Value *Idx : drop_begin(cast<GEPOperator>(I)->indices())) { + unsigned SubType = 0; + if (GTI.isStruct()) { + ConstantInt *IdxC = + Idx->getType()->isVectorTy() + ? cast<ConstantInt>(cast<Constant>(Idx)->getSplatValue()) + : cast<ConstantInt>(Idx); + SubType = IdxC->getZExtValue(); + } + ResTypeID = getContainedTypeID(ResTypeID, SubType); + ++GTI; + } + } + + // At this point ResTypeID is the result element type. We need a pointer + // or vector of pointer to it. + ResTypeID = getVirtualTypeID(I->getType()->getScalarType(), ResTypeID); + if (I->getType()->isVectorTy()) + ResTypeID = getVirtualTypeID(I->getType(), ResTypeID); + InstructionList.push_back(I); if (InBounds) cast<GetElementPtrInst>(I)->setIsInBounds(true); @@ -4263,7 +4822,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // EXTRACTVAL: [opty, opval, n x indices] unsigned OpNum = 0; Value *Agg; - if (getValueTypePair(Record, OpNum, NextValueNo, Agg)) + unsigned AggTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Agg, AggTypeID, CurBB)) return error("Invalid record"); Type *Ty = Agg->getType(); @@ -4272,6 +4832,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { return error("EXTRACTVAL: Invalid instruction with 0 indices"); SmallVector<unsigned, 4> EXTRACTVALIdx; + ResTypeID = AggTypeID; for (; OpNum != RecSize; ++OpNum) { bool IsArray = Ty->isArrayTy(); bool IsStruct = Ty->isStructTy(); @@ -4287,10 +4848,13 @@ Error BitcodeReader::parseFunctionBody(Function *F) { return error("EXTRACTVAL: Invalid array index"); EXTRACTVALIdx.push_back((unsigned)Index); - if (IsStruct) + if (IsStruct) { Ty = Ty->getStructElementType(Index); - else + ResTypeID = getContainedTypeID(ResTypeID, Index); + } else { Ty = Ty->getArrayElementType(); + ResTypeID = getContainedTypeID(ResTypeID); + } } I = ExtractValueInst::Create(Agg, EXTRACTVALIdx); @@ -4302,10 +4866,12 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // INSERTVAL: [opty, opval, opty, opval, n x indices] unsigned OpNum = 0; Value *Agg; - if (getValueTypePair(Record, OpNum, NextValueNo, Agg)) + unsigned AggTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Agg, AggTypeID, CurBB)) return error("Invalid record"); Value *Val; - if (getValueTypePair(Record, OpNum, NextValueNo, Val)) + unsigned ValTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID, CurBB)) return error("Invalid record"); unsigned RecSize = Record.size(); @@ -4339,6 +4905,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { return error("Inserted value type doesn't match aggregate type"); I = InsertValueInst::Create(Agg, Val, INSERTVALIdx); + ResTypeID = AggTypeID; InstructionList.push_back(I); break; } @@ -4348,12 +4915,18 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // handles select i1 ... in old bitcode unsigned OpNum = 0; Value *TrueVal, *FalseVal, *Cond; - if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) || - popValue(Record, OpNum, NextValueNo, TrueVal->getType(), FalseVal) || - popValue(Record, OpNum, NextValueNo, Type::getInt1Ty(Context), Cond)) + unsigned TypeID; + Type *CondType = Type::getInt1Ty(Context); + if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal, TypeID, + CurBB) || + popValue(Record, OpNum, NextValueNo, TrueVal->getType(), TypeID, + FalseVal, CurBB) || + popValue(Record, OpNum, NextValueNo, CondType, + getVirtualTypeID(CondType), Cond, CurBB)) return error("Invalid record"); I = SelectInst::Create(Cond, TrueVal, FalseVal); + ResTypeID = TypeID; InstructionList.push_back(I); break; } @@ -4363,9 +4936,12 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // handles select i1 or select [N x i1] unsigned OpNum = 0; Value *TrueVal, *FalseVal, *Cond; - if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) || - popValue(Record, OpNum, NextValueNo, TrueVal->getType(), FalseVal) || - getValueTypePair(Record, OpNum, NextValueNo, Cond)) + unsigned ValTypeID, CondTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal, ValTypeID, + CurBB) || + popValue(Record, OpNum, NextValueNo, TrueVal->getType(), ValTypeID, + FalseVal, CurBB) || + getValueTypePair(Record, OpNum, NextValueNo, Cond, CondTypeID, CurBB)) return error("Invalid record"); // select condition can be either i1 or [N x i1] @@ -4381,6 +4957,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { } I = SelectInst::Create(Cond, TrueVal, FalseVal); + ResTypeID = ValTypeID; InstructionList.push_back(I); if (OpNum < Record.size() && isa<FPMathOperator>(I)) { FastMathFlags FMF = getDecodedFastMathFlags(Record[OpNum]); @@ -4393,12 +4970,14 @@ Error BitcodeReader::parseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_EXTRACTELT: { // EXTRACTELT: [opty, opval, opval] unsigned OpNum = 0; Value *Vec, *Idx; - if (getValueTypePair(Record, OpNum, NextValueNo, Vec) || - getValueTypePair(Record, OpNum, NextValueNo, Idx)) + unsigned VecTypeID, IdxTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Vec, VecTypeID, CurBB) || + getValueTypePair(Record, OpNum, NextValueNo, Idx, IdxTypeID, CurBB)) return error("Invalid record"); if (!Vec->getType()->isVectorTy()) return error("Invalid type for value"); I = ExtractElementInst::Create(Vec, Idx); + ResTypeID = getContainedTypeID(VecTypeID); InstructionList.push_back(I); break; } @@ -4406,15 +4985,18 @@ Error BitcodeReader::parseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_INSERTELT: { // INSERTELT: [ty, opval,opval,opval] unsigned OpNum = 0; Value *Vec, *Elt, *Idx; - if (getValueTypePair(Record, OpNum, NextValueNo, Vec)) + unsigned VecTypeID, IdxTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Vec, VecTypeID, CurBB)) return error("Invalid record"); if (!Vec->getType()->isVectorTy()) return error("Invalid type for value"); if (popValue(Record, OpNum, NextValueNo, - cast<VectorType>(Vec->getType())->getElementType(), Elt) || - getValueTypePair(Record, OpNum, NextValueNo, Idx)) + cast<VectorType>(Vec->getType())->getElementType(), + getContainedTypeID(VecTypeID), Elt, CurBB) || + getValueTypePair(Record, OpNum, NextValueNo, Idx, IdxTypeID, CurBB)) return error("Invalid record"); I = InsertElementInst::Create(Vec, Elt, Idx); + ResTypeID = VecTypeID; InstructionList.push_back(I); break; } @@ -4422,16 +5004,22 @@ Error BitcodeReader::parseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_SHUFFLEVEC: {// SHUFFLEVEC: [opval,ty,opval,opval] unsigned OpNum = 0; Value *Vec1, *Vec2, *Mask; - if (getValueTypePair(Record, OpNum, NextValueNo, Vec1) || - popValue(Record, OpNum, NextValueNo, Vec1->getType(), Vec2)) + unsigned Vec1TypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Vec1, Vec1TypeID, + CurBB) || + popValue(Record, OpNum, NextValueNo, Vec1->getType(), Vec1TypeID, + Vec2, CurBB)) return error("Invalid record"); - if (getValueTypePair(Record, OpNum, NextValueNo, Mask)) + unsigned MaskTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Mask, MaskTypeID, CurBB)) return error("Invalid record"); if (!Vec1->getType()->isVectorTy() || !Vec2->getType()->isVectorTy()) return error("Invalid type for value"); I = new ShuffleVectorInst(Vec1, Vec2, Mask); + ResTypeID = + getVirtualTypeID(I->getType(), getContainedTypeID(Vec1TypeID)); InstructionList.push_back(I); break; } @@ -4445,8 +5033,10 @@ Error BitcodeReader::parseFunctionBody(Function *F) { unsigned OpNum = 0; Value *LHS, *RHS; - if (getValueTypePair(Record, OpNum, NextValueNo, LHS) || - popValue(Record, OpNum, NextValueNo, LHS->getType(), RHS)) + unsigned LHSTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, LHS, LHSTypeID, CurBB) || + popValue(Record, OpNum, NextValueNo, LHS->getType(), LHSTypeID, RHS, + CurBB)) return error("Invalid record"); if (OpNum >= Record.size()) @@ -4467,6 +5057,10 @@ Error BitcodeReader::parseFunctionBody(Function *F) { else I = new ICmpInst((ICmpInst::Predicate)PredVal, LHS, RHS); + ResTypeID = getVirtualTypeID(I->getType()->getScalarType()); + if (LHS->getType()->isVectorTy()) + ResTypeID = getVirtualTypeID(I->getType(), ResTypeID); + if (FMF.any()) I->setFastMathFlags(FMF); InstructionList.push_back(I); @@ -4484,7 +5078,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { unsigned OpNum = 0; Value *Op = nullptr; - if (getValueTypePair(Record, OpNum, NextValueNo, Op)) + unsigned OpTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID, CurBB)) return error("Invalid record"); if (OpNum != Record.size()) return error("Invalid record"); @@ -4506,8 +5101,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) { } else { BasicBlock *FalseDest = getBasicBlock(Record[1]); - Value *Cond = getValue(Record, 2, NextValueNo, - Type::getInt1Ty(Context)); + Type *CondType = Type::getInt1Ty(Context); + Value *Cond = getValue(Record, 2, NextValueNo, CondType, + getVirtualTypeID(CondType), CurBB); if (!FalseDest || !Cond) return error("Invalid record"); I = BranchInst::Create(TrueDest, FalseDest, Cond); @@ -4519,8 +5115,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) { if (Record.size() != 1 && Record.size() != 2) return error("Invalid record"); unsigned Idx = 0; - Value *CleanupPad = - getValue(Record, Idx++, NextValueNo, Type::getTokenTy(Context)); + Type *TokenTy = Type::getTokenTy(Context); + Value *CleanupPad = getValue(Record, Idx++, NextValueNo, TokenTy, + getVirtualTypeID(TokenTy), CurBB); if (!CleanupPad) return error("Invalid record"); BasicBlock *UnwindDest = nullptr; @@ -4538,8 +5135,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) { if (Record.size() != 2) return error("Invalid record"); unsigned Idx = 0; - Value *CatchPad = - getValue(Record, Idx++, NextValueNo, Type::getTokenTy(Context)); + Type *TokenTy = Type::getTokenTy(Context); + Value *CatchPad = getValue(Record, Idx++, NextValueNo, TokenTy, + getVirtualTypeID(TokenTy), CurBB); if (!CatchPad) return error("Invalid record"); BasicBlock *BB = getBasicBlock(Record[Idx++]); @@ -4557,8 +5155,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) { unsigned Idx = 0; - Value *ParentPad = - getValue(Record, Idx++, NextValueNo, Type::getTokenTy(Context)); + Type *TokenTy = Type::getTokenTy(Context); + Value *ParentPad = getValue(Record, Idx++, NextValueNo, TokenTy, + getVirtualTypeID(TokenTy), CurBB); unsigned NumHandlers = Record[Idx++]; @@ -4585,6 +5184,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { for (BasicBlock *Handler : Handlers) CatchSwitch->addHandler(Handler); I = CatchSwitch; + ResTypeID = getVirtualTypeID(I->getType()); InstructionList.push_back(I); break; } @@ -4596,15 +5196,17 @@ Error BitcodeReader::parseFunctionBody(Function *F) { unsigned Idx = 0; - Value *ParentPad = - getValue(Record, Idx++, NextValueNo, Type::getTokenTy(Context)); + Type *TokenTy = Type::getTokenTy(Context); + Value *ParentPad = getValue(Record, Idx++, NextValueNo, TokenTy, + getVirtualTypeID(TokenTy), CurBB); unsigned NumArgOperands = Record[Idx++]; SmallVector<Value *, 2> Args; for (unsigned Op = 0; Op != NumArgOperands; ++Op) { Value *Val; - if (getValueTypePair(Record, Idx, NextValueNo, Val)) + unsigned ValTypeID; + if (getValueTypePair(Record, Idx, NextValueNo, Val, ValTypeID, nullptr)) return error("Invalid record"); Args.push_back(Val); } @@ -4616,6 +5218,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { I = CleanupPadInst::Create(ParentPad, Args); else I = CatchPadInst::Create(ParentPad, Args); + ResTypeID = getVirtualTypeID(I->getType()); InstructionList.push_back(I); break; } @@ -4627,10 +5230,11 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // Hopefully someday we will have support for case ranges and can use // this format again. - Type *OpTy = getTypeByID(Record[1]); + unsigned OpTyID = Record[1]; + Type *OpTy = getTypeByID(OpTyID); unsigned ValueBitWidth = cast<IntegerType>(OpTy)->getBitWidth(); - Value *Cond = getValue(Record, 2, NextValueNo, OpTy); + Value *Cond = getValue(Record, 2, NextValueNo, OpTy, OpTyID, CurBB); BasicBlock *Default = getBasicBlock(Record[3]); if (!OpTy || !Cond || !Default) return error("Invalid record"); @@ -4684,8 +5288,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) { if (Record.size() < 3 || (Record.size() & 1) == 0) return error("Invalid record"); - Type *OpTy = getTypeByID(Record[0]); - Value *Cond = getValue(Record, 1, NextValueNo, OpTy); + unsigned OpTyID = Record[0]; + Type *OpTy = getTypeByID(OpTyID); + Value *Cond = getValue(Record, 1, NextValueNo, OpTy, OpTyID, CurBB); BasicBlock *Default = getBasicBlock(Record[2]); if (!OpTy || !Cond || !Default) return error("Invalid record"); @@ -4693,8 +5298,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { SwitchInst *SI = SwitchInst::Create(Cond, Default, NumCases); InstructionList.push_back(SI); for (unsigned i = 0, e = NumCases; i != e; ++i) { - ConstantInt *CaseVal = - dyn_cast_or_null<ConstantInt>(getFnValueByID(Record[3+i*2], OpTy)); + ConstantInt *CaseVal = dyn_cast_or_null<ConstantInt>( + getFnValueByID(Record[3+i*2], OpTy, OpTyID, nullptr)); BasicBlock *DestBB = getBasicBlock(Record[1+3+i*2]); if (!CaseVal || !DestBB) { delete SI; @@ -4708,8 +5313,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_INDIRECTBR: { // INDIRECTBR: [opty, op0, op1, ...] if (Record.size() < 2) return error("Invalid record"); - Type *OpTy = getTypeByID(Record[0]); - Value *Address = getValue(Record, 1, NextValueNo, OpTy); + unsigned OpTyID = Record[0]; + Type *OpTy = getTypeByID(OpTyID); + Value *Address = getValue(Record, 1, NextValueNo, OpTy, OpTyID, CurBB); if (!OpTy || !Address) return error("Invalid record"); unsigned NumDests = Record.size()-2; @@ -4737,23 +5343,27 @@ Error BitcodeReader::parseFunctionBody(Function *F) { BasicBlock *NormalBB = getBasicBlock(Record[OpNum++]); BasicBlock *UnwindBB = getBasicBlock(Record[OpNum++]); + unsigned FTyID = InvalidTypeID; FunctionType *FTy = nullptr; if ((CCInfo >> 13) & 1) { - FTy = dyn_cast<FunctionType>(getTypeByID(Record[OpNum++])); + FTyID = Record[OpNum++]; + FTy = dyn_cast<FunctionType>(getTypeByID(FTyID)); if (!FTy) return error("Explicit invoke type is not a function type"); } Value *Callee; - if (getValueTypePair(Record, OpNum, NextValueNo, Callee)) + unsigned CalleeTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Callee, CalleeTypeID, + CurBB)) return error("Invalid record"); PointerType *CalleeTy = dyn_cast<PointerType>(Callee->getType()); if (!CalleeTy) return error("Callee is not a pointer"); if (!FTy) { - FTy = - dyn_cast<FunctionType>(Callee->getType()->getPointerElementType()); + FTyID = getContainedTypeID(CalleeTypeID); + FTy = dyn_cast_or_null<FunctionType>(getTypeByID(FTyID)); if (!FTy) return error("Callee is not of pointer to function type"); } else if (!CalleeTy->isOpaqueOrPointeeTypeMatches(FTy)) @@ -4763,11 +5373,12 @@ Error BitcodeReader::parseFunctionBody(Function *F) { return error("Insufficient operands to call"); SmallVector<Value*, 16> Ops; - SmallVector<Type *, 16> ArgsTys; + SmallVector<unsigned, 16> ArgTyIDs; for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) { - Ops.push_back(getValue(Record, OpNum, NextValueNo, - FTy->getParamType(i))); - ArgsTys.push_back(FTy->getParamType(i)); + unsigned ArgTyID = getContainedTypeID(FTyID, i + 1); + Ops.push_back(getValue(Record, OpNum, NextValueNo, FTy->getParamType(i), + ArgTyID, CurBB)); + ArgTyIDs.push_back(ArgTyID); if (!Ops.back()) return error("Invalid record"); } @@ -4779,28 +5390,38 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // Read type/value pairs for varargs params. while (OpNum != Record.size()) { Value *Op; - if (getValueTypePair(Record, OpNum, NextValueNo, Op)) + unsigned OpTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID, CurBB)) return error("Invalid record"); Ops.push_back(Op); - ArgsTys.push_back(Op->getType()); + ArgTyIDs.push_back(OpTypeID); } } + // Upgrade the bundles if needed. + if (!OperandBundles.empty()) + UpgradeOperandBundles(OperandBundles); + I = InvokeInst::Create(FTy, Callee, NormalBB, UnwindBB, Ops, OperandBundles); + ResTypeID = getContainedTypeID(FTyID); OperandBundles.clear(); InstructionList.push_back(I); cast<InvokeInst>(I)->setCallingConv( static_cast<CallingConv::ID>(CallingConv::MaxID & CCInfo)); cast<InvokeInst>(I)->setAttributes(PAL); - propagateAttributeTypes(cast<CallBase>(I), ArgsTys); + if (Error Err = propagateAttributeTypes(cast<CallBase>(I), ArgTyIDs)) { + I->deleteValue(); + return Err; + } break; } case bitc::FUNC_CODE_INST_RESUME: { // RESUME: [opval] unsigned Idx = 0; Value *Val = nullptr; - if (getValueTypePair(Record, Idx, NextValueNo, Val)) + unsigned ValTypeID; + if (getValueTypePair(Record, Idx, NextValueNo, Val, ValTypeID, CurBB)) return error("Invalid record"); I = ResumeInst::Create(Val); InstructionList.push_back(I); @@ -4818,23 +5439,27 @@ Error BitcodeReader::parseFunctionBody(Function *F) { for (unsigned i = 0, e = NumIndirectDests; i != e; ++i) IndirectDests.push_back(getBasicBlock(Record[OpNum++])); + unsigned FTyID = InvalidTypeID; FunctionType *FTy = nullptr; if ((CCInfo >> bitc::CALL_EXPLICIT_TYPE) & 1) { - FTy = dyn_cast<FunctionType>(getTypeByID(Record[OpNum++])); + FTyID = Record[OpNum++]; + FTy = dyn_cast_or_null<FunctionType>(getTypeByID(FTyID)); if (!FTy) return error("Explicit call type is not a function type"); } Value *Callee; - if (getValueTypePair(Record, OpNum, NextValueNo, Callee)) + unsigned CalleeTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Callee, CalleeTypeID, + CurBB)) return error("Invalid record"); PointerType *OpTy = dyn_cast<PointerType>(Callee->getType()); if (!OpTy) return error("Callee is not a pointer type"); if (!FTy) { - FTy = - dyn_cast<FunctionType>(Callee->getType()->getPointerElementType()); + FTyID = getContainedTypeID(CalleeTypeID); + FTy = dyn_cast_or_null<FunctionType>(getTypeByID(FTyID)); if (!FTy) return error("Callee is not of pointer to function type"); } else if (!OpTy->isOpaqueOrPointeeTypeMatches(FTy)) @@ -4844,18 +5469,20 @@ Error BitcodeReader::parseFunctionBody(Function *F) { return error("Insufficient operands to call"); SmallVector<Value*, 16> Args; - SmallVector<Type *, 16> ArgsTys; + SmallVector<unsigned, 16> ArgTyIDs; // Read the fixed params. for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) { Value *Arg; + unsigned ArgTyID = getContainedTypeID(FTyID, i + 1); if (FTy->getParamType(i)->isLabelTy()) Arg = getBasicBlock(Record[OpNum]); else - Arg = getValue(Record, OpNum, NextValueNo, FTy->getParamType(i)); + Arg = getValue(Record, OpNum, NextValueNo, FTy->getParamType(i), + ArgTyID, CurBB); if (!Arg) return error("Invalid record"); Args.push_back(Arg); - ArgsTys.push_back(Arg->getType()); + ArgTyIDs.push_back(ArgTyID); } // Read type/value pairs for varargs params. @@ -4865,21 +5492,30 @@ Error BitcodeReader::parseFunctionBody(Function *F) { } else { while (OpNum != Record.size()) { Value *Op; - if (getValueTypePair(Record, OpNum, NextValueNo, Op)) + unsigned OpTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID, CurBB)) return error("Invalid record"); Args.push_back(Op); - ArgsTys.push_back(Op->getType()); + ArgTyIDs.push_back(OpTypeID); } } + // Upgrade the bundles if needed. + if (!OperandBundles.empty()) + UpgradeOperandBundles(OperandBundles); + I = CallBrInst::Create(FTy, Callee, DefaultDest, IndirectDests, Args, OperandBundles); + ResTypeID = getContainedTypeID(FTyID); OperandBundles.clear(); InstructionList.push_back(I); cast<CallBrInst>(I)->setCallingConv( static_cast<CallingConv::ID>((0x7ff & CCInfo) >> bitc::CALL_CCONV)); cast<CallBrInst>(I)->setAttributes(PAL); - propagateAttributeTypes(cast<CallBase>(I), ArgsTys); + if (Error Err = propagateAttributeTypes(cast<CallBase>(I), ArgTyIDs)) { + I->deleteValue(); + return Err; + } break; } case bitc::FUNC_CODE_INST_UNREACHABLE: // UNREACHABLE @@ -4888,36 +5524,76 @@ Error BitcodeReader::parseFunctionBody(Function *F) { break; case bitc::FUNC_CODE_INST_PHI: { // PHI: [ty, val0,bb0, ...] if (Record.empty()) - return error("Invalid record"); + return error("Invalid phi record"); // The first record specifies the type. - Type *Ty = getTypeByID(Record[0]); + unsigned TyID = Record[0]; + Type *Ty = getTypeByID(TyID); if (!Ty) - return error("Invalid record"); + return error("Invalid phi record"); // Phi arguments are pairs of records of [value, basic block]. // There is an optional final record for fast-math-flags if this phi has a // floating-point type. size_t NumArgs = (Record.size() - 1) / 2; PHINode *PN = PHINode::Create(Ty, NumArgs); - if ((Record.size() - 1) % 2 == 1 && !isa<FPMathOperator>(PN)) - return error("Invalid record"); + if ((Record.size() - 1) % 2 == 1 && !isa<FPMathOperator>(PN)) { + PN->deleteValue(); + return error("Invalid phi record"); + } InstructionList.push_back(PN); + SmallDenseMap<BasicBlock *, Value *> Args; for (unsigned i = 0; i != NumArgs; i++) { - Value *V; + BasicBlock *BB = getBasicBlock(Record[i * 2 + 2]); + if (!BB) { + PN->deleteValue(); + return error("Invalid phi BB"); + } + + // Phi nodes may contain the same predecessor multiple times, in which + // case the incoming value must be identical. Directly reuse the already + // seen value here, to avoid expanding a constant expression multiple + // times. + auto It = Args.find(BB); + if (It != Args.end()) { + PN->addIncoming(It->second, BB); + continue; + } + + // If there already is a block for this edge (from a different phi), + // use it. + BasicBlock *EdgeBB = ConstExprEdgeBBs.lookup({BB, CurBB}); + if (!EdgeBB) { + // Otherwise, use a temporary block (that we will discard if it + // turns out to be unnecessary). + if (!PhiConstExprBB) + PhiConstExprBB = BasicBlock::Create(Context, "phi.constexpr", F); + EdgeBB = PhiConstExprBB; + } + // With the new function encoding, it is possible that operands have // negative IDs (for forward references). Use a signed VBR // representation to keep the encoding small. + Value *V; if (UseRelativeIDs) - V = getValueSigned(Record, i * 2 + 1, NextValueNo, Ty); + V = getValueSigned(Record, i * 2 + 1, NextValueNo, Ty, TyID, EdgeBB); else - V = getValue(Record, i * 2 + 1, NextValueNo, Ty); - BasicBlock *BB = getBasicBlock(Record[i * 2 + 2]); - if (!V || !BB) - return error("Invalid record"); + V = getValue(Record, i * 2 + 1, NextValueNo, Ty, TyID, EdgeBB); + if (!V) { + PN->deleteValue(); + PhiConstExprBB->eraseFromParent(); + return error("Invalid phi record"); + } + + if (EdgeBB == PhiConstExprBB && !EdgeBB->empty()) { + ConstExprEdgeBBs.insert({{BB, CurBB}, EdgeBB}); + PhiConstExprBB = nullptr; + } PN->addIncoming(V, BB); + Args.insert({BB, V}); } I = PN; + ResTypeID = TyID; // If there are an even number of records, the final record must be FMF. if (Record.size() % 2 == 0) { @@ -4942,12 +5618,15 @@ Error BitcodeReader::parseFunctionBody(Function *F) { if (Record.size() < 4) return error("Invalid record"); } - Type *Ty = getTypeByID(Record[Idx++]); + ResTypeID = Record[Idx++]; + Type *Ty = getTypeByID(ResTypeID); if (!Ty) return error("Invalid record"); if (BitCode == bitc::FUNC_CODE_INST_LANDINGPAD_OLD) { Value *PersFn = nullptr; - if (getValueTypePair(Record, Idx, NextValueNo, PersFn)) + unsigned PersFnTypeID; + if (getValueTypePair(Record, Idx, NextValueNo, PersFn, PersFnTypeID, + nullptr)) return error("Invalid record"); if (!F->hasPersonalityFn()) @@ -4964,8 +5643,10 @@ Error BitcodeReader::parseFunctionBody(Function *F) { LandingPadInst::ClauseType CT = LandingPadInst::ClauseType(Record[Idx++]); (void)CT; Value *Val; + unsigned ValTypeID; - if (getValueTypePair(Record, Idx, NextValueNo, Val)) { + if (getValueTypePair(Record, Idx, NextValueNo, Val, ValTypeID, + nullptr)) { delete LP; return error("Invalid record"); } @@ -4985,21 +5666,23 @@ Error BitcodeReader::parseFunctionBody(Function *F) { } case bitc::FUNC_CODE_INST_ALLOCA: { // ALLOCA: [instty, opty, op, align] - if (Record.size() != 4) + if (Record.size() != 4 && Record.size() != 5) return error("Invalid record"); using APV = AllocaPackedValues; const uint64_t Rec = Record[3]; const bool InAlloca = Bitfield::get<APV::UsedWithInAlloca>(Rec); const bool SwiftError = Bitfield::get<APV::SwiftError>(Rec); - Type *Ty = getTypeByID(Record[0]); + unsigned TyID = Record[0]; + Type *Ty = getTypeByID(TyID); if (!Bitfield::get<APV::ExplicitType>(Rec)) { - auto *PTy = dyn_cast_or_null<PointerType>(Ty); - if (!PTy) - return error("Old-style alloca with a non-pointer type"); - Ty = PTy->getPointerElementType(); + TyID = getContainedTypeID(TyID); + Ty = getTypeByID(TyID); + if (!Ty) + return error("Missing element type for old-style alloca"); } - Type *OpTy = getTypeByID(Record[1]); - Value *Size = getFnValueByID(Record[2], OpTy); + unsigned OpTyID = Record[1]; + Type *OpTy = getTypeByID(OpTyID); + Value *Size = getFnValueByID(Record[2], OpTy, OpTyID, CurBB); MaybeAlign Align; uint64_t AlignExp = Bitfield::get<APV::AlignLower>(Rec) | @@ -5010,9 +5693,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { if (!Ty || !Size) return error("Invalid record"); - // FIXME: Make this an optional field. const DataLayout &DL = TheModule->getDataLayout(); - unsigned AS = DL.getAllocaAddrSpace(); + unsigned AS = Record.size() == 5 ? Record[4] : DL.getAllocaAddrSpace(); SmallPtrSet<Type *, 4> Visited; if (!Align && !Ty->isSized(&Visited)) @@ -5024,13 +5706,15 @@ Error BitcodeReader::parseFunctionBody(Function *F) { AI->setUsedWithInAlloca(InAlloca); AI->setSwiftError(SwiftError); I = AI; + ResTypeID = getVirtualTypeID(AI->getType(), TyID); InstructionList.push_back(I); break; } case bitc::FUNC_CODE_INST_LOAD: { // LOAD: [opty, op, align, vol] unsigned OpNum = 0; Value *Op; - if (getValueTypePair(Record, OpNum, NextValueNo, Op) || + unsigned OpTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID, CurBB) || (OpNum + 2 != Record.size() && OpNum + 3 != Record.size())) return error("Invalid record"); @@ -5039,9 +5723,13 @@ Error BitcodeReader::parseFunctionBody(Function *F) { Type *Ty = nullptr; if (OpNum + 3 == Record.size()) { - Ty = getTypeByID(Record[OpNum++]); + ResTypeID = Record[OpNum++]; + Ty = getTypeByID(ResTypeID); } else { - Ty = Op->getType()->getPointerElementType(); + ResTypeID = getContainedTypeID(OpTypeID); + Ty = getTypeByID(ResTypeID); + if (!Ty) + return error("Missing element type for old-style load"); } if (Error Err = typeCheckLoadStoreInst(Ty, Op->getType())) @@ -5063,7 +5751,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // LOADATOMIC: [opty, op, align, vol, ordering, ssid] unsigned OpNum = 0; Value *Op; - if (getValueTypePair(Record, OpNum, NextValueNo, Op) || + unsigned OpTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID, CurBB) || (OpNum + 4 != Record.size() && OpNum + 5 != Record.size())) return error("Invalid record"); @@ -5072,9 +5761,13 @@ Error BitcodeReader::parseFunctionBody(Function *F) { Type *Ty = nullptr; if (OpNum + 5 == Record.size()) { - Ty = getTypeByID(Record[OpNum++]); + ResTypeID = Record[OpNum++]; + Ty = getTypeByID(ResTypeID); } else { - Ty = Op->getType()->getPointerElementType(); + ResTypeID = getContainedTypeID(OpTypeID); + Ty = getTypeByID(ResTypeID); + if (!Ty) + return error("Missing element type for old style atomic load"); } if (Error Err = typeCheckLoadStoreInst(Ty, Op->getType())) @@ -5102,12 +5795,21 @@ Error BitcodeReader::parseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_STORE_OLD: { // STORE2:[ptrty, ptr, val, align, vol] unsigned OpNum = 0; Value *Val, *Ptr; - if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || - (BitCode == bitc::FUNC_CODE_INST_STORE - ? getValueTypePair(Record, OpNum, NextValueNo, Val) - : popValue(Record, OpNum, NextValueNo, - Ptr->getType()->getPointerElementType(), Val)) || - OpNum + 2 != Record.size()) + unsigned PtrTypeID, ValTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, PtrTypeID, CurBB)) + return error("Invalid record"); + + if (BitCode == bitc::FUNC_CODE_INST_STORE) { + if (getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID, CurBB)) + return error("Invalid record"); + } else { + ValTypeID = getContainedTypeID(PtrTypeID); + if (popValue(Record, OpNum, NextValueNo, getTypeByID(ValTypeID), + ValTypeID, Val, CurBB)) + return error("Invalid record"); + } + + if (OpNum + 2 != Record.size()) return error("Invalid record"); if (Error Err = typeCheckLoadStoreInst(Val->getType(), Ptr->getType())) @@ -5129,13 +5831,21 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // STOREATOMIC: [ptrty, ptr, val, align, vol, ordering, ssid] unsigned OpNum = 0; Value *Val, *Ptr; - if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || - !isa<PointerType>(Ptr->getType()) || - (BitCode == bitc::FUNC_CODE_INST_STOREATOMIC - ? getValueTypePair(Record, OpNum, NextValueNo, Val) - : popValue(Record, OpNum, NextValueNo, - Ptr->getType()->getPointerElementType(), Val)) || - OpNum + 4 != Record.size()) + unsigned PtrTypeID, ValTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, PtrTypeID, CurBB) || + !isa<PointerType>(Ptr->getType())) + return error("Invalid record"); + if (BitCode == bitc::FUNC_CODE_INST_STOREATOMIC) { + if (getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID, CurBB)) + return error("Invalid record"); + } else { + ValTypeID = getContainedTypeID(PtrTypeID); + if (popValue(Record, OpNum, NextValueNo, getTypeByID(ValTypeID), + ValTypeID, Val, CurBB)) + return error("Invalid record"); + } + + if (OpNum + 4 != Record.size()) return error("Invalid record"); if (Error Err = typeCheckLoadStoreInst(Val->getType(), Ptr->getType())) @@ -5164,20 +5874,22 @@ Error BitcodeReader::parseFunctionBody(Function *F) { const size_t NumRecords = Record.size(); unsigned OpNum = 0; Value *Ptr = nullptr; - if (getValueTypePair(Record, OpNum, NextValueNo, Ptr)) + unsigned PtrTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, PtrTypeID, CurBB)) return error("Invalid record"); if (!isa<PointerType>(Ptr->getType())) return error("Cmpxchg operand is not a pointer type"); Value *Cmp = nullptr; - if (popValue(Record, OpNum, NextValueNo, - cast<PointerType>(Ptr->getType())->getPointerElementType(), - Cmp)) + unsigned CmpTypeID = getContainedTypeID(PtrTypeID); + if (popValue(Record, OpNum, NextValueNo, getTypeByID(CmpTypeID), + CmpTypeID, Cmp, CurBB)) return error("Invalid record"); Value *New = nullptr; - if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), New) || + if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), CmpTypeID, + New, CurBB) || NumRecords < OpNum + 3 || NumRecords > OpNum + 5) return error("Invalid record"); @@ -5214,8 +5926,11 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // expecting the first component of a modern cmpxchg. CurBB->getInstList().push_back(I); I = ExtractValueInst::Create(I, 0); + ResTypeID = CmpTypeID; } else { cast<AtomicCmpXchgInst>(I)->setWeak(Record[OpNum + 4]); + unsigned I1TypeID = getVirtualTypeID(Type::getInt1Ty(Context)); + ResTypeID = getVirtualTypeID(I->getType(), {CmpTypeID, I1TypeID}); } InstructionList.push_back(I); @@ -5227,18 +5942,21 @@ Error BitcodeReader::parseFunctionBody(Function *F) { const size_t NumRecords = Record.size(); unsigned OpNum = 0; Value *Ptr = nullptr; - if (getValueTypePair(Record, OpNum, NextValueNo, Ptr)) + unsigned PtrTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, PtrTypeID, CurBB)) return error("Invalid record"); if (!isa<PointerType>(Ptr->getType())) return error("Cmpxchg operand is not a pointer type"); Value *Cmp = nullptr; - if (getValueTypePair(Record, OpNum, NextValueNo, Cmp)) + unsigned CmpTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Cmp, CmpTypeID, CurBB)) return error("Invalid record"); Value *Val = nullptr; - if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), Val)) + if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), CmpTypeID, Val, + CurBB)) return error("Invalid record"); if (NumRecords < OpNum + 3 || NumRecords > OpNum + 6) @@ -5278,6 +5996,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) { cast<AtomicCmpXchgInst>(I)->setVolatile(IsVol); cast<AtomicCmpXchgInst>(I)->setWeak(IsWeak); + unsigned I1TypeID = getVirtualTypeID(Type::getInt1Ty(Context)); + ResTypeID = getVirtualTypeID(I->getType(), {CmpTypeID, I1TypeID}); + InstructionList.push_back(I); break; } @@ -5289,20 +6010,22 @@ Error BitcodeReader::parseFunctionBody(Function *F) { unsigned OpNum = 0; Value *Ptr = nullptr; - if (getValueTypePair(Record, OpNum, NextValueNo, Ptr)) + unsigned PtrTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, PtrTypeID, CurBB)) return error("Invalid record"); if (!isa<PointerType>(Ptr->getType())) return error("Invalid record"); Value *Val = nullptr; + unsigned ValTypeID = InvalidTypeID; if (BitCode == bitc::FUNC_CODE_INST_ATOMICRMW_OLD) { + ValTypeID = getContainedTypeID(PtrTypeID); if (popValue(Record, OpNum, NextValueNo, - cast<PointerType>(Ptr->getType())->getPointerElementType(), - Val)) + getTypeByID(ValTypeID), ValTypeID, Val, CurBB)) return error("Invalid record"); } else { - if (getValueTypePair(Record, OpNum, NextValueNo, Val)) + if (getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID, CurBB)) return error("Invalid record"); } @@ -5336,6 +6059,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { Align(TheModule->getDataLayout().getTypeStoreSize(Val->getType())); I = new AtomicRMWInst(Operation, Ptr, Val, *Alignment, Ordering, SSID); + ResTypeID = ValTypeID; cast<AtomicRMWInst>(I)->setVolatile(IsVol); InstructionList.push_back(I); @@ -5370,23 +6094,27 @@ Error BitcodeReader::parseFunctionBody(Function *F) { return error("Fast math flags indicator set for call with no FMF"); } + unsigned FTyID = InvalidTypeID; FunctionType *FTy = nullptr; if ((CCInfo >> bitc::CALL_EXPLICIT_TYPE) & 1) { - FTy = dyn_cast<FunctionType>(getTypeByID(Record[OpNum++])); + FTyID = Record[OpNum++]; + FTy = dyn_cast_or_null<FunctionType>(getTypeByID(FTyID)); if (!FTy) return error("Explicit call type is not a function type"); } Value *Callee; - if (getValueTypePair(Record, OpNum, NextValueNo, Callee)) + unsigned CalleeTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Callee, CalleeTypeID, + CurBB)) return error("Invalid record"); PointerType *OpTy = dyn_cast<PointerType>(Callee->getType()); if (!OpTy) return error("Callee is not a pointer type"); if (!FTy) { - FTy = - dyn_cast<FunctionType>(Callee->getType()->getPointerElementType()); + FTyID = getContainedTypeID(CalleeTypeID); + FTy = dyn_cast_or_null<FunctionType>(getTypeByID(FTyID)); if (!FTy) return error("Callee is not of pointer to function type"); } else if (!OpTy->isOpaqueOrPointeeTypeMatches(FTy)) @@ -5396,15 +6124,16 @@ Error BitcodeReader::parseFunctionBody(Function *F) { return error("Insufficient operands to call"); SmallVector<Value*, 16> Args; - SmallVector<Type *, 16> ArgsTys; + SmallVector<unsigned, 16> ArgTyIDs; // Read the fixed params. for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) { + unsigned ArgTyID = getContainedTypeID(FTyID, i + 1); if (FTy->getParamType(i)->isLabelTy()) Args.push_back(getBasicBlock(Record[OpNum])); else Args.push_back(getValue(Record, OpNum, NextValueNo, - FTy->getParamType(i))); - ArgsTys.push_back(FTy->getParamType(i)); + FTy->getParamType(i), ArgTyID, CurBB)); + ArgTyIDs.push_back(ArgTyID); if (!Args.back()) return error("Invalid record"); } @@ -5416,14 +6145,20 @@ Error BitcodeReader::parseFunctionBody(Function *F) { } else { while (OpNum != Record.size()) { Value *Op; - if (getValueTypePair(Record, OpNum, NextValueNo, Op)) + unsigned OpTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID, CurBB)) return error("Invalid record"); Args.push_back(Op); - ArgsTys.push_back(Op->getType()); + ArgTyIDs.push_back(OpTypeID); } } + // Upgrade the bundles if needed. + if (!OperandBundles.empty()) + UpgradeOperandBundles(OperandBundles); + I = CallInst::Create(FTy, Callee, Args, OperandBundles); + ResTypeID = getContainedTypeID(FTyID); OperandBundles.clear(); InstructionList.push_back(I); cast<CallInst>(I)->setCallingConv( @@ -5437,7 +6172,10 @@ Error BitcodeReader::parseFunctionBody(Function *F) { TCK = CallInst::TCK_NoTail; cast<CallInst>(I)->setTailCallKind(TCK); cast<CallInst>(I)->setAttributes(PAL); - propagateAttributeTypes(cast<CallBase>(I), ArgsTys); + if (Error Err = propagateAttributeTypes(cast<CallBase>(I), ArgTyIDs)) { + I->deleteValue(); + return Err; + } if (FMF.any()) { if (!isa<FPMathOperator>(I)) return error("Fast-math-flags specified for call without " @@ -5449,9 +6187,11 @@ Error BitcodeReader::parseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_VAARG: { // VAARG: [valistty, valist, instty] if (Record.size() < 3) return error("Invalid record"); - Type *OpTy = getTypeByID(Record[0]); - Value *Op = getValue(Record, 1, NextValueNo, OpTy); - Type *ResTy = getTypeByID(Record[2]); + unsigned OpTyID = Record[0]; + Type *OpTy = getTypeByID(OpTyID); + Value *Op = getValue(Record, 1, NextValueNo, OpTy, OpTyID, CurBB); + ResTypeID = Record[2]; + Type *ResTy = getTypeByID(ResTypeID); if (!OpTy || !Op || !ResTy) return error("Invalid record"); I = new VAArgInst(Op, ResTy); @@ -5472,7 +6212,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { unsigned OpNum = 1; while (OpNum != Record.size()) { Value *Op; - if (getValueTypePair(Record, OpNum, NextValueNo, Op)) + unsigned OpTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID, CurBB)) return error("Invalid record"); Inputs.push_back(Op); } @@ -5484,12 +6225,14 @@ Error BitcodeReader::parseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_FREEZE: { // FREEZE: [opty,opval] unsigned OpNum = 0; Value *Op = nullptr; - if (getValueTypePair(Record, OpNum, NextValueNo, Op)) + unsigned OpTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID, CurBB)) return error("Invalid record"); if (OpNum != Record.size()) return error("Invalid record"); I = new FreezeInst(Op); + ResTypeID = OpTypeID; InstructionList.push_back(I); break; } @@ -5514,8 +6257,12 @@ Error BitcodeReader::parseFunctionBody(Function *F) { } // Non-void values get registered in the value table for future use. - if (!I->getType()->isVoidTy()) - ValueList.assignValue(I, NextValueNo++); + if (!I->getType()->isVoidTy()) { + assert(I->getType() == getTypeByID(ResTypeID) && + "Incorrect result type ID"); + if (Error Err = ValueList.assignValue(NextValueNo++, I, ResTypeID)) + return Err; + } } OutOfRecordLoop: @@ -5541,6 +6288,19 @@ OutOfRecordLoop: if (MDLoader->hasFwdRefs()) return error("Invalid function metadata: outgoing forward refs"); + if (PhiConstExprBB) + PhiConstExprBB->eraseFromParent(); + + for (const auto &Pair : ConstExprEdgeBBs) { + BasicBlock *From = Pair.first.first; + BasicBlock *To = Pair.first.second; + BasicBlock *EdgeBB = Pair.second; + BranchInst::Create(To, EdgeBB); + From->getTerminator()->replaceSuccessorWith(To, EdgeBB); + To->replacePhiUsesWith(From, EdgeBB); + EdgeBB->moveBefore(To); + } + // Trim the value list down to the size it was before we parsed this function. ValueList.shrinkTo(ModuleValueListSize); MDLoader->shrinkTo(ModuleMDLoaderSize); @@ -5913,8 +6673,8 @@ Error ModuleSummaryIndexBitcodeReader::parseModule() { break; case bitc::BLOCKINFO_BLOCK_ID: // Need to parse these to get abbrev ids (e.g. for VST) - if (readBlockInfo()) - return error("Malformed block"); + if (Error Err = readBlockInfo()) + return Err; break; case bitc::VALUE_SYMTAB_BLOCK_ID: // Should have been parsed earlier via VSTOffset, unless there |