aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-07-04 19:20:19 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-02-08 19:02:26 +0000
commit81ad626541db97eb356e2c1d4a20eb2a26a766ab (patch)
tree311b6a8987c32b1e1dcbab65c54cfac3fdb56175 /contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
parent5fff09660e06a66bed6482da9c70df328e16bbb6 (diff)
parent145449b1e420787bb99721a429341fa6be3adfb6 (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp1774
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