[llvm] r246235 - [WinEH] Add some support for code generating catchpad

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 27 16:27:48 PDT 2015


Author: rnk
Date: Thu Aug 27 18:27:47 2015
New Revision: 246235

URL: http://llvm.org/viewvc/llvm-project?rev=246235&view=rev
Log:
[WinEH] Add some support for code generating catchpad

We can now run 32-bit programs with empty catch bodies.  The next step
is to change PEI so that we get funclet prologues and epilogues.

Added:
    llvm/trunk/test/CodeGen/X86/win-catchpad.ll
Modified:
    llvm/trunk/include/llvm/CodeGen/FunctionLoweringInfo.h
    llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h
    llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h
    llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h
    llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h
    llvm/trunk/include/llvm/CodeGen/WinEHFuncInfo.h
    llvm/trunk/include/llvm/Target/TargetSelectionDAG.td
    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp
    llvm/trunk/lib/CodeGen/BranchFolding.cpp
    llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
    llvm/trunk/lib/CodeGen/LiveVariables.cpp
    llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp
    llvm/trunk/lib/CodeGen/MIRPrinter.cpp
    llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp
    llvm/trunk/lib/CodeGen/MachineBlockPlacement.cpp
    llvm/trunk/lib/CodeGen/MachineLICM.cpp
    llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp
    llvm/trunk/lib/CodeGen/MachineSink.cpp
    llvm/trunk/lib/CodeGen/MachineVerifier.cpp
    llvm/trunk/lib/CodeGen/PHIElimination.cpp
    llvm/trunk/lib/CodeGen/PHIEliminationUtils.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
    llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
    llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
    llvm/trunk/lib/Target/Hexagon/BitTracker.cpp
    llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp
    llvm/trunk/lib/Target/Mips/MipsDelaySlotFiller.cpp
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
    llvm/trunk/lib/Target/X86/X86ISelLowering.h
    llvm/trunk/lib/Target/X86/X86InstrCompiler.td
    llvm/trunk/lib/Target/X86/X86InstrInfo.td
    llvm/trunk/lib/Target/X86/X86MCInstLower.cpp
    llvm/trunk/lib/Target/X86/X86WinEHState.cpp

