diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -595,15 +595,17 @@ StructType *createIdentifiedStructType(LLVMContext &Context); static constexpr unsigned InvalidTypeID = ~0u; + /// Placeholder for value type IDs we don't yet determine. + static constexpr unsigned TODOTypeID = InvalidTypeID - 1; Type *getTypeByID(unsigned ID); Type *getPtrElementTypeByID(unsigned ID); - unsigned getContainedTypeID(unsigned ID, unsigned Idx); + unsigned getContainedTypeID(unsigned ID, unsigned Idx = 0); - Value *getFnValueByID(unsigned ID, Type *Ty) { + Value *getFnValueByID(unsigned ID, Type *Ty, unsigned TyID) { if (Ty && Ty->isMetadataTy()) return MetadataAsValue::get(Ty->getContext(), getFnMetadataByID(ID)); - return ValueList.getValueFwdRef(ID, Ty); + return ValueList.getValueFwdRef(ID, Ty, TyID); } Metadata *getFnMetadataByID(unsigned ID) { @@ -625,7 +627,7 @@ /// Increment Slot past the number of slots used in the record. Return true on /// failure. bool getValueTypePair(const SmallVectorImpl &Record, unsigned &Slot, - unsigned InstNum, Value *&ResVal) { + unsigned InstNum, Value *&ResVal, unsigned &TypeID) { if (Slot == Record.size()) return true; unsigned ValNo = (unsigned)Record[Slot++]; // Adjust the ValNo, if it was encoded relative to the InstNum. @@ -634,14 +636,15 @@ 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); 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); return ResVal == nullptr; } @@ -649,8 +652,8 @@ /// past the number of slots used by the value in the record. Return true if /// there is an error. bool popValue(const SmallVectorImpl &Record, unsigned &Slot, - unsigned InstNum, Type *Ty, Value *&ResVal) { - if (getValue(Record, Slot, InstNum, Ty, ResVal)) + unsigned InstNum, Type *Ty, unsigned TyID, Value *&ResVal) { + if (getValue(Record, Slot, InstNum, Ty, TyID, ResVal)) return true; // All values currently take a single record slot. ++Slot; @@ -659,32 +662,32 @@ /// Like popValue, but does not increment the Slot number. bool getValue(const SmallVectorImpl &Record, unsigned Slot, - unsigned InstNum, Type *Ty, Value *&ResVal) { - ResVal = getValue(Record, Slot, InstNum, Ty); + unsigned InstNum, Type *Ty, unsigned TyID, Value *&ResVal) { + ResVal = getValue(Record, Slot, InstNum, Ty, TyID); return ResVal == nullptr; } /// Version of getValue that returns ResVal directly, or 0 if there is an /// error. Value *getValue(const SmallVectorImpl &Record, unsigned Slot, - unsigned InstNum, Type *Ty) { + unsigned InstNum, Type *Ty, unsigned TyID) { 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); } /// Like getValue, but decodes signed VBRs. Value *getValueSigned(const SmallVectorImpl &Record, unsigned Slot, - unsigned InstNum, Type *Ty) { + unsigned InstNum, Type *Ty, unsigned TyID) { 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); } /// Upgrades old-style typeless byval/sret/inalloca attributes by adding the @@ -1185,6 +1188,9 @@ } unsigned BitcodeReader::getContainedTypeID(unsigned ID, unsigned Idx) { + if (ID == TODOTypeID) + return TODOTypeID; + auto It = ContainedTypeIDs.find(ID); if (It == ContainedTypeIDs.end()) return InvalidTypeID; @@ -2398,12 +2404,14 @@ SmallVector Record; // Read all the records for this value table. + unsigned CurTyID = TODOTypeID; Type *CurTy = Type::getInt32Ty(Context); Type *CurElemTy = nullptr; unsigned NextCstNo = ValueList.size(); struct DelayedShufTy { VectorType *OpTy; + unsigned OpTyID; VectorType *RTy; uint64_t Op0Idx; uint64_t Op1Idx; @@ -2413,6 +2421,7 @@ std::vector DelayedShuffles; struct DelayedSelTy { Type *OpTy; + unsigned OpTyID; uint64_t Op0Idx; uint64_t Op1Idx; uint64_t Op2Idx; @@ -2439,32 +2448,34 @@ // and we can't convert a forward reference. for (auto &DelayedShuffle : DelayedShuffles) { VectorType *OpTy = DelayedShuffle.OpTy; + unsigned OpTyID = DelayedShuffle.OpTyID; 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); + Constant *Op0 = ValueList.getConstantFwdRef(Op0Idx, OpTy, OpTyID); + Constant *Op1 = ValueList.getConstantFwdRef(Op1Idx, OpTy, OpTyID); Type *ShufTy = VectorType::get(Type::getInt32Ty(Context), RTy->getElementCount()); - Constant *Op2 = ValueList.getConstantFwdRef(Op2Idx, ShufTy); + Constant *Op2 = ValueList.getConstantFwdRef(Op2Idx, ShufTy, TODOTypeID); if (!ShuffleVectorInst::isValidOperands(Op0, Op1, Op2)) return error("Invalid shufflevector operands"); SmallVector Mask; ShuffleVectorInst::getShuffleMask(Op2, Mask); Value *V = ConstantExpr::getShuffleVector(Op0, Op1, Mask); - ValueList.assignValue(CstNo, V); + ValueList.assignValue(CstNo, V, TODOTypeID); } for (auto &DelayedSelector : DelayedSelectors) { Type *OpTy = DelayedSelector.OpTy; + unsigned OpTyID = DelayedSelector.OpTyID; 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); + Constant *Op1 = ValueList.getConstantFwdRef(Op1Idx, OpTy, OpTyID); + Constant *Op2 = ValueList.getConstantFwdRef(Op2Idx, OpTy, OpTyID); // The selector might be an i1 or an // Get the type from the ValueList before getting a forward ref. if (VectorType *VTy = dyn_cast(OpTy)) { @@ -2473,9 +2484,10 @@ if (SelectorTy != V->getType()) SelectorTy = VectorType::get(SelectorTy, VTy->getElementCount()); } - Constant *Op0 = ValueList.getConstantFwdRef(Op0Idx, SelectorTy); + Constant *Op0 = + ValueList.getConstantFwdRef(Op0Idx, SelectorTy, TODOTypeID); Value *V = ConstantExpr::getSelect(Op0, Op1, Op2); - ValueList.assignValue(CstNo, V); + ValueList.assignValue(CstNo, V, TODOTypeID); } if (NextCstNo != ValueList.size()) @@ -2510,8 +2522,9 @@ return error("Invalid record"); if (TypeList[Record[0]] == VoidType) return error("Invalid constant type"); - CurTy = TypeList[Record[0]]; - CurElemTy = getPtrElementTypeByID(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()) @@ -2575,18 +2588,23 @@ if (StructType *STy = dyn_cast(CurTy)) { for (unsigned i = 0; i != Size; ++i) - Elts.push_back(ValueList.getConstantFwdRef(Record[i], - STy->getElementType(i))); + Elts.push_back(ValueList.getConstantFwdRef( + Record[i], STy->getElementType(i), + getContainedTypeID(CurTyID, i))); V = ConstantStruct::get(STy, Elts); } else if (ArrayType *ATy = dyn_cast(CurTy)) { Type *EltTy = ATy->getElementType(); + unsigned EltTyID = getContainedTypeID(CurTyID); for (unsigned i = 0; i != Size; ++i) - Elts.push_back(ValueList.getConstantFwdRef(Record[i], EltTy)); + Elts.push_back(ValueList.getConstantFwdRef(Record[i], EltTy, + EltTyID)); V = ConstantArray::get(ATy, Elts); } else if (VectorType *VTy = dyn_cast(CurTy)) { Type *EltTy = VTy->getElementType(); + unsigned EltTyID = getContainedTypeID(CurTyID); for (unsigned i = 0; i != Size; ++i) - Elts.push_back(ValueList.getConstantFwdRef(Record[i], EltTy)); + Elts.push_back(ValueList.getConstantFwdRef(Record[i], EltTy, + EltTyID)); V = ConstantVector::get(Elts); } else { V = UndefValue::get(CurTy); @@ -2672,7 +2690,7 @@ if (Opc < 0) { V = UndefValue::get(CurTy); // Unknown unop. } else { - Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy); + Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy, CurTyID); unsigned Flags = 0; V = ConstantExpr::get(Opc, LHS, Flags); } @@ -2685,8 +2703,8 @@ if (Opc < 0) { V = UndefValue::get(CurTy); // Unknown binop. } else { - Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy); - Constant *RHS = ValueList.getConstantFwdRef(Record[2], CurTy); + Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy, CurTyID); + Constant *RHS = ValueList.getConstantFwdRef(Record[2], CurTy, CurTyID); unsigned Flags = 0; if (Record.size() >= 4) { if (Opc == Instruction::Add || @@ -2716,10 +2734,11 @@ 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); + Constant *Op = ValueList.getConstantFwdRef(Record[2], OpTy, OpTyID); V = UpgradeBitCastExpr(Opc, Op, CurTy); if (!V) V = ConstantExpr::getCast(Opc, Op, CurTy); } @@ -2749,10 +2768,12 @@ SmallVector Elts; unsigned BaseTypeID = Record[OpNum]; while (OpNum != Record.size()) { - 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)); + Elts.push_back(ValueList.getConstantFwdRef(Record[OpNum++], ElTy, + ElTyID)); } if (Elts.size() < 1) @@ -2786,8 +2807,8 @@ return error("Invalid record"); DelayedSelectors.push_back( - {CurTy, Record[0], Record[1], Record[2], NextCstNo}); - (void)ValueList.getConstantFwdRef(NextCstNo, CurTy); + {CurTy, CurTyID, Record[0], Record[1], Record[2], NextCstNo}); + (void)ValueList.getConstantFwdRef(NextCstNo, CurTy, CurTyID); ++NextCstNo; continue; } @@ -2795,20 +2816,23 @@ : { // CE_EXTRACTELT: [opty, opval, opty, opval] if (Record.size() < 3) return error("Invalid record"); + unsigned OpTyID = Record[0]; VectorType *OpTy = - dyn_cast_or_null(getTypeByID(Record[0])); + dyn_cast_or_null(getTypeByID(OpTyID)); if (!OpTy) return error("Invalid record"); - Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy); + Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy, OpTyID); Constant *Op1 = nullptr; 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); + Op1 = ValueList.getConstantFwdRef(Record[3], IdxTy, IdxTyID); } else { // Deprecated, but still needed to read old bitcode files. - Op1 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context)); + Op1 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context), + TODOTypeID); } if (!Op1) return error("Invalid record"); @@ -2820,18 +2844,21 @@ VectorType *OpTy = dyn_cast(CurTy); if (Record.size() < 3 || !OpTy) return error("Invalid record"); - Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy); + Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy, CurTyID); Constant *Op1 = ValueList.getConstantFwdRef(Record[1], - OpTy->getElementType()); + OpTy->getElementType(), + getContainedTypeID(CurTyID)); Constant *Op2 = nullptr; 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); + Op2 = ValueList.getConstantFwdRef(Record[3], IdxTy, IdxTyID); } else { // Deprecated, but still needed to read old bitcode files. - Op2 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context)); + Op2 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context), + TODOTypeID); } if (!Op2) return error("Invalid record"); @@ -2843,7 +2870,7 @@ if (Record.size() < 3 || !OpTy) return error("Invalid record"); DelayedShuffles.push_back( - {OpTy, OpTy, Record[0], Record[1], Record[2], NextCstNo}); + {OpTy, CurTyID, OpTy, Record[0], Record[1], Record[2], NextCstNo}); ++NextCstNo; continue; } @@ -2854,18 +2881,19 @@ if (Record.size() < 4 || !RTy || !OpTy) return error("Invalid record"); DelayedShuffles.push_back( - {OpTy, RTy, Record[1], Record[2], Record[3], NextCstNo}); + {OpTy, CurTyID, RTy, Record[1], Record[2], Record[3], NextCstNo}); ++NextCstNo; continue; } 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]); + 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); + Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy, OpTyID); + Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy, OpTyID); if (OpTy->isFPOrFPVectorTy()) V = ConstantExpr::getFCmp(Record[3], Op0, Op1); @@ -2995,11 +3023,12 @@ case bitc::CST_CODE_BLOCKADDRESS:{ if (Record.size() < 3) return error("Invalid record"); - Type *FnTy = getTypeByID(Record[0]); + unsigned FnTyID = Record[0]; + Type *FnTy = getTypeByID(FnTyID); if (!FnTy) return error("Invalid record"); - Function *Fn = - dyn_cast_or_null(ValueList.getConstantFwdRef(Record[1],FnTy)); + Function *Fn = dyn_cast_or_null( + ValueList.getConstantFwdRef(Record[1], FnTy, FnTyID)); if (!Fn) return error("Invalid record"); @@ -3036,11 +3065,12 @@ case bitc::CST_CODE_DSO_LOCAL_EQUIVALENT: { if (Record.size() < 2) return error("Invalid record"); - Type *GVTy = getTypeByID(Record[0]); + unsigned GVTyID = Record[0]; + Type *GVTy = getTypeByID(GVTyID); if (!GVTy) return error("Invalid record"); GlobalValue *GV = dyn_cast_or_null( - ValueList.getConstantFwdRef(Record[1], GVTy)); + ValueList.getConstantFwdRef(Record[1], GVTy, GVTyID)); if (!GV) return error("Invalid record"); @@ -3050,11 +3080,12 @@ case bitc::CST_CODE_NO_CFI_VALUE: { if (Record.size() < 2) return error("Invalid record"); - Type *GVTy = getTypeByID(Record[0]); + unsigned GVTyID = Record[0]; + Type *GVTy = getTypeByID(GVTyID); if (!GVTy) return error("Invalid record"); GlobalValue *GV = dyn_cast_or_null( - ValueList.getConstantFwdRef(Record[1], GVTy)); + ValueList.getConstantFwdRef(Record[1], GVTy, GVTyID)); if (!GV) return error("Invalid record"); V = NoCFIValue::get(GV); @@ -3062,7 +3093,7 @@ } } - ValueList.assignValue(NextCstNo, V); + ValueList.assignValue(NextCstNo, V, CurTyID); ++NextCstNo; } } @@ -3341,7 +3372,8 @@ 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; @@ -3401,7 +3433,7 @@ else upgradeDLLImportExportLinkage(NewGV, RawLinkage); - ValueList.push_back(NewGV); + ValueList.push_back(NewGV, TyID); // Remember which value to use for the global initializer. if (unsigned InitID = Record[2]) @@ -3579,7 +3611,7 @@ Func->setPartition(StringRef(Strtab.data() + Record[17], Record[18])); } - ValueList.push_back(Func); + ValueList.push_back(Func, TODOTypeID); if (OperandInfo.PersonalityFn || OperandInfo.Prefix || OperandInfo.Prologue) FunctionOperands.push_back(OperandInfo); @@ -3669,7 +3701,7 @@ OpNum += 2; } - ValueList.push_back(NewGA); + ValueList.push_back(NewGA, TypeID); IndirectSymbolInits.push_back(std::make_pair(NewGA, Val)); return Error::success(); } @@ -4067,7 +4099,7 @@ for (Argument &I : F->args()) { assert(I.getType() == FTy->getParamType(ArgNo++) && "Incorrect fully specified type for Function Argument"); - ValueList.push_back(&I); + ValueList.push_back(&I, TODOTypeID); } unsigned NextValueNo = ValueList.size(); BasicBlock *CurBB = nullptr; @@ -4140,6 +4172,7 @@ // Read a record. Record.clear(); Instruction *I = nullptr; + unsigned ResTypeID = InvalidTypeID; Expected MaybeBitCode = Stream.readRecord(Entry.ID, Record); if (!MaybeBitCode) return MaybeBitCode.takeError(); @@ -4223,7 +4256,8 @@ 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) || OpNum+1 > Record.size()) return error("Invalid record"); @@ -4231,6 +4265,7 @@ 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(I)) { @@ -4244,8 +4279,9 @@ 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) || + popValue(Record, OpNum, NextValueNo, LHS->getType(), TypeID, RHS) || OpNum+1 > Record.size()) return error("Invalid record"); @@ -4253,6 +4289,7 @@ 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 || @@ -4281,11 +4318,13 @@ 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) || 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"); @@ -4322,7 +4361,8 @@ } Value *BasePtr; - if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr)) + unsigned BasePtrTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr, BasePtrTypeID)) return error("Invalid record"); if (!Ty) { @@ -4336,12 +4376,14 @@ SmallVector GEPIdx; while (OpNum != Record.size()) { Value *Op; - if (getValueTypePair(Record, OpNum, NextValueNo, Op)) + unsigned OpTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID)) return error("Invalid record"); GEPIdx.push_back(Op); } I = GetElementPtrInst::Create(Ty, BasePtr, GEPIdx); + ResTypeID = TODOTypeID; InstructionList.push_back(I); if (InBounds) @@ -4353,7 +4395,8 @@ // 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)) return error("Invalid record"); Type *Ty = Agg->getType(); @@ -4362,6 +4405,7 @@ return error("EXTRACTVAL: Invalid instruction with 0 indices"); SmallVector EXTRACTVALIdx; + ResTypeID = AggTypeID; for (; OpNum != RecSize; ++OpNum) { bool IsArray = Ty->isArrayTy(); bool IsStruct = Ty->isStructTy(); @@ -4377,10 +4421,13 @@ 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); @@ -4392,10 +4439,12 @@ // 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)) return error("Invalid record"); Value *Val; - if (getValueTypePair(Record, OpNum, NextValueNo, Val)) + unsigned ValTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID)) return error("Invalid record"); unsigned RecSize = Record.size(); @@ -4429,6 +4478,7 @@ return error("Inserted value type doesn't match aggregate type"); I = InsertValueInst::Create(Agg, Val, INSERTVALIdx); + ResTypeID = AggTypeID; InstructionList.push_back(I); break; } @@ -4438,12 +4488,16 @@ // 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; + if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal, TypeID) || + popValue(Record, OpNum, NextValueNo, TrueVal->getType(), TypeID, + FalseVal) || + popValue(Record, OpNum, NextValueNo, Type::getInt1Ty(Context), + TODOTypeID, Cond)) return error("Invalid record"); I = SelectInst::Create(Cond, TrueVal, FalseVal); + ResTypeID = TypeID; InstructionList.push_back(I); break; } @@ -4453,9 +4507,11 @@ // 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) || + popValue(Record, OpNum, NextValueNo, TrueVal->getType(), ValTypeID, + FalseVal) || + getValueTypePair(Record, OpNum, NextValueNo, Cond, CondTypeID)) return error("Invalid record"); // select condition can be either i1 or [N x i1] @@ -4471,6 +4527,7 @@ } I = SelectInst::Create(Cond, TrueVal, FalseVal); + ResTypeID = ValTypeID; InstructionList.push_back(I); if (OpNum < Record.size() && isa(I)) { FastMathFlags FMF = getDecodedFastMathFlags(Record[OpNum]); @@ -4483,12 +4540,14 @@ 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) || + getValueTypePair(Record, OpNum, NextValueNo, Idx, IdxTypeID)) 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; } @@ -4496,15 +4555,18 @@ 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)) return error("Invalid record"); if (!Vec->getType()->isVectorTy()) return error("Invalid type for value"); if (popValue(Record, OpNum, NextValueNo, - cast(Vec->getType())->getElementType(), Elt) || - getValueTypePair(Record, OpNum, NextValueNo, Idx)) + cast(Vec->getType())->getElementType(), + getContainedTypeID(VecTypeID), Elt) || + getValueTypePair(Record, OpNum, NextValueNo, Idx, IdxTypeID)) return error("Invalid record"); I = InsertElementInst::Create(Vec, Elt, Idx); + ResTypeID = VecTypeID; InstructionList.push_back(I); break; } @@ -4512,16 +4574,20 @@ 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) || + popValue(Record, OpNum, NextValueNo, Vec1->getType(), Vec1TypeID, + Vec2)) return error("Invalid record"); - if (getValueTypePair(Record, OpNum, NextValueNo, Mask)) + unsigned MaskTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Mask, MaskTypeID)) return error("Invalid record"); if (!Vec1->getType()->isVectorTy() || !Vec2->getType()->isVectorTy()) return error("Invalid type for value"); I = new ShuffleVectorInst(Vec1, Vec2, Mask); + ResTypeID = TODOTypeID; InstructionList.push_back(I); break; } @@ -4535,8 +4601,9 @@ 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) || + popValue(Record, OpNum, NextValueNo, LHS->getType(), LHSTypeID, RHS)) return error("Invalid record"); if (OpNum >= Record.size()) @@ -4556,6 +4623,7 @@ I = new FCmpInst((FCmpInst::Predicate)PredVal, LHS, RHS); else I = new ICmpInst((ICmpInst::Predicate)PredVal, LHS, RHS); + ResTypeID = TODOTypeID; if (FMF.any()) I->setFastMathFlags(FMF); @@ -4574,7 +4642,8 @@ unsigned OpNum = 0; Value *Op = nullptr; - if (getValueTypePair(Record, OpNum, NextValueNo, Op)) + unsigned OpTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID)) return error("Invalid record"); if (OpNum != Record.size()) return error("Invalid record"); @@ -4597,7 +4666,7 @@ else { BasicBlock *FalseDest = getBasicBlock(Record[1]); Value *Cond = getValue(Record, 2, NextValueNo, - Type::getInt1Ty(Context)); + Type::getInt1Ty(Context), TODOTypeID); if (!FalseDest || !Cond) return error("Invalid record"); I = BranchInst::Create(TrueDest, FalseDest, Cond); @@ -4609,8 +4678,8 @@ if (Record.size() != 1 && Record.size() != 2) return error("Invalid record"); unsigned Idx = 0; - Value *CleanupPad = - getValue(Record, Idx++, NextValueNo, Type::getTokenTy(Context)); + Value *CleanupPad = getValue( + Record, Idx++, NextValueNo, Type::getTokenTy(Context), TODOTypeID); if (!CleanupPad) return error("Invalid record"); BasicBlock *UnwindDest = nullptr; @@ -4628,8 +4697,8 @@ if (Record.size() != 2) return error("Invalid record"); unsigned Idx = 0; - Value *CatchPad = - getValue(Record, Idx++, NextValueNo, Type::getTokenTy(Context)); + Value *CatchPad = getValue( + Record, Idx++, NextValueNo, Type::getTokenTy(Context), TODOTypeID); if (!CatchPad) return error("Invalid record"); BasicBlock *BB = getBasicBlock(Record[Idx++]); @@ -4647,8 +4716,8 @@ unsigned Idx = 0; - Value *ParentPad = - getValue(Record, Idx++, NextValueNo, Type::getTokenTy(Context)); + Value *ParentPad = getValue( + Record, Idx++, NextValueNo, Type::getTokenTy(Context), TODOTypeID); unsigned NumHandlers = Record[Idx++]; @@ -4675,6 +4744,7 @@ for (BasicBlock *Handler : Handlers) CatchSwitch->addHandler(Handler); I = CatchSwitch; + ResTypeID = TODOTypeID; InstructionList.push_back(I); break; } @@ -4686,15 +4756,16 @@ unsigned Idx = 0; - Value *ParentPad = - getValue(Record, Idx++, NextValueNo, Type::getTokenTy(Context)); + Value *ParentPad = getValue( + Record, Idx++, NextValueNo, Type::getTokenTy(Context), TODOTypeID); unsigned NumArgOperands = Record[Idx++]; SmallVector 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)) return error("Invalid record"); Args.push_back(Val); } @@ -4706,6 +4777,7 @@ I = CleanupPadInst::Create(ParentPad, Args); else I = CatchPadInst::Create(ParentPad, Args); + ResTypeID = TODOTypeID; InstructionList.push_back(I); break; } @@ -4717,10 +4789,11 @@ // 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(OpTy)->getBitWidth(); - Value *Cond = getValue(Record, 2, NextValueNo, OpTy); + Value *Cond = getValue(Record, 2, NextValueNo, OpTy, OpTyID); BasicBlock *Default = getBasicBlock(Record[3]); if (!OpTy || !Cond || !Default) return error("Invalid record"); @@ -4774,8 +4847,9 @@ 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); BasicBlock *Default = getBasicBlock(Record[2]); if (!OpTy || !Cond || !Default) return error("Invalid record"); @@ -4783,8 +4857,8 @@ 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(getFnValueByID(Record[3+i*2], OpTy)); + ConstantInt *CaseVal = dyn_cast_or_null( + getFnValueByID(Record[3+i*2], OpTy, OpTyID)); BasicBlock *DestBB = getBasicBlock(Record[1+3+i*2]); if (!CaseVal || !DestBB) { delete SI; @@ -4798,8 +4872,9 @@ 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); if (!OpTy || !Address) return error("Invalid record"); unsigned NumDests = Record.size()-2; @@ -4835,7 +4910,8 @@ } Value *Callee; - if (getValueTypePair(Record, OpNum, NextValueNo, Callee)) + unsigned CalleeTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Callee, CalleeTypeID)) return error("Invalid record"); PointerType *CalleeTy = dyn_cast(Callee->getType()); @@ -4856,7 +4932,7 @@ SmallVector ArgsTys; for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) { Ops.push_back(getValue(Record, OpNum, NextValueNo, - FTy->getParamType(i))); + FTy->getParamType(i), TODOTypeID)); ArgsTys.push_back(FTy->getParamType(i)); if (!Ops.back()) return error("Invalid record"); @@ -4869,7 +4945,8 @@ // 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)) return error("Invalid record"); Ops.push_back(Op); ArgsTys.push_back(Op->getType()); @@ -4878,6 +4955,7 @@ I = InvokeInst::Create(FTy, Callee, NormalBB, UnwindBB, Ops, OperandBundles); + ResTypeID = TODOTypeID; OperandBundles.clear(); InstructionList.push_back(I); cast(I)->setCallingConv( @@ -4890,7 +4968,8 @@ 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)) return error("Invalid record"); I = ResumeInst::Create(Val); InstructionList.push_back(I); @@ -4916,7 +4995,8 @@ } Value *Callee; - if (getValueTypePair(Record, OpNum, NextValueNo, Callee)) + unsigned CalleeTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Callee, CalleeTypeID)) return error("Invalid record"); PointerType *OpTy = dyn_cast(Callee->getType()); @@ -4941,7 +5021,8 @@ 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), + TODOTypeID); if (!Arg) return error("Invalid record"); Args.push_back(Arg); @@ -4955,7 +5036,8 @@ } else { while (OpNum != Record.size()) { Value *Op; - if (getValueTypePair(Record, OpNum, NextValueNo, Op)) + unsigned OpTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID)) return error("Invalid record"); Args.push_back(Op); ArgsTys.push_back(Op->getType()); @@ -4964,6 +5046,7 @@ I = CallBrInst::Create(FTy, Callee, DefaultDest, IndirectDests, Args, OperandBundles); + ResTypeID = TODOTypeID; OperandBundles.clear(); InstructionList.push_back(I); cast(I)->setCallingConv( @@ -4980,7 +5063,8 @@ if (Record.empty()) return error("Invalid 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"); @@ -4999,15 +5083,16 @@ // negative IDs (for forward references). Use a signed VBR // representation to keep the encoding small. if (UseRelativeIDs) - V = getValueSigned(Record, i * 2 + 1, NextValueNo, Ty); + V = getValueSigned(Record, i * 2 + 1, NextValueNo, Ty, TyID); else - V = getValue(Record, i * 2 + 1, NextValueNo, Ty); + V = getValue(Record, i * 2 + 1, NextValueNo, Ty, TyID); BasicBlock *BB = getBasicBlock(Record[i * 2 + 2]); if (!V || !BB) return error("Invalid record"); PN->addIncoming(V, BB); } I = PN; + ResTypeID = TyID; // If there are an even number of records, the final record must be FMF. if (Record.size() % 2 == 0) { @@ -5032,12 +5117,14 @@ 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)) return error("Invalid record"); if (!F->hasPersonalityFn()) @@ -5054,8 +5141,9 @@ 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)) { delete LP; return error("Invalid record"); } @@ -5087,8 +5175,9 @@ 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); MaybeAlign Align; uint64_t AlignExp = Bitfield::get(Rec) | @@ -5113,13 +5202,15 @@ AI->setUsedWithInAlloca(InAlloca); AI->setSwiftError(SwiftError); I = AI; + ResTypeID = TODOTypeID; 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) || (OpNum + 2 != Record.size() && OpNum + 3 != Record.size())) return error("Invalid record"); @@ -5128,8 +5219,10 @@ Type *Ty = nullptr; if (OpNum + 3 == Record.size()) { - Ty = getTypeByID(Record[OpNum++]); + ResTypeID = Record[OpNum++]; + Ty = getTypeByID(ResTypeID); } else { + ResTypeID = getContainedTypeID(OpTypeID); Ty = Op->getType()->getPointerElementType(); } @@ -5152,7 +5245,8 @@ // 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) || (OpNum + 4 != Record.size() && OpNum + 5 != Record.size())) return error("Invalid record"); @@ -5161,8 +5255,10 @@ Type *Ty = nullptr; if (OpNum + 5 == Record.size()) { - Ty = getTypeByID(Record[OpNum++]); + ResTypeID = Record[OpNum++]; + Ty = getTypeByID(ResTypeID); } else { + ResTypeID = getContainedTypeID(OpTypeID); Ty = Op->getType()->getPointerElementType(); } @@ -5191,11 +5287,13 @@ 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) || + unsigned PtrTypeID, ValTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, PtrTypeID) || (BitCode == bitc::FUNC_CODE_INST_STORE - ? getValueTypePair(Record, OpNum, NextValueNo, Val) + ? getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID) : popValue(Record, OpNum, NextValueNo, - Ptr->getType()->getPointerElementType(), Val)) || + Ptr->getType()->getPointerElementType(), + getContainedTypeID(PtrTypeID), Val)) || OpNum + 2 != Record.size()) return error("Invalid record"); @@ -5218,12 +5316,14 @@ // STOREATOMIC: [ptrty, ptr, val, align, vol, ordering, ssid] unsigned OpNum = 0; Value *Val, *Ptr; - if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || + unsigned PtrTypeID, ValTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, PtrTypeID) || !isa(Ptr->getType()) || (BitCode == bitc::FUNC_CODE_INST_STOREATOMIC - ? getValueTypePair(Record, OpNum, NextValueNo, Val) + ? getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID) : popValue(Record, OpNum, NextValueNo, - Ptr->getType()->getPointerElementType(), Val)) || + Ptr->getType()->getPointerElementType(), + getContainedTypeID(PtrTypeID), Val)) || OpNum + 4 != Record.size()) return error("Invalid record"); @@ -5253,20 +5353,23 @@ 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)) return error("Invalid record"); if (!isa(Ptr->getType())) return error("Cmpxchg operand is not a pointer type"); Value *Cmp = nullptr; + unsigned CmpTypeID = getContainedTypeID(PtrTypeID); if (popValue(Record, OpNum, NextValueNo, cast(Ptr->getType())->getPointerElementType(), - Cmp)) + CmpTypeID, Cmp)) return error("Invalid record"); Value *New = nullptr; - if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), New) || + if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), CmpTypeID, + New) || NumRecords < OpNum + 3 || NumRecords > OpNum + 5) return error("Invalid record"); @@ -5295,6 +5398,7 @@ I = new AtomicCmpXchgInst(Ptr, Cmp, New, Alignment, SuccessOrdering, FailureOrdering, SSID); + ResTypeID = TODOTypeID; cast(I)->setVolatile(Record[OpNum]); if (NumRecords < 8) { @@ -5303,6 +5407,7 @@ // expecting the first component of a modern cmpxchg. CurBB->getInstList().push_back(I); I = ExtractValueInst::Create(I, 0); + ResTypeID = TODOTypeID; } else { cast(I)->setWeak(Record[OpNum + 4]); } @@ -5316,18 +5421,20 @@ 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)) return error("Invalid record"); if (!isa(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)) return error("Invalid record"); Value *Val = nullptr; - if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), Val)) + if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), CmpTypeID, Val)) return error("Invalid record"); if (NumRecords < OpNum + 3 || NumRecords > OpNum + 6) @@ -5366,6 +5473,7 @@ FailureOrdering, SSID); cast(I)->setVolatile(IsVol); cast(I)->setWeak(IsWeak); + ResTypeID = TODOTypeID; InstructionList.push_back(I); break; @@ -5378,7 +5486,8 @@ unsigned OpNum = 0; Value *Ptr = nullptr; - if (getValueTypePair(Record, OpNum, NextValueNo, Ptr)) + unsigned PtrTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, PtrTypeID)) return error("Invalid record"); if (!isa(Ptr->getType())) @@ -5388,10 +5497,11 @@ if (BitCode == bitc::FUNC_CODE_INST_ATOMICRMW_OLD) { if (popValue(Record, OpNum, NextValueNo, cast(Ptr->getType())->getPointerElementType(), - Val)) + getContainedTypeID(PtrTypeID), Val)) return error("Invalid record"); } else { - if (getValueTypePair(Record, OpNum, NextValueNo, Val)) + unsigned ValTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID)) return error("Invalid record"); } @@ -5425,6 +5535,7 @@ Align(TheModule->getDataLayout().getTypeStoreSize(Val->getType())); I = new AtomicRMWInst(Operation, Ptr, Val, *Alignment, Ordering, SSID); + ResTypeID = TODOTypeID; cast(I)->setVolatile(IsVol); InstructionList.push_back(I); @@ -5467,7 +5578,8 @@ } Value *Callee; - if (getValueTypePair(Record, OpNum, NextValueNo, Callee)) + unsigned CalleeTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Callee, CalleeTypeID)) return error("Invalid record"); PointerType *OpTy = dyn_cast(Callee->getType()); @@ -5492,7 +5604,7 @@ Args.push_back(getBasicBlock(Record[OpNum])); else Args.push_back(getValue(Record, OpNum, NextValueNo, - FTy->getParamType(i))); + FTy->getParamType(i), TODOTypeID)); ArgsTys.push_back(FTy->getParamType(i)); if (!Args.back()) return error("Invalid record"); @@ -5505,7 +5617,8 @@ } else { while (OpNum != Record.size()) { Value *Op; - if (getValueTypePair(Record, OpNum, NextValueNo, Op)) + unsigned OpTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID)) return error("Invalid record"); Args.push_back(Op); ArgsTys.push_back(Op->getType()); @@ -5513,6 +5626,7 @@ } I = CallInst::Create(FTy, Callee, Args, OperandBundles); + ResTypeID = TODOTypeID; OperandBundles.clear(); InstructionList.push_back(I); cast(I)->setCallingConv( @@ -5538,9 +5652,11 @@ 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); + ResTypeID = Record[2]; + Type *ResTy = getTypeByID(ResTypeID); if (!OpTy || !Op || !ResTy) return error("Invalid record"); I = new VAArgInst(Op, ResTy); @@ -5561,7 +5677,8 @@ unsigned OpNum = 1; while (OpNum != Record.size()) { Value *Op; - if (getValueTypePair(Record, OpNum, NextValueNo, Op)) + unsigned OpTypeID; + if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID)) return error("Invalid record"); Inputs.push_back(Op); } @@ -5573,12 +5690,14 @@ 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)) return error("Invalid record"); if (OpNum != Record.size()) return error("Invalid record"); I = new FreezeInst(Op); + ResTypeID = OpTypeID; InstructionList.push_back(I); break; } @@ -5603,8 +5722,10 @@ } // Non-void values get registered in the value table for future use. - if (!I->getType()->isVoidTy()) - ValueList.assignValue(NextValueNo++, I); + if (!I->getType()->isVoidTy()) { + assert(ResTypeID != InvalidTypeID && "Should have ID for non-void type"); + ValueList.assignValue(NextValueNo++, I, ResTypeID); + } } OutOfRecordLoop: diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1219,14 +1219,15 @@ break; } - Type *Ty = getTypeByID(Record[0]); + unsigned TyID = Record[0]; + Type *Ty = getTypeByID(TyID); if (Ty->isMetadataTy() || Ty->isVoidTy()) { dropRecord(); break; } MetadataList.assignValue( - LocalAsMetadata::get(ValueList.getValueFwdRef(Record[1], Ty)), + LocalAsMetadata::get(ValueList.getValueFwdRef(Record[1], Ty, TyID)), NextMetadataNo); NextMetadataNo++; break; @@ -1239,14 +1240,15 @@ unsigned Size = Record.size(); SmallVector Elts; for (unsigned i = 0; i != Size; i += 2) { - Type *Ty = getTypeByID(Record[i]); + unsigned TyID = Record[i]; + Type *Ty = getTypeByID(TyID); if (!Ty) return error("Invalid record"); if (Ty->isMetadataTy()) Elts.push_back(getMD(Record[i + 1])); else if (!Ty->isVoidTy()) { - auto *MD = - ValueAsMetadata::get(ValueList.getValueFwdRef(Record[i + 1], Ty)); + auto *MD = ValueAsMetadata::get( + ValueList.getValueFwdRef(Record[i + 1], Ty, TyID)); assert(isa(MD) && "Expected non-function-local metadata"); Elts.push_back(MD); @@ -1261,12 +1263,13 @@ if (Record.size() != 2) return error("Invalid record"); - Type *Ty = getTypeByID(Record[0]); + unsigned TyID = Record[0]; + Type *Ty = getTypeByID(TyID); if (Ty->isMetadataTy() || Ty->isVoidTy()) return error("Invalid record"); MetadataList.assignValue( - ValueAsMetadata::get(ValueList.getValueFwdRef(Record[1], Ty)), + ValueAsMetadata::get(ValueList.getValueFwdRef(Record[1], Ty, TyID)), NextMetadataNo); NextMetadataNo++; break; diff --git a/llvm/lib/Bitcode/Reader/ValueList.h b/llvm/lib/Bitcode/Reader/ValueList.h --- a/llvm/lib/Bitcode/Reader/ValueList.h +++ b/llvm/lib/Bitcode/Reader/ValueList.h @@ -26,7 +26,8 @@ class Value; class BitcodeReaderValueList { - std::vector ValuePtrs; + /// Maps Value ID to pair of Value* and Type ID. + std::vector> ValuePtrs; /// As we resolve forward-referenced constants, we add information about them /// to this vector. This allows us to resolve them in bulk instead of @@ -58,7 +59,9 @@ void resize(unsigned N) { ValuePtrs.resize(N); } - void push_back(Value *V) { ValuePtrs.emplace_back(V); } + void push_back(Value *V, unsigned TypeID) { + ValuePtrs.emplace_back(V, TypeID); + } void clear() { assert(ResolveConstants.empty() && "Constants not resolved?"); @@ -67,10 +70,15 @@ Value *operator[](unsigned i) const { assert(i < ValuePtrs.size()); - return ValuePtrs[i]; + return ValuePtrs[i].first; + } + + unsigned getTypeID(unsigned ValNo) const { + assert(ValNo < ValuePtrs.size()); + return ValuePtrs[ValNo].second; } - Value *back() const { return ValuePtrs.back(); } + Value *back() const { return ValuePtrs.back().first; } void pop_back() { ValuePtrs.pop_back(); } @@ -81,10 +89,10 @@ ValuePtrs.resize(N); } - Constant *getConstantFwdRef(unsigned Idx, Type *Ty); - Value *getValueFwdRef(unsigned Idx, Type *Ty); + Constant *getConstantFwdRef(unsigned Idx, Type *Ty, unsigned TyID); + Value *getValueFwdRef(unsigned Idx, Type *Ty, unsigned TyID); - void assignValue(unsigned Idx, Value *V); + void assignValue(unsigned Idx, Value *V, unsigned TypeID); /// Once all constants are read, this method bulk resolves any forward /// references. diff --git a/llvm/lib/Bitcode/Reader/ValueList.cpp b/llvm/lib/Bitcode/Reader/ValueList.cpp --- a/llvm/lib/Bitcode/Reader/ValueList.cpp +++ b/llvm/lib/Bitcode/Reader/ValueList.cpp @@ -60,35 +60,39 @@ } // end namespace llvm -void BitcodeReaderValueList::assignValue(unsigned Idx, Value *V) { +void BitcodeReaderValueList::assignValue(unsigned Idx, Value *V, + unsigned TypeID) { if (Idx == size()) { - push_back(V); + push_back(V, TypeID); return; } if (Idx >= size()) resize(Idx + 1); - WeakTrackingVH &OldV = ValuePtrs[Idx]; - if (!OldV) { - OldV = V; + auto &Old = ValuePtrs[Idx]; + if (!Old.first) { + Old.first = V; + Old.second = TypeID; return; } // Handle constants and non-constants (e.g. instrs) differently for // efficiency. - if (Constant *PHC = dyn_cast(&*OldV)) { + if (Constant *PHC = dyn_cast(&*Old.first)) { ResolveConstants.push_back(std::make_pair(PHC, Idx)); - OldV = V; + Old.first = V; + Old.second = TypeID; } else { // If there was a forward reference to this value, replace it. - Value *PrevVal = OldV; - OldV->replaceAllUsesWith(V); + Value *PrevVal = Old.first; + Old.first->replaceAllUsesWith(V); PrevVal->deleteValue(); } } -Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx, Type *Ty) { +Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx, Type *Ty, + unsigned TyID) { // Bail out for a clearly invalid value. if (Idx >= RefsUpperBound) return nullptr; @@ -96,7 +100,7 @@ if (Idx >= size()) resize(Idx + 1); - if (Value *V = ValuePtrs[Idx]) { + if (Value *V = ValuePtrs[Idx].first) { if (Ty != V->getType()) report_fatal_error("Type mismatch in constant table!"); return cast(V); @@ -104,11 +108,12 @@ // Create and return a placeholder, which will later be RAUW'd. Constant *C = new ConstantPlaceHolder(Ty, Context); - ValuePtrs[Idx] = C; + ValuePtrs[Idx] = {C, TyID}; return C; } -Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty) { +Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty, + unsigned TyID) { // Bail out for a clearly invalid value. if (Idx >= RefsUpperBound) return nullptr; @@ -116,7 +121,7 @@ if (Idx >= size()) resize(Idx + 1); - if (Value *V = ValuePtrs[Idx]) { + if (Value *V = ValuePtrs[Idx].first) { // If the types don't match, it's invalid. if (Ty && Ty != V->getType()) return nullptr; @@ -129,7 +134,7 @@ // Create and return a placeholder, which will later be RAUW'd. Value *V = new Argument(Ty); - ValuePtrs[Idx] = V; + ValuePtrs[Idx] = {V, TyID}; return V; }