summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp1
-rw-r--r--llvm/lib/AsmParser/LLLexer.cpp1
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp30
-rw-r--r--llvm/lib/AsmParser/LLParser.h1
-rw-r--r--llvm/lib/AsmParser/LLToken.h2
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp19
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp8
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp4
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h1
-rw-r--r--llvm/lib/CodeGen/TargetLoweringBase.cpp1
-rw-r--r--llvm/lib/CodeGen/WinEHPrepare.cpp36
-rw-r--r--llvm/lib/IR/AsmWriter.cpp9
-rw-r--r--llvm/lib/IR/Instruction.cpp3
-rw-r--r--llvm/lib/IR/Instructions.cpp59
-rw-r--r--llvm/lib/IR/Verifier.cpp56
-rw-r--r--llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp5
-rw-r--r--llvm/lib/Transforms/Utils/InlineFunction.cpp6
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;
OpenPOWER on IntegriCloud