[llvm] r248824 - [WinEH] Teach AsmPrinter about funclets

David Majnemer via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 29 13:12:33 PDT 2015


Author: majnemer
Date: Tue Sep 29 15:12:33 2015
New Revision: 248824

URL: http://llvm.org/viewvc/llvm-project?rev=248824&view=rev
Log:
[WinEH] Teach AsmPrinter about funclets

Summary:
Funclets have been turned into functions by the time they hit the object
file.  Make sure that they have decent names for the symbol table and
CFI directives explaining how to reason about their prologues.

Differential Revision: http://reviews.llvm.org/D13261

Added:
    llvm/trunk/test/CodeGen/X86/win-funclet-cfi.ll
Modified:
    llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h
    llvm/trunk/include/llvm/CodeGen/WinEHFuncInfo.h
    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterHandler.h
    llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/WinException.h
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
    llvm/trunk/lib/Target/X86/X86FrameLowering.cpp
    llvm/trunk/test/CodeGen/WinEH/seh-prepared-basic.ll
    llvm/trunk/test/CodeGen/X86/gcc_except_table.ll
    llvm/trunk/test/CodeGen/X86/seh-catch-all.ll
    llvm/trunk/test/CodeGen/X86/seh-except-finally.ll
    llvm/trunk/test/CodeGen/X86/seh-finally.ll
    llvm/trunk/test/CodeGen/X86/seh-safe-div.ll
    llvm/trunk/test/CodeGen/X86/win-catchpad-csrs.ll
    llvm/trunk/test/CodeGen/X86/win-catchpad.ll
    llvm/trunk/test/CodeGen/X86/win-cleanuppad.ll

Modified: llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h?rev=248824&r1=248823&r2=248824&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h Tue Sep 29 15:12:33 2015
@@ -114,6 +114,9 @@ protected:
   /// Indicate that this basic block is the entry block of an EH funclet.
   bool IsEHFuncletEntry = false;
 
+  /// Indicate that this basic block is the entry block of a cleanup funclet.
+  bool IsCleanupFuncletEntry = false;
+
   /// \brief since getSymbol is a relatively heavy-weight operation, the symbol
   /// is only computed once and is cached.
   mutable MCSymbol *CachedMCSymbol = nullptr;
@@ -392,6 +395,12 @@ public:
   /// Indicates if this is the entry block of an EH funclet.
   void setIsEHFuncletEntry(bool V = true) { IsEHFuncletEntry = V; }
 
+  /// Returns true if this is the entry block of a cleanup funclet.
+  bool isCleanupFuncletEntry() const { return IsCleanupFuncletEntry; }
+
+  /// Indicates if this is the entry block of a cleanup funclet.
+  void setIsCleanupFuncletEntry(bool V = true) { IsCleanupFuncletEntry = V; }
+
   // Code Layout methods.
 
   /// Move 'this' block before or after the specified block.  This only moves