Modified: llvm/trunk/include/llvm/CodeGen/FunctionLoweringInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/FunctionLoweringInfo.h?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/FunctionLoweringInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/FunctionLoweringInfo.h Thu Aug 27 18:27:47 2015
@@ -165,6 +165,9 @@ public:
   unsigned CreateRegs(Type *Ty);
   
   unsigned InitializeRegForValue(const Value *V) {
+    // Tokens never live in vregs.
+    if (V->getType()->isTokenTy())
+      return 0;
     unsigned &R = ValueMap[V];
     assert(R == 0 && "Already initialized this value register!");
     return R = CreateRegs(V->getType());

Modified: llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h (original)
+++ llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h Thu Aug 27 18:27:47 2015
@@ -591,6 +591,10 @@ namespace ISD {
     /// take a chain as input and return a chain.
     EH_LABEL,
 
+    CATCHRET,
+
+    CLEANUPRET,
+
     /// STACKSAVE - STACKSAVE has one operand, an input chain.  It produces a
     /// value, the same type as the pointer type for the system, and an output
     /// chain.

Modified: llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h Thu Aug 27 18:27:47 2015
@@ -85,18 +85,21 @@ class MachineBasicBlock : public ilist_n
 
   /// Alignment of the basic block. Zero if the basic block does not need to be
   /// aligned. The alignment is specified as log2(bytes).
-  unsigned Alignment;
+  unsigned Alignment = 0;
 
   /// Indicate that this basic block is entered via an exception handler.
-  bool IsLandingPad;
+  bool IsEHPad = false;
 
   /// Indicate that this basic block is potentially the target of an indirect
   /// branch.
-  bool AddressTaken;
+  bool AddressTaken = false;
+
+  /// Indicate that this basic block is the entry block of an EH funclet.
+  bool IsEHFuncletEntry = false;
 
   /// \brief since getSymbol is a relatively heavy-weight operation, the symbol
   /// is only computed once and is cached.
-  mutable MCSymbol *CachedMCSymbol;
+  mutable MCSymbol *CachedMCSymbol = nullptr;
 
   // Intrusive list support
   MachineBasicBlock() {}
@@ -352,16 +355,22 @@ public:
 
   /// Returns true if the block is a landing pad. That is this basic block is
   /// entered via an exception handler.
-  bool isLandingPad() const { return IsLandingPad; }
+  bool isEHPad() const { return IsEHPad; }
 
   /// Indicates the block is a landing pad.  That is this basic block is entered
   /// via an exception handler.
-  void setIsLandingPad(bool V = true) { IsLandingPad = V; }
+  void setIsEHPad(bool V = true) { IsEHPad = V; }
 
   /// If this block has a successor that is a landing pad, return it. Otherwise
   /// return NULL.
   const MachineBasicBlock *getLandingPadSuccessor() const;
 
+  /// Returns true if this is the entry block of an EH funclet.
+  bool isEHFuncletEntry() const { return IsEHFuncletEntry; }
+
+  /// Indicates if this is the entry block of an EH funclet.
+  void setIsEHFuncletEntry(bool V = true) { IsEHFuncletEntry = V; }
+
   // Code Layout methods.
 
   /// Move 'this' block before or after the specified block.  This only moves

Modified: llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h Thu Aug 27 18:27:47 2015
@@ -163,6 +163,7 @@ class MachineModuleInfo : public Immutab
 
   bool CallsEHReturn;
   bool CallsUnwindInit;
+  bool HasEHFunclets;
 
   /// DbgInfoAvailable - True if debugging information is available
   /// in this module.
@@ -371,6 +372,12 @@ public:
     return LandingPads;
   }
 
+  bool hasEHFunclets() const {
+    return HasEHFunclets;
+  }
+
+  void setHasEHFunclets(bool V) { HasEHFunclets = true; }
+
   /// setCallSiteLandingPad - Map the landing pad's EH symbol to the call
   /// site indexes.
   void setCallSiteLandingPad(MCSymbol *Sym, ArrayRef<unsigned> Sites);

Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h Thu Aug 27 18:27:47 2015
@@ -264,6 +264,7 @@ private:
   /// personality specific tasks. Returns true if the block should be
   /// instruction selected, false if no code should be emitted for it.
   bool PrepareEHLandingPad();
+  bool PrepareEHPad();
 
   /// \brief Perform instruction selection on all basic blocks in the function.
   void SelectAllBasicBlocks(const Function &Fn);

Modified: llvm/trunk/include/llvm/CodeGen/WinEHFuncInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/WinEHFuncInfo.h?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/WinEHFuncInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/WinEHFuncInfo.h Thu Aug 27 18:27:47 2015
@@ -27,6 +27,7 @@ class InvokeInst;
 class IntrinsicInst;
 class LandingPadInst;
 class MCSymbol;
+class MachineBasicBlock;
 class Value;
 
 enum ActionType { Catch, Cleanup };
@@ -123,6 +124,7 @@ struct WinEHHandlerType {
   GlobalVariable *TypeDescriptor;
   int CatchObjRecoverIdx;
   const Value *Handler;
+  MachineBasicBlock *HandlerMBB;
 };
 
 struct WinEHTryBlockMapEntry {

Modified: llvm/trunk/include/llvm/Target/TargetSelectionDAG.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSelectionDAG.td?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetSelectionDAG.td (original)
+++ llvm/trunk/include/llvm/Target/TargetSelectionDAG.td Thu Aug 27 18:27:47 2015
@@ -451,6 +451,8 @@ def brcc       : SDNode<"ISD::BR_CC"
 def brcond     : SDNode<"ISD::BRCOND"     , SDTBrcond, [SDNPHasChain]>;
 def brind      : SDNode<"ISD::BRIND"      , SDTBrind,  [SDNPHasChain]>;
 def br         : SDNode<"ISD::BR"         , SDTBr,     [SDNPHasChain]>;
+def catchret   : SDNode<"ISD::CATCHRET"   , SDTBr,     [SDNPHasChain]>;
+
 def trap       : SDNode<"ISD::TRAP"       , SDTNone,
                         [SDNPHasChain, SDNPSideEffect]>;
 def debugtrap  : SDNode<"ISD::DEBUGTRAP"  , SDTNone,

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Thu Aug 27 18:27:47 2015
@@ -2485,7 +2485,8 @@ void AsmPrinter::EmitBasicBlockStart(con
   }
 
   // Print the main label for the block.
-  if (MBB.pred_empty() || isBlockOnlyReachableByFallthrough(&MBB)) {
+  if (MBB.pred_empty() ||
+      (isBlockOnlyReachableByFallthrough(&MBB) && !MBB.isEHFuncletEntry())) {
     if (isVerbose()) {
       // NOTE: Want this comment at start of line, don't emit with AddComment.
       OutStreamer->emitRawComment(" BB#" + Twine(MBB.getNumber()) + ":", false);
@@ -2523,7 +2524,7 @@ bool AsmPrinter::
 isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
   // If this is a landing pad, it isn't a fall through.  If it has no preds,
   // then nothing falls through to it.
-  if (MBB->isLandingPad() || MBB->pred_empty())
+  if (MBB->isEHPad() || MBB->pred_empty())
     return false;
 
   // If there isn't exactly one predecessor, it can't be a fall through.

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp Thu Aug 27 18:27:47 2015
@@ -62,6 +62,7 @@ void WinException::beginFunction(const M
 
   // If any landing pads survive, we need an EH table.
   bool hasLandingPads = !MMI->getLandingPads().empty();
+  bool hasEHFunclets = MMI->hasEHFunclets();
 
   const Function *F = MF->getFunction();
   const Function *ParentF = MMI->getWinEHParent(F);
@@ -78,19 +79,21 @@ void WinException::beginFunction(const M
     F->hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
     F->needsUnwindTableEntry();
 
-  shouldEmitPersonality = forceEmitPersonality || (hasLandingPads &&
-    PerEncoding != dwarf::DW_EH_PE_omit && Per);
+  shouldEmitPersonality =
+      forceEmitPersonality || ((hasLandingPads || hasEHFunclets) &&
+                               PerEncoding != dwarf::DW_EH_PE_omit && Per);
 
   unsigned LSDAEncoding = TLOF.getLSDAEncoding();
   shouldEmitLSDA = shouldEmitPersonality &&
     LSDAEncoding != dwarf::DW_EH_PE_omit;
 
-  // If we're not using CFI, we don't want the CFI or the personality. If
-  // WinEHPrepare outlined something, we should emit the LSDA.
+  // If we're not using CFI, we don't want the CFI or the personality, but we
+  // might want EH tables if we had EH pads.
+  // FIXME: If WinEHPrepare outlined something, we should emit the LSDA. Remove
+  // this once WinEHPrepare stops doing that.
   if (!Asm->MAI->usesWindowsCFI()) {
-    bool HasOutlinedChildren =
-        F->hasFnAttribute("wineh-parent") && F == ParentF;
-    shouldEmitLSDA = HasOutlinedChildren;
+    shouldEmitLSDA =
+        hasEHFunclets || (F->hasFnAttribute("wineh-parent") && F == ParentF);
     shouldEmitPersonality = false;
     return;
   }
@@ -185,7 +188,10 @@ const MCExpr *WinException::create32bitR
 const MCExpr *WinException::create32bitRef(const Value *V) {
   if (!V)
     return MCConstantExpr::create(0, Asm->OutContext);
-  return create32bitRef(Asm->getSymbol(cast<GlobalValue>(V)));
+  // FIXME: Delete the GlobalValue case once the new IR is fully functional.
+  if (const auto *GV = dyn_cast<GlobalValue>(V))
+    return create32bitRef(Asm->getSymbol(GV));
+  return create32bitRef(MMI->getAddrLabelSymbol(cast<BasicBlock>(V)));
 }
 
 /// Emit the language-specific data that __C_specific_handler expects.  This
@@ -320,14 +326,17 @@ void WinException::emitCXXFrameHandler3T
 
     extendIP2StateTable(MF, ParentF, FuncInfo);
 
-    // Defer emission until we've visited the parent function and all the catch
-    // handlers.  Cleanups don't contribute to the ip2state table, so don't count
-    // them.
-    if (ParentF != F && !FuncInfo.CatchHandlerMaxState.count(F))
-      return;
-    ++FuncInfo.NumIPToStateFuncsVisited;
-    if (FuncInfo.NumIPToStateFuncsVisited != FuncInfo.CatchHandlerMaxState.size())
-      return;
+    if (!MMI->hasEHFunclets()) {
+      // Defer emission until we've visited the parent function and all the
+      // catch handlers.  Cleanups don't contribute to the ip2state table, so
+      // don't count them.
+      if (ParentF != F && !FuncInfo.CatchHandlerMaxState.count(F))
+        return;
+      ++FuncInfo.NumIPToStateFuncsVisited;
+      if (FuncInfo.NumIPToStateFuncsVisited !=
+          FuncInfo.CatchHandlerMaxState.size())
+        return;
+    }
   } else {
     FuncInfoXData = Asm->OutContext.getOrCreateLSDASymbol(ParentLinkageName);
     emitEHRegistrationOffsetLabel(FuncInfo, ParentLinkageName);
@@ -410,11 +419,13 @@ void WinException::emitCXXFrameHandler3T
 
       HandlerMaps.push_back(HandlerMapXData);
 
-      int CatchHigh = -1;
-      for (WinEHHandlerType &HT : TBME.HandlerArray)
-        CatchHigh =
-            std::max(CatchHigh,
-                     FuncInfo.CatchHandlerMaxState[cast<Function>(HT.Handler)]);
+      int CatchHigh = TBME.CatchHigh;
+      if (CatchHigh == -1) {
+        for (WinEHHandlerType &HT : TBME.HandlerArray)
+          CatchHigh = std::max(
+              CatchHigh,
+              FuncInfo.CatchHandlerMaxState[cast<Function>(HT.Handler)]);
+      }
 
       assert(TBME.TryLow <= TBME.TryHigh);
       OS.EmitIntValue(TBME.TryLow, 4);                    // TryLow
@@ -456,7 +467,10 @@ void WinException::emitCXXFrameHandler3T
         OS.EmitIntValue(HT.Adjectives, 4);                    // Adjectives
         OS.EmitValue(create32bitRef(HT.TypeDescriptor), 4);   // Type
         OS.EmitValue(FrameAllocOffsetRef, 4);                 // CatchObjOffset
-        OS.EmitValue(create32bitRef(HT.Handler), 4);          // Handler
+        if (HT.HandlerMBB)                                    // Handler
+          OS.EmitValue(create32bitRef(HT.HandlerMBB->getSymbol()), 4);
+        else
+          OS.EmitValue(create32bitRef(HT.Handler), 4);
 
         if (shouldEmitPersonality) {
           MCSymbol *ParentFrameOffset =

Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original)
+++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Thu Aug 27 18:27:47 2015
@@ -1001,7 +1001,7 @@ bool BranchFolder::TailMergeBlocks(Machi
         // Failing case: the only way IBB can be reached from PBB is via
         // exception handling.  Happens for landing pads.  Would be nice to have
         // a bit in the edge so we didn't have to do all this.
-        if (IBB->isLandingPad()) {
+        if (IBB->isEHPad()) {
           MachineFunction::iterator IP = PBB;  IP++;
           MachineBasicBlock *PredNextBB = nullptr;
           if (IP != MF.end())
@@ -1178,13 +1178,13 @@ ReoptimizeBlock:
   // explicitly.  Landing pads should not do this since the landing-pad table
   // points to this block.  Blocks with their addresses taken shouldn't be
   // optimized away.
-  if (IsEmptyBlock(MBB) && !MBB->isLandingPad() && !MBB->hasAddressTaken()) {
+  if (IsEmptyBlock(MBB) && !MBB->isEHPad() && !MBB->hasAddressTaken()) {
     // Dead block?  Leave for cleanup later.
     if (MBB->pred_empty()) return MadeChange;
 
     if (FallThrough == MF.end()) {
       // TODO: Simplify preds to not branch here if possible!
-    } else if (FallThrough->isLandingPad()) {
+    } else if (FallThrough->isEHPad()) {
       // Don't rewrite to a landing pad fallthough.  That could lead to the case
       // where a BB jumps to more than one landing pad.
       // TODO: Is it ever worth rewriting predecessors which don't already
@@ -1241,7 +1241,7 @@ ReoptimizeBlock:
     // AnalyzeBranch.
     if (PriorCond.empty() && !PriorTBB && MBB->pred_size() == 1 &&
         PrevBB.succ_size() == 1 &&
-        !MBB->hasAddressTaken() && !MBB->isLandingPad()) {
+        !MBB->hasAddressTaken() && !MBB->isEHPad()) {
       DEBUG(dbgs() << "\nMerging into block: " << PrevBB
                    << "From MBB: " << *MBB);
       // Remove redundant DBG_VALUEs first.
@@ -1472,7 +1472,7 @@ ReoptimizeBlock:
     // see if it has a fall-through into its successor.
     bool CurFallsThru = MBB->canFallThrough();
 
-    if (!MBB->isLandingPad()) {
+    if (!MBB->isEHPad()) {
       // Check all the predecessors of this block.  If one of them has no fall
       // throughs, move this block right after it.
       for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
@@ -1523,7 +1523,7 @@ ReoptimizeBlock:
         // fallthrough to happen.
         if (SuccBB != MBB && &*SuccPrev != MBB &&
             !SuccPrev->canFallThrough() && !CurUnAnalyzable &&
-            !SuccBB->isLandingPad()) {
+            !SuccBB->isEHPad()) {
           MBB->moveBefore(SuccBB);
           MadeChange = true;
           goto ReoptimizeBlock;

Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Thu Aug 27 18:27:47 2015
@@ -299,7 +299,7 @@ void LiveIntervals::computeLiveInRegUnit
     const MachineBasicBlock *MBB = MFI;
 
     // We only care about ABI blocks: Entry + landing pads.
-    if ((MFI != MF->begin() && !MBB->isLandingPad()) || MBB->livein_empty())
+    if ((MFI != MF->begin() && !MBB->isEHPad()) || MBB->livein_empty())
       continue;
 
     // Create phi-defs at Begin for all live-in registers.

Modified: llvm/trunk/lib/CodeGen/LiveVariables.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveVariables.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveVariables.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveVariables.cpp Thu Aug 27 18:27:47 2015
@@ -598,7 +598,7 @@ void LiveVariables::runOnBlock(MachineBa
   for (MachineBasicBlock::const_succ_iterator SI = MBB->succ_begin(),
          SE = MBB->succ_end(); SI != SE; ++SI) {
     MachineBasicBlock *SuccMBB = *SI;
-    if (SuccMBB->isLandingPad())
+    if (SuccMBB->isEHPad())
       continue;
     for (unsigned LI : SuccMBB->liveins()) {
       if (!TRI->isInAllocatableClass(LI))

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp Thu Aug 27 18:27:47 2015
@@ -368,7 +368,7 @@ bool MIParser::parseBasicBlockDefinition
     MBB->setAlignment(Alignment);
   if (HasAddressTaken)
     MBB->setHasAddressTaken();
-  MBB->setIsLandingPad(IsLandingPad);
+  MBB->setIsEHPad(IsLandingPad);
   return false;
 }
 

Modified: llvm/trunk/lib/CodeGen/MIRPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRPrinter.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRPrinter.cpp Thu Aug 27 18:27:47 2015
@@ -439,7 +439,7 @@ void MIPrinter::print(const MachineBasic
     OS << "address-taken";
     HasAttributes = true;
   }
-  if (MBB.isLandingPad()) {
+  if (MBB.isEHPad()) {
     OS << (HasAttributes ? ", " : " (");
     OS << "landing-pad";
     HasAttributes = true;

Modified: llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Thu Aug 27 18:27:47 2015
@@ -39,8 +39,7 @@ using namespace llvm;
 #define DEBUG_TYPE "codegen"
 
 MachineBasicBlock::MachineBasicBlock(MachineFunction &mf, const BasicBlock *bb)
-  : BB(bb), Number(-1), xParent(&mf), Alignment(0), IsLandingPad(false),
-    AddressTaken(false), CachedMCSymbol(nullptr) {
+    : BB(bb), Number(-1), xParent(&mf) {
   Insts.Parent = this;
 }
 
@@ -203,7 +202,7 @@ const MachineBasicBlock *MachineBasicBlo
   if (succ_size() > 2)
     return nullptr;
   for (const_succ_iterator I = succ_begin(), E = succ_end(); I != E; ++I)
-    if ((*I)->isLandingPad())
+    if ((*I)->isEHPad())
       return *I;
   return nullptr;
 }
@@ -266,7 +265,7 @@ void MachineBasicBlock::print(raw_ostrea
     LBB->printAsOperand(OS, /*PrintType=*/false, MST);
     Comma = ", ";
   }
-  if (isLandingPad()) { OS << Comma << "EH LANDING PAD"; Comma = ", "; }
+  if (isEHPad()) { OS << Comma << "EH LANDING PAD"; Comma = ", "; }
   if (hasAddressTaken()) { OS << Comma << "ADDRESS TAKEN"; Comma = ", "; }
   if (Alignment)
     OS << Comma << "Align " << Alignment << " (" << (1u << Alignment)
@@ -338,7 +337,7 @@ MachineBasicBlock::addLiveIn(MCPhysReg P
   assert(getParent() && "MBB must be inserted in function");
   assert(TargetRegisterInfo::isPhysicalRegister(PhysReg) && "Expected physreg");
   assert(RC && "Register class is required");
-  assert((isLandingPad() || this == &getParent()->front()) &&
+  assert((isEHPad() || this == &getParent()->front()) &&
          "Only the entry block and landing pads can have physreg live ins");
 
   bool LiveIn = isLiveIn(PhysReg);
@@ -396,7 +395,7 @@ void MachineBasicBlock::updateTerminator
       // its layout successor, insert a branch. First we have to locate the
       // only non-landing-pad successor, as that is the fallthrough block.
       for (succ_iterator SI = succ_begin(), SE = succ_end(); SI != SE; ++SI) {
-        if ((*SI)->isLandingPad())
+        if ((*SI)->isEHPad())
           continue;
         assert(!TBB && "Found more than one non-landing-pad successor!");
         TBB = *SI;
@@ -432,7 +431,7 @@ void MachineBasicBlock::updateTerminator
       // as the fallthrough successor.
       MachineBasicBlock *FallthroughBB = nullptr;
       for (succ_iterator SI = succ_begin(), SE = succ_end(); SI != SE; ++SI) {
-        if ((*SI)->isLandingPad() || *SI == TBB)
+        if ((*SI)->isEHPad() || *SI == TBB)
           continue;
         assert(!FallthroughBB && "Found more than one fallthrough successor.");
         FallthroughBB = *SI;
@@ -662,7 +661,7 @@ MachineBasicBlock *
 MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) {
   // Splitting the critical edge to a landing pad block is non-trivial. Don't do
   // it in this generic function.
-  if (Succ->isLandingPad())
+  if (Succ->isEHPad())
     return nullptr;
 
   MachineFunction *MF = getParent();
@@ -1046,7 +1045,7 @@ bool MachineBasicBlock::CorrectExtraCFGE
   while (SI != succ_end()) {
     const MachineBasicBlock *MBB = *SI;
     if (!SeenMBBs.insert(MBB).second ||
-        (MBB != DestA && MBB != DestB && !MBB->isLandingPad())) {
+        (MBB != DestA && MBB != DestB && !MBB->isEHPad())) {
       // This is a superfluous edge, remove it.
       SI = removeSuccessor(SI);
       Changed = true;

Modified: llvm/trunk/lib/CodeGen/MachineBlockPlacement.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineBlockPlacement.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineBlockPlacement.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineBlockPlacement.cpp Thu Aug 27 18:27:47 2015
@@ -678,7 +678,7 @@ MachineBlockPlacement::findBestLoopExit(
     uint32_t WeightScale = 0;
     uint32_t SumWeight = MBPI->getSumForBlock(MBB, WeightScale);
     for (MachineBasicBlock *Succ : MBB->successors()) {
-      if (Succ->isLandingPad())
+      if (Succ->isEHPad())
         continue;
       if (Succ == MBB)
         continue;

Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLICM.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineLICM.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineLICM.cpp Thu Aug 27 18:27:47 2015
@@ -529,7 +529,7 @@ void MachineLICM::HoistRegionPostRA() {
     // If the header of the loop containing this basic block is a landing pad,
     // then don't try to hoist instructions out of this loop.
     const MachineLoop *ML = MLI->getLoopFor(BB);
-    if (ML && ML->getHeader()->isLandingPad()) continue;
+    if (ML && ML->getHeader()->isEHPad()) continue;
 
     // Conservatively treat live-in's as an external def.
     // FIXME: That means a reload that're reused in successor block(s) will not
@@ -725,7 +725,7 @@ void MachineLICM::HoistOutOfLoop(Machine
     // If the header of the loop containing this basic block is a landing pad,
     // then don't try to hoist instructions out of this loop.
     const MachineLoop *ML = MLI->getLoopFor(BB);
-    if (ML && ML->getHeader()->isLandingPad())
+    if (ML && ML->getHeader()->isEHPad())
       continue;
 
     // If this subregion is not in the top level loop at all, exit.

Modified: llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp Thu Aug 27 18:27:47 2015
@@ -209,6 +209,7 @@ bool MachineModuleInfo::doInitialization
   CurCallSite = 0;
   CallsEHReturn = false;
   CallsUnwindInit = false;
+  HasEHFunclets = false;
   DbgInfoAvailable = UsesVAFloatArgument = UsesMorestackAddr = false;
   // Always emit some info, by default "no personality" info.
   Personalities.push_back(nullptr);
@@ -249,6 +250,7 @@ void MachineModuleInfo::EndFunction() {
   FilterEnds.clear();
   CallsEHReturn = false;
   CallsUnwindInit = false;
+  HasEHFunclets = false;
   VariableDbgInfos.clear();
 }
 

Modified: llvm/trunk/lib/CodeGen/MachineSink.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineSink.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineSink.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineSink.cpp Thu Aug 27 18:27:47 2015
@@ -667,7 +667,7 @@ MachineBasicBlock *MachineSinking::FindS
 
   // It's not safe to sink instructions to EH landing pad. Control flow into
   // landing pad is implicitly defined.
-  if (SuccToSinkTo && SuccToSinkTo->isLandingPad())
+  if (SuccToSinkTo && SuccToSinkTo->isEHPad())
     return nullptr;
 
   return SuccToSinkTo;

Modified: llvm/trunk/lib/CodeGen/MachineVerifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineVerifier.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineVerifier.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineVerifier.cpp Thu Aug 27 18:27:47 2015
@@ -508,7 +508,7 @@ MachineVerifier::visitMachineBasicBlockB
     // If this block has allocatable physical registers live-in, check that
     // it is an entry block or landing pad.
     for (unsigned LI : MBB->liveins()) {
-      if (isAllocatable(LI) && !MBB->isLandingPad() &&
+      if (isAllocatable(LI) && !MBB->isEHPad() &&
           MBB != MBB->getParent()->begin()) {
         report("MBB has allocable live-in, but isn't entry or landing-pad.", MBB);
       }
@@ -519,7 +519,7 @@ MachineVerifier::visitMachineBasicBlockB
   SmallPtrSet<MachineBasicBlock*, 4> LandingPadSuccs;
   for (MachineBasicBlock::const_succ_iterator I = MBB->succ_begin(),
        E = MBB->succ_end(); I != E; ++I) {
-    if ((*I)->isLandingPad())
+    if ((*I)->isEHPad())
       LandingPadSuccs.insert(*I);
     if (!FunctionBlocks.count(*I))
       report("MBB has successor that isn't part of the function.", MBB);
@@ -1606,7 +1606,7 @@ void MachineVerifier::verifyLiveRangeSeg
     assert(LiveInts->isLiveInToMBB(LR, MFI));
     // We don't know how to track physregs into a landing pad.
     if (!TargetRegisterInfo::isVirtualRegister(Reg) &&
-        MFI->isLandingPad()) {
+        MFI->isEHPad()) {
       if (&*MFI == EndMBB)
         break;
       ++MFI;

Modified: llvm/trunk/lib/CodeGen/PHIElimination.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PHIElimination.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/PHIElimination.cpp (original)
+++ llvm/trunk/lib/CodeGen/PHIElimination.cpp Thu Aug 27 18:27:47 2015
@@ -548,7 +548,7 @@ void PHIElimination::analyzePHINodes(con
 bool PHIElimination::SplitPHIEdges(MachineFunction &MF,
                                    MachineBasicBlock &MBB,
                                    MachineLoopInfo *MLI) {
-  if (MBB.empty() || !MBB.front().isPHI() || MBB.isLandingPad())
+  if (MBB.empty() || !MBB.front().isPHI() || MBB.isEHPad())
     return false;   // Quick exit for basic blocks without PHIs.
 
   const MachineLoop *CurLoop = MLI ? MLI->getLoopFor(&MBB) : nullptr;

Modified: llvm/trunk/lib/CodeGen/PHIEliminationUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PHIEliminationUtils.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/PHIEliminationUtils.cpp (original)
+++ llvm/trunk/lib/CodeGen/PHIEliminationUtils.cpp Thu Aug 27 18:27:47 2015
@@ -28,7 +28,7 @@ llvm::findPHICopyInsertPoint(MachineBasi
   // Usually, we just want to insert the copy before the first terminator
   // instruction. However, for the edge going to a landing pad, we must insert
   // the copy before the call/invoke instruction.
-  if (!SuccMBB->isLandingPad())
+  if (!SuccMBB->isEHPad())
     return MBB->getFirstTerminator();
 
   // Discover any defs/uses in this basic block.

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp Thu Aug 27 18:27:47 2015
@@ -252,16 +252,17 @@ void FunctionLoweringInfo::set(const Fun
   // Mark landing pad blocks.
   SmallVector<const LandingPadInst *, 4> LPads;
   for (BB = Fn->begin(); BB != EB; ++BB) {
-    if (const auto *Invoke = dyn_cast<InvokeInst>(BB->getTerminator()))
-      MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad();
-    if (BB->isLandingPad())
-      LPads.push_back(BB->getLandingPadInst());
+    if (BB->isEHPad())
+      MBBMap[BB]->setIsEHPad();
+    const Instruction *FNP = BB->getFirstNonPHI();
+    if (const auto *LPI = dyn_cast<LandingPadInst>(FNP))
+      LPads.push_back(LPI);
   }
 
   // If this is an MSVC EH personality, we need to do a bit more work.
-  EHPersonality Personality = EHPersonality::Unknown;
-  if (Fn->hasPersonalityFn())
-    Personality = classifyEHPersonality(Fn->getPersonalityFn());
+  if (!Fn->hasPersonalityFn())
+    return;
+  EHPersonality Personality = classifyEHPersonality(Fn->getPersonalityFn());
   if (!isMSVCEHPersonality(Personality))
     return;
 
@@ -272,8 +273,13 @@ void FunctionLoweringInfo::set(const Fun
 
   WinEHFuncInfo &EHInfo = MMI.getWinEHFuncInfo(&fn);
   if (Personality == EHPersonality::MSVC_CXX) {
+    // Calculate state numbers and then map from funclet BBs to MBBs.
     const Function *WinEHParentFn = MMI.getWinEHParent(&fn);
     calculateWinCXXEHStateNumbers(WinEHParentFn, EHInfo);
+    for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap)
+      for (WinEHHandlerType &H : TBME.HandlerArray)
+        if (const auto *BB = dyn_cast<BasicBlock>(H.Handler))
+          H.HandlerMBB = MBBMap[BB];
   }
 
   // Copy the state numbers to LandingPadInfo for the current function, which

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Thu Aug 27 18:27:47 2015
@@ -1158,30 +1158,56 @@ SDValue SelectionDAGBuilder::getValueImp
   llvm_unreachable("Can't get register for value!");
 }
 
-void SelectionDAGBuilder::visitCleanupRet(const CleanupReturnInst &I) {
-  report_fatal_error("visitCleanupRet not yet implemented!");
-}
+void SelectionDAGBuilder::visitCatchPad(const CatchPadInst &I) {
+  // Update machine-CFG edges.
+  MachineBasicBlock *PadMBB = FuncInfo.MBB;
+  MachineBasicBlock *CatchingMBB = FuncInfo.MBBMap[I.getNormalDest()];
+  MachineBasicBlock *UnwindMBB = FuncInfo.MBBMap[I.getUnwindDest()];
+  PadMBB->addSuccessor(CatchingMBB);
+  PadMBB->addSuccessor(UnwindMBB);
 
-void SelectionDAGBuilder::visitCatchEndPad(const CatchEndPadInst &I) {
-  report_fatal_error("visitCatchEndPad not yet implemented!");
+  CatchingMBB->setIsEHFuncletEntry();
+  MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
+  MMI.setHasEHFunclets(true);
 }
 
 void SelectionDAGBuilder::visitCatchRet(const CatchReturnInst &I) {
-  report_fatal_error("visitCatchRet not yet implemented!");
+  // Update machine-CFG edge.
+  MachineBasicBlock *PadMBB = FuncInfo.MBB;
+  MachineBasicBlock *TargetMBB = FuncInfo.MBBMap[I.getSuccessor()];
+  PadMBB->addSuccessor(TargetMBB);
+
+  // Create the terminator node.
+  SDValue Ret = DAG.getNode(ISD::CATCHRET, getCurSDLoc(), MVT::Other,
+                            getControlRoot(), DAG.getBasicBlock(TargetMBB));
+  DAG.setRoot(Ret);
 }
 
-void SelectionDAGBuilder::visitCatchPad(const CatchPadInst &I) {
-  report_fatal_error("visitCatchPad not yet implemented!");
-}
+void SelectionDAGBuilder::visitCatchEndPad(const CatchEndPadInst &I) {
+  // If this unwinds to caller, we don't need a DAG node hanging around.
+  if (!I.hasUnwindDest())
+    return;
 
-void SelectionDAGBuilder::visitTerminatePad(const TerminatePadInst &TPI) {
-  report_fatal_error("visitTerminatePad not yet implemented!");
+  // Update machine-CFG edge.
+  MachineBasicBlock *PadMBB = FuncInfo.MBB;
+  MachineBasicBlock *UnwindMBB = FuncInfo.MBBMap[I.getUnwindDest()];
+  PadMBB->addSuccessor(UnwindMBB);
 }
 
 void SelectionDAGBuilder::visitCleanupPad(const CleanupPadInst &CPI) {
+  MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
+  MMI.setHasEHFunclets(true);
   report_fatal_error("visitCleanupPad not yet implemented!");
 }
 
+void SelectionDAGBuilder::visitCleanupRet(const CleanupReturnInst &I) {
+  report_fatal_error("visitCleanupRet not yet implemented!");
+}
+
+void SelectionDAGBuilder::visitTerminatePad(const TerminatePadInst &TPI) {
+  report_fatal_error("visitTerminatePad not yet implemented!");
+}
+
 void SelectionDAGBuilder::visitRet(const ReturnInst &I) {
   const TargetLowering &TLI = DAG.getTargetLoweringInfo();
   auto &DL = DAG.getDataLayout();
@@ -2021,7 +2047,7 @@ void SelectionDAGBuilder::visitResume(co
 }
 
 void SelectionDAGBuilder::visitLandingPad(const LandingPadInst &LP) {
-  assert(FuncInfo.MBB->isLandingPad() &&
+  assert(FuncInfo.MBB->isEHPad() &&
          "Call to landingpad not in landing pad!");
 
   MachineBasicBlock *MBB = FuncInfo.MBB;
@@ -5094,7 +5120,7 @@ SelectionDAGBuilder::visitIntrinsicCall(
     assert(Reg && "cannot get exception code on this platform");
     MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
     const TargetRegisterClass *PtrRC = TLI.getRegClassFor(PtrVT);
-    assert(FuncInfo.MBB->isLandingPad() && "eh.exceptioncode in non-lpad");
+    assert(FuncInfo.MBB->isEHPad() && "eh.exceptioncode in non-lpad");
     unsigned VReg = FuncInfo.MBB->addLiveIn(Reg, PtrRC);
     SDValue N =
         DAG.getCopyFromReg(DAG.getEntryNode(), getCurSDLoc(), VReg, PtrVT);

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp Thu Aug 27 18:27:47 2015
@@ -278,6 +278,10 @@ std::string SDNode::getOperationName(con
   case ISD::CALLSEQ_START:              return "callseq_start";
   case ISD::CALLSEQ_END:                return "callseq_end";
 
+    // EH instructions
+  case ISD::CATCHRET:                   return "catchret";
+  case ISD::CLEANUPRET:                 return "cleanupret";
+
     // Other operators
   case ISD::LOAD:                       return "load";
   case ISD::STORE:                      return "store";

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Aug 27 18:27:47 2015
@@ -19,6 +19,7 @@
 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/Analysis/BranchProbabilityInfo.h"
 #include "llvm/Analysis/CFG.h"
+#include "llvm/Analysis/LibCallSemantics.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/CodeGen/Analysis.h"
 #include "llvm/CodeGen/FastISel.h"
@@ -969,7 +970,7 @@ bool SelectionDAGISel::PrepareEHLandingP
           InvokeBB->addSuccessor(ClauseBB);
 
         // Mark the clause as a landing pad or MI passes will delete it.
-        ClauseBB->setIsLandingPad();
+        ClauseBB->setIsEHPad();
       }
     }
 
@@ -998,9 +999,9 @@ bool SelectionDAGISel::PrepareEHLandingP
 static bool isFoldedOrDeadInstruction(const Instruction *I,
                                       FunctionLoweringInfo *FuncInfo) {
   return !I->mayWriteToMemory() && // Side-effecting instructions aren't folded.
-         !isa<TerminatorInst>(I) && // Terminators aren't folded.
+         !isa<TerminatorInst>(I) &&    // Terminators aren't folded.
          !isa<DbgInfoIntrinsic>(I) &&  // Debug instructions aren't folded.
-         !isa<LandingPadInst>(I) &&    // Landingpad instructions aren't folded.
+         !I->isEHPad() &&              // EH pad instructions aren't folded.
          !FuncInfo->isExportedInst(I); // Exported instrs must be computed.
 }
 
@@ -1163,6 +1164,7 @@ void SelectionDAGISel::SelectAllBasicBlo
       if (!PrepareEHLandingPad())
         continue;
 
+
     // Before doing SelectionDAG ISel, see if FastISel has been requested.
     if (FastIS) {
       FastIS->startNewBlock();
@@ -1251,7 +1253,8 @@ void SelectionDAGISel::SelectAllBasicBlo
             // For the purpose of debugging, just abort.
             report_fatal_error("FastISel didn't select the entire block");
 
-          if (!Inst->getType()->isVoidTy() && !Inst->use_empty()) {
+          if (!Inst->getType()->isVoidTy() && !Inst->getType()->isTokenTy() &&
+              !Inst->use_empty()) {
             unsigned &R = FuncInfo->ValueMap[Inst];
             if (!R)
               R = FuncInfo->CreateRegs(Inst->getType());

Modified: llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/WinEHPrepare.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/WinEHPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/WinEHPrepare.cpp Thu Aug 27 18:27:47 2015
@@ -2608,7 +2608,8 @@ static void addTryBlockMapEntry(WinEHFun
       HT.TypeDescriptor =
           cast<GlobalVariable>(CS->getAggregateElement(1)->stripPointerCasts());
     }
-    HT.Handler = CPI->getParent();
+    HT.Handler = CPI->getNormalDest();
+    HT.HandlerMBB = nullptr;
     // FIXME: Pass CPI->getArgOperand(1).
     HT.CatchObjRecoverIdx = -1;
     TBME.HandlerArray.push_back(HT);
@@ -2684,6 +2685,7 @@ void WinEHNumbering::createTryBlockMapEn
           cast<GlobalVariable>(CS->getAggregateElement(1)->stripPointerCasts());
     }
     HT.Handler = cast<Function>(CH->getHandlerBlockOrFunc());
+    HT.HandlerMBB = nullptr;
     HT.CatchObjRecoverIdx = CH->getExceptionVarIndex();
     TBME.HandlerArray.push_back(HT);
   }

Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Thu Aug 27 18:27:47 2015
@@ -6931,7 +6931,7 @@ void ARMTargetLowering::EmitSjLjDispatch
   MachineModuleInfo &MMI = MF->getMMI();
   for (MachineFunction::iterator BB = MF->begin(), E = MF->end(); BB != E;
        ++BB) {
-    if (!BB->isLandingPad()) continue;
+    if (!BB->isEHPad()) continue;
 
     // FIXME: We should assert that the EH_LABEL is the first MI in the landing
     // pad.
@@ -6979,7 +6979,7 @@ void ARMTargetLowering::EmitSjLjDispatch
 
   // Shove the dispatch's address into the return slot in the function context.
   MachineBasicBlock *DispatchBB = MF->CreateMachineBasicBlock();
-  DispatchBB->setIsLandingPad();
+  DispatchBB->setIsEHPad();
 
   MachineBasicBlock *TrapBB = MF->CreateMachineBasicBlock();
   unsigned trap_opcode;
@@ -7245,7 +7245,7 @@ void ARMTargetLowering::EmitSjLjDispatch
                                                   BB->succ_end());
     while (!Successors.empty()) {
       MachineBasicBlock *SMBB = Successors.pop_back_val();
-      if (SMBB->isLandingPad()) {
+      if (SMBB->isEHPad()) {
         BB->removeSuccessor(SMBB);
         MBBLPads.push_back(SMBB);
       }
@@ -7293,7 +7293,7 @@ void ARMTargetLowering::EmitSjLjDispatch
   // landing pad now.
   for (SmallVectorImpl<MachineBasicBlock*>::iterator
          I = MBBLPads.begin(), E = MBBLPads.end(); I != E; ++I)
-    (*I)->setIsLandingPad(false);
+    (*I)->setIsEHPad(false);
 
   // The instruction is gone now.
   MI->eraseFromParent();

Modified: llvm/trunk/lib/Target/Hexagon/BitTracker.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/BitTracker.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/BitTracker.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/BitTracker.cpp Thu Aug 27 18:27:47 2015
@@ -951,7 +951,7 @@ void BT::visitBranchesFrom(const Machine
     // be processed.
     for (succ_iterator I = B.succ_begin(), E = B.succ_end(); I != E; ++I) {
       const MachineBasicBlock *SB = *I;
-      if (SB->isLandingPad())
+      if (SB->isEHPad())
         Targets.insert(SB);
     }
     if (FallsThrough) {

Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp Thu Aug 27 18:27:47 2015
@@ -405,7 +405,7 @@ bool MipsAsmPrinter::isBlockOnlyReachabl
 
   // If this is a landing pad, it isn't a fall through.  If it has no preds,
   // then nothing falls through to it.
-  if (MBB->isLandingPad() || MBB->pred_empty())
+  if (MBB->isEHPad() || MBB->pred_empty())
     return false;
 
   // If there isn't exactly one predecessor, it can't be a fall through.

Modified: llvm/trunk/lib/Target/Mips/MipsDelaySlotFiller.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsDelaySlotFiller.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsDelaySlotFiller.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsDelaySlotFiller.cpp Thu Aug 27 18:27:47 2015
@@ -806,7 +806,7 @@ MachineBasicBlock *Filler::selectSuccBB(
                                                const MachineBasicBlock *Dst1) {
     return Prob.getEdgeWeight(&B, Dst0) < Prob.getEdgeWeight(&B, Dst1);
   });
-  return S->isLandingPad() ? nullptr : S;
+  return S->isEHPad() ? nullptr : S;
 }
 
 std::pair<MipsInstrInfo::BranchType, MachineInstr *>

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu Aug 27 18:27:47 2015
@@ -407,6 +407,7 @@ X86TargetLowering::X86TargetLowering(con
     setOperationAction(ISD::SETCC         , MVT::i64  , Custom);
   }
   setOperationAction(ISD::EH_RETURN       , MVT::Other, Custom);
+  setOperationAction(ISD::CATCHRET        , MVT::Other, Custom);
   // NOTE: EH_SJLJ_SETJMP/_LONGJMP supported here is NOT intended to support
   // SjLj exception handling but a light-weight setjmp/longjmp replacement to
   // support continuation, user-level threading, and etc.. As a result, no
@@ -16664,6 +16665,25 @@ SDValue X86TargetLowering::LowerEH_RETUR
                      DAG.getRegister(StoreAddrReg, PtrVT));
 }
 
+SDValue X86TargetLowering::LowerCATCHRET(SDValue Op, SelectionDAG &DAG) const {
+  SDValue Chain = Op.getOperand(0);
+  SDValue Dest = Op.getOperand(1);
+  SDLoc DL(Op);
+
+  MVT PtrVT = getPointerTy(DAG.getDataLayout());
+  unsigned ReturnReg = (PtrVT == MVT::i64 ? X86::RAX : X86::EAX);
+
+  // Load the address of the destination block.
+  MachineBasicBlock *DestMBB = cast<BasicBlockSDNode>(Dest)->getBasicBlock();
+  SDValue BlockPtr = DAG.getMCSymbol(DestMBB->getSymbol(), PtrVT);
+  unsigned WrapperKind =
+      Subtarget->isPICStyleRIPRel() ? X86ISD::WrapperRIP : X86ISD::Wrapper;
+  SDValue WrappedPtr = DAG.getNode(WrapperKind, DL, PtrVT, BlockPtr);
+  Chain = DAG.getCopyToReg(Chain, DL, ReturnReg, WrappedPtr);
+  return DAG.getNode(X86ISD::CATCHRET, DL, MVT::Other, Chain,
+                     DAG.getRegister(ReturnReg, PtrVT));
+}
+
 SDValue X86TargetLowering::lowerEH_SJLJ_SETJMP(SDValue Op,
                                                SelectionDAG &DAG) const {
   SDLoc DL(Op);
@@ -18903,6 +18923,7 @@ SDValue X86TargetLowering::LowerOperatio
                                 return LowerFRAME_TO_ARGS_OFFSET(Op, DAG);
   case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
   case ISD::EH_RETURN:          return LowerEH_RETURN(Op, DAG);
+  case ISD::CATCHRET:           return LowerCATCHRET(Op, DAG);
   case ISD::EH_SJLJ_SETJMP:     return lowerEH_SJLJ_SETJMP(Op, DAG);
   case ISD::EH_SJLJ_LONGJMP:    return lowerEH_SJLJ_LONGJMP(Op, DAG);
   case ISD::INIT_TRAMPOLINE:    return LowerINIT_TRAMPOLINE(Op, DAG);
@@ -19238,6 +19259,7 @@ const char *X86TargetLowering::getTarget
   case X86ISD::EH_SJLJ_SETJMP:     return "X86ISD::EH_SJLJ_SETJMP";
   case X86ISD::EH_SJLJ_LONGJMP:    return "X86ISD::EH_SJLJ_LONGJMP";
   case X86ISD::EH_RETURN:          return "X86ISD::EH_RETURN";
+  case X86ISD::CATCHRET:           return "X86ISD::CATCHRET";
   case X86ISD::TC_RETURN:          return "X86ISD::TC_RETURN";
   case X86ISD::FNSTCW16m:          return "X86ISD::FNSTCW16m";
   case X86ISD::FNSTSW16r:          return "X86ISD::FNSTSW16r";

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Thu Aug 27 18:27:47 2015
@@ -261,6 +261,8 @@ namespace llvm {
       // Exception Handling helpers.
       EH_RETURN,
 
+      CATCHRET,
+
       // SjLj exception handling setjmp.
       EH_SJLJ_SETJMP,
 
@@ -998,6 +1000,7 @@ namespace llvm {
     SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerFRAME_TO_ARGS_OFFSET(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
+    SDValue LowerCATCHRET(SDValue Op, SelectionDAG &DAG) const;
     SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const;
     SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;

Modified: llvm/trunk/lib/Target/X86/X86InstrCompiler.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrCompiler.td?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrCompiler.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrCompiler.td Thu Aug 27 18:27:47 2015
@@ -152,6 +152,15 @@ def EH_RETURN64   : I<0xC3, RawFrm, (out
 
 }
 
+let isTerminator = 1, isBarrier = 1, hasCtrlDep = 1, isCodeGenOnly = 1 in {
+def CATCHRET   : I<0xC3, RawFrm, (outs), (ins GR32:$addr),
+                   "ret{l}\t# CATCHRET",
+                   [(X86catchret GR32:$addr)], IIC_RET>, Sched<[WriteJumpLd]>;
+def CATCHRET64 : I<0xC3, RawFrm, (outs), (ins GR64:$addr),
+                   "ret{q}\t# CATCHRET",
+                   [(X86catchret GR64:$addr)], IIC_RET>, Sched<[WriteJumpLd]>;
+}
+
 let hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1,
     usesCustomInserter = 1 in {
   def EH_SjLj_SetJmp32  : I<0, Pseudo, (outs GR32:$dst), (ins i32mem:$buf),

Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Thu Aug 27 18:27:47 2015
@@ -205,6 +205,8 @@ def X86tlsbaseaddr : SDNode<"X86ISD::TLS
 def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET,
                         [SDNPHasChain]>;
 
+def X86catchret : SDNode<"X86ISD::CATCHRET", SDT_X86EHRET, [SDNPHasChain]>;
+
 def X86eh_sjlj_setjmp  : SDNode<"X86ISD::EH_SJLJ_SETJMP",
                                 SDTypeProfile<1, 1, [SDTCisInt<0>,
                                                      SDTCisPtrTy<1>]>,

Modified: llvm/trunk/lib/Target/X86/X86MCInstLower.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86MCInstLower.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86MCInstLower.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86MCInstLower.cpp Thu Aug 27 18:27:47 2015
@@ -531,6 +531,12 @@ ReSimplify:
     break;
   }
 
+  case X86::CATCHRET: {
+    OutMI = MCInst();
+    OutMI.setOpcode(getRetOpcode(AsmPrinter.getSubtarget()));
+    break;
+  }
+
   // TAILJMPd, TAILJMPd64 - Lower to the correct jump instructions.
   case X86::TAILJMPr:
   case X86::TAILJMPd:

Modified: llvm/trunk/lib/Target/X86/X86WinEHState.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86WinEHState.cpp?rev=246235&r1=246234&r2=246235&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86WinEHState.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86WinEHState.cpp Thu Aug 27 18:27:47 2015
@@ -471,6 +471,8 @@ int WinEHStatePass::escapeRegNode(Functi
 void WinEHStatePass::addCXXStateStoresToFunclet(Value *ParentRegNode,
                                                 WinEHFuncInfo &FuncInfo,
                                                 Function &F, int BaseState) {
+  Function *RestoreFrame =
+      Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_restoreframe);
   // Iterate all the instructions and emit state number stores.
   for (BasicBlock &BB : F) {
     for (Instruction &I : BB) {
@@ -489,6 +491,14 @@ void WinEHStatePass::addCXXStateStoresTo
         insertStateNumberStore(ParentRegNode, II, State);
       }
     }
+
+    // Insert calls to llvm.x86.seh.restoreframe at catchret destinations.
+    if (auto *CR = dyn_cast<CatchReturnInst>(BB.getTerminator())) {
+      //llvm::errs() << "BB: " << BB << '\n';
+      //llvm::errs() << "CR->getSuccessor(): " << *CR->getSuccessor() << '\n';
+      IRBuilder<> Builder(CR->getSuccessor()->begin());
+      Builder.CreateCall(RestoreFrame, {});
+    }
   }
 }
 

Added: llvm/trunk/test/CodeGen/X86/win-catchpad.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/win-catchpad.ll?rev=246235&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/win-catchpad.ll (added)
+++ llvm/trunk/test/CodeGen/X86/win-catchpad.ll Thu Aug 27 18:27:47 2015
@@ -0,0 +1,130 @@
+; RUN: llc -mtriple=i686-pc-windows-msvc < %s | FileCheck --check-prefix=X86 %s
+; RUN: llc -mtriple=x86_64-pc-windows-msvc < %s | FileCheck --check-prefix=X64 %s
+
+; Loosely based on IR for this C++ source code:
+;   void f(int p);
+;   int main() {
+;     try {
+;       f(1);
+;     } catch (int) {
+;       f(2);
+;     } catch (...) {
+;       f(3);
+;     }
+;   }
+
+%rtti.TypeDescriptor2 = type { i8**, i8*, [3 x i8] }
+%eh.CatchableType = type { i32, i8*, i32, i32, i32, i32, i8* }
+%eh.CatchableTypeArray.1 = type { i32, [1 x %eh.CatchableType*] }
+%eh.ThrowInfo = type { i32, i8*, i8*, i8* }
+%eh.CatchHandlerType = type { i32, i8* }
+
+$"\01??_R0H at 8" = comdat any
+
+@"\01??_7type_info@@6B@" = external constant i8*
+@"\01??_R0H at 8" = linkonce_odr global %rtti.TypeDescriptor2 { i8** @"\01??_7type_info@@6B@", i8* null, [3 x i8] c".H\00" }, comdat
+
+ at llvm.eh.handlertype.H.0 = private unnamed_addr constant %eh.CatchHandlerType { i32 0, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H at 8" to i8*) }, section "llvm.metadata"
+ at llvm.eh.handlertype.H.1 = private unnamed_addr constant %eh.CatchHandlerType { i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H at 8" to i8*) }, section "llvm.metadata"
+
+declare void @f(i32 %p)
+declare i32 @__CxxFrameHandler3(...)
+
+define i32 @try_catch_catch() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
+entry:
+  invoke void @f(i32 1)
+          to label %try.cont unwind label %catch.dispatch
+
+catch.dispatch:                                   ; preds = %entry
+  %0 = catchpad [%eh.CatchHandlerType* @llvm.eh.handlertype.H.0, i8* null]
+          to label %catch unwind label %catch.dispatch.2
+
+catch:                                            ; preds = %catch.dispatch
+  invoke void @f(i32 2)
+          to label %invoke.cont.2 unwind label %catchendblock
+
+invoke.cont.2:                                    ; preds = %catch
+  catchret %0 to label %try.cont
+
+catch.dispatch.2:                                   ; preds = %catch.dispatch
+  %1 = catchpad [%eh.CatchHandlerType* @llvm.eh.handlertype.H.0, i8* null]
+          to label %catch.2 unwind label %catchendblock
+
+catch.2:                                            ; preds = %catch.dispatch.2
+  invoke void @f(i32 3)
+          to label %invoke.cont.3 unwind label %catchendblock
+
+invoke.cont.3:                                    ; preds = %catch.2
+  catchret %1 to label %try.cont
+
+try.cont:                                         ; preds = %entry, %invoke.cont.2, %invoke.cont.3
+  ret i32 0
+
+catchendblock:                                    ; preds = %catch, %catch.2, %catch.dispatch.2
+  catchendpad unwind to caller
+}
+
+; X86-LABEL: _try_catch_catch:
+; X86: movl $0, -{{[0-9]+}}(%ebp)
+; X86: movl $1, (%esp)
+; X86: calll _f
+; X86: [[contbb:LBB0_[0-9]+]]:
+; X86: movl -{{[0-9]+}}(%ebp), %esp
+; X86: retl
+
+; X86: [[catch1bb:LBB0_[0-9]+]]: # %catch{{$}}
+; X86: movl $1, -{{[0-9]+}}(%ebp)
+; X86: movl $2, (%esp)
+; X86: calll _f
+; X86: movl $[[contbb]], %eax
+; X86-NEXT: retl
+
+; X86: [[catch2bb:LBB0_[0-9]+]]: # %catch.2{{$}}
+; X86: movl $1, -{{[0-9]+}}(%ebp)
+; X86: movl $3, (%esp)
+; X86: calll _f
+; X86: movl $[[contbb]], %eax
+; X86-NEXT: retl
+
+; X86: L__ehtable$try_catch_catch:
+; X86: $handlerMap$0$try_catch_catch:
+; X86:   .long   0
+; X86:   .long   "??_R0H at 8"
+; X86:   .long   0
+; X86:   .long   [[catch1bb]]
+; X86:   .long   0
+; X86:   .long   "??_R0H at 8"
+; X86:   .long   0
+; X86:   .long   [[catch2bb]]
+
+; X64-LABEL: try_catch_catch:
+; X64: movl $1, %ecx
+; X64: callq f
+; X64: [[contbb:\.LBB0_[0-9]+]]:
+; X64: retq
+
+; X64: [[catch1bb:\.LBB0_[0-9]+]]: # %catch{{$}}
+; X64: movl $2, %ecx
+; X64: callq f
+; X64: leaq [[contbb]](%rip), %rax
+; X64: retq
+
+; X64: [[catch2bb:\.LBB0_[0-9]+]]: # %catch.2{{$}}
+; X64: movl $3, %ecx
+; X64: callq f
+; X64: leaq [[contbb]](%rip), %rax
+; X64: retq
+
+; FIXME: Get rid of these parent_frame_offset things below. They are leftover
+; from our IR outlining strategy.
+; X64: $handlerMap$0$try_catch_catch:
+; X64:   .long   0
+; X64:   .long   "??_R0H at 8"@IMGREL
+; X64:   .long   0
+; X64:   .long   [[catch1bb]]@IMGREL
+; X64    .long   .Lcatch$parent_frame_offset
+; X64:   .long   0
+; X64:   .long   "??_R0H at 8"@IMGREL
+; X64:   .long   0
+; X64:   .long   [[catch2bb]]@IMGREL
+; X64    .long   .Lcatch.2$parent_frame_offset




More information about the llvm-commits mailing list