diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/InlineCost.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 184 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.h | 25 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 154 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/CodeGen/WinEHPrepare.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 22 | ||||
-rw-r--r-- | llvm/lib/IR/Instruction.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/IR/Instructions.cpp | 102 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 47 | ||||
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp | 12 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/InlineFunction.cpp | 3 |
12 files changed, 334 insertions, 236 deletions
diff --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp index 40bfac56719..32dc50ae62c 100644 --- a/llvm/lib/Analysis/InlineCost.cpp +++ b/llvm/lib/Analysis/InlineCost.cpp @@ -913,7 +913,7 @@ bool CallAnalyzer::visitCleanupReturnInst(CleanupReturnInst &CRI) { bool CallAnalyzer::visitCatchReturnInst(CatchReturnInst &CRI) { // FIXME: It's not clear that a single instruction is an accurate model for - // the inline cost of a cleanupret instruction. + // the inline cost of a catchret instruction. return false; } diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index fc7fceb2a26..082637bf0b8 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -2237,8 +2237,8 @@ bool LLParser::PerFunctionState::FinishFunction() { /// GetVal - Get a value with the specified name or ID, creating a /// forward reference record if needed. This can return null if the value /// exists but does not have the right type. -Value *LLParser::PerFunctionState::GetVal(const std::string &Name, - Type *Ty, LocTy Loc) { +Value *LLParser::PerFunctionState::GetVal(const std::string &Name, Type *Ty, + LocTy Loc, OperatorConstraint OC) { // Look this name up in the normal function symbol table. Value *Val = F.getValueSymbolTable().lookup(Name); @@ -2253,6 +2253,24 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name, // If we have the value in the symbol table or fwd-ref table, return it. if (Val) { + // Check operator constraints. + switch (OC) { + case OC_None: + // no constraint + break; + case OC_CatchPad: + if (!isa<CatchPadInst>(Val)) { + P.Error(Loc, "'%" + Name + "' is not a catchpad"); + return nullptr; + } + break; + case OC_CleanupPad: + if (!isa<CleanupPadInst>(Val)) { + P.Error(Loc, "'%" + Name + "' is not a cleanuppad"); + return nullptr; + } + break; + } if (Val->getType() == Ty) return Val; if (Ty->isLabelTy()) P.Error(Loc, "'%" + Name + "' is not a basic block"); @@ -2270,17 +2288,31 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name, // Otherwise, create a new forward reference for this value and remember it. Value *FwdVal; - if (Ty->isLabelTy()) + if (Ty->isLabelTy()) { + assert(!OC); FwdVal = BasicBlock::Create(F.getContext(), Name, &F); - else + } else if (!OC) { FwdVal = new Argument(Ty, Name); + } else { + switch (OC) { + case OC_CatchPad: + FwdVal = CatchPadInst::Create(&F.getEntryBlock(), &F.getEntryBlock(), {}, + Name); + break; + case OC_CleanupPad: + FwdVal = CleanupPadInst::Create(F.getContext(), {}, Name); + break; + default: + llvm_unreachable("unexpected constraint"); + } + } ForwardRefVals[Name] = std::make_pair(FwdVal, Loc); return FwdVal; } -Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, - LocTy Loc) { +Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, LocTy Loc, + OperatorConstraint OC) { // Look this name up in the normal function symbol table. Value *Val = ID < NumberedVals.size() ? NumberedVals[ID] : nullptr; @@ -2295,6 +2327,24 @@ Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, // If we have the value in the symbol table or fwd-ref table, return it. if (Val) { + // Check operator constraint. + switch (OC) { + case OC_None: + // no constraint + break; + case OC_CatchPad: + if (!isa<CatchPadInst>(Val)) { + P.Error(Loc, "'%" + Twine(ID) + "' is not a catchpad"); + return nullptr; + } + break; + case OC_CleanupPad: + if (!isa<CleanupPadInst>(Val)) { + P.Error(Loc, "'%" + Twine(ID) + "' is not a cleanuppad"); + return nullptr; + } + break; + } if (Val->getType() == Ty) return Val; if (Ty->isLabelTy()) P.Error(Loc, "'%" + Twine(ID) + "' is not a basic block"); @@ -2311,10 +2361,23 @@ Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, // Otherwise, create a new forward reference for this value and remember it. Value *FwdVal; - if (Ty->isLabelTy()) + if (Ty->isLabelTy()) { + assert(!OC); FwdVal = BasicBlock::Create(F.getContext(), "", &F); - else + } else if (!OC) { FwdVal = new Argument(Ty); + } else { + switch (OC) { + case OC_CatchPad: + FwdVal = CatchPadInst::Create(&F.getEntryBlock(), &F.getEntryBlock(), {}); + break; + case OC_CleanupPad: + FwdVal = CleanupPadInst::Create(F.getContext(), {}); + break; + default: + llvm_unreachable("unexpected constraint"); + } + } ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc); return FwdVal; @@ -2346,11 +2409,24 @@ bool LLParser::PerFunctionState::SetInstName(int NameID, std::map<unsigned, std::pair<Value*, LocTy> >::iterator FI = ForwardRefValIDs.find(NameID); if (FI != ForwardRefValIDs.end()) { - if (FI->second.first->getType() != Inst->getType()) + Value *Sentinel = FI->second.first; + if (Sentinel->getType() != Inst->getType()) return P.Error(NameLoc, "instruction forward referenced with type '" + getTypeString(FI->second.first->getType()) + "'"); - FI->second.first->replaceAllUsesWith(Inst); - delete FI->second.first; + // Check operator constraints. We only put cleanuppads or catchpads in + // the forward value map if the value is constrained to match. + if (isa<CatchPadInst>(Sentinel)) { + if (!isa<CatchPadInst>(Inst)) + return P.Error(FI->second.second, + "'%" + Twine(NameID) + "' is not a catchpad"); + } else if (isa<CleanupPadInst>(Sentinel)) { + if (!isa<CleanupPadInst>(Inst)) + return P.Error(FI->second.second, + "'%" + Twine(NameID) + "' is not a cleanuppad"); + } + + Sentinel->replaceAllUsesWith(Inst); + delete Sentinel; ForwardRefValIDs.erase(FI); } @@ -2362,11 +2438,24 @@ bool LLParser::PerFunctionState::SetInstName(int NameID, std::map<std::string, std::pair<Value*, LocTy> >::iterator FI = ForwardRefVals.find(NameStr); if (FI != ForwardRefVals.end()) { - if (FI->second.first->getType() != Inst->getType()) + Value *Sentinel = FI->second.first; + if (Sentinel->getType() != Inst->getType()) return P.Error(NameLoc, "instruction forward referenced with type '" + getTypeString(FI->second.first->getType()) + "'"); - FI->second.first->replaceAllUsesWith(Inst); - delete FI->second.first; + // Check operator constraints. We only put cleanuppads or catchpads in + // the forward value map if the value is constrained to match. + if (isa<CatchPadInst>(Sentinel)) { + if (!isa<CatchPadInst>(Inst)) + return P.Error(FI->second.second, + "'%" + NameStr + "' is not a catchpad"); + } else if (isa<CleanupPadInst>(Sentinel)) { + if (!isa<CleanupPadInst>(Inst)) + return P.Error(FI->second.second, + "'%" + NameStr + "' is not a cleanuppad"); + } + + Sentinel->replaceAllUsesWith(Inst); + delete Sentinel; ForwardRefVals.erase(FI); } @@ -4007,18 +4096,30 @@ bool LLParser::ParseMetadata(Metadata *&MD, PerFunctionState *PFS) { //===----------------------------------------------------------------------===// bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, - PerFunctionState *PFS) { + PerFunctionState *PFS, + OperatorConstraint OC) { if (Ty->isFunctionTy()) return Error(ID.Loc, "functions are not values, refer to them as pointers"); + if (OC && ID.Kind != ValID::t_LocalID && ID.Kind != ValID::t_LocalName) { + switch (OC) { + case OC_CatchPad: + return Error(ID.Loc, "Catchpad value required in this position"); + case OC_CleanupPad: + return Error(ID.Loc, "Cleanuppad value required in this position"); + default: + llvm_unreachable("Unexpected constraint kind"); + } + } + switch (ID.Kind) { case ValID::t_LocalID: if (!PFS) return Error(ID.Loc, "invalid use of function-local name"); - V = PFS->GetVal(ID.UIntVal, Ty, ID.Loc); + V = PFS->GetVal(ID.UIntVal, Ty, ID.Loc, OC); return V == nullptr; case ValID::t_LocalName: if (!PFS) return Error(ID.Loc, "invalid use of function-local name"); - V = PFS->GetVal(ID.StrVal, Ty, ID.Loc); + V = PFS->GetVal(ID.StrVal, Ty, ID.Loc, OC); return V == nullptr; case ValID::t_InlineAsm: { assert(ID.FTy); @@ -4140,11 +4241,11 @@ bool LLParser::parseConstantValue(Type *Ty, Constant *&C) { } } -bool LLParser::ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS) { +bool LLParser::ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS, + OperatorConstraint OC) { V = nullptr; ValID ID; - return ParseValID(ID, PFS) || - ConvertValIDToValue(Ty, ID, V, PFS); + return ParseValID(ID, PFS) || ConvertValIDToValue(Ty, ID, V, PFS, OC); } bool LLParser::ParseTypeAndValue(Value *&V, PerFunctionState *PFS) { @@ -4985,7 +5086,7 @@ bool LLParser::ParseResume(Instruction *&Inst, PerFunctionState &PFS) { bool LLParser::ParseExceptionArgs(SmallVectorImpl<Value *> &Args, PerFunctionState &PFS) { - if (ParseToken(lltok::lsquare, "expected '[' in cleanuppad")) + if (ParseToken(lltok::lsquare, "expected '[' in catchpad/cleanuppad")) return true; while (Lex.getKind() != lltok::rsquare) { @@ -5016,16 +5117,12 @@ bool LLParser::ParseExceptionArgs(SmallVectorImpl<Value *> &Args, } /// ParseCleanupRet -/// ::= 'cleanupret' ('void' | TypeAndValue) unwind ('to' 'caller' | TypeAndValue) +/// ::= 'cleanupret' Value unwind ('to' 'caller' | TypeAndValue) bool LLParser::ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) { - Type *RetTy = nullptr; - Value *RetVal = nullptr; - if (ParseType(RetTy, /*AllowVoid=*/true)) - return true; + Value *CleanupPad = nullptr; - if (!RetTy->isVoidTy()) - if (ParseValue(RetTy, RetVal, PFS)) - return true; + if (ParseValue(Type::getTokenTy(Context), CleanupPad, PFS, OC_CleanupPad)) + return true; if (ParseToken(lltok::kw_unwind, "expected 'unwind' in cleanupret")) return true; @@ -5041,39 +5138,32 @@ bool LLParser::ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) { } } - Inst = CleanupReturnInst::Create(Context, RetVal, UnwindBB); + Inst = CleanupReturnInst::Create(cast<CleanupPadInst>(CleanupPad), UnwindBB); return false; } /// ParseCatchRet -/// ::= 'catchret' ('void' | TypeAndValue) 'to' TypeAndValue +/// ::= 'catchret' Value 'to' TypeAndValue bool LLParser::ParseCatchRet(Instruction *&Inst, PerFunctionState &PFS) { - Type *RetTy = nullptr; - Value *RetVal = nullptr; + Value *CatchPad = nullptr; - if (ParseType(RetTy, /*AllowVoid=*/true)) + if (ParseValue(Type::getTokenTy(Context), CatchPad, PFS, OC_CatchPad)) return true; - if (!RetTy->isVoidTy()) - if (ParseValue(RetTy, RetVal, PFS)) - return true; - BasicBlock *BB; if (ParseToken(lltok::kw_to, "expected 'to' in catchret") || ParseTypeAndBasicBlock(BB, PFS)) return true; - Inst = CatchReturnInst::Create(BB, RetVal); + Inst = CatchReturnInst::Create(cast<CatchPadInst>(CatchPad), BB); return false; } /// ParseCatchPad -/// ::= 'catchpad' Type ParamList 'to' TypeAndValue 'unwind' TypeAndValue +/// ::= 'catchpad' ParamList 'to' TypeAndValue 'unwind' TypeAndValue bool LLParser::ParseCatchPad(Instruction *&Inst, PerFunctionState &PFS) { - Type *RetType = nullptr; - SmallVector<Value *, 8> Args; - if (ParseType(RetType, /*AllowVoid=*/true) || ParseExceptionArgs(Args, PFS)) + if (ParseExceptionArgs(Args, PFS)) return true; BasicBlock *NormalBB, *UnwindBB; @@ -5083,7 +5173,7 @@ bool LLParser::ParseCatchPad(Instruction *&Inst, PerFunctionState &PFS) { ParseTypeAndBasicBlock(UnwindBB, PFS)) return true; - Inst = CatchPadInst::Create(RetType, NormalBB, UnwindBB, Args); + Inst = CatchPadInst::Create(NormalBB, UnwindBB, Args); return false; } @@ -5115,13 +5205,11 @@ bool LLParser::ParseTerminatePad(Instruction *&Inst, PerFunctionState &PFS) { /// ParseCleanupPad /// ::= 'cleanuppad' ParamList bool LLParser::ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS) { - Type *RetType = nullptr; - SmallVector<Value *, 8> Args; - if (ParseType(RetType, /*AllowVoid=*/true) || ParseExceptionArgs(Args, PFS)) + if (ParseExceptionArgs(Args, PFS)) return true; - Inst = CleanupPadInst::Create(RetType, Args); + Inst = CleanupPadInst::Create(Context, Args); return false; } diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h index 96fb06a1f29..8b7e9560a69 100644 --- a/llvm/lib/AsmParser/LLParser.h +++ b/llvm/lib/AsmParser/LLParser.h @@ -108,6 +108,14 @@ namespace llvm { unsigned MDKind, MDSlot; }; + /// Indicates which operator an operand allows (for the few operands that + /// may only reference a certain operator). + enum OperatorConstraint { + OC_None = 0, // No constraint + OC_CatchPad, // Must be CatchPadInst + OC_CleanupPad // Must be CleanupPadInst + }; + SmallVector<Instruction*, 64> InstsWithTBAATag; // Type resolution handling data structures. The location is set when we @@ -329,8 +337,10 @@ namespace llvm { /// GetVal - Get a value with the specified name or ID, creating a /// forward reference record if needed. This can return null if the value /// exists but does not have the right type. - Value *GetVal(const std::string &Name, Type *Ty, LocTy Loc); - Value *GetVal(unsigned ID, Type *Ty, LocTy Loc); + Value *GetVal(const std::string &Name, Type *Ty, LocTy Loc, + OperatorConstraint OC = OC_None); + Value *GetVal(unsigned ID, Type *Ty, LocTy Loc, + OperatorConstraint OC = OC_None); /// SetInstName - After an instruction is parsed and inserted into its /// basic block, this installs its name. @@ -352,12 +362,15 @@ namespace llvm { }; bool ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, - PerFunctionState *PFS); + PerFunctionState *PFS, + OperatorConstraint OC = OC_None); bool parseConstantValue(Type *Ty, Constant *&C); - bool ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS); - bool ParseValue(Type *Ty, Value *&V, PerFunctionState &PFS) { - return ParseValue(Ty, V, &PFS); + bool ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS, + OperatorConstraint OC = OC_None); + bool ParseValue(Type *Ty, Value *&V, PerFunctionState &PFS, + OperatorConstraint OC = OC_None) { + return ParseValue(Ty, V, &PFS, OC); } bool ParseValue(Type *Ty, Value *&V, LocTy &Loc, PerFunctionState &PFS) { diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index b379e59236d..7ede794bc76 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -41,6 +41,14 @@ enum { SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex }; +/// Indicates which operator an operand allows (for the few operands that may +/// only reference a certain operator). +enum OperatorConstraint { + OC_None = 0, // No constraint + OC_CatchPad, // Must be CatchPadInst + OC_CleanupPad // Must be CleanupPadInst +}; + class BitcodeReaderValueList { std::vector<WeakVH> ValuePtrs; @@ -84,9 +92,10 @@ public: } Constant *getConstantFwdRef(unsigned Idx, Type *Ty); - Value *getValueFwdRef(unsigned Idx, Type *Ty); + Value *getValueFwdRef(unsigned Idx, Type *Ty, + OperatorConstraint OC = OC_None); - void assignValue(Value *V, unsigned Idx); + bool assignValue(Value *V, unsigned Idx); /// Once all constants are read, this method bulk resolves any forward /// references. @@ -262,10 +271,11 @@ private: StructType *createIdentifiedStructType(LLVMContext &Context); Type *getTypeByID(unsigned ID); - Value *getFnValueByID(unsigned ID, Type *Ty) { + Value *getFnValueByID(unsigned ID, Type *Ty, + OperatorConstraint OC = OC_None) { if (Ty && Ty->isMetadataTy()) return MetadataAsValue::get(Ty->getContext(), getFnMetadataByID(ID)); - return ValueList.getValueFwdRef(ID, Ty); + return ValueList.getValueFwdRef(ID, Ty, OC); } Metadata *getFnMetadataByID(unsigned ID) { return MDValueList.getValueFwdRef(ID); @@ -308,8 +318,9 @@ private: /// past the number of slots used by the value in the record. Return true if /// there is an error. bool popValue(SmallVectorImpl<uint64_t> &Record, unsigned &Slot, - unsigned InstNum, Type *Ty, Value *&ResVal) { - if (getValue(Record, Slot, InstNum, Ty, ResVal)) + unsigned InstNum, Type *Ty, Value *&ResVal, + OperatorConstraint OC = OC_None) { + if (getValue(Record, Slot, InstNum, Ty, ResVal, OC)) return true; // All values currently take a single record slot. ++Slot; @@ -318,32 +329,34 @@ private: /// Like popValue, but does not increment the Slot number. bool getValue(SmallVectorImpl<uint64_t> &Record, unsigned Slot, - unsigned InstNum, Type *Ty, Value *&ResVal) { - ResVal = getValue(Record, Slot, InstNum, Ty); + unsigned InstNum, Type *Ty, Value *&ResVal, + OperatorConstraint OC = OC_None) { + ResVal = getValue(Record, Slot, InstNum, Ty, OC); return ResVal == nullptr; } /// Version of getValue that returns ResVal directly, or 0 if there is an /// error. Value *getValue(SmallVectorImpl<uint64_t> &Record, unsigned Slot, - unsigned InstNum, Type *Ty) { + unsigned InstNum, Type *Ty, OperatorConstraint OC = OC_None) { 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, OC); } /// Like getValue, but decodes signed VBRs. Value *getValueSigned(SmallVectorImpl<uint64_t> &Record, unsigned Slot, - unsigned InstNum, Type *Ty) { + unsigned InstNum, Type *Ty, + OperatorConstraint OC = OC_None) { 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, OC); } /// Converts alignment exponent (i.e. power of two (or zero)) to the @@ -753,10 +766,10 @@ struct OperandTraits<ConstantPlaceHolder> : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantPlaceHolder, Value) } -void BitcodeReaderValueList::assignValue(Value *V, unsigned Idx) { +bool BitcodeReaderValueList::assignValue(Value *V, unsigned Idx) { if (Idx == size()) { push_back(V); - return; + return false; } if (Idx >= size()) @@ -765,7 +778,7 @@ void BitcodeReaderValueList::assignValue(Value *V, unsigned Idx) { WeakVH &OldV = ValuePtrs[Idx]; if (!OldV) { OldV = V; - return; + return false; } // Handle constants and non-constants (e.g. instrs) differently for @@ -776,9 +789,26 @@ void BitcodeReaderValueList::assignValue(Value *V, unsigned Idx) { } else { // If there was a forward reference to this value, replace it. Value *PrevVal = OldV; + // Check operator constraints. We only put cleanuppads or catchpads in + // the forward value map if the value is constrained to match. + if (CatchPadInst *CatchPad = dyn_cast<CatchPadInst>(PrevVal)) { + if (!isa<CatchPadInst>(V)) + return true; + // Delete the dummy basic block that was created with the sentinel + // catchpad. + BasicBlock *DummyBlock = CatchPad->getUnwindDest(); + assert(DummyBlock == CatchPad->getNormalDest()); + CatchPad->dropAllReferences(); + delete DummyBlock; + } else if (isa<CleanupPadInst>(PrevVal)) { + if (!isa<CleanupPadInst>(V)) + return true; + } OldV->replaceAllUsesWith(V); delete PrevVal; } + + return false; } @@ -799,7 +829,8 @@ Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx, return C; } -Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty) { +Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty, + OperatorConstraint OC) { // Bail out for a clearly invalid value. This would make us call resize(0) if (Idx == UINT_MAX) return nullptr; @@ -811,14 +842,39 @@ Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty) { // If the types don't match, it's invalid. if (Ty && Ty != V->getType()) return nullptr; - return V; + if (!OC) + return V; + // Use dyn_cast to enforce operator constraints + switch (OC) { + case OC_CatchPad: + return dyn_cast<CatchPadInst>(V); + case OC_CleanupPad: + return dyn_cast<CleanupPadInst>(V); + default: + llvm_unreachable("Unexpected operator constraint"); + } } // No type specified, must be invalid reference. if (!Ty) return nullptr; // Create and return a placeholder, which will later be RAUW'd. - Value *V = new Argument(Ty); + Value *V; + switch (OC) { + case OC_None: + V = new Argument(Ty); + break; + case OC_CatchPad: { + BasicBlock *BB = BasicBlock::Create(Context); + V = CatchPadInst::Create(BB, BB, {}); + break; + } + default: + assert(OC == OC_CleanupPad && "unexpected operator constraint"); + V = CleanupPadInst::Create(Context, {}); + break; + } + ValuePtrs[Idx] = V; return V; } @@ -2610,7 +2666,8 @@ std::error_code BitcodeReader::parseConstants() { } } - ValueList.assignValue(V, NextCstNo); + if (ValueList.assignValue(V, NextCstNo)) + return error("Invalid forward reference"); ++NextCstNo; } } @@ -3819,56 +3876,47 @@ std::error_code BitcodeReader::parseFunctionBody(Function *F) { } break; } - // CLEANUPRET: [] or [ty,val] or [bb#] or [ty,val,bb#] + // CLEANUPRET: [val] or [val,bb#] case bitc::FUNC_CODE_INST_CLEANUPRET: { - if (Record.size() < 2) + if (Record.size() != 1 && Record.size() != 2) return error("Invalid record"); unsigned Idx = 0; - bool HasReturnValue = !!Record[Idx++]; - bool HasUnwindDest = !!Record[Idx++]; - Value *RetVal = nullptr; - BasicBlock *UnwindDest = nullptr; - - if (HasReturnValue && getValueTypePair(Record, Idx, NextValueNo, RetVal)) + Value *CleanupPad = getValue(Record, Idx++, NextValueNo, + Type::getTokenTy(Context), OC_CleanupPad); + if (!CleanupPad) return error("Invalid record"); - if (HasUnwindDest) { - if (Idx == Record.size()) - return error("Invalid record"); + BasicBlock *UnwindDest = nullptr; + if (Record.size() == 2) { UnwindDest = getBasicBlock(Record[Idx++]); if (!UnwindDest) return error("Invalid record"); } - if (Record.size() != Idx) - return error("Invalid record"); - - I = CleanupReturnInst::Create(Context, RetVal, UnwindDest); + I = CleanupReturnInst::Create(cast<CleanupPadInst>(CleanupPad), + UnwindDest); InstructionList.push_back(I); break; } - case bitc::FUNC_CODE_INST_CATCHRET: { // CATCHRET: [bb#] - if (Record.size() != 1 && Record.size() != 3) + case bitc::FUNC_CODE_INST_CATCHRET: { // CATCHRET: [val,bb#] + if (Record.size() != 2) return error("Invalid record"); unsigned Idx = 0; + Value *CatchPad = getValue(Record, Idx++, NextValueNo, + Type::getTokenTy(Context), OC_CatchPad); + if (!CatchPad) + return error("Invalid record"); BasicBlock *BB = getBasicBlock(Record[Idx++]); if (!BB) return error("Invalid record"); - Value *RetVal = nullptr; - if (Record.size() == 3 && - getValueTypePair(Record, Idx, NextValueNo, RetVal)) - return error("Invalid record"); - I = CatchReturnInst::Create(BB, RetVal); + I = CatchReturnInst::Create(cast<CatchPadInst>(CatchPad), BB); InstructionList.push_back(I); break; } - case bitc::FUNC_CODE_INST_CATCHPAD: { // CATCHPAD: [ty,bb#,bb#,num,(ty,val)*] - if (Record.size() < 4) + case bitc::FUNC_CODE_INST_CATCHPAD: { // CATCHPAD: [bb#,bb#,num,(ty,val)*] + if (Record.size() < 3) return error("Invalid record"); unsigned Idx = 0; - Type *Ty = getTypeByID(Record[Idx++]); - if (!Ty) - return error("Invalid record"); BasicBlock *NormalBB = getBasicBlock(Record[Idx++]); if (!NormalBB) return error("Invalid record"); @@ -3886,7 +3934,7 @@ std::error_code BitcodeReader::parseFunctionBody(Function *F) { if (Record.size() != Idx) return error("Invalid record"); - I = CatchPadInst::Create(Ty, NormalBB, UnwindBB, Args); + I = CatchPadInst::Create(NormalBB, UnwindBB, Args); InstructionList.push_back(I); break; } @@ -3918,13 +3966,10 @@ std::error_code BitcodeReader::parseFunctionBody(Function *F) { InstructionList.push_back(I); break; } - case bitc::FUNC_CODE_INST_CLEANUPPAD: { // CLEANUPPAD: [ty, num,(ty,val)*] - if (Record.size() < 2) + case bitc::FUNC_CODE_INST_CLEANUPPAD: { // CLEANUPPAD: [num,(ty,val)*] + if (Record.size() < 1) return error("Invalid record"); unsigned Idx = 0; - Type *Ty = getTypeByID(Record[Idx++]); - if (!Ty) - return error("Invalid record"); unsigned NumArgOperands = Record[Idx++]; SmallVector<Value *, 2> Args; for (unsigned Op = 0; Op != NumArgOperands; ++Op) { @@ -3936,7 +3981,7 @@ std::error_code BitcodeReader::parseFunctionBody(Function *F) { if (Record.size() != Idx) return error("Invalid record"); - I = CleanupPadInst::Create(Ty, Args); + I = CleanupPadInst::Create(Context, Args); InstructionList.push_back(I); break; } @@ -4541,7 +4586,8 @@ std::error_code BitcodeReader::parseFunctionBody(Function *F) { // Non-void values get registered in the value table for future use. if (I && !I->getType()->isVoidTy()) - ValueList.assignValue(I, NextValueNo++); + if (ValueList.assignValue(I, NextValueNo++)) + return error("Invalid forward reference"); } OutOfRecordLoop: diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 87b02e3dca4..c0eb5d497bc 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1855,10 +1855,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, case Instruction::CleanupRet: { Code = bitc::FUNC_CODE_INST_CLEANUPRET; const auto &CRI = cast<CleanupReturnInst>(I); - Vals.push_back(CRI.hasReturnValue()); - Vals.push_back(CRI.hasUnwindDest()); - if (CRI.hasReturnValue()) - PushValueAndType(CRI.getReturnValue(), InstID, Vals, VE); + pushValue(CRI.getCleanupPad(), InstID, Vals, VE); if (CRI.hasUnwindDest()) Vals.push_back(VE.getValueID(CRI.getUnwindDest())); break; @@ -1866,15 +1863,13 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, case Instruction::CatchRet: { Code = bitc::FUNC_CODE_INST_CATCHRET; const auto &CRI = cast<CatchReturnInst>(I); + pushValue(CRI.getCatchPad(), InstID, Vals, VE); Vals.push_back(VE.getValueID(CRI.getSuccessor())); - if (CRI.hasReturnValue()) - PushValueAndType(CRI.getReturnValue(), InstID, Vals, VE); break; } case Instruction::CatchPad: { Code = bitc::FUNC_CODE_INST_CATCHPAD; const auto &CPI = cast<CatchPadInst>(I); - Vals.push_back(VE.getTypeID(CPI.getType())); Vals.push_back(VE.getValueID(CPI.getNormalDest())); Vals.push_back(VE.getValueID(CPI.getUnwindDest())); unsigned NumArgOperands = CPI.getNumArgOperands(); @@ -1898,7 +1893,6 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, case Instruction::CleanupPad: { Code = bitc::FUNC_CODE_INST_CLEANUPPAD; const auto &CPI = cast<CleanupPadInst>(I); - Vals.push_back(VE.getTypeID(CPI.getType())); unsigned NumOperands = CPI.getNumOperands(); Vals.push_back(NumOperands); for (unsigned Op = 0; Op != NumOperands; ++Op) diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp index 68384f08b7c..3cc9c395c22 100644 --- a/llvm/lib/CodeGen/WinEHPrepare.cpp +++ b/llvm/lib/CodeGen/WinEHPrepare.cpp @@ -2956,8 +2956,7 @@ static const BasicBlock *getEHPadFromPredecessor(const BasicBlock *BB) { if (isa<CatchPadInst>(TI) || isa<CatchEndPadInst>(TI) || isa<TerminatePadInst>(TI)) return BB; - return cast<CleanupPadInst>(cast<CleanupReturnInst>(TI)->getReturnValue()) - ->getParent(); + return cast<CleanupReturnInst>(TI)->getCleanupPad()->getParent(); } static void calculateExplicitStateNumbers(WinEHFuncInfo &FuncInfo, @@ -3242,11 +3241,11 @@ bool WinEHPrepare::prepareExplicitEH(Function &F) { // The token consumed by a CatchReturnInst must match the funclet token. bool IsUnreachableCatchret = false; if (auto *CRI = dyn_cast<CatchReturnInst>(TI)) - IsUnreachableCatchret = CRI->getReturnValue() != CatchPad; + IsUnreachableCatchret = CRI->getCatchPad() != CatchPad; // The token consumed by a CleanupPadInst must match the funclet token. bool IsUnreachableCleanupret = false; if (auto *CRI = dyn_cast<CleanupReturnInst>(TI)) - IsUnreachableCleanupret = CRI->getReturnValue() != CleanupPad; + IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad; if (IsUnreachableRet || IsUnreachableCatchret || IsUnreachableCleanupret) { new UnreachableInst(BB->getContext(), TI); TI->eraseFromParent(); diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 5ec111869f0..ae9ab8d6187 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2860,9 +2860,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) { writeOperand(LPI->getClause(i), true); } } else if (const auto *CPI = dyn_cast<CatchPadInst>(&I)) { - Out << ' '; - TypePrinter.print(I.getType(), Out); - Out << " ["; for (unsigned Op = 0, NumOps = CPI->getNumArgOperands(); Op < NumOps; ++Op) { @@ -2888,9 +2885,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) { else Out << "to caller"; } else if (const auto *CPI = dyn_cast<CleanupPadInst>(&I)) { - Out << ' '; - TypePrinter.print(I.getType(), Out); - Out << " ["; for (unsigned Op = 0, NumOps = CPI->getNumOperands(); Op < NumOps; ++Op) { if (Op > 0) @@ -2901,22 +2895,14 @@ void AssemblyWriter::printInstruction(const Instruction &I) { } else if (isa<ReturnInst>(I) && !Operand) { Out << " void"; } else if (const auto *CRI = dyn_cast<CatchReturnInst>(&I)) { - if (CRI->hasReturnValue()) { - Out << ' '; - writeOperand(CRI->getReturnValue(), /*PrintType=*/true); - } else { - Out << " void"; - } + Out << ' '; + writeOperand(CRI->getCatchPad(), /*PrintType=*/false); Out << " to "; writeOperand(CRI->getSuccessor(), /*PrintType=*/true); } else if (const auto *CRI = dyn_cast<CleanupReturnInst>(&I)) { - if (CRI->hasReturnValue()) { - Out << ' '; - writeOperand(CRI->getReturnValue(), /*PrintType=*/true); - } else { - Out << " void"; - } + Out << ' '; + writeOperand(CRI->getCleanupPad(), /*PrintType=*/false); Out << " unwind "; if (CRI->hasUnwindDest()) diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp index 85173d96562..0dc8633ac2a 100644 --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -261,7 +261,7 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { case ExtractValue: return "extractvalue"; case InsertValue: return "insertvalue"; case LandingPad: return "landingpad"; - case CleanupPad: return "cleanuppad"; + case CleanupPad: return "cleanuppad"; default: return "<Invalid operator> "; } diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index 46c799ece2c..e79fa415ffb 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -684,51 +684,39 @@ CleanupReturnInst::CleanupReturnInst(const CleanupReturnInst &CRI) CRI.getNumOperands()) { SubclassOptionalData = CRI.SubclassOptionalData; setInstructionSubclassData(CRI.getSubclassDataFromInstruction()); - if (Value *RetVal = CRI.getReturnValue()) - setReturnValue(RetVal); - if (BasicBlock *UnwindDest = CRI.getUnwindDest()) - setUnwindDest(UnwindDest); + Op<-1>() = CRI.Op<-1>(); + if (CRI.hasUnwindDest()) + Op<-2>() = CRI.Op<-2>(); } -void CleanupReturnInst::init(Value *RetVal, BasicBlock *UnwindBB) { +void CleanupReturnInst::init(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB) { SubclassOptionalData = 0; if (UnwindBB) setInstructionSubclassData(getSubclassDataFromInstruction() | 1); - if (RetVal) - setInstructionSubclassData(getSubclassDataFromInstruction() | 2); + Op<-1>() = CleanupPad; if (UnwindBB) - setUnwindDest(UnwindBB); - if (RetVal) - setReturnValue(RetVal); + Op<-2>() = UnwindBB; } -CleanupReturnInst::CleanupReturnInst(LLVMContext &C, Value *RetVal, +CleanupReturnInst::CleanupReturnInst(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB, unsigned Values, Instruction *InsertBefore) - : TerminatorInst(Type::getVoidTy(C), Instruction::CleanupRet, + : TerminatorInst(Type::getVoidTy(CleanupPad->getContext()), + Instruction::CleanupRet, OperandTraits<CleanupReturnInst>::op_end(this) - Values, Values, InsertBefore) { - init(RetVal, UnwindBB); + init(CleanupPad, UnwindBB); } -CleanupReturnInst::CleanupReturnInst(LLVMContext &C, Value *RetVal, +CleanupReturnInst::CleanupReturnInst(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB, unsigned Values, BasicBlock *InsertAtEnd) - : TerminatorInst(Type::getVoidTy(C), Instruction::CleanupRet, + : TerminatorInst(Type::getVoidTy(CleanupPad->getContext()), + Instruction::CleanupRet, OperandTraits<CleanupReturnInst>::op_end(this) - Values, Values, InsertAtEnd) { - init(RetVal, UnwindBB); -} - -BasicBlock *CleanupReturnInst::getUnwindDest() const { - if (hasUnwindDest()) - return cast<BasicBlock>(getOperand(getUnwindLabelOpIdx())); - return nullptr; -} -void CleanupReturnInst::setUnwindDest(BasicBlock *NewDest) { - assert(NewDest); - setOperand(getUnwindLabelOpIdx(), NewDest); + init(CleanupPad, UnwindBB); } BasicBlock *CleanupReturnInst::getSuccessorV(unsigned Idx) const { @@ -797,38 +785,32 @@ void CatchEndPadInst::setSuccessorV(unsigned Idx, BasicBlock *B) { //===----------------------------------------------------------------------===// // CatchReturnInst Implementation //===----------------------------------------------------------------------===// -void CatchReturnInst::init(BasicBlock *BB, Value *RetVal) { - Op<-1>() = BB; - if (RetVal) - Op<-2>() = RetVal; +void CatchReturnInst::init(CatchPadInst *CatchPad, BasicBlock *BB) { + Op<0>() = CatchPad; + Op<1>() = BB; } CatchReturnInst::CatchReturnInst(const CatchReturnInst &CRI) : TerminatorInst(Type::getVoidTy(CRI.getContext()), Instruction::CatchRet, - OperandTraits<CatchReturnInst>::op_end(this) - - CRI.getNumOperands(), - CRI.getNumOperands()) { - Op<-1>() = CRI.Op<-1>(); - if (CRI.getNumOperands() != 1) { - assert(CRI.getNumOperands() == 2); - Op<-2>() = CRI.Op<-2>(); - } + OperandTraits<CatchReturnInst>::op_begin(this), 2) { + Op<0>() = CRI.Op<0>(); + Op<1>() = CRI.Op<1>(); } -CatchReturnInst::CatchReturnInst(BasicBlock *BB, Value *RetVal, unsigned Values, +CatchReturnInst::CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB, Instruction *InsertBefore) : TerminatorInst(Type::getVoidTy(BB->getContext()), Instruction::CatchRet, - OperandTraits<CatchReturnInst>::op_end(this) - Values, - Values, InsertBefore) { - init(BB, RetVal); + OperandTraits<CatchReturnInst>::op_begin(this), 2, + InsertBefore) { + init(CatchPad, BB); } -CatchReturnInst::CatchReturnInst(BasicBlock *BB, Value *RetVal, unsigned Values, +CatchReturnInst::CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB, BasicBlock *InsertAtEnd) : TerminatorInst(Type::getVoidTy(BB->getContext()), Instruction::CatchRet, - OperandTraits<CatchReturnInst>::op_end(this) - Values, - Values, InsertAtEnd) { - init(BB, RetVal); + OperandTraits<CatchReturnInst>::op_begin(this), 2, + InsertAtEnd) { + init(CatchPad, BB); } BasicBlock *CatchReturnInst::getSuccessorV(unsigned Idx) const { @@ -863,21 +845,21 @@ CatchPadInst::CatchPadInst(const CatchPadInst &CPI) std::copy(CPI.op_begin(), CPI.op_end(), op_begin()); } -CatchPadInst::CatchPadInst(Type *RetTy, BasicBlock *IfNormal, - BasicBlock *IfException, ArrayRef<Value *> Args, - unsigned Values, const Twine &NameStr, - Instruction *InsertBefore) - : TerminatorInst(RetTy, Instruction::CatchPad, +CatchPadInst::CatchPadInst(BasicBlock *IfNormal, BasicBlock *IfException, + ArrayRef<Value *> Args, unsigned Values, + const Twine &NameStr, Instruction *InsertBefore) + : TerminatorInst(Type::getTokenTy(IfNormal->getContext()), + Instruction::CatchPad, OperandTraits<CatchPadInst>::op_end(this) - Values, Values, InsertBefore) { init(IfNormal, IfException, Args, NameStr); } -CatchPadInst::CatchPadInst(Type *RetTy, BasicBlock *IfNormal, - BasicBlock *IfException, ArrayRef<Value *> Args, - unsigned Values, const Twine &NameStr, - BasicBlock *InsertAtEnd) - : TerminatorInst(RetTy, Instruction::CatchPad, +CatchPadInst::CatchPadInst(BasicBlock *IfNormal, BasicBlock *IfException, + ArrayRef<Value *> Args, unsigned Values, + const Twine &NameStr, BasicBlock *InsertAtEnd) + : TerminatorInst(Type::getTokenTy(IfNormal->getContext()), + Instruction::CatchPad, OperandTraits<CatchPadInst>::op_end(this) - Values, Values, InsertAtEnd) { init(IfNormal, IfException, Args, NameStr); @@ -962,17 +944,17 @@ CleanupPadInst::CleanupPadInst(const CleanupPadInst &CPI) std::copy(CPI.op_begin(), CPI.op_end(), op_begin()); } -CleanupPadInst::CleanupPadInst(Type *RetTy, ArrayRef<Value *> Args, +CleanupPadInst::CleanupPadInst(LLVMContext &C, ArrayRef<Value *> Args, const Twine &NameStr, Instruction *InsertBefore) - : Instruction(RetTy, Instruction::CleanupPad, + : Instruction(Type::getTokenTy(C), Instruction::CleanupPad, OperandTraits<CleanupPadInst>::op_end(this) - Args.size(), Args.size(), InsertBefore) { init(Args, NameStr); } -CleanupPadInst::CleanupPadInst(Type *RetTy, ArrayRef<Value *> Args, +CleanupPadInst::CleanupPadInst(LLVMContext &C, ArrayRef<Value *> Args, const Twine &NameStr, BasicBlock *InsertAtEnd) - : Instruction(RetTy, Instruction::CleanupPad, + : Instruction(Type::getTokenTy(C), Instruction::CleanupPad, OperandTraits<CleanupPadInst>::op_end(this) - Args.size(), Args.size(), InsertAtEnd) { init(Args, NameStr); diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 813d06cf643..7e10e4e1cee 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -184,12 +184,6 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport { /// \brief Track unresolved string-based type references. SmallDenseMap<const MDString *, const MDNode *, 32> UnresolvedTypeRefs; - /// \brief The result type for a catchpad. - Type *CatchPadResultTy; - - /// \brief The result type for a cleanuppad. - Type *CleanupPadResultTy; - /// \brief The result type for a landingpad. Type *LandingPadResultTy; @@ -203,8 +197,7 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport { public: explicit Verifier(raw_ostream &OS) - : VerifierSupport(OS), Context(nullptr), CatchPadResultTy(nullptr), - CleanupPadResultTy(nullptr), LandingPadResultTy(nullptr), + : VerifierSupport(OS), Context(nullptr), LandingPadResultTy(nullptr), SawFrameEscape(false) {} bool verify(const Function &F) { @@ -239,8 +232,6 @@ public: // FIXME: We strip const here because the inst visitor strips const. visit(const_cast<Function &>(F)); InstsInThisBlock.clear(); - CatchPadResultTy = nullptr; - CleanupPadResultTy = nullptr; LandingPadResultTy = nullptr; SawFrameEscape = false; @@ -2877,14 +2868,6 @@ void Verifier::visitLandingPadInst(LandingPadInst &LPI) { void Verifier::visitCatchPadInst(CatchPadInst &CPI) { visitEHPadPredecessors(CPI); - if (!CatchPadResultTy) - CatchPadResultTy = CPI.getType(); - else - Assert(CatchPadResultTy == CPI.getType(), - "The catchpad instruction should have a consistent result type " - "inside a function.", - &CPI); - BasicBlock *BB = CPI.getParent(); Function *F = BB->getParent(); Assert(F->hasPersonalityFn(), @@ -2896,6 +2879,14 @@ void Verifier::visitCatchPadInst(CatchPadInst &CPI) { "CatchPadInst not the first non-PHI instruction in the block.", &CPI); + if (!BB->getSinglePredecessor()) + for (BasicBlock *PredBB : predecessors(BB)) { + Assert(!isa<CatchPadInst>(PredBB->getTerminator()), + "CatchPadInst with CatchPadInst predecessor cannot have any other " + "predecessors.", + &CPI); + } + BasicBlock *UnwindDest = CPI.getUnwindDest(); Instruction *I = UnwindDest->getFirstNonPHI(); Assert( @@ -2946,14 +2937,6 @@ void Verifier::visitCleanupPadInst(CleanupPadInst &CPI) { BasicBlock *BB = CPI.getParent(); - if (!CleanupPadResultTy) - CleanupPadResultTy = CPI.getType(); - else - Assert(CleanupPadResultTy == CPI.getType(), - "The cleanuppad instruction should have a consistent result type " - "inside a function.", - &CPI); - Function *F = BB->getParent(); Assert(F->hasPersonalityFn(), "CleanupPadInst needs to be in a function with a personality.", &CPI); @@ -2964,6 +2947,18 @@ void Verifier::visitCleanupPadInst(CleanupPadInst &CPI) { "CleanupPadInst not the first non-PHI instruction in the block.", &CPI); + CleanupReturnInst *FirstCRI = nullptr; + for (User *U : CPI.users()) + if (CleanupReturnInst *CRI = dyn_cast<CleanupReturnInst>(U)) { + if (!FirstCRI) + FirstCRI = CRI; + else + Assert(CRI->getUnwindDest() == FirstCRI->getUnwindDest(), + "Cleanuprets from same cleanuppad have different exceptional " + "successors.", + FirstCRI, CRI); + } + visitInstruction(CPI); } diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp index 46593ca7233..e36637a4fd8 100644 --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -2674,17 +2674,13 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> { } void visitCleanupPadInst(CleanupPadInst &I) { - if (!I.getType()->isVoidTy()) { - setShadow(&I, getCleanShadow(&I)); - setOrigin(&I, getCleanOrigin()); - } + setShadow(&I, getCleanShadow(&I)); + setOrigin(&I, getCleanOrigin()); } void visitCatchPad(CatchPadInst &I) { - if (!I.getType()->isVoidTy()) { - setShadow(&I, getCleanShadow(&I)); - setOrigin(&I, getCleanOrigin()); - } + setShadow(&I, getCleanShadow(&I)); + setOrigin(&I, getCleanOrigin()); } void visitTerminatePad(TerminatePadInst &I) { diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index 83dd1826c22..22d86c4fdc0 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -344,8 +344,7 @@ static void HandleInlinedEHPad(InvokeInst *II, BasicBlock *FirstNewBlock, if (auto *CRI = dyn_cast<CleanupReturnInst>(BB->getTerminator())) { if (CRI->unwindsToCaller()) { - CleanupReturnInst::Create(CRI->getContext(), CRI->getReturnValue(), - UnwindDest, CRI); + CleanupReturnInst::Create(CRI->getCleanupPad(), UnwindDest, CRI); CRI->eraseFromParent(); UpdatePHINodes(BB); } |