Modified: llvm/trunk/include/llvm/CodeGen/WinEHFuncInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/WinEHFuncInfo.h?rev=248824&r1=248823&r2=248824&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/WinEHFuncInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/WinEHFuncInfo.h Tue Sep 29 15:12:33 2015
@@ -118,7 +118,7 @@ void parseEHActions(const IntrinsicInst
 // exceptions on Windows.
 
 typedef PointerUnion<const BasicBlock *, MachineBasicBlock *> MBBOrBasicBlock;
-typedef PointerUnion<const Value *, MachineBasicBlock *> ValueOrMBB;
+typedef PointerUnion<const Value *, const MachineBasicBlock *> ValueOrMBB;
 
 struct WinEHUnwindMapEntry {
   int ToState;

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=248824&r1=248823&r2=248824&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Tue Sep 29 15:12:33 2015
@@ -2459,6 +2459,14 @@ static void emitBasicBlockLoopComments(c
 /// MachineBasicBlock, an alignment (if present) and a comment describing
 /// it if appropriate.
 void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock &MBB) const {
+  // End the previous funclet and start a new one.
+  if (MBB.isEHFuncletEntry()) {
+    for (const HandlerInfo &HI : Handlers) {
+      HI.Handler->endFunclet();
+      HI.Handler->beginFunclet(MBB);
+    }
+  }
+
   // Emit an alignment directive for this block, if needed.
   if (unsigned Align = MBB.getAlignment())
     EmitAlignment(Align);

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterHandler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterHandler.h?rev=248824&r1=248823&r2=248824&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterHandler.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterHandler.h Tue Sep 29 15:12:33 2015
@@ -19,6 +19,7 @@
 
 namespace llvm {
 
+class MachineBasicBlock;
 class MachineFunction;
 class MachineInstr;
 class MCSymbol;
@@ -50,6 +51,11 @@ public:
   /// beginFunction at all.
   virtual void endFunction(const MachineFunction *MF) = 0;
 
+  /// \brief Emit target-specific EH funclet machinery.
+  virtual void beginFunclet(const MachineBasicBlock &MBB,
+                            MCSymbol *Sym = nullptr) {}
+  virtual void endFunclet() {}
+
   /// \brief Process beginning of an instruction.
   virtual void beginInstruction(const MachineInstr *MI) = 0;
 

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp?rev=248824&r1=248823&r2=248824&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp Tue Sep 29 15:12:33 2015
@@ -30,6 +30,7 @@
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/MC/MCWin64EH.h"
+#include "llvm/Support/COFF.h"
 #include "llvm/Support/Dwarf.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FormattedStream.h"
@@ -98,14 +99,7 @@ void WinException::beginFunction(const M
     return;
   }
 
-  if (shouldEmitMoves || shouldEmitPersonality)
-    Asm->OutStreamer->EmitWinCFIStartProc(Asm->CurrentFnSym);
-
-  if (shouldEmitPersonality) {
-    const MCSymbol *PersHandlerSym =
-        TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, Asm->TM, MMI);
-    Asm->OutStreamer->EmitWinEHHandler(PersHandlerSym, true, true);
-  }
+  beginFunclet(MF->front(), Asm->CurrentFnSym);
 }
 
 /// endFunction - Gather and emit post-function exception information.
@@ -125,20 +119,16 @@ void WinException::endFunction(const Mac
   if (!isMSVCEHPersonality(Per))
     MMI->TidyLandingPads();
 
+  endFunclet();
+
   if (shouldEmitPersonality || shouldEmitLSDA) {
     Asm->OutStreamer->PushSection();
 
-    if (shouldEmitMoves || shouldEmitPersonality) {
-      // Emit an UNWIND_INFO struct describing the prologue.
-      Asm->OutStreamer->EmitWinEHHandlerData();
-    } else {
-      // Just switch sections to the right xdata section. This use of
-      // CurrentFnSym assumes that we only emit the LSDA when ending the parent
-      // function.
-      MCSection *XData = WinEH::UnwindEmitter::getXDataSection(
-          Asm->CurrentFnSym, Asm->OutContext);
-      Asm->OutStreamer->SwitchSection(XData);
-    }
+    // Just switch sections to the right xdata section. This use of CurrentFnSym
+    // assumes that we only emit the LSDA when ending the parent function.
+    MCSection *XData = WinEH::UnwindEmitter::getXDataSection(Asm->CurrentFnSym,
+                                                             Asm->OutContext);
+    Asm->OutStreamer->SwitchSection(XData);
 
     // Emit the tables appropriate to the personality function in use. If we
     // don't recognize the personality, assume it uses an Itanium-style LSDA.
@@ -153,9 +143,120 @@ void WinException::endFunction(const Mac
 
     Asm->OutStreamer->PopSection();
   }
+}
 
+/// Retreive the MCSymbol for a GlobalValue or MachineBasicBlock. GlobalValues
+/// are used in the old WinEH scheme, and they will be removed eventually.
+static MCSymbol *getMCSymbolForMBBOrGV(AsmPrinter *Asm, ValueOrMBB Handler) {
+  if (!Handler)
+    return nullptr;
+  if (Handler.is<const MachineBasicBlock *>()) {
+    auto *MBB = Handler.get<const MachineBasicBlock *>();
+    assert(MBB->isEHFuncletEntry());
+
+    // Give catches and cleanups a name based off of their parent function and
+    // their funclet entry block's number.
+    const MachineFunction *MF = MBB->getParent();
+    const Function *F = MF->getFunction();
+    StringRef FuncLinkageName = GlobalValue::getRealLinkageName(F->getName());
+    MCContext &Ctx = MF->getContext();
+    StringRef HandlerPrefix = MBB->isCleanupFuncletEntry() ? "dtor" : "catch";
+    return Ctx.getOrCreateSymbol("?" + HandlerPrefix + "$" +
+                                 Twine(MBB->getNumber()) + "@?0?" +
+                                 FuncLinkageName + "@4HA");
+  }
+  return Asm->getSymbol(cast<GlobalValue>(Handler.get<const Value *>()));
+}
+
+void WinException::beginFunclet(const MachineBasicBlock &MBB,
+                                MCSymbol *Sym) {
+  CurrentFuncletEntry = &MBB;
+
+  const Function *F = Asm->MF->getFunction();
+  // If a symbol was not provided for the funclet, invent one.
+  if (!Sym) {
+    Sym = getMCSymbolForMBBOrGV(Asm, &MBB);
+
+    // Describe our funclet symbol as a function with internal linkage.
+    Asm->OutStreamer->BeginCOFFSymbolDef(Sym);
+    Asm->OutStreamer->EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC);
+    Asm->OutStreamer->EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
+                                         << COFF::SCT_COMPLEX_TYPE_SHIFT);
+    Asm->OutStreamer->EndCOFFSymbolDef();
+
+    // We want our funclet's entry point to be aligned such that no nops will be
+    // present after the label.
+    Asm->EmitAlignment(std::max(Asm->MF->getAlignment(), MBB.getAlignment()),
+                       F);
+
+    // Now that we've emitted the alignment directive, point at our funclet.
+    Asm->OutStreamer->EmitLabel(Sym);
+  }
+
+  // Mark 'Sym' as starting our funclet.
   if (shouldEmitMoves || shouldEmitPersonality)
+    Asm->OutStreamer->EmitWinCFIStartProc(Sym);
+
+  if (shouldEmitPersonality) {
+    const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
+    const Function *PerFn = nullptr;
+
+    // Determine which personality routine we are using for this funclet.
+    if (F->hasPersonalityFn())
+      PerFn = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts());
+    const MCSymbol *PersHandlerSym =
+        TLOF.getCFIPersonalitySymbol(PerFn, *Asm->Mang, Asm->TM, MMI);
+
+    // Classify the personality routine so that we may reason about it.
+    EHPersonality Per = EHPersonality::Unknown;
+    if (F->hasPersonalityFn())
+      Per = classifyEHPersonality(F->getPersonalityFn());
+
+    // Do not emit a .seh_handler directive if it is a C++ cleanup funclet.
+    if (Per != EHPersonality::MSVC_CXX ||
+        !CurrentFuncletEntry->isCleanupFuncletEntry())
+      Asm->OutStreamer->EmitWinEHHandler(PersHandlerSym, true, true);
+  }
+}
+
+void WinException::endFunclet() {
+  // No funclet to process?  Great, we have nothing to do.
+  if (!CurrentFuncletEntry)
+    return;
+
+  if (shouldEmitMoves || shouldEmitPersonality) {
+    const Function *F = Asm->MF->getFunction();
+    EHPersonality Per = EHPersonality::Unknown;
+    if (F->hasPersonalityFn())
+      Per = classifyEHPersonality(F->getPersonalityFn());
+
+    // The .seh_handlerdata directive implicitly switches section, push the
+    // current section so that we may return to it.
+    Asm->OutStreamer->PushSection();
+
+    // Emit an UNWIND_INFO struct describing the prologue.
+    Asm->OutStreamer->EmitWinEHHandlerData();
+
+    // If this is a C++ catch funclet (or the parent function),
+    // emit a reference to the LSDA for the parent function.
+    if (Per == EHPersonality::MSVC_CXX && shouldEmitPersonality &&
+        !CurrentFuncletEntry->isCleanupFuncletEntry()) {
+      StringRef FuncLinkageName = GlobalValue::getRealLinkageName(F->getName());
+      MCSymbol *FuncInfoXData = Asm->OutContext.getOrCreateSymbol(
+          Twine("$cppxdata$", FuncLinkageName));
+      Asm->OutStreamer->EmitValue(create32bitRef(FuncInfoXData), 4);
+    }
+
+    // Switch back to the previous section now that we are done writing to
+    // .xdata.
+    Asm->OutStreamer->PopSection();
+
+    // Emit a .seh_endproc directive to mark the end of the function.
     Asm->OutStreamer->EmitWinCFIEndProc();
+  }
+
+  // Let's make sure we don't try to end the same funclet twice.
+  CurrentFuncletEntry = nullptr;
 }
 
 const MCExpr *WinException::create32bitRef(const MCSymbol *Value) {
@@ -299,16 +400,6 @@ void WinException::emitCSpecificHandlerT
   }
 }
 
