diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLLexer.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 30 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.h | 1 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLToken.h | 2 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 19 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h | 1 | ||||
-rw-r--r-- | llvm/lib/CodeGen/TargetLoweringBase.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/CodeGen/WinEHPrepare.cpp | 36 | ||||
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/IR/Instruction.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/IR/Instructions.cpp | 59 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 56 | ||||
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/InlineFunction.cpp | 6 |
17 files changed, 223 insertions, 19 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 7de719579ad..7000210e1fa 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -3207,6 +3207,7 @@ bool llvm::isSafeToSpeculativelyExecute(const Value *V, case Instruction::CatchEndPad: case Instruction::CatchRet: case Instruction::CleanupPad: + case Instruction::CleanupEndPad: case Instruction::CleanupRet: case Instruction::TerminatePad: return false; // Misc instructions which have effects diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index af7705c5666..b166c17b124 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -757,6 +757,7 @@ lltok::Kind LLLexer::LexIdentifier() { INSTKEYWORD(terminatepad, TerminatePad); INSTKEYWORD(cleanuppad, CleanupPad); INSTKEYWORD(catchendpad, CatchEndPad); + INSTKEYWORD(cleanupendpad, CleanupEndPad); #undef INSTKEYWORD #define DWKEYWORD(TYPE, TOKEN) \ diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index c8390d44cca..df34ba8697f 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -4686,6 +4686,7 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, case lltok::kw_terminatepad: return ParseTerminatePad(Inst, PFS); case lltok::kw_cleanuppad: return ParseCleanupPad(Inst, PFS); case lltok::kw_catchendpad: return ParseCatchEndPad(Inst, PFS); + case lltok::kw_cleanupendpad: return ParseCleanupEndPad(Inst, PFS); // Binary Operators. case lltok::kw_add: case lltok::kw_sub: @@ -5243,6 +5244,35 @@ bool LLParser::ParseCatchEndPad(Instruction *&Inst, PerFunctionState &PFS) { return false; } +/// ParseCatchEndPad +/// ::= 'cleanupendpad' Value unwind ('to' 'caller' | TypeAndValue) +bool LLParser::ParseCleanupEndPad(Instruction *&Inst, PerFunctionState &PFS) { + Value *CleanupPad = nullptr; + + if (ParseValue(Type::getTokenTy(Context), CleanupPad, PFS, OC_CleanupPad)) + return true; + + if (ParseToken(lltok::kw_unwind, "expected 'unwind' in catchendpad")) + return true; + + BasicBlock *UnwindBB = nullptr; + if (Lex.getKind() == lltok::kw_to) { + Lex.Lex(); + if (Lex.getKind() == lltok::kw_caller) { + Lex.Lex(); + } else { + return true; + } + } else { + if (ParseTypeAndBasicBlock(UnwindBB, PFS)) { + return true; + } + } + + Inst = CleanupEndPadInst::Create(cast<CleanupPadInst>(CleanupPad), UnwindBB); + return false; +} + //===----------------------------------------------------------------------===// // Binary Operators. //===----------------------------------------------------------------------===// diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h index 8b7e9560a69..e161f95248c 100644 --- a/llvm/lib/AsmParser/LLParser.h +++ b/llvm/lib/AsmParser/LLParser.h @@ -475,6 +475,7 @@ namespace llvm { bool ParseTerminatePad(Instruction *&Inst, PerFunctionState &PFS); bool ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS); bool ParseCatchEndPad(Instruction *&Inst, PerFunctionState &PFS); + bool ParseCleanupEndPad(Instruction *&Inst, PerFunctionState &PFS); bool ParseArithmetic(Instruction *&I, PerFunctionState &PFS, unsigned Opc, unsigned OperandType); diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h index 19bf7e4e4c1..b83ca2c652f 100644 --- a/llvm/lib/AsmParser/LLToken.h +++ b/llvm/lib/AsmParser/LLToken.h @@ -179,7 +179,7 @@ namespace lltok { kw_ret, kw_br, kw_switch, kw_indirectbr, kw_invoke, kw_resume, kw_unreachable, kw_cleanupret, kw_catchret, kw_catchpad, - kw_terminatepad, kw_cleanuppad, kw_catchendpad, + kw_terminatepad, kw_cleanuppad, kw_catchendpad, kw_cleanupendpad, kw_alloca, kw_load, kw_store, kw_fence, kw_cmpxchg, kw_atomicrmw, kw_getelementptr, diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index b9604af3bc8..be39b88b822 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -3999,6 +3999,25 @@ std::error_code BitcodeReader::parseFunctionBody(Function *F) { InstructionList.push_back(I); break; } + case bitc::FUNC_CODE_INST_CLEANUPENDPAD: { // CLEANUPENDPADINST: [val] or [val,bb#] + if (Record.size() != 1 && Record.size() != 2) + return error("Invalid record"); + unsigned Idx = 0; + Value *CleanupPad = getValue(Record, Idx++, NextValueNo, + Type::getTokenTy(Context), OC_CleanupPad); + if (!CleanupPad) + return error("Invalid record"); + + BasicBlock *BB = nullptr; + if (Record.size() == 2) { + BB = getBasicBlock(Record[Idx++]); + if (!BB) + return error("Invalid record"); + } + I = CleanupEndPadInst::Create(cast<CleanupPadInst>(CleanupPad), BB); + InstructionList.push_back(I); + break; + } case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, op0, op1, ...] // Check magic if ((Record[0] >> 16) == SWITCH_INST_MAGIC) { diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index c0eb5d497bc..9986718f08b 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1906,6 +1906,14 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, Vals.push_back(VE.getValueID(CEPI.getUnwindDest())); break; } + case Instruction::CleanupEndPad: { + Code = bitc::FUNC_CODE_INST_CLEANUPENDPAD; + const auto &CEPI = cast<CleanupEndPadInst>(I); + pushValue(CEPI.getCleanupPad(), InstID, Vals, VE); + if (CEPI.hasUnwindDest()) + Vals.push_back(VE.getValueID(CEPI.getUnwindDest())); + break; + } case Instruction::Unreachable: Code = bitc::FUNC_CODE_INST_UNREACHABLE; AbbrevToUse = FUNCTION_INST_UNREACHABLE_ABBREV; diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 7c1706f6edc..9aa9755796d 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1205,6 +1205,10 @@ void SelectionDAGBuilder::visitCleanupRet(const CleanupReturnInst &I) { report_fatal_error("visitCleanupRet not yet implemented!"); } +void SelectionDAGBuilder::visitCleanupEndPad(const CleanupEndPadInst &I) { + report_fatal_error("visitCleanupEndPad not yet implemented!"); +} + void SelectionDAGBuilder::visitTerminatePad(const TerminatePadInst &TPI) { report_fatal_error("visitTerminatePad not yet implemented!"); } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index 3b97d469f5e..2331127a966 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -740,6 +740,7 @@ private: void visitSwitch(const SwitchInst &I); void visitIndirectBr(const IndirectBrInst &I); void visitUnreachable(const UnreachableInst &I); + void visitCleanupEndPad(const CleanupEndPadInst &I); void visitCleanupRet(const CleanupReturnInst &I); void visitCatchEndPad(const CatchEndPadInst &I); void visitCatchRet(const CatchReturnInst &I); diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp index d7a58f9686d..7250fdc9385 100644 --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -1574,6 +1574,7 @@ int TargetLoweringBase::InstructionOpcodeToISD(unsigned Opcode) const { case Invoke: return 0; case Resume: return 0; case Unreachable: return 0; + case CleanupEndPad: return 0; case CleanupRet: return 0; case CatchEndPad: return 0; case CatchRet: return 0; diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp index 8c15b7e4413..c333c074900 100644 --- a/llvm/lib/CodeGen/WinEHPrepare.cpp +++ b/llvm/lib/CodeGen/WinEHPrepare.cpp @@ -403,7 +403,7 @@ bool WinEHPrepare::runOnFunction(Function &Fn) { } else if (First->isEHPad()) { if (!ForExplicitEH) EntryBlocks.push_back(&Fn.getEntryBlock()); - if (!isa<CatchEndPadInst>(First)) + if (!isa<CatchEndPadInst>(First) && !isa<CleanupEndPadInst>(First)) EntryBlocks.push_back(&BB); ForExplicitEH = true; } @@ -2965,6 +2965,8 @@ static const BasicBlock *getEHPadFromPredecessor(const BasicBlock *BB) { if (isa<CatchPadInst>(TI) || isa<CatchEndPadInst>(TI) || isa<TerminatePadInst>(TI)) return BB; + if (auto *CEPI = dyn_cast<CleanupEndPadInst>(TI)) + return CEPI->getCleanupPad()->getParent(); return cast<CleanupReturnInst>(TI)->getCleanupPad()->getParent(); } @@ -3035,18 +3037,27 @@ void llvm::calculateWinCXXEHStateNumbers(const Function *ParentFn, for (const BasicBlock &BB : *ParentFn) { if (!BB.isEHPad()) continue; + const Instruction *FirstNonPHI = BB.getFirstNonPHI(); + // Skip cleanupendpads; they are exits, not entries. + if (isa<CleanupEndPadInst>(FirstNonPHI)) + continue; // Check if the EH Pad has no exceptional successors (i.e. it unwinds to // caller). Cleanups are a little bit of a special case because their // control flow cannot be determined by looking at the pad but instead by // the pad's users. bool HasNoSuccessors = false; - const Instruction *FirstNonPHI = BB.getFirstNonPHI(); if (FirstNonPHI->mayThrow()) { HasNoSuccessors = true; } else if (auto *CPI = dyn_cast<CleanupPadInst>(FirstNonPHI)) { - HasNoSuccessors = - CPI->use_empty() || - cast<CleanupReturnInst>(CPI->user_back())->unwindsToCaller(); + if (CPI->use_empty()) { + HasNoSuccessors = true; + } else { + const Instruction *User = CPI->user_back(); + if (auto *CRI = dyn_cast<CleanupReturnInst>(User)) + HasNoSuccessors = CRI->unwindsToCaller(); + else + HasNoSuccessors = cast<CleanupEndPadInst>(User)->unwindsToCaller(); + } } if (!HasNoSuccessors) @@ -3096,7 +3107,8 @@ void WinEHPrepare::colorFunclets(Function &F, BasicBlock *Color; std::tie(Visiting, Color) = Worklist.pop_back_val(); Instruction *VisitingHead = Visiting->getFirstNonPHI(); - if (VisitingHead->isEHPad() && !isa<CatchEndPadInst>(VisitingHead)) { + if (VisitingHead->isEHPad() && !isa<CatchEndPadInst>(VisitingHead) && + !isa<CleanupEndPadInst>(VisitingHead)) { // Mark this as a funclet head as a member of itself. FuncletBlocks[Visiting].insert(Visiting); // Queue exits with the parent color. @@ -3132,7 +3144,8 @@ void WinEHPrepare::colorFunclets(Function &F, FuncletBlocks[Color].insert(Visiting); TerminatorInst *Terminator = Visiting->getTerminator(); if (isa<CleanupReturnInst>(Terminator) || - isa<CatchReturnInst>(Terminator)) { + isa<CatchReturnInst>(Terminator) || + isa<CleanupEndPadInst>(Terminator)) { // These block's successors have already been queued with the parent // color. continue; @@ -3288,11 +3301,16 @@ bool WinEHPrepare::prepareExplicitEH( bool IsUnreachableCatchret = false; if (auto *CRI = dyn_cast<CatchReturnInst>(TI)) IsUnreachableCatchret = CRI->getCatchPad() != CatchPad; - // The token consumed by a CleanupPadInst must match the funclet token. + // The token consumed by a CleanupReturnInst must match the funclet token. bool IsUnreachableCleanupret = false; if (auto *CRI = dyn_cast<CleanupReturnInst>(TI)) IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad; - if (IsUnreachableRet || IsUnreachableCatchret || IsUnreachableCleanupret) { + // The token consumed by a CleanupEndPadInst must match the funclet token. + bool IsUnreachableCleanupendpad = false; + if (auto *CEPI = dyn_cast<CleanupEndPadInst>(TI)) + IsUnreachableCleanupendpad = CEPI->getCleanupPad() != CleanupPad; + if (IsUnreachableRet || IsUnreachableCatchret || + IsUnreachableCleanupret || IsUnreachableCleanupendpad) { new UnreachableInst(BB->getContext(), TI); TI->eraseFromParent(); } diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 86d923e5d83..db7fd7a2324 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2889,6 +2889,15 @@ void AssemblyWriter::printInstruction(const Instruction &I) { writeOperand(CEPI->getUnwindDest(), /*PrintType=*/true); else Out << "to caller"; + } else if (const auto *CEPI = dyn_cast<CleanupEndPadInst>(&I)) { + Out << ' '; + writeOperand(CEPI->getCleanupPad(), /*PrintType=*/false); + + Out << " unwind "; + if (CEPI->hasUnwindDest()) + writeOperand(CEPI->getUnwindDest(), /*PrintType=*/true); + else + Out << "to caller"; } else if (const CallInst *CI = dyn_cast<CallInst>(&I)) { // Print the calling convention being used. if (CI->getCallingConv() != CallingConv::C) { diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp index 0dc8633ac2a..908e79039b5 100644 --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -196,6 +196,7 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { case Invoke: return "invoke"; case Resume: return "resume"; case Unreachable: return "unreachable"; + case CleanupEndPad: return "cleanupendpad"; case CleanupRet: return "cleanupret"; case CatchEndPad: return "catchendpad"; case CatchRet: return "catchret"; @@ -467,6 +468,8 @@ bool Instruction::mayThrow() const { return !CI->doesNotThrow(); if (const auto *CRI = dyn_cast<CleanupReturnInst>(this)) return CRI->unwindsToCaller(); + if (const auto *CEPI = dyn_cast<CleanupEndPadInst>(this)) + return CEPI->unwindsToCaller(); if (const auto *CEPI = dyn_cast<CatchEndPadInst>(this)) return CEPI->unwindsToCaller(); if (const auto *TPI = dyn_cast<TerminatePadInst>(this)) diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index 6b2cd6dac22..ff681401b50 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -674,6 +674,61 @@ BasicBlock *ResumeInst::getSuccessorV(unsigned idx) const { } //===----------------------------------------------------------------------===// +// CleanupEndPadInst Implementation +//===----------------------------------------------------------------------===// + +CleanupEndPadInst::CleanupEndPadInst(const CleanupEndPadInst &CEPI) + : TerminatorInst(CEPI.getType(), Instruction::CleanupEndPad, + OperandTraits<CleanupEndPadInst>::op_end(this) - + CEPI.getNumOperands(), + CEPI.getNumOperands()) { + setInstructionSubclassData(CEPI.getSubclassDataFromInstruction()); + setCleanupPad(CEPI.getCleanupPad()); + if (BasicBlock *UnwindDest = CEPI.getUnwindDest()) + setUnwindDest(UnwindDest); +} + +void CleanupEndPadInst::init(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB) { + setCleanupPad(CleanupPad); + if (UnwindBB) { + setInstructionSubclassData(getSubclassDataFromInstruction() | 1); + setUnwindDest(UnwindBB); + } +} + +CleanupEndPadInst::CleanupEndPadInst(CleanupPadInst *CleanupPad, + BasicBlock *UnwindBB, unsigned Values, + Instruction *InsertBefore) + : TerminatorInst(Type::getVoidTy(CleanupPad->getContext()), + Instruction::CleanupEndPad, + OperandTraits<CleanupEndPadInst>::op_end(this) - Values, + Values, InsertBefore) { + init(CleanupPad, UnwindBB); +} + +CleanupEndPadInst::CleanupEndPadInst(CleanupPadInst *CleanupPad, + BasicBlock *UnwindBB, unsigned Values, + BasicBlock *InsertAtEnd) + : TerminatorInst(Type::getVoidTy(CleanupPad->getContext()), + Instruction::CleanupEndPad, + OperandTraits<CleanupEndPadInst>::op_end(this) - Values, + Values, InsertAtEnd) { + init(CleanupPad, UnwindBB); +} + +BasicBlock *CleanupEndPadInst::getSuccessorV(unsigned Idx) const { + assert(Idx == 0); + return getUnwindDest(); +} +unsigned CleanupEndPadInst::getNumSuccessorsV() const { + return getNumSuccessors(); +} +void CleanupEndPadInst::setSuccessorV(unsigned Idx, BasicBlock *B) { + assert(Idx == 0); + setUnwindDest(B); +} + +//===----------------------------------------------------------------------===// // CleanupReturnInst Implementation //===----------------------------------------------------------------------===// @@ -3902,6 +3957,10 @@ InvokeInst *InvokeInst::cloneImpl() const { ResumeInst *ResumeInst::cloneImpl() const { return new (1) ResumeInst(*this); } +CleanupEndPadInst *CleanupEndPadInst::cloneImpl() const { + return new (getNumOperands()) CleanupEndPadInst(*this); +} + CleanupReturnInst *CleanupReturnInst::cloneImpl() const { return new (getNumOperands()) CleanupReturnInst(*this); } diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 51058cd5ab0..44158afeb07 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -388,6 +388,7 @@ private: void visitCatchPadInst(CatchPadInst &CPI); void visitCatchEndPadInst(CatchEndPadInst &CEPI); void visitCleanupPadInst(CleanupPadInst &CPI); + void visitCleanupEndPadInst(CleanupEndPadInst &CEPI); void visitCleanupReturnInst(CleanupReturnInst &CRI); void visitTerminatePadInst(TerminatePadInst &TPI); @@ -2832,6 +2833,8 @@ void Verifier::visitEHPadPredecessors(Instruction &I) { ; else if (isa<CleanupReturnInst>(TI)) ; + else if (isa<CleanupEndPadInst>(TI)) + ; else if (isa<TerminatePadInst>(TI)) ; else @@ -2962,21 +2965,56 @@ void Verifier::visitCleanupPadInst(CleanupPadInst &CPI) { "CleanupPadInst not the first non-PHI instruction in the block.", &CPI); - CleanupReturnInst *FirstCRI = nullptr; - for (User *U : CPI.users()) + User *FirstUser = nullptr; + BasicBlock *FirstUnwindDest = nullptr; + for (User *U : CPI.users()) { + BasicBlock *UnwindDest; 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); + UnwindDest = CRI->getUnwindDest(); + } else { + UnwindDest = cast<CleanupEndPadInst>(U)->getUnwindDest(); } + if (!FirstUser) { + FirstUser = U; + FirstUnwindDest = UnwindDest; + } else { + Assert(UnwindDest == FirstUnwindDest, + "Cleanuprets/cleanupendpads from the same cleanuppad must " + "have the same unwind destination", + FirstUser, U); + } + } + visitInstruction(CPI); } +void Verifier::visitCleanupEndPadInst(CleanupEndPadInst &CEPI) { + visitEHPadPredecessors(CEPI); + + BasicBlock *BB = CEPI.getParent(); + Function *F = BB->getParent(); + Assert(F->hasPersonalityFn(), + "CleanupEndPadInst needs to be in a function with a personality.", + &CEPI); + + // The cleanupendpad instruction must be the first non-PHI instruction in the + // block. + Assert(BB->getFirstNonPHI() == &CEPI, + "CleanupEndPadInst not the first non-PHI instruction in the block.", + &CEPI); + + if (BasicBlock *UnwindDest = CEPI.getUnwindDest()) { + Instruction *I = UnwindDest->getFirstNonPHI(); + Assert( + I->isEHPad() && !isa<LandingPadInst>(I), + "CleanupEndPad must unwind to an EH block which is not a landingpad.", + &CEPI); + } + + visitTerminatorInst(CEPI); +} + void Verifier::visitCleanupReturnInst(CleanupReturnInst &CRI) { if (BasicBlock *UnwindDest = CRI.getUnwindDest()) { Instruction *I = UnwindDest->getFirstNonPHI(); diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp index eb2a5b3653c..be8e25505ca 100644 --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -2698,6 +2698,11 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> { // Nothing to do here. } + void visitCleanupEndPadInst(CleanupEndPadInst &I) { + DEBUG(dbgs() << "CleanupEndPad: " << I << "\n"); + // Nothing to do here. + } + void visitGetElementPtrInst(GetElementPtrInst &I) { handleShadowOr(I); } diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index 22d86c4fdc0..e884176093f 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -328,6 +328,12 @@ static void HandleInlinedEHPad(InvokeInst *II, BasicBlock *FirstNewBlock, CEPI->eraseFromParent(); UpdatePHINodes(BB); } + } else if (auto *CEPI = dyn_cast<CleanupEndPadInst>(I)) { + if (CEPI->unwindsToCaller()) { + CleanupEndPadInst::Create(CEPI->getCleanupPad(), UnwindDest, CEPI); + CEPI->eraseFromParent(); + UpdatePHINodes(BB); + } } else if (auto *TPI = dyn_cast<TerminatePadInst>(I)) { if (TPI->unwindsToCaller()) { SmallVector<Value *, 3> TerminatePadArgs; |