-/// Retreive the MCSymbol for a GlobalValue or MachineBasicBlock. GlobalValues
-/// are used in the old WinEH scheme, and they will be removed eventually.
-static MCSymbol *getMCSymbolForMBBOrGV(AsmPrinter *Asm, ValueOrMBB Handler) {
-  if (!Handler)
-    return nullptr;
-  if (Handler.is<MachineBasicBlock *>())
-    return Handler.get<MachineBasicBlock *>()->getSymbol();
-  return Asm->getSymbol(cast<GlobalValue>(Handler.get<const Value *>()));
-}
-
 void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
   const Function *F = MF->getFunction();
   auto &OS = *Asm->OutStreamer;
@@ -323,7 +414,6 @@ void WinException::emitCXXFrameHandler3T
     // IPs to state numbers.
     FuncInfoXData =
         Asm->OutContext.getOrCreateSymbol(Twine("$cppxdata$", FuncLinkageName));
-    OS.EmitValue(create32bitRef(FuncInfoXData), 4);
     computeIP2StateTable(MF, FuncInfo, IPToStateTable);
   } else {
     FuncInfoXData = Asm->OutContext.getOrCreateLSDASymbol(FuncLinkageName);

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/WinException.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/WinException.h?rev=248824&r1=248823&r2=248824&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/WinException.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/WinException.h Tue Sep 29 15:12:33 2015
@@ -36,6 +36,9 @@ class LLVM_LIBRARY_VISIBILITY WinExcepti
   /// True if this is a 64-bit target and we should use image relative offsets.
   bool useImageRel32 = false;
 
+  /// Pointer to the current funclet entry BB.
+  const MachineBasicBlock *CurrentFuncletEntry = nullptr;
+
   void emitCSpecificHandlerTable(const MachineFunction *MF);
 
   /// Emit the EH table data for 32-bit and 64-bit functions using
@@ -76,6 +79,10 @@ public:
 
   /// Gather and emit post-function exception information.
   void endFunction(const MachineFunction *) override;
+
+  /// \brief Emit target-specific EH funclet machinery.
+  void beginFunclet(const MachineBasicBlock &MBB, MCSymbol *Sym) override;
+  void endFunclet() override;
 };
 }
 

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=248824&r1=248823&r2=248824&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Tue Sep 29 15:12:33 2015
@@ -1182,6 +1182,7 @@ void SelectionDAGBuilder::visitCleanupPa
   // Don't emit any special code for the cleanuppad instruction. It just marks
   // the start of a funclet.
   FuncInfo.MBB->setIsEHFuncletEntry();
+  FuncInfo.MBB->setIsCleanupFuncletEntry();
 }
 
 /// When an invoke or a cleanupret unwinds to the next EH pad, there are

Modified: llvm/trunk/lib/Target/X86/X86FrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FrameLowering.cpp?rev=248824&r1=248823&r2=248824&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FrameLowering.cpp Tue Sep 29 15:12:33 2015
@@ -713,8 +713,6 @@ void X86FrameLowering::emitPrologue(Mach
       // Reset EBP / ESI to something good.
       MBBI = restoreWin32EHStackPointers(MBB, MBBI, DL);
     } else {
-      // FIXME: Add SEH directives.
-      NeedsWinCFI = false;
       // Immediately spill RDX into the home slot. The runtime cares about this.
       unsigned RDX = Uses64BitFramePtr ? X86::RDX : X86::EDX;
       // MOV64mr %rdx, 16(%rsp)
@@ -727,6 +725,9 @@ void X86FrameLowering::emitPrologue(Mach
       BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH64r))
           .addReg(MachineFramePtr, RegState::Kill)
           .setMIFlag(MachineInstr::FrameSetup);
+      BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_PushReg))
+          .addImm(MachineFramePtr)
+          .setMIFlag(MachineInstr::FrameSetup);
       // MOV64rr %rdx, %rbp
       unsigned MOVrr = Uses64BitFramePtr ? X86::MOV64rr : X86::MOV32rr;
       BuildMI(MBB, MBBI, DL, TII.get(MOVrr), FramePtr)

Modified: llvm/trunk/test/CodeGen/WinEH/seh-prepared-basic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WinEH/seh-prepared-basic.ll?rev=248824&r1=248823&r2=248824&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WinEH/seh-prepared-basic.ll (original)
+++ llvm/trunk/test/CodeGen/WinEH/seh-prepared-basic.ll Tue Sep 29 15:12:33 2015
@@ -35,6 +35,9 @@ __try.cont:
 ; CHECK: .seh_handler __C_specific_handler
 ; CHECK-NOT: jmpq *
 ; CHECK: .seh_handlerdata
+; CHECK-NEXT: .text
+; CHECK: .seh_endproc
+; CHECK: .section .xdata,"dr"
 ; CHECK-NEXT: .long 1
 ; CHECK-NEXT: .long .Ltmp{{.*}}
 ; CHECK-NEXT: .long .Ltmp{{.*}}

Modified: llvm/trunk/test/CodeGen/X86/gcc_except_table.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/gcc_except_table.ll?rev=248824&r1=248823&r2=248824&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/gcc_except_table.ll (original)
+++ llvm/trunk/test/CodeGen/X86/gcc_except_table.ll Tue Sep 29 15:12:33 2015
@@ -18,9 +18,9 @@ define i32 @main() uwtable optsize ssp p
 ; MINGW64: .seh_setframe 5, 32
 ; MINGW64: callq _Unwind_Resume
 ; MINGW64: .seh_handlerdata
+; MINGW64: .seh_endproc
 ; MINGW64: GCC_except_table0:
 ; MINGW64: Lexception0:
-; MINGW64: .seh_endproc
 
 ; MINGW32: .cfi_startproc
 ; MINGW32: .cfi_personality 0, ___gxx_personality_v0

Modified: llvm/trunk/test/CodeGen/X86/seh-catch-all.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/seh-catch-all.ll?rev=248824&r1=248823&r2=248824&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/seh-catch-all.ll (original)
+++ llvm/trunk/test/CodeGen/X86/seh-catch-all.ll Tue Sep 29 15:12:33 2015
@@ -38,6 +38,10 @@ eh.resume:
 ; CHECK: callq printf
 
 ; CHECK: .seh_handlerdata
+; CHECK-NEXT: .text
+; CHECK-NEXT: .Ltmp{{[0-9]+}}
+; CHECK-NEXT: .seh_endproc
+; CHECK-NEXT: .section .xdata,"dr"
 ; CHECK-NEXT: .long 1
 ; CHECK-NEXT: .long .Ltmp{{[0-9]+}}@IMGREL
 ; CHECK-NEXT: .long .Ltmp{{[0-9]+}}@IMGREL+1

Modified: llvm/trunk/test/CodeGen/X86/seh-except-finally.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/seh-except-finally.ll?rev=248824&r1=248823&r2=248824&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/seh-except-finally.ll (original)
+++ llvm/trunk/test/CodeGen/X86/seh-except-finally.ll Tue Sep 29 15:12:33 2015
@@ -103,6 +103,10 @@ eh.resume:
 ; CHECK: retq
 ;
 ; CHECK: .seh_handlerdata
+; CHECK-NEXT: .text
+; CHECK-NEXT: .Ltmp{{[0-9]+}}
+; CHECK-NEXT: .seh_endproc
+; CHECK-NEXT: .section .xdata,"dr"
 ; CHECK-NEXT: .long 3
 ; CHECK-NEXT: .long .Ltmp0 at IMGREL
 ; CHECK-NEXT: .long .Ltmp1 at IMGREL+1

Modified: llvm/trunk/test/CodeGen/X86/seh-finally.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/seh-finally.ll?rev=248824&r1=248823&r2=248824&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/seh-finally.ll (original)
+++ llvm/trunk/test/CodeGen/X86/seh-finally.ll Tue Sep 29 15:12:33 2015
@@ -38,6 +38,10 @@ terminate.lpad:
 ; X64: retq
 
 ; X64: .seh_handlerdata
+; X64-NEXT: .text
+; X64-NEXT: .Ltmp{{[0-9]+}}:
+; X64-NEXT: .seh_endproc
+; X64-NEXT: .section .xdata,"dr"
 ; X64-NEXT: .long 1
 ; X64-NEXT: .long .Ltmp0 at IMGREL
 ; X64-NEXT: .long .Ltmp1 at IMGREL

Modified: llvm/trunk/test/CodeGen/X86/seh-safe-div.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/seh-safe-div.ll?rev=248824&r1=248823&r2=248824&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/seh-safe-div.ll (original)
+++ llvm/trunk/test/CodeGen/X86/seh-safe-div.ll Tue Sep 29 15:12:33 2015
@@ -90,6 +90,10 @@ __try.cont:
 ; CHECK: jmp [[cont_bb]]
 
 ; CHECK: .seh_handlerdata
+; CHECK-NEXT: .text
+; CHECK-NEXT: .Ltmp{{[0-9]+}}
+; CHECK-NEXT: .seh_endproc
+; CHECK-NEXT: .section .xdata,"dr"
 ; CHECK-NEXT: .long 2
 ; CHECK-NEXT: .long .Ltmp0 at IMGREL
 ; CHECK-NEXT: .long .Ltmp1 at IMGREL+1

Modified: llvm/trunk/test/CodeGen/X86/win-catchpad-csrs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/win-catchpad-csrs.ll?rev=248824&r1=248823&r2=248824&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/win-catchpad-csrs.ll (original)
+++ llvm/trunk/test/CodeGen/X86/win-catchpad-csrs.ll Tue Sep 29 15:12:33 2015
@@ -71,7 +71,8 @@ catchendblock:
 ; X86: addl $12, %ebp
 ; X86: jmp [[contbb]]
 
-; X86: [[catch1bb:LBB0_[0-9]+]]: # %catch{{$}}
+; X86: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch at 4HA":
+; X86: LBB0_[[catch1bb]]: # %catch{{$}}
 ; X86: pushl %ebp
 ; X86-NOT: pushl
 ; X86: addl $12, %ebp
@@ -89,7 +90,7 @@ catchendblock:
 ; X86:   .long   0
 ; X86:   .long   "??_R0H at 8"
 ; X86:   .long   0
-; X86:   .long   [[catch1bb]]
+; X86:   .long   "?catch$[[catch1bb]]@?0?try_catch_catch at 4HA"
 
 ; X64-LABEL: try_catch_catch:
 ; X64: pushq %rbp
@@ -116,7 +117,8 @@ catchendblock:
 ; X64: popq %rbp
 ; X64: retq
 
-; X64: [[catch1bb:\.LBB0_[0-9]+]]: # %catch{{$}}
+; X64: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch at 4HA":
+; X64: LBB0_[[catch1bb]]: # %catch{{$}}
 ; X64: movq %rdx, 16(%rsp)
 ; X64: pushq %rbp
 ; X64: movq %rdx, %rbp
@@ -132,5 +134,5 @@ catchendblock:
 ; X64:   .long   0
 ; X64:   .long   "??_R0H at 8"@IMGREL
 ; X64:   .long   0
-; X64:   .long   [[catch1bb]]@IMGREL
+; X64:   .long   "?catch$[[catch1bb]]@?0?try_catch_catch at 4HA"@IMGREL
 ; X64:   .long   56

Modified: llvm/trunk/test/CodeGen/X86/win-catchpad.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/win-catchpad.ll?rev=248824&r1=248823&r2=248824&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/win-catchpad.ll (original)
+++ llvm/trunk/test/CodeGen/X86/win-catchpad.ll Tue Sep 29 15:12:33 2015
@@ -78,7 +78,8 @@ catchendblock:
 ; X86: addl $12, %ebp
 ; X86: jmp [[contbb]]
 
-; X86: [[catch1bb:LBB0_[0-9]+]]: # %catch{{$}}
+; X86: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch at 4HA":
+; X86: LBB0_[[catch1bb]]: # %catch{{$}}
 ; X86: pushl %ebp
 ; X86: addl $12, %ebp
 ; X86: subl $8, %esp
@@ -93,7 +94,8 @@ catchendblock:
 ; X86-NEXT: movl $[[restorebb]], %eax
 ; X86-NEXT: retl
 
-; X86: [[catch2bb:LBB0_[0-9]+]]: # %catch.2{{$}}
+; X86: "?catch$[[catch2bb:[0-9]+]]@?0?try_catch_catch at 4HA":
+; X86: LBB0_[[catch2bb]]: # %catch.2{{$}}
 ; X86: pushl %ebp
 ; X86: addl $12, %ebp
 ; X86: subl $8, %esp
@@ -112,11 +114,11 @@ catchendblock:
 ; X86-NEXT:   .long   0
 ; X86-NEXT:   .long   "??_R0H at 8"
 ; X86-NEXT:   .long   -20
-; X86-NEXT:   .long   [[catch1bb]]
+; X86-NEXT:   .long   "?catch$[[catch1bb]]@?0?try_catch_catch at 4HA"
 ; X86-NEXT:   .long   64
 ; X86-NEXT:   .long   0
 ; X86-NEXT:   .long   0
-; X86-NEXT:   .long   [[catch2bb]]
+; X86-NEXT:   .long   "?catch$[[catch2bb]]@?0?try_catch_catch at 4HA"
 
 ; X64-LABEL: try_catch_catch:
 ; X64: Lfunc_begin0:
@@ -135,7 +137,8 @@ catchendblock:
 ; X64: popq %rbp
 ; X64: retq
 
-; X64: [[catch1bb:\.LBB0_[0-9]+]]: # %catch{{$}}
+; X64: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch at 4HA":
+; X64: LBB0_[[catch1bb]]: # %catch{{$}}
 ; X64: movq %rdx, 16(%rsp)
 ; X64: pushq %rbp
 ; X64: movq %rdx, %rbp
@@ -149,7 +152,8 @@ catchendblock:
 ; X64-NEXT: leaq [[contbb]](%rip), %rax
 ; X64-NEXT: retq
 
-; X64: [[catch2bb:\.LBB0_[0-9]+]]: # %catch.2{{$}}
+; X64: "?catch$[[catch2bb:[0-9]+]]@?0?try_catch_catch at 4HA":
+; X64: LBB0_[[catch2bb]]: # %catch.2{{$}}
 ; X64: movq %rdx, 16(%rsp)
 ; X64: pushq %rbp
 ; X64: movq %rdx, %rbp
@@ -187,12 +191,12 @@ catchendblock:
 ; X64-NEXT:   .long   "??_R0H at 8"@IMGREL
 ; FIXME: This should probably be offset from rsp, not rbp.
 ; X64-NEXT:   .long   [[e_addr]]
-; X64-NEXT:   .long   [[catch1bb]]@IMGREL
+; X64-NEXT:   .long   "?catch$[[catch1bb]]@?0?try_catch_catch at 4HA"@IMGREL
 ; X64-NEXT:   .long   56
 ; X64-NEXT:   .long   64
 ; X64-NEXT:   .long   0
 ; X64-NEXT:   .long   0
-; X64-NEXT:   .long   [[catch2bb]]@IMGREL
+; X64-NEXT:   .long   "?catch$[[catch2bb]]@?0?try_catch_catch at 4HA"@IMGREL
 ; X64-NEXT:   .long   56
 
 ; X64: $ip2state$try_catch_catch:

Modified: llvm/trunk/test/CodeGen/X86/win-cleanuppad.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/win-cleanuppad.ll?rev=248824&r1=248823&r2=248824&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/win-cleanuppad.ll (original)
+++ llvm/trunk/test/CodeGen/X86/win-cleanuppad.ll Tue Sep 29 15:12:33 2015
@@ -65,14 +65,16 @@ cleanup.outer:
 ; X86: movl    $3, (%esp)
 ; X86: calll   _f
 
-; X86: LBB1_[[cleanup_inner:[0-9]+]]: # %cleanup.inner
+; X86: "?dtor$[[cleanup_inner:[0-9]+]]@?0?nested_cleanup at 4HA":
+; X86: LBB1_[[cleanup_inner]]: # %cleanup.inner{{$}}
 ; X86: pushl %ebp
 ; X86: leal    {{.*}}(%ebp), %ecx
 ; X86: calll   "??1Dtor@@QAE at XZ"
 ; X86: popl %ebp
 ; X86: retl
 
-; X86: LBB1_[[cleanup_outer:[0-9]+]]: # %cleanup.outer
+; X86: "?dtor$[[cleanup_outer:[0-9]+]]@?0?nested_cleanup at 4HA":
+; X86: LBB1_[[cleanup_outer]]: # %cleanup.outer{{$}}
 ; X86: pushl %ebp
 ; X86: leal    {{.*}}(%ebp), %ecx
 ; X86: calll   "??1Dtor@@QAE at XZ"
@@ -91,41 +93,46 @@ cleanup.outer:
 ; X86:         .long   1
 ; X86: $stateUnwindMap$nested_cleanup:
 ; X86:         .long   -1
-; X86:         .long   LBB1_[[cleanup_outer]]
+; X86:         .long   "?dtor$[[cleanup_outer]]@?0?nested_cleanup at 4HA"
 ; X86:         .long   0
-; X86:         .long   LBB1_[[cleanup_inner]]
+; X86:         .long   "?dtor$[[cleanup_inner]]@?0?nested_cleanup at 4HA"
 
 ; X64-LABEL: nested_cleanup:
 ; X64: .Lfunc_begin1:
-; X64: .Ltmp8:
+; X64: .Ltmp14:
 ; X64: movl    $1, %ecx
 ; X64: callq   f
-; X64: .Ltmp10:
+; X64: .Ltmp16:
 ; X64: movl    $2, %ecx
 ; X64: callq   f
-; X64: .Ltmp11:
+; X64: .Ltmp17:
 ; X64: callq   "??1Dtor@@QAE at XZ"
-; X64: .Ltmp12:
+; X64: .Ltmp18:
 ; X64: movl    $3, %ecx
 ; X64: callq   f
-; X64: .Ltmp13:
+; X64: .Ltmp19:
 
-; X64: .LBB1_[[cleanup_inner:[0-9]+]]: # %cleanup.inner
+; X64: "?dtor$[[cleanup_inner:[0-9]+]]@?0?nested_cleanup at 4HA":
+; X64: LBB1_[[cleanup_inner]]: # %cleanup.inner{{$}}
 ; X64: pushq %rbp
 ; X64: leaq    {{.*}}(%rbp), %rcx
 ; X64: callq   "??1Dtor@@QAE at XZ"
 ; X64: popq %rbp
 ; X64: retq
 
-; X64: .LBB1_[[cleanup_outer:[0-9]+]]: # %cleanup.outer
+; X64:        .seh_handlerdata
+; X64:        .text
+; X64:        .seh_endproc
+
+; X64: "?dtor$[[cleanup_outer:[0-9]+]]@?0?nested_cleanup at 4HA":
+; X64: LBB1_[[cleanup_outer]]: # %cleanup.outer{{$}}
 ; X64: pushq %rbp
 ; X64: leaq    {{.*}}(%rbp), %rcx
 ; X64: callq   "??1Dtor@@QAE at XZ"
 ; X64: popq %rbp
 ; X64: retq
 
-; X64: .seh_handlerdata
-; X64-NEXT: .long   ($cppxdata$nested_cleanup)@IMGREL
+; X64:        .section .xdata,"dr"
 ; X64-NEXT: .align  4
 ; X64: $cppxdata$nested_cleanup:
 ; X64-NEXT: .long   429065506
@@ -141,20 +148,20 @@ cleanup.outer:
 
 ; X64: $stateUnwindMap$nested_cleanup:
 ; X64-NEXT: .long   -1
-; X64-NEXT: .long   .LBB1_[[cleanup_outer]]@IMGREL
+; X64-NEXT: .long   "?dtor$[[cleanup_outer]]@?0?nested_cleanup at 4HA"@IMGREL
 ; X64-NEXT: .long   0
-; X64-NEXT: .long   .LBB1_[[cleanup_inner]]@IMGREL
+; X64-NEXT: .long   "?dtor$[[cleanup_inner]]@?0?nested_cleanup at 4HA"@IMGREL
 
 ; X64: $ip2state$nested_cleanup:
 ; X64-NEXT: .long   .Lfunc_begin1 at IMGREL
 ; X64-NEXT: .long   -1
-; X64-NEXT: .long   .Ltmp8 at IMGREL
+; X64-NEXT: .long   .Ltmp14 at IMGREL
 ; X64-NEXT: .long   0
-; X64-NEXT: .long   .Ltmp10 at IMGREL
+; X64-NEXT: .long   .Ltmp16 at IMGREL
 ; X64-NEXT: .long   1
-; X64-NEXT: .long   .Ltmp12 at IMGREL
+; X64-NEXT: .long   .Ltmp18 at IMGREL
 ; X64-NEXT: .long   0
-; X64-NEXT: .long   .Ltmp13 at IMGREL+1
+; X64-NEXT: .long   .Ltmp19 at IMGREL+1
 ; X64-NEXT: .long   -1
 
 attributes #0 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }

Added: llvm/trunk/test/CodeGen/X86/win-funclet-cfi.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/win-funclet-cfi.ll?rev=248824&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/win-funclet-cfi.ll (added)
+++ llvm/trunk/test/CodeGen/X86/win-funclet-cfi.ll Tue Sep 29 15:12:33 2015
@@ -0,0 +1,100 @@
+; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s
+
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc"
+
+define void @"\01?f@@YAXXZ"(i1 %B) personality i32 (...)* @__CxxFrameHandler3 {
+entry:
+  invoke void @g()
+          to label %unreachable unwind label %cleanupblock
+
+cleanupblock:
+  %cleanp = cleanuppad []
+  call void @g()
+  cleanupret %cleanp unwind label %catch.dispatch
+
+catch.dispatch:
+  %cp = catchpad [i8* null, i32 64, i8* null]
+          to label %catch unwind label %catchendblock
+
+catch:
+  call void @g()
+  catchret %cp to label %try.cont
+
+try.cont:
+  ret void
+
+catchendblock:
+  catchendpad unwind to caller
+
+unreachable:
+  unreachable
+}
+
+
+declare void @g()
+
+declare i32 @__CxxFrameHandler3(...)
+
+; Destructors need CFI but they shouldn't use the .seh_handler directive.
+; CHECK: "?dtor$[[cleanup:[0-9]+]]@?0??f@@YAXXZ at 4HA":
+; CHECK: .seh_proc "?dtor$[[cleanup]]@?0??f@@YAXXZ at 4HA"
+; CHECK-NOT: .seh_handler __CxxFrameHandler3
+; CHECK: LBB0_[[cleanup]]: # %cleanupblock{{$}}
+
+; Emit CFI for pushing RBP.
+; CHECK: movq    %rdx, 16(%rsp)
+; CHECK: pushq   %rbp
+; CHECK: .seh_pushreg 5
+
+; Emit CFI for allocating from the stack pointer.
+; CHECK: subq    $32, %rsp
+; CHECK: .seh_stackalloc 32
+
+; FIXME: This looks wrong...
+; CHECK: leaq    32(%rsp), %rbp
+; CHECK: .seh_setframe 5, 32
+
+; Prologue is done, emit the .seh_endprologue directive.
+; CHECK: .seh_endprologue
+
+; Make sure there is a nop after a call if the call precedes the epilogue.
+; CHECK: callq g
+; CHECK-NEXT: nop
+
+; Don't emit a reference to the LSDA.
+; CHECK: .seh_handlerdata
+; CHECK-NOT:  .long   ("$cppxdata$?f@@YAXXZ")@IMGREL
+; CHECK-NEXT: .text
+; CHECK: .seh_endproc
+
+; CHECK: "?catch$[[catch:[0-9]+]]@?0??f@@YAXXZ at 4HA":
+; CHECK: .seh_proc "?catch$[[catch]]@?0??f@@YAXXZ at 4HA"
+; CHECK-NEXT: .seh_handler __CxxFrameHandler3, @unwind, @except
+; CHECK: LBB0_[[catch]]: # %catch{{$}}
+
+; Emit CFI for pushing RBP.
+; CHECK: movq    %rdx, 16(%rsp)
+; CHECK: pushq   %rbp
+; CHECK: .seh_pushreg 5
+
+; Emit CFI for allocating from the stack pointer.
+; CHECK: subq    $32, %rsp
+; CHECK: .seh_stackalloc 32
+
+; FIXME: This looks wrong...
+; CHECK: leaq    32(%rsp), %rbp
+; CHECK: .seh_setframe 5, 32
+
+; Prologue is done, emit the .seh_endprologue directive.
+; CHECK: .seh_endprologue
+
+; Make sure there is a nop after a call if the call precedes the epilogue.
+; CHECK: callq g
+; CHECK-NEXT: nop
+
+; Emit a reference to the LSDA.
+; CHECK: .seh_handlerdata
+; CHECK-NEXT:  .long   ("$cppxdata$?f@@YAXXZ")@IMGREL
+; CHECK-NEXT: .text
+; CHECK: .seh_endproc




More information about the llvm-commits mailing list