[llvm] [llvm] Win x64 Unwind V2 1/n: Mark beginning and end of epilogs (PR #110024)

Daniel Paoliello via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 25 11:38:59 PDT 2024


https://github.com/dpaoliello created https://github.com/llvm/llvm-project/pull/110024

Windows x64 Unwind V2 adds epilog information to unwind data: specifically, the length of the epilog and the offset of each epilog.

The first step to do this is to add markers to the beginning and end of each epilog when generating Windows x64 code. I've modelled this after how LLVM was marking ARM and AArch64 epilogs in Windows (and unified the code between the three).

>From e476becfe97550c420a1853fd2c7605022b7e606 Mon Sep 17 00:00:00 2001
From: Daniel Paoliello <danpao at microsoft.com>
Date: Tue, 24 Sep 2024 10:49:31 -0700
Subject: [PATCH] Mark the beginning and end of epilogs for Win x64

---
 llvm/include/llvm/MC/MCStreamer.h             | 12 ++++++
 llvm/lib/MC/MCAsmStreamer.cpp                 | 16 ++++++++
 llvm/lib/MC/MCParser/COFFAsmParser.cpp        | 18 +++++++++
 llvm/lib/MC/MCStreamer.cpp                    | 20 ++++++++++
 .../MCTargetDesc/AArch64TargetStreamer.h      |  6 ---
 .../MCTargetDesc/AArch64WinCOFFStreamer.cpp   | 19 +++-------
 .../ARM/MCTargetDesc/ARMWinCOFFStreamer.cpp   | 27 ++++---------
 llvm/lib/Target/X86/X86FrameLowering.cpp      | 11 ++----
 llvm/lib/Target/X86/X86InstrCompiler.td       |  8 ++--
 llvm/lib/Target/X86/X86MCInstLower.cpp        | 18 ++++++++-
 .../CodeGen/X86/apx/push2-pop2-cfi-seh.ll     |  6 +++
 llvm/test/CodeGen/X86/avx512-intel-ocl.ll     |  4 ++
 llvm/test/CodeGen/X86/avx512-regcall-Mask.ll  | 22 +++++++++++
 .../test/CodeGen/X86/avx512-regcall-NoMask.ll | 26 +++++++++++++
 llvm/test/CodeGen/X86/break-false-dep.ll      | 22 +++++++++++
 .../CodeGen/X86/catchpad-realign-savexmm.ll   |  4 ++
 .../CodeGen/X86/cfguard-x86-64-vectorcall.ll  |  2 +
 llvm/test/CodeGen/X86/cleanuppad-realign.ll   |  2 +
 .../CodeGen/X86/conditional-tailcall-pgso.ll  |  4 ++
 llvm/test/CodeGen/X86/conditional-tailcall.ll |  4 ++
 llvm/test/CodeGen/X86/ldexp.ll                | 12 ++++++
 llvm/test/CodeGen/X86/localescape.ll          |  2 +
 llvm/test/CodeGen/X86/mixed-ptr-sizes.ll      |  2 +
 llvm/test/CodeGen/X86/musttail-varargs.ll     |  2 +
 llvm/test/CodeGen/X86/no-sse-win64.ll         |  8 ++++
 .../CodeGen/X86/preserve_nonecc_call_win.ll   |  2 +
 llvm/test/CodeGen/X86/segmented-stacks.ll     | 14 +++++++
 llvm/test/CodeGen/X86/seh-catchpad.ll         |  2 +
 llvm/test/CodeGen/X86/sse-regcall.ll          |  2 +
 llvm/test/CodeGen/X86/sse-regcall4.ll         |  2 +
 llvm/test/CodeGen/X86/stack-coloring-wineh.ll |  6 +++
 llvm/test/CodeGen/X86/swift-async-win64.ll    |  2 +
 llvm/test/CodeGen/X86/tailcc-ssp.ll           |  4 ++
 .../test/CodeGen/X86/taildup-callsiteinfo.mir |  3 +-
 llvm/test/CodeGen/X86/win-catchpad-csrs.ll    | 12 ++++++
 llvm/test/CodeGen/X86/win-catchpad.ll         | 10 +++++
 llvm/test/CodeGen/X86/win-funclet-cfi.ll      |  2 +
 llvm/test/CodeGen/X86/win-smallparams.ll      |  2 +
 llvm/test/CodeGen/X86/win64-byval.ll          |  6 +++
 .../CodeGen/X86/win64-eh-empty-block-2.mir    |  6 ++-
 .../test/CodeGen/X86/win64-funclet-savexmm.ll |  2 +
 .../X86/win64-seh-epilogue-statepoint.ll      |  2 +
 llvm/test/CodeGen/X86/win64_eh.ll             |  4 ++
 llvm/test/CodeGen/X86/win64_frame.ll          | 22 +++++++++++
 .../CodeGen/X86/x86-64-flags-intrinsics.ll    |  4 ++
 .../CodeGen/X86/x86-win64-shrink-wrapping.ll  | 38 +++++++++++++------
 .../COFF/trailing-inlined-function.s          |  2 +
 .../MIR/X86/instr-ref-join-def-vphi.mir       |  3 +-
 .../JITLink/x86-64/COFF_pdata_no_strip.s      |  2 +
 .../JITLink/x86-64/COFF_pdata_strip.s         |  2 +
 llvm/test/MC/AsmParser/directive_seh.s        |  4 ++
 llvm/test/MC/AsmParser/seh-directive-errors.s |  6 +++
 llvm/test/MC/COFF/cv-def-range-align.s        |  2 +
 .../MC/COFF/cv-inline-linetable-unlikely.s    |  2 +
 llvm/test/MC/COFF/seh-align2.s                |  2 +
 llvm/test/MC/COFF/seh-align3.s                |  2 +
 llvm/test/MC/COFF/seh-linkonce.s              |  2 +
 llvm/test/MC/COFF/seh-section-2.s             |  2 +
 llvm/test/MC/COFF/seh-section.s               |  6 +++
 llvm/test/MC/COFF/seh.s                       |  2 +
 .../Inputs/x86-basic.ll.expected              |  2 +
 61 files changed, 399 insertions(+), 66 deletions(-)

diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h
index 707aecc5dc578e..c3770ffa6a5dc8 100644
--- a/llvm/include/llvm/MC/MCStreamer.h
+++ b/llvm/include/llvm/MC/MCStreamer.h
@@ -252,6 +252,12 @@ class MCStreamer {
   bool AllowAutoPadding = false;
 
 protected:
+  // True if we are processing SEH directives in an epilogue.
+  bool InEpilogCFI = false;
+
+  // Symbol of the current epilog for which we are processing SEH directives.
+  MCSymbol *CurrentEpilog = nullptr;
+
   MCFragment *CurFrag = nullptr;
 
   MCStreamer(MCContext &Ctx);
@@ -331,6 +337,10 @@ class MCStreamer {
     return WinFrameInfos;
   }
 
+  MCSymbol *getCurrentEpilog() const { return CurrentEpilog; }
+
+  bool isInEpilogCFI() const { return InEpilogCFI; }
+
   void generateCompactUnwindEncodings(MCAsmBackend *MAB);
 
   /// \name Assembly File Formatting.
@@ -1043,6 +1053,8 @@ class MCStreamer {
                                  SMLoc Loc = SMLoc());
   virtual void emitWinCFIPushFrame(bool Code, SMLoc Loc = SMLoc());
   virtual void emitWinCFIEndProlog(SMLoc Loc = SMLoc());
+  virtual void emitWinCFIBeginEpilogue(SMLoc Loc = SMLoc());
+  virtual void emitWinCFIEndEpilogue(SMLoc Loc = SMLoc());
   virtual void emitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
                                 SMLoc Loc = SMLoc());
   virtual void emitWinEHHandlerData(SMLoc Loc = SMLoc());
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 31b519a3e5c56a..34bfa139cea290 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -391,6 +391,8 @@ class MCAsmStreamer final : public MCStreamer {
                          SMLoc Loc) override;
   void emitWinCFIPushFrame(bool Code, SMLoc Loc) override;
   void emitWinCFIEndProlog(SMLoc Loc) override;
+  void emitWinCFIBeginEpilogue(SMLoc Loc) override;
+  void emitWinCFIEndEpilogue(SMLoc Loc) override;
 
   void emitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
                         SMLoc Loc) override;
@@ -2306,6 +2308,20 @@ void MCAsmStreamer::emitWinCFIEndProlog(SMLoc Loc) {
   EmitEOL();
 }
 
+void MCAsmStreamer::emitWinCFIBeginEpilogue(SMLoc Loc) {
+  MCStreamer::emitWinCFIBeginEpilogue(Loc);
+
+  OS << "\t.seh_beginepilogue";
+  EmitEOL();
+}
+
+void MCAsmStreamer::emitWinCFIEndEpilogue(SMLoc Loc) {
+  MCStreamer::emitWinCFIEndEpilogue(Loc);
+
+  OS << "\t.seh_endepilogue";
+  EmitEOL();
+}
+
 void MCAsmStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
                                        const MCSymbolRefExpr *To,
                                        uint64_t Count) {
diff --git a/llvm/lib/MC/MCParser/COFFAsmParser.cpp b/llvm/lib/MC/MCParser/COFFAsmParser.cpp
index a69276c36c56b3..22e72292966f46 100644
--- a/llvm/lib/MC/MCParser/COFFAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/COFFAsmParser.cpp
@@ -90,6 +90,10 @@ class COFFAsmParser : public MCAsmParserExtension {
                                                              ".seh_stackalloc");
     addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
                                                             ".seh_endprologue");
+    addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveBeginEpilog>(
+        ".seh_beginepilogue");
+    addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndEpilog>(
+        ".seh_endepilogue");
   }
 
   bool ParseSectionDirectiveText(StringRef, SMLoc) {
@@ -137,6 +141,8 @@ class COFFAsmParser : public MCAsmParserExtension {
   bool ParseSEHDirectiveHandlerData(StringRef, SMLoc);
   bool ParseSEHDirectiveAllocStack(StringRef, SMLoc);
   bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);
+  bool ParseSEHDirectiveBeginEpilog(StringRef, SMLoc);
+  bool ParseSEHDirectiveEndEpilog(StringRef, SMLoc);
 
   bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except);
   bool ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc);
@@ -715,6 +721,18 @@ bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc Loc) {
   return false;
 }
 
+bool COFFAsmParser::ParseSEHDirectiveBeginEpilog(StringRef, SMLoc Loc) {
+  Lex();
+  getStreamer().emitWinCFIBeginEpilogue(Loc);
+  return false;
+}
+
+bool COFFAsmParser::ParseSEHDirectiveEndEpilog(StringRef, SMLoc Loc) {
+  Lex();
+  getStreamer().emitWinCFIEndEpilogue(Loc);
+  return false;
+}
+
 bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) {
   StringRef identifier;
   if (getLexer().isNot(AsmToken::At) && getLexer().isNot(AsmToken::Percent))
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 13b162768578c5..b179aa1cef39c9 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -979,6 +979,26 @@ void MCStreamer::emitWinCFIEndProlog(SMLoc Loc) {
   CurFrame->PrologEnd = Label;
 }
 
+void MCStreamer::emitWinCFIBeginEpilogue(SMLoc Loc) {
+  WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
+  if (!CurFrame)
+    return;
+
+  InEpilogCFI = true;
+  CurrentEpilog = emitCFILabel();
+}
+
+void MCStreamer::emitWinCFIEndEpilogue(SMLoc Loc) {
+  WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
+  if (!CurFrame)
+    return;
+
+  InEpilogCFI = false;
+  MCSymbol *Label = emitCFILabel();
+  CurFrame->EpilogMap[CurrentEpilog].End = Label;
+  CurrentEpilog = nullptr;
+}
+
 void MCStreamer::emitCOFFSafeSEH(MCSymbol const *Symbol) {}
 
 void MCStreamer::emitCOFFSymbolIndex(MCSymbol const *Symbol) {}
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
index ac441ae3b603ff..119dcc38edbfcd 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
@@ -100,12 +100,6 @@ class AArch64TargetELFStreamer : public AArch64TargetStreamer {
 };
 
 class AArch64TargetWinCOFFStreamer : public llvm::AArch64TargetStreamer {
-private:
-  // True if we are processing SEH directives in an epilogue.
-  bool InEpilogCFI = false;
-
-  // Symbol of the current epilog for which we are processing SEH directives.
-  MCSymbol *CurrentEpilog = nullptr;
 public:
   AArch64TargetWinCOFFStreamer(llvm::MCStreamer &S)
     : AArch64TargetStreamer(S) {}
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp
index 208d43502cb88a..160768350a6b86 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp
@@ -73,8 +73,8 @@ void AArch64TargetWinCOFFStreamer::emitARM64WinUnwindCode(unsigned UnwindCode,
   if (!CurFrame)
     return;
   auto Inst = WinEH::Instruction(UnwindCode, /*Label=*/nullptr, Reg, Offset);
-  if (InEpilogCFI)
-    CurFrame->EpilogMap[CurrentEpilog].Instructions.push_back(Inst);
+  if (S.isInEpilogCFI())
+    CurFrame->EpilogMap[S.getCurrentEpilog()].Instructions.push_back(Inst);
   else
     CurFrame->Instructions.push_back(Inst);
 }
@@ -183,13 +183,7 @@ void AArch64TargetWinCOFFStreamer::emitARM64WinCFIPrologEnd() {
 }
 
 void AArch64TargetWinCOFFStreamer::emitARM64WinCFIEpilogStart() {
-  auto &S = getStreamer();
-  WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
-  if (!CurFrame)
-    return;
-
-  InEpilogCFI = true;
-  CurrentEpilog = S.emitCFILabel();
+  getStreamer().emitWinCFIBeginEpilogue();
 }
 
 void AArch64TargetWinCOFFStreamer::emitARM64WinCFIEpilogEnd() {
@@ -198,13 +192,10 @@ void AArch64TargetWinCOFFStreamer::emitARM64WinCFIEpilogEnd() {
   if (!CurFrame)
     return;
 
-  InEpilogCFI = false;
   WinEH::Instruction Inst =
       WinEH::Instruction(Win64EH::UOP_End, /*Label=*/nullptr, -1, 0);
-  CurFrame->EpilogMap[CurrentEpilog].Instructions.push_back(Inst);
-  MCSymbol *Label = S.emitCFILabel();
-  CurFrame->EpilogMap[CurrentEpilog].End = Label;
-  CurrentEpilog = nullptr;
+  CurFrame->EpilogMap[S.getCurrentEpilog()].Instructions.push_back(Inst);
+  S.emitWinCFIEndEpilogue();
 }
 
 void AArch64TargetWinCOFFStreamer::emitARM64WinCFITrapFrame() {
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMWinCOFFStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMWinCOFFStreamer.cpp
index e66059c2a0e096..b541755cf6b621 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMWinCOFFStreamer.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMWinCOFFStreamer.cpp
@@ -77,13 +77,6 @@ llvm::createARMWinCOFFStreamer(MCContext &Context,
 
 namespace {
 class ARMTargetWinCOFFStreamer : public llvm::ARMTargetStreamer {
-private:
-  // True if we are processing SEH directives in an epilogue.
-  bool InEpilogCFI = false;
-
-  // Symbol of the current epilog for which we are processing SEH directives.
-  MCSymbol *CurrentEpilog = nullptr;
-
 public:
   ARMTargetWinCOFFStreamer(llvm::MCStreamer &S) : ARMTargetStreamer(S) {}
 
@@ -114,8 +107,8 @@ void ARMTargetWinCOFFStreamer::emitARMWinUnwindCode(unsigned UnwindCode,
     return;
   MCSymbol *Label = S.emitCFILabel();
   auto Inst = WinEH::Instruction(UnwindCode, Label, Reg, Offset);
-  if (InEpilogCFI)
-    CurFrame->EpilogMap[CurrentEpilog].Instructions.push_back(Inst);
+  if (S.isInEpilogCFI())
+    CurFrame->EpilogMap[S.getCurrentEpilog()].Instructions.push_back(Inst);
   else
     CurFrame->Instructions.push_back(Inst);
 }
@@ -224,9 +217,8 @@ void ARMTargetWinCOFFStreamer::emitARMWinCFIEpilogStart(unsigned Condition) {
   if (!CurFrame)
     return;
 
-  InEpilogCFI = true;
-  CurrentEpilog = S.emitCFILabel();
-  CurFrame->EpilogMap[CurrentEpilog].Condition = Condition;
+  S.emitWinCFIBeginEpilogue();
+  CurFrame->EpilogMap[S.getCurrentEpilog()].Condition = Condition;
 }
 
 void ARMTargetWinCOFFStreamer::emitARMWinCFIEpilogEnd() {
@@ -235,14 +227,14 @@ void ARMTargetWinCOFFStreamer::emitARMWinCFIEpilogEnd() {
   if (!CurFrame)
     return;
 
-  if (!CurrentEpilog) {
+  if (!S.getCurrentEpilog()) {
     S.getContext().reportError(SMLoc(), "Stray .seh_endepilogue in " +
                                             CurFrame->Function->getName());
     return;
   }
 
   std::vector<WinEH::Instruction> &Epilog =
-      CurFrame->EpilogMap[CurrentEpilog].Instructions;
+      CurFrame->EpilogMap[S.getCurrentEpilog()].Instructions;
 
   unsigned UnwindCode = Win64EH::UOP_End;
   if (!Epilog.empty()) {
@@ -256,12 +248,9 @@ void ARMTargetWinCOFFStreamer::emitARMWinCFIEpilogEnd() {
     }
   }
 
-  InEpilogCFI = false;
   WinEH::Instruction Inst = WinEH::Instruction(UnwindCode, nullptr, -1, 0);
-  CurFrame->EpilogMap[CurrentEpilog].Instructions.push_back(Inst);
-  MCSymbol *Label = S.emitCFILabel();
-  CurFrame->EpilogMap[CurrentEpilog].End = Label;
-  CurrentEpilog = nullptr;
+  CurFrame->EpilogMap[S.getCurrentEpilog()].Instructions.push_back(Inst);
+  S.emitWinCFIEndEpilogue();
 }
 
 void ARMTargetWinCOFFStreamer::emitARMWinCFICustom(unsigned Opcode) {
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp
index 4f83267c999e4a..f49c6c1125d613 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -2549,14 +2549,8 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
     --MBBI;
   }
 
-  // Windows unwinder will not invoke function's exception handler if IP is
-  // either in prologue or in epilogue.  This behavior causes a problem when a
-  // call immediately precedes an epilogue, because the return address points
-  // into the epilogue.  To cope with that, we insert an epilogue marker here,
-  // then replace it with a 'nop' if it ends up immediately after a CALL in the
-  // final emitted code.
   if (NeedsWin64CFI && MF.hasWinCFI())
-    BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_Epilogue));
+    BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_BeginEpilogue));
 
   if (!HasFP && NeedsDwarfCFI) {
     MBBI = FirstCSPop;
@@ -2601,6 +2595,9 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
   // Emit tilerelease for AMX kernel.
   if (X86FI->getAMXProgModel() == AMXProgModelEnum::ManagedRA)
     BuildMI(MBB, Terminator, DL, TII.get(X86::TILERELEASE));
+
+  if (NeedsWin64CFI && MF.hasWinCFI())
+    BuildMI(MBB, Terminator, DL, TII.get(X86::SEH_EndEpilogue));
 }
 
 StackOffset X86FrameLowering::getFrameIndexReference(const MachineFunction &MF,
diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td
index 5a8177e2b3607b..f8f572d662aa1a 100644
--- a/llvm/lib/Target/X86/X86InstrCompiler.td
+++ b/llvm/lib/Target/X86/X86InstrCompiler.td
@@ -235,7 +235,7 @@ let isBranch = 1, isTerminator = 1, isCodeGenOnly = 1 in {
 //===----------------------------------------------------------------------===//
 // Pseudo instructions used by unwind info.
 //
-let isPseudo = 1, SchedRW = [WriteSystem] in {
+let isPseudo = 1, isMeta = 1, SchedRW = [WriteSystem] in {
   def SEH_PushReg : I<0, Pseudo, (outs), (ins i32imm:$reg),
                             "#SEH_PushReg $reg", []>;
   def SEH_SaveReg : I<0, Pseudo, (outs), (ins i32imm:$reg, i32imm:$dst),
@@ -252,8 +252,10 @@ let isPseudo = 1, SchedRW = [WriteSystem] in {
                             "#SEH_PushFrame $mode", []>;
   def SEH_EndPrologue : I<0, Pseudo, (outs), (ins),
                             "#SEH_EndPrologue", []>;
-  def SEH_Epilogue : I<0, Pseudo, (outs), (ins),
-                            "#SEH_Epilogue", []>;
+  def SEH_BeginEpilogue : I<0, Pseudo, (outs), (ins),
+                            "#SEH_BeginEpilogue", []>;
+  def SEH_EndEpilogue : I<0, Pseudo, (outs), (ins),
+                            "#SEH_EndEpilogue", []>;
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp
index 24db39c4e98b96..83c7ac6562b854 100644
--- a/llvm/lib/Target/X86/X86MCInstLower.cpp
+++ b/llvm/lib/Target/X86/X86MCInstLower.cpp
@@ -1781,6 +1781,14 @@ void X86AsmPrinter::EmitSEHInstruction(const MachineInstr *MI) {
     OutStreamer->emitWinCFIEndProlog();
     break;
 
+  case X86::SEH_BeginEpilogue:
+    OutStreamer->emitWinCFIBeginEpilogue();
+    break;
+
+  case X86::SEH_EndEpilogue:
+    OutStreamer->emitWinCFIEndEpilogue();
+    break;
+
   default:
     llvm_unreachable("expected SEH_ instruction");
   }
@@ -2422,11 +2430,17 @@ void X86AsmPrinter::emitInstruction(const MachineInstr *MI) {
   case X86::SEH_SetFrame:
   case X86::SEH_PushFrame:
   case X86::SEH_EndPrologue:
+  case X86::SEH_EndEpilogue:
     EmitSEHInstruction(MI);
     return;
 
-  case X86::SEH_Epilogue: {
+  case X86::SEH_BeginEpilogue: {
     assert(MF->hasWinCFI() && "SEH_ instruction in function without WinCFI?");
+    // Windows unwinder will not invoke function's exception handler if IP is
+    // either in prologue or in epilogue.  This behavior causes a problem when a
+    // call immediately precedes an epilogue, because the return address points
+    // into the epilogue.  To cope with that, we insert a 'nop' if it ends up
+    // immediately after a CALL in the final emitted code.
     MachineBasicBlock::const_iterator MBBI(MI);
     // Check if preceded by a call and emit nop if so.
     for (MBBI = PrevCrossBBInst(MBBI);
@@ -2441,6 +2455,8 @@ void X86AsmPrinter::emitInstruction(const MachineInstr *MI) {
         break;
       }
     }
+
+    EmitSEHInstruction(MI);
     return;
   }
   case X86::UBSAN_UD1:
diff --git a/llvm/test/CodeGen/X86/apx/push2-pop2-cfi-seh.ll b/llvm/test/CodeGen/X86/apx/push2-pop2-cfi-seh.ll
index 6c9fdc2adce2ff..224e4c1cc09f8d 100644
--- a/llvm/test/CodeGen/X86/apx/push2-pop2-cfi-seh.ll
+++ b/llvm/test/CodeGen/X86/apx/push2-pop2-cfi-seh.ll
@@ -142,6 +142,7 @@ define i32 @csr6_alloc16(ptr %argv) {
 ; WIN-REF-NEXT:    xorl %eax, %eax
 ; WIN-REF-NEXT:    callq *%rax
 ; WIN-REF-NEXT:    nop
+; WIN-REF-NEXT:    .seh_beginepilogue
 ; WIN-REF-NEXT:    addq $56, %rsp
 ; WIN-REF-NEXT:    popq %rbx
 ; WIN-REF-NEXT:    popq %rbp
@@ -149,6 +150,7 @@ define i32 @csr6_alloc16(ptr %argv) {
 ; WIN-REF-NEXT:    popq %r13
 ; WIN-REF-NEXT:    popq %r14
 ; WIN-REF-NEXT:    popq %r15
+; WIN-REF-NEXT:    .seh_endepilogue
 ; WIN-REF-NEXT:    retq
 ; WIN-REF-NEXT:    .seh_endproc
 ;
@@ -173,11 +175,13 @@ define i32 @csr6_alloc16(ptr %argv) {
 ; WIN-NEXT:    xorl %eax, %eax
 ; WIN-NEXT:    callq *%rax
 ; WIN-NEXT:    nop
+; WIN-NEXT:    .seh_beginepilogue
 ; WIN-NEXT:    addq $64, %rsp
 ; WIN-NEXT:    pop2 %rbp, %rbx
 ; WIN-NEXT:    pop2 %r13, %r12
 ; WIN-NEXT:    pop2 %r15, %r14
 ; WIN-NEXT:    popq %rcx
+; WIN-NEXT:    .seh_endepilogue
 ; WIN-NEXT:    retq
 ; WIN-NEXT:    .seh_endproc
 ;
@@ -202,11 +206,13 @@ define i32 @csr6_alloc16(ptr %argv) {
 ; WIN-PPX-NEXT:    xorl %eax, %eax
 ; WIN-PPX-NEXT:    callq *%rax
 ; WIN-PPX-NEXT:    nop
+; WIN-PPX-NEXT:    .seh_beginepilogue
 ; WIN-PPX-NEXT:    addq $64, %rsp
 ; WIN-PPX-NEXT:    pop2p %rbp, %rbx
 ; WIN-PPX-NEXT:    pop2p %r13, %r12
 ; WIN-PPX-NEXT:    pop2p %r15, %r14
 ; WIN-PPX-NEXT:    popq %rcx
+; WIN-PPX-NEXT:    .seh_endepilogue
 ; WIN-PPX-NEXT:    retq
 ; WIN-PPX-NEXT:    .seh_endproc
 entry:
diff --git a/llvm/test/CodeGen/X86/avx512-intel-ocl.ll b/llvm/test/CodeGen/X86/avx512-intel-ocl.ll
index 6c68279b8d04ae..941bf0d63778f0 100644
--- a/llvm/test/CodeGen/X86/avx512-intel-ocl.ll
+++ b/llvm/test/CodeGen/X86/avx512-intel-ocl.ll
@@ -429,7 +429,9 @@ define <16 x float> @testf16_inp_mask(<16 x float> %a, i16 %mask)  {
 ; WIN64-KNL-NEXT:    kmovw %edx, %k1
 ; WIN64-KNL-NEXT:    callq func_float16_mask
 ; WIN64-KNL-NEXT:    nop
+; WIN64-KNL-NEXT:    .seh_beginepilogue
 ; WIN64-KNL-NEXT:    addq $40, %rsp
+; WIN64-KNL-NEXT:    .seh_endepilogue
 ; WIN64-KNL-NEXT:    retq
 ; WIN64-KNL-NEXT:    .seh_endproc
 ;
@@ -443,7 +445,9 @@ define <16 x float> @testf16_inp_mask(<16 x float> %a, i16 %mask)  {
 ; WIN64-SKX-NEXT:    kmovd %edx, %k1
 ; WIN64-SKX-NEXT:    callq func_float16_mask
 ; WIN64-SKX-NEXT:    nop
+; WIN64-SKX-NEXT:    .seh_beginepilogue
 ; WIN64-SKX-NEXT:    addq $40, %rsp
+; WIN64-SKX-NEXT:    .seh_endepilogue
 ; WIN64-SKX-NEXT:    retq
 ; WIN64-SKX-NEXT:    .seh_endproc
 ;
diff --git a/llvm/test/CodeGen/X86/avx512-regcall-Mask.ll b/llvm/test/CodeGen/X86/avx512-regcall-Mask.ll
index b3a0c7dffae117..d9efc35e6893b8 100644
--- a/llvm/test/CodeGen/X86/avx512-regcall-Mask.ll
+++ b/llvm/test/CodeGen/X86/avx512-regcall-Mask.ll
@@ -149,12 +149,14 @@ define dso_local i64 @caller_argv64i1() #0 {
 ; WIN64-NEXT:    callq test_argv64i1
 ; WIN64-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm6 # 16-byte Reload
 ; WIN64-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    addq $48, %rsp
 ; WIN64-NEXT:    popq %rdi
 ; WIN64-NEXT:    popq %rsi
 ; WIN64-NEXT:    popq %r12
 ; WIN64-NEXT:    popq %r14
 ; WIN64-NEXT:    popq %r15
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -256,9 +258,11 @@ define dso_local <64 x i1> @caller_retv64i1() #0 {
 ; WIN64-NEXT:    vpmovm2b %k0, %zmm0
 ; WIN64-NEXT:    vmovaps (%rsp), %xmm6 # 16-byte Reload
 ; WIN64-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    addq $40, %rsp
 ; WIN64-NEXT:    popq %rdi
 ; WIN64-NEXT:    popq %rsi
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -334,10 +338,12 @@ define dso_local x86_regcallcc i32 @test_argv32i1(<32 x i1> %x0, <32 x i1> %x1,
 ; WIN64-NEXT:    vzeroupper
 ; WIN64-NEXT:    callq test_argv32i1helper
 ; WIN64-NEXT:    nop
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    movq %rbp, %rsp
 ; WIN64-NEXT:    popq %r10
 ; WIN64-NEXT:    popq %r11
 ; WIN64-NEXT:    popq %rbp
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -417,9 +423,11 @@ define dso_local i32 @caller_argv32i1() #0 {
 ; WIN64-NEXT:    callq test_argv32i1
 ; WIN64-NEXT:    vmovaps (%rsp), %xmm6 # 16-byte Reload
 ; WIN64-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    addq $40, %rsp
 ; WIN64-NEXT:    popq %rdi
 ; WIN64-NEXT:    popq %rsi
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -480,9 +488,11 @@ define dso_local i32 @caller_retv32i1() #0 {
 ; WIN64-NEXT:    incl %eax
 ; WIN64-NEXT:    vmovaps (%rsp), %xmm6 # 16-byte Reload
 ; WIN64-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    addq $40, %rsp
 ; WIN64-NEXT:    popq %rdi
 ; WIN64-NEXT:    popq %rsi
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -554,9 +564,11 @@ define dso_local x86_regcallcc i16 @test_argv16i1(<16 x i1> %x0, <16 x i1> %x1,
 ; WIN64-NEXT:    vzeroupper
 ; WIN64-NEXT:    callq test_argv16i1helper
 ; WIN64-NEXT:    nop
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    addq $88, %rsp
 ; WIN64-NEXT:    popq %r10
 ; WIN64-NEXT:    popq %r11
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -635,9 +647,11 @@ define dso_local i16 @caller_argv16i1() #0 {
 ; WIN64-NEXT:    callq test_argv16i1
 ; WIN64-NEXT:    vmovaps (%rsp), %xmm6 # 16-byte Reload
 ; WIN64-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    addq $40, %rsp
 ; WIN64-NEXT:    popq %rdi
 ; WIN64-NEXT:    popq %rsi
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -702,9 +716,11 @@ define dso_local i16 @caller_retv16i1() #0 {
 ; WIN64-NEXT:    # kill: def $ax killed $ax killed $eax
 ; WIN64-NEXT:    vmovaps (%rsp), %xmm6 # 16-byte Reload
 ; WIN64-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    addq $40, %rsp
 ; WIN64-NEXT:    popq %rdi
 ; WIN64-NEXT:    popq %rsi
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -778,9 +794,11 @@ define dso_local x86_regcallcc i8 @test_argv8i1(<8 x i1> %x0, <8 x i1> %x1, <8 x
 ; WIN64-NEXT:    vzeroupper
 ; WIN64-NEXT:    callq test_argv8i1helper
 ; WIN64-NEXT:    nop
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    addq $88, %rsp
 ; WIN64-NEXT:    popq %r10
 ; WIN64-NEXT:    popq %r11
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -859,9 +877,11 @@ define dso_local i8 @caller_argv8i1() #0 {
 ; WIN64-NEXT:    callq test_argv8i1
 ; WIN64-NEXT:    vmovaps (%rsp), %xmm6 # 16-byte Reload
 ; WIN64-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    addq $40, %rsp
 ; WIN64-NEXT:    popq %rdi
 ; WIN64-NEXT:    popq %rsi
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -929,9 +949,11 @@ define dso_local <8 x i1> @caller_retv8i1() #0 {
 ; WIN64-NEXT:    # kill: def $xmm0 killed $xmm0 killed $zmm0
 ; WIN64-NEXT:    vmovaps (%rsp), %xmm6 # 16-byte Reload
 ; WIN64-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    addq $40, %rsp
 ; WIN64-NEXT:    popq %rdi
 ; WIN64-NEXT:    popq %rsi
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    vzeroupper
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
diff --git a/llvm/test/CodeGen/X86/avx512-regcall-NoMask.ll b/llvm/test/CodeGen/X86/avx512-regcall-NoMask.ll
index 2081d201704f3a..940dc7fb2e4898 100644
--- a/llvm/test/CodeGen/X86/avx512-regcall-NoMask.ll
+++ b/llvm/test/CodeGen/X86/avx512-regcall-NoMask.ll
@@ -45,7 +45,9 @@ define dso_local x86_regcallcc i1 @test_CallargReti1(i1 %a)  {
 ; WIN64-NEXT:    movzbl %al, %eax
 ; WIN64-NEXT:    callq test_argReti1
 ; WIN64-NEXT:    incb %al
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    popq %rcx
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -108,7 +110,9 @@ define dso_local x86_regcallcc i8 @test_CallargReti8(i8 %a)  {
 ; WIN64-NEXT:    movzbl %al, %eax
 ; WIN64-NEXT:    callq test_argReti8
 ; WIN64-NEXT:    incb %al
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    popq %rcx
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -173,7 +177,9 @@ define dso_local x86_regcallcc i16 @test_CallargReti16(i16 %a)  {
 ; WIN64-NEXT:    # kill: def $ax killed $ax def $eax
 ; WIN64-NEXT:    incl %eax
 ; WIN64-NEXT:    # kill: def $ax killed $ax killed $eax
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    popq %rcx
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -232,7 +238,9 @@ define dso_local x86_regcallcc i32 @test_CallargReti32(i32 %a)  {
 ; WIN64-NEXT:    incl %eax
 ; WIN64-NEXT:    callq test_argReti32
 ; WIN64-NEXT:    incl %eax
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    popq %rcx
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -294,7 +302,9 @@ define dso_local x86_regcallcc i64 @test_CallargReti64(i64 %a)  {
 ; WIN64-NEXT:    incq %rax
 ; WIN64-NEXT:    callq test_argReti64
 ; WIN64-NEXT:    incq %rax
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    popq %rcx
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -360,7 +370,9 @@ define dso_local x86_regcallcc float @test_CallargRetFloat(float %a)  {
 ; WIN64-NEXT:    callq test_argRetFloat
 ; WIN64-NEXT:    vaddss %xmm0, %xmm8, %xmm0
 ; WIN64-NEXT:    vmovaps (%rsp), %xmm8 # 16-byte Reload
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    addq $24, %rsp
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -430,7 +442,9 @@ define dso_local x86_regcallcc double @test_CallargRetDouble(double %a)  {
 ; WIN64-NEXT:    callq test_argRetDouble
 ; WIN64-NEXT:    vaddsd %xmm0, %xmm8, %xmm0
 ; WIN64-NEXT:    vmovaps (%rsp), %xmm8 # 16-byte Reload
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    addq $24, %rsp
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -522,7 +536,9 @@ define x86_regcallcc x86_fp80 @test_CallargRetf80(x86_fp80 %a)  {
 ; WIN64-NEXT:    fadd %st, %st(0)
 ; WIN64-NEXT:    callq test_argRetf80
 ; WIN64-NEXT:    fadd %st, %st(0)
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    popq %rax
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -558,7 +574,9 @@ define dso_local x86_regcallcc double @test_CallargParamf80(x86_fp80 %a)  {
 ; WIN64-NEXT:    fadd %st, %st(0)
 ; WIN64-NEXT:    callq test_argParamf80
 ; WIN64-NEXT:    vaddsd %xmm0, %xmm0, %xmm0
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    popq %rax
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -617,7 +635,9 @@ define dso_local x86_regcallcc ptr @test_CallargRetPointer(ptr %a)  {
 ; WIN64-NEXT:    incl %eax
 ; WIN64-NEXT:    callq test_argRetPointer
 ; WIN64-NEXT:    incl %eax
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    popq %rcx
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -703,7 +723,9 @@ define dso_local x86_regcallcc <4 x i32> @test_CallargRet128Vector(<4 x i1> %x,
 ; WIN64-NEXT:    kmovw {{[-0-9]+}}(%r{{[sb]}}p), %k1 # 2-byte Reload
 ; WIN64-NEXT:    vmovdqa32 %xmm8, %xmm0 {%k1}
 ; WIN64-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm8 # 16-byte Reload
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    addq $40, %rsp
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -783,7 +805,9 @@ define dso_local x86_regcallcc <8 x i32> @test_CallargRet256Vector(<8 x i1> %x,
 ; WIN64-NEXT:    kmovw {{[-0-9]+}}(%r{{[sb]}}p), %k1 # 2-byte Reload
 ; WIN64-NEXT:    vmovdqu {{[-0-9]+}}(%r{{[sb]}}p), %ymm1 # 32-byte Reload
 ; WIN64-NEXT:    vmovdqa32 %ymm1, %ymm0 {%k1}
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    addq $56, %rsp
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -859,7 +883,9 @@ define dso_local x86_regcallcc <16 x i32> @test_CallargRet512Vector(<16 x i1> %x
 ; WIN64-NEXT:    kmovw {{[-0-9]+}}(%r{{[sb]}}p), %k1 # 2-byte Reload
 ; WIN64-NEXT:    vmovdqu64 {{[-0-9]+}}(%r{{[sb]}}p), %zmm1 # 64-byte Reload
 ; WIN64-NEXT:    vmovdqa32 %zmm1, %zmm0 {%k1}
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    addq $88, %rsp
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
diff --git a/llvm/test/CodeGen/X86/break-false-dep.ll b/llvm/test/CodeGen/X86/break-false-dep.ll
index 8ff7fb2d351ad1..4d74f4dd4c8255 100644
--- a/llvm/test/CodeGen/X86/break-false-dep.ll
+++ b/llvm/test/CodeGen/X86/break-false-dep.ll
@@ -516,8 +516,10 @@ define dso_local void @loopdep3() {
 ; SSE-WIN-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm13 # 16-byte Reload
 ; SSE-WIN-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm14 # 16-byte Reload
 ; SSE-WIN-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm15 # 16-byte Reload
+; SSE-WIN-NEXT:    .seh_beginepilogue
 ; SSE-WIN-NEXT:    addq $160, %rsp
 ; SSE-WIN-NEXT:    popq %rsi
+; SSE-WIN-NEXT:    .seh_endepilogue
 ; SSE-WIN-NEXT:    retq
 ; SSE-WIN-NEXT:    .seh_endproc
 ;
@@ -592,8 +594,10 @@ define dso_local void @loopdep3() {
 ; AVX-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm13 # 16-byte Reload
 ; AVX-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm14 # 16-byte Reload
 ; AVX-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm15 # 16-byte Reload
+; AVX-NEXT:    .seh_beginepilogue
 ; AVX-NEXT:    addq $160, %rsp
 ; AVX-NEXT:    popq %rsi
+; AVX-NEXT:    .seh_endepilogue
 ; AVX-NEXT:    retq
 ; AVX-NEXT:    .seh_endproc
 entry:
@@ -710,7 +714,9 @@ define dso_local double @inlineasmdep(i64 %arg) {
 ; SSE-WIN-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm13 # 16-byte Reload
 ; SSE-WIN-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm14 # 16-byte Reload
 ; SSE-WIN-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm15 # 16-byte Reload
+; SSE-WIN-NEXT:    .seh_beginepilogue
 ; SSE-WIN-NEXT:    addq $168, %rsp
+; SSE-WIN-NEXT:    .seh_endepilogue
 ; SSE-WIN-NEXT:    retq
 ; SSE-WIN-NEXT:    .seh_endproc
 ;
@@ -767,7 +773,9 @@ define dso_local double @inlineasmdep(i64 %arg) {
 ; AVX-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm13 # 16-byte Reload
 ; AVX-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm14 # 16-byte Reload
 ; AVX-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm15 # 16-byte Reload
+; AVX-NEXT:    .seh_beginepilogue
 ; AVX-NEXT:    addq $168, %rsp
+; AVX-NEXT:    .seh_endepilogue
 ; AVX-NEXT:    retq
 ; AVX-NEXT:    .seh_endproc
 top:
@@ -869,7 +877,9 @@ define dso_local double @truedeps(float %arg) {
 ; SSE-WIN-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm13 # 16-byte Reload
 ; SSE-WIN-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm14 # 16-byte Reload
 ; SSE-WIN-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm15 # 16-byte Reload
+; SSE-WIN-NEXT:    .seh_beginepilogue
 ; SSE-WIN-NEXT:    addq $184, %rsp
+; SSE-WIN-NEXT:    .seh_endepilogue
 ; SSE-WIN-NEXT:    retq
 ; SSE-WIN-NEXT:    .seh_endproc
 ;
@@ -930,7 +940,9 @@ define dso_local double @truedeps(float %arg) {
 ; AVX-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm13 # 16-byte Reload
 ; AVX-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm14 # 16-byte Reload
 ; AVX-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm15 # 16-byte Reload
+; AVX-NEXT:    .seh_beginepilogue
 ; AVX-NEXT:    addq $184, %rsp
+; AVX-NEXT:    .seh_endepilogue
 ; AVX-NEXT:    retq
 ; AVX-NEXT:    .seh_endproc
 top:
@@ -1029,7 +1041,9 @@ define dso_local double @clearence(i64 %arg) {
 ; SSE-WIN-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm13 # 16-byte Reload
 ; SSE-WIN-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm14 # 16-byte Reload
 ; SSE-WIN-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm15 # 16-byte Reload
+; SSE-WIN-NEXT:    .seh_beginepilogue
 ; SSE-WIN-NEXT:    addq $168, %rsp
+; SSE-WIN-NEXT:    .seh_endepilogue
 ; SSE-WIN-NEXT:    retq
 ; SSE-WIN-NEXT:    .seh_endproc
 ;
@@ -1088,7 +1102,9 @@ define dso_local double @clearence(i64 %arg) {
 ; AVX-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm13 # 16-byte Reload
 ; AVX-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm14 # 16-byte Reload
 ; AVX-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm15 # 16-byte Reload
+; AVX-NEXT:    .seh_beginepilogue
 ; AVX-NEXT:    addq $168, %rsp
+; AVX-NEXT:    .seh_endepilogue
 ; AVX-NEXT:    retq
 ; AVX-NEXT:    .seh_endproc
 top:
@@ -1397,7 +1413,9 @@ define dso_local void @loopclearance2(ptr nocapture %y, ptr %x, double %c1, doub
 ; SSE-WIN-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm13 # 16-byte Reload
 ; SSE-WIN-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm14 # 16-byte Reload
 ; SSE-WIN-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm15 # 16-byte Reload
+; SSE-WIN-NEXT:    .seh_beginepilogue
 ; SSE-WIN-NEXT:    addq $152, %rsp
+; SSE-WIN-NEXT:    .seh_endepilogue
 ; SSE-WIN-NEXT:    retq
 ; SSE-WIN-NEXT:    .seh_endproc
 ;
@@ -1477,7 +1495,9 @@ define dso_local void @loopclearance2(ptr nocapture %y, ptr %x, double %c1, doub
 ; AVX1-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm13 # 16-byte Reload
 ; AVX1-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm14 # 16-byte Reload
 ; AVX1-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm15 # 16-byte Reload
+; AVX1-NEXT:    .seh_beginepilogue
 ; AVX1-NEXT:    addq $152, %rsp
+; AVX1-NEXT:    .seh_endepilogue
 ; AVX1-NEXT:    retq
 ; AVX1-NEXT:    .seh_endproc
 ;
@@ -1557,7 +1577,9 @@ define dso_local void @loopclearance2(ptr nocapture %y, ptr %x, double %c1, doub
 ; AVX512VL-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm13 # 16-byte Reload
 ; AVX512VL-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm14 # 16-byte Reload
 ; AVX512VL-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm15 # 16-byte Reload
+; AVX512VL-NEXT:    .seh_beginepilogue
 ; AVX512VL-NEXT:    addq $152, %rsp
+; AVX512VL-NEXT:    .seh_endepilogue
 ; AVX512VL-NEXT:    retq
 ; AVX512VL-NEXT:    .seh_endproc
 entry:
diff --git a/llvm/test/CodeGen/X86/catchpad-realign-savexmm.ll b/llvm/test/CodeGen/X86/catchpad-realign-savexmm.ll
index 84267acf3db210..4f7f4040ab17a5 100644
--- a/llvm/test/CodeGen/X86/catchpad-realign-savexmm.ll
+++ b/llvm/test/CodeGen/X86/catchpad-realign-savexmm.ll
@@ -47,8 +47,10 @@ catch:
 ; CHECK: .Ltmp{{.*}}
 ; CHECK: .LBB{{.*}} # Block address taken
 ; CHECK: movaps  -16(%rbp), %xmm6
+; CHECK: .seh_beginepilogue
 ; CHECK: addq    $64, %rsp
 ; CHECK: popq    %rbp
+; CHECK: .seh_endepilogue
 ; CHECK: retq
 ; CHECK: .seh_handlerdata
 ; CHECK: # %catch
@@ -63,6 +65,8 @@ catch:
 ; CHECK: .seh_endprologue
 ; CHECK: movapd  32(%rsp), %xmm6
 ; CHECK: leaq    .LBB0_1(%rip), %rax
+; CHECK: .seh_beginepilogue
 ; CHECK: addq    $48, %rsp
 ; CHECK: popq    %rbp
+; CHECK: .seh_endepilogue
 ; CHECK: retq # CATCHRET
diff --git a/llvm/test/CodeGen/X86/cfguard-x86-64-vectorcall.ll b/llvm/test/CodeGen/X86/cfguard-x86-64-vectorcall.ll
index fbba8f4bcaaee0..b1323de3a69a7f 100644
--- a/llvm/test/CodeGen/X86/cfguard-x86-64-vectorcall.ll
+++ b/llvm/test/CodeGen/X86/cfguard-x86-64-vectorcall.ll
@@ -22,7 +22,9 @@ define void @func_cf_vector_x64(ptr %0, ptr %1) #0 {
 ; X64-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
 ; X64-NEXT:    callq *__guard_dispatch_icall_fptr(%rip)
 ; X64-NEXT:    nop
+; X64-NEXT:    .seh_beginepilogue
 ; X64-NEXT:    addq $72, %rsp
+; X64-NEXT:    .seh_endepilogue
 ; X64-NEXT:    retq
 ; X64-NEXT:    .seh_endproc
 entry:
diff --git a/llvm/test/CodeGen/X86/cleanuppad-realign.ll b/llvm/test/CodeGen/X86/cleanuppad-realign.ll
index be766425da9cff..a802350798344f 100644
--- a/llvm/test/CodeGen/X86/cleanuppad-realign.ll
+++ b/llvm/test/CodeGen/X86/cleanuppad-realign.ll
@@ -74,5 +74,7 @@ ehcleanup:                                        ; preds = %entry
 ; X64: 	       andq    $-32, %rdx
 ; X64: 	       movq    %rdx, %rbx
 ; X64-NOT: 	mov{{.*}}, %rbx
+; X64:         .seh_beginepilogue
 ; X64:         popq    %rbp
+; X64:         .seh_endepilogue
 ; X64:         retq                            # CLEANUPRET
diff --git a/llvm/test/CodeGen/X86/conditional-tailcall-pgso.ll b/llvm/test/CodeGen/X86/conditional-tailcall-pgso.ll
index 396e0e7b065703..18ceec3d486b98 100644
--- a/llvm/test/CodeGen/X86/conditional-tailcall-pgso.ll
+++ b/llvm/test/CodeGen/X86/conditional-tailcall-pgso.ll
@@ -114,13 +114,17 @@ define void @f_non_leaf(i32 %x, i32 %y) !prof !14 {
 ; WIN64-NEXT:    jne .LBB1_2 # encoding: [0x75,A]
 ; WIN64-NEXT:    # fixup A - offset: 1, value: .LBB1_2-1, kind: FK_PCRel_1
 ; WIN64-NEXT:  # %bb.1: # %bb1
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    popq %rbx # encoding: [0x5b]
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    jmp foo # TAILCALL
 ; WIN64-NEXT:    # encoding: [0xeb,A]
 ; WIN64-NEXT:    # fixup A - offset: 1, value: foo-1, kind: FK_PCRel_1
 ; WIN64-NEXT:  .LBB1_2: # %bb2
 ; WIN64-NEXT:    nop # encoding: [0x90]
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    popq %rbx # encoding: [0x5b]
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    jmp bar # TAILCALL
 ; WIN64-NEXT:    # encoding: [0xeb,A]
 ; WIN64-NEXT:    # fixup A - offset: 1, value: bar-1, kind: FK_PCRel_1
diff --git a/llvm/test/CodeGen/X86/conditional-tailcall.ll b/llvm/test/CodeGen/X86/conditional-tailcall.ll
index 88a132d3850d1d..3a5fc714b08b46 100644
--- a/llvm/test/CodeGen/X86/conditional-tailcall.ll
+++ b/llvm/test/CodeGen/X86/conditional-tailcall.ll
@@ -114,13 +114,17 @@ define void @f_non_leaf(i32 %x, i32 %y) optsize {
 ; WIN64-NEXT:    jne .LBB1_2 # encoding: [0x75,A]
 ; WIN64-NEXT:    # fixup A - offset: 1, value: .LBB1_2-1, kind: FK_PCRel_1
 ; WIN64-NEXT:  # %bb.1: # %bb1
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    popq %rbx # encoding: [0x5b]
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    jmp foo # TAILCALL
 ; WIN64-NEXT:    # encoding: [0xeb,A]
 ; WIN64-NEXT:    # fixup A - offset: 1, value: foo-1, kind: FK_PCRel_1
 ; WIN64-NEXT:  .LBB1_2: # %bb2
 ; WIN64-NEXT:    nop # encoding: [0x90]
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    popq %rbx # encoding: [0x5b]
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    jmp bar # TAILCALL
 ; WIN64-NEXT:    # encoding: [0xeb,A]
 ; WIN64-NEXT:    # fixup A - offset: 1, value: bar-1, kind: FK_PCRel_1
diff --git a/llvm/test/CodeGen/X86/ldexp.ll b/llvm/test/CodeGen/X86/ldexp.ll
index 0aa376195627d4..49f2be7184a0af 100644
--- a/llvm/test/CodeGen/X86/ldexp.ll
+++ b/llvm/test/CodeGen/X86/ldexp.ll
@@ -18,7 +18,9 @@ define float @ldexp_f32(i8 zeroext %x) {
 ; WIN64-NEXT:    movsd {{.*#+}} xmm0 = [1.0E+0,0.0E+0]
 ; WIN64-NEXT:    callq ldexp
 ; WIN64-NEXT:    cvtsd2ss %xmm0, %xmm0
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    addq $40, %rsp
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -138,8 +140,10 @@ define <2 x float> @ldexp_v2f32(<2 x float> %val, <2 x i32> %exp) {
 ; WIN64-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm6 # 16-byte Reload
 ; WIN64-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
 ; WIN64-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm8 # 16-byte Reload
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    addq $80, %rsp
 ; WIN64-NEXT:    popq %rsi
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -258,8 +262,10 @@ define <4 x float> @ldexp_v4f32(<4 x float> %val, <4 x i32> %exp) {
 ; WIN64-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm6 # 16-byte Reload
 ; WIN64-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
 ; WIN64-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm8 # 16-byte Reload
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    addq $80, %rsp
 ; WIN64-NEXT:    popq %rsi
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -367,8 +373,10 @@ define <2 x double> @ldexp_v2f64(<2 x double> %val, <2 x i32> %exp) {
 ; WIN64-NEXT:    movaps %xmm7, %xmm0
 ; WIN64-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm6 # 16-byte Reload
 ; WIN64-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    addq $64, %rsp
 ; WIN64-NEXT:    popq %rsi
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -493,10 +501,12 @@ define <4 x double> @ldexp_v4f64(<4 x double> %val, <4 x i32> %exp) {
 ; WIN64-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm6 # 16-byte Reload
 ; WIN64-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
 ; WIN64-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm8 # 16-byte Reload
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    addq $80, %rsp
 ; WIN64-NEXT:    popq %rbx
 ; WIN64-NEXT:    popq %rdi
 ; WIN64-NEXT:    popq %rsi
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
@@ -584,8 +594,10 @@ define half @ldexp_f16(half %arg0, i32 %arg1) {
 ; WIN64-NEXT:    callq ldexp
 ; WIN64-NEXT:    callq __truncdfhf2
 ; WIN64-NEXT:    nop
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    addq $32, %rsp
 ; WIN64-NEXT:    popq %rsi
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
diff --git a/llvm/test/CodeGen/X86/localescape.ll b/llvm/test/CodeGen/X86/localescape.ll
index 399e1b38e017d7..1eaea26c8ce4c4 100644
--- a/llvm/test/CodeGen/X86/localescape.ll
+++ b/llvm/test/CodeGen/X86/localescape.ll
@@ -124,7 +124,9 @@ define void @alloc_func_no_frameaddr() {
 ; X64: movl $13, 32(%rsp)
 ; X64: xorl %ecx, %ecx
 ; X64: callq print_framealloc_from_fp
+; X64: .seh_beginepilogue
 ; X64: addq $40, %rsp
+; X64: .seh_endepilogue
 ; X64: retq
 
 ; X86-LABEL: alloc_func_no_frameaddr:
diff --git a/llvm/test/CodeGen/X86/mixed-ptr-sizes.ll b/llvm/test/CodeGen/X86/mixed-ptr-sizes.ll
index 67539b07f5716c..f2f6fabf05edf8 100644
--- a/llvm/test/CodeGen/X86/mixed-ptr-sizes.ll
+++ b/llvm/test/CodeGen/X86/mixed-ptr-sizes.ll
@@ -131,7 +131,9 @@ define dso_local void @test_null_arg(ptr %f) {
 ; ALL-NEXT:    xorl %edx, %edx
 ; ALL-NEXT:    callq test_noop1
 ; ALL-NEXT:    nop
+; ALL-NEXT:    .seh_beginepilogue
 ; ALL-NEXT:    addq $40, %rsp
+; ALL-NEXT:    .seh_endepilogue
 ; ALL-NEXT:    retq
 ; ALL-NEXT:    .seh_endproc
 entry:
diff --git a/llvm/test/CodeGen/X86/musttail-varargs.ll b/llvm/test/CodeGen/X86/musttail-varargs.ll
index d3ded0b2a03d87..0da98b758faf7d 100644
--- a/llvm/test/CodeGen/X86/musttail-varargs.ll
+++ b/llvm/test/CodeGen/X86/musttail-varargs.ll
@@ -228,11 +228,13 @@ define void @f_thunk(ptr %this, ...) {
 ; WINDOWS-NEXT:    movq %rbx, %rdx
 ; WINDOWS-NEXT:    movq %rdi, %r8
 ; WINDOWS-NEXT:    movq %rsi, %r9
+; WINDOWS-NEXT:    .seh_beginepilogue
 ; WINDOWS-NEXT:    addq $72, %rsp
 ; WINDOWS-NEXT:    popq %rbx
 ; WINDOWS-NEXT:    popq %rdi
 ; WINDOWS-NEXT:    popq %rsi
 ; WINDOWS-NEXT:    popq %r14
+; WINDOWS-NEXT:    .seh_endepilogue
 ; WINDOWS-NEXT:    rex64 jmpq *%rax # TAILCALL
 ; WINDOWS-NEXT:    .seh_endproc
 ;
diff --git a/llvm/test/CodeGen/X86/no-sse-win64.ll b/llvm/test/CodeGen/X86/no-sse-win64.ll
index e8531dc8b9516b..6ce292d465b236 100644
--- a/llvm/test/CodeGen/X86/no-sse-win64.ll
+++ b/llvm/test/CodeGen/X86/no-sse-win64.ll
@@ -52,7 +52,9 @@ define void @pass_double(ptr %p) {
 ; CHECK-NEXT:    movq (%rcx), %rcx
 ; CHECK-NEXT:    callq take_double
 ; CHECK-NEXT:    nop
+; CHECK-NEXT:    .seh_beginepilogue
 ; CHECK-NEXT:    addq $40, %rsp
+; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    retq
 ; CHECK-NEXT:    .seh_endproc
   %v = load double, ptr %p
@@ -69,7 +71,9 @@ define void @pass_float(ptr %p) {
 ; CHECK-NEXT:    movl (%rcx), %ecx
 ; CHECK-NEXT:    callq take_float
 ; CHECK-NEXT:    nop
+; CHECK-NEXT:    .seh_beginepilogue
 ; CHECK-NEXT:    addq $40, %rsp
+; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    retq
 ; CHECK-NEXT:    .seh_endproc
   %v = load float, ptr %p
@@ -91,8 +95,10 @@ define void @call_double(ptr %p) {
 ; CHECK-NEXT:    movq %rcx, %rsi
 ; CHECK-NEXT:    callq produce_double
 ; CHECK-NEXT:    movq %rax, (%rsi)
+; CHECK-NEXT:    .seh_beginepilogue
 ; CHECK-NEXT:    addq $32, %rsp
 ; CHECK-NEXT:    popq %rsi
+; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    retq
 ; CHECK-NEXT:    .seh_endproc
   %v = call double @produce_double()
@@ -111,8 +117,10 @@ define void @call_float(ptr %p) {
 ; CHECK-NEXT:    movq %rcx, %rsi
 ; CHECK-NEXT:    callq produce_float
 ; CHECK-NEXT:    movl %eax, (%rsi)
+; CHECK-NEXT:    .seh_beginepilogue
 ; CHECK-NEXT:    addq $32, %rsp
 ; CHECK-NEXT:    popq %rsi
+; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    retq
 ; CHECK-NEXT:    .seh_endproc
   %v = call float @produce_float()
diff --git a/llvm/test/CodeGen/X86/preserve_nonecc_call_win.ll b/llvm/test/CodeGen/X86/preserve_nonecc_call_win.ll
index 232ac345057825..1d47f388de0b07 100644
--- a/llvm/test/CodeGen/X86/preserve_nonecc_call_win.ll
+++ b/llvm/test/CodeGen/X86/preserve_nonecc_call_win.ll
@@ -12,7 +12,9 @@ define preserve_nonecc void @entry(ptr %r12, ptr %r13, ptr %r14, ptr %r15, ptr %
 ; CHECK-NEXT:    .seh_endprologue
 ; CHECK-NEXT:    callq boring
 ; CHECK-NEXT:    nop
+; CHECK-NEXT:    .seh_beginepilogue
 ; CHECK-NEXT:    addq $40, %rsp
+; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    jmp continuation # TAILCALL
 ; CHECK-NEXT:    .seh_endproc
   call void @boring()
diff --git a/llvm/test/CodeGen/X86/segmented-stacks.ll b/llvm/test/CodeGen/X86/segmented-stacks.ll
index 7304fedd287587..295f4f371495e0 100644
--- a/llvm/test/CodeGen/X86/segmented-stacks.ll
+++ b/llvm/test/CodeGen/X86/segmented-stacks.ll
@@ -257,7 +257,9 @@ define void @test_basic() #0 {
 ; X64-MinGW-NEXT:    movl $10, %edx
 ; X64-MinGW-NEXT:    callq dummy_use
 ; X64-MinGW-NEXT:    nop
+; X64-MinGW-NEXT:    .seh_beginepilogue
 ; X64-MinGW-NEXT:    addq $72, %rsp
+; X64-MinGW-NEXT:    .seh_endepilogue
 ; X64-MinGW-NEXT:    retq
 ; X64-MinGW-NEXT:  .LBB0_1:
 ; X64-MinGW-NEXT:    movl $72, %r10d
@@ -603,8 +605,10 @@ define i32 @test_nested(ptr nest %closure, i32 %other) #0 {
 ; X64-MinGW-NEXT:    movl $10, %edx
 ; X64-MinGW-NEXT:    callq dummy_use
 ; X64-MinGW-NEXT:    movl %esi, %eax
+; X64-MinGW-NEXT:    .seh_beginepilogue
 ; X64-MinGW-NEXT:    addq $80, %rsp
 ; X64-MinGW-NEXT:    popq %rsi
+; X64-MinGW-NEXT:    .seh_endepilogue
 ; X64-MinGW-NEXT:    retq
 ; X64-MinGW-NEXT:  .LBB1_1:
 ; X64-MinGW-NEXT:    movq %r10, %rax
@@ -859,7 +863,9 @@ define void @test_large() #0 {
 ; X64-MinGW-NEXT:    movl $3, %edx
 ; X64-MinGW-NEXT:    callq dummy_use
 ; X64-MinGW-NEXT:    nop
+; X64-MinGW-NEXT:    .seh_beginepilogue
 ; X64-MinGW-NEXT:    addq $40040, %rsp # imm = 0x9C68
+; X64-MinGW-NEXT:    .seh_endepilogue
 ; X64-MinGW-NEXT:    retq
 ; X64-MinGW-NEXT:  .LBB2_1:
 ; X64-MinGW-NEXT:    movl $40040, %r10d # imm = 0x9C68
@@ -1096,7 +1102,9 @@ define fastcc void @test_fastcc() #0 {
 ; X64-MinGW-NEXT:    movl $10, %edx
 ; X64-MinGW-NEXT:    callq dummy_use
 ; X64-MinGW-NEXT:    nop
+; X64-MinGW-NEXT:    .seh_beginepilogue
 ; X64-MinGW-NEXT:    addq $72, %rsp
+; X64-MinGW-NEXT:    .seh_endepilogue
 ; X64-MinGW-NEXT:    retq
 ; X64-MinGW-NEXT:  .LBB3_1:
 ; X64-MinGW-NEXT:    movl $72, %r10d
@@ -1347,7 +1355,9 @@ define fastcc void @test_fastcc_large() #0 {
 ; X64-MinGW-NEXT:    movl $3, %edx
 ; X64-MinGW-NEXT:    callq dummy_use
 ; X64-MinGW-NEXT:    nop
+; X64-MinGW-NEXT:    .seh_beginepilogue
 ; X64-MinGW-NEXT:    addq $40040, %rsp # imm = 0x9C68
+; X64-MinGW-NEXT:    .seh_endepilogue
 ; X64-MinGW-NEXT:    retq
 ; X64-MinGW-NEXT:  .LBB4_1:
 ; X64-MinGW-NEXT:    movl $40040, %r10d # imm = 0x9C68
@@ -1602,7 +1612,9 @@ define fastcc void @test_fastcc_large_with_ecx_arg(i32 %a) #0 {
 ; X64-MinGW-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
 ; X64-MinGW-NEXT:    callq dummy_use
 ; X64-MinGW-NEXT:    nop
+; X64-MinGW-NEXT:    .seh_beginepilogue
 ; X64-MinGW-NEXT:    addq $40040, %rsp # imm = 0x9C68
+; X64-MinGW-NEXT:    .seh_endepilogue
 ; X64-MinGW-NEXT:    retq
 ; X64-MinGW-NEXT:  .LBB5_1:
 ; X64-MinGW-NEXT:    movl $40040, %r10d # imm = 0x9C68
@@ -2087,7 +2099,9 @@ define i32 @test_nested_unused(ptr nest %unused) #0 {
 ; X64-MinGW-NEXT:    movl $10, %edx
 ; X64-MinGW-NEXT:    callq dummy_use
 ; X64-MinGW-NEXT:    movl $123, %eax
+; X64-MinGW-NEXT:    .seh_beginepilogue
 ; X64-MinGW-NEXT:    addq $72, %rsp
+; X64-MinGW-NEXT:    .seh_endepilogue
 ; X64-MinGW-NEXT:    retq
 ; X64-MinGW-NEXT:  .LBB9_1:
 ; X64-MinGW-NEXT:    movl $72, %r10d
diff --git a/llvm/test/CodeGen/X86/seh-catchpad.ll b/llvm/test/CodeGen/X86/seh-catchpad.ll
index 62b431a830c793..673f88fb609b65 100644
--- a/llvm/test/CodeGen/X86/seh-catchpad.ll
+++ b/llvm/test/CodeGen/X86/seh-catchpad.ll
@@ -100,8 +100,10 @@ __except.ret:                                     ; preds = %catch.dispatch.7
 ; CHECK: .Ltmp1:
 ; CHECK: .LBB1_[[epilogue:[0-9]+]]:                                # %__try.cont.12
 ; CHECK:         xorl    %eax, %eax
+; CHECK:         .seh_beginepilogue
 ; CHECK:         addq    $32, %rsp
 ; CHECK:         popq    %rbp
+; CHECK:         .seh_endepilogue
 ; CHECK:         retq
 ; CHECK: .LBB1_[[except1bb:[0-9]+]]:                                # %__except
 ; CHECK: .Ltmp2:
diff --git a/llvm/test/CodeGen/X86/sse-regcall.ll b/llvm/test/CodeGen/X86/sse-regcall.ll
index 6f0293392eef2b..0e60e2cd6727ae 100644
--- a/llvm/test/CodeGen/X86/sse-regcall.ll
+++ b/llvm/test/CodeGen/X86/sse-regcall.ll
@@ -45,7 +45,9 @@ define x86_regcallcc i1 @test_CallargReti1(i1 %a)  {
 ; WIN64-NEXT:    movzbl %al, %eax
 ; WIN64-NEXT:    callq test_argReti1
 ; WIN64-NEXT:    incb %al
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    popq %rcx
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
diff --git a/llvm/test/CodeGen/X86/sse-regcall4.ll b/llvm/test/CodeGen/X86/sse-regcall4.ll
index c8df7a233d7e3f..11dd220b27bcd8 100644
--- a/llvm/test/CodeGen/X86/sse-regcall4.ll
+++ b/llvm/test/CodeGen/X86/sse-regcall4.ll
@@ -45,7 +45,9 @@ define x86_regcallcc i1 @test_CallargReti1(i1 %a)  {
 ; WIN64-NEXT:    movzbl %al, %eax
 ; WIN64-NEXT:    callq test_argReti1
 ; WIN64-NEXT:    incb %al
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    popq %rcx
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
diff --git a/llvm/test/CodeGen/X86/stack-coloring-wineh.ll b/llvm/test/CodeGen/X86/stack-coloring-wineh.ll
index 79057e0ea78d39..f3d8a720638c80 100644
--- a/llvm/test/CodeGen/X86/stack-coloring-wineh.ll
+++ b/llvm/test/CodeGen/X86/stack-coloring-wineh.ll
@@ -90,8 +90,10 @@ define void @pr66984(ptr %arg) personality ptr @__CxxFrameHandler3 {
 ; X86_64-NEXT:    # %exit
 ; X86_64-NEXT:  $ehgcr_0_3:
 ; X86_64-NEXT:    nop
+; X86_64-NEXT:    .seh_beginepilogue
 ; X86_64-NEXT:    addq $64, %rsp
 ; X86_64-NEXT:    popq %rbp
+; X86_64-NEXT:    .seh_endepilogue
 ; X86_64-NEXT:    retq
 ; X86_64-NEXT:    .seh_handlerdata
 ; X86_64-NEXT:    .long ($cppxdata$pr66984)@IMGREL
@@ -116,8 +118,10 @@ define void @pr66984(ptr %arg) personality ptr @__CxxFrameHandler3 {
 ; X86_64-NEXT:    movq -8(%rbp), %rcx
 ; X86_64-NEXT:    callq cleanup
 ; X86_64-NEXT:    leaq .LBB0_3(%rip), %rax
+; X86_64-NEXT:    .seh_beginepilogue
 ; X86_64-NEXT:    addq $32, %rsp
 ; X86_64-NEXT:    popq %rbp
+; X86_64-NEXT:    .seh_endepilogue
 ; X86_64-NEXT:    retq # CATCHRET
 ; X86_64-NEXT:    .seh_handlerdata
 ; X86_64-NEXT:    .long ($cppxdata$pr66984)@IMGREL
@@ -143,8 +147,10 @@ define void @pr66984(ptr %arg) personality ptr @__CxxFrameHandler3 {
 ; X86_64-NEXT:    leaq -32(%rbp), %rcx
 ; X86_64-NEXT:    callq foo
 ; X86_64-NEXT:    nop
+; X86_64-NEXT:    .seh_beginepilogue
 ; X86_64-NEXT:    addq $32, %rsp
 ; X86_64-NEXT:    popq %rbp
+; X86_64-NEXT:    .seh_endepilogue
 ; X86_64-NEXT:    retq # CLEANUPRET
 ; X86_64-NEXT:  .Lfunc_end0:
 ; X86_64-NEXT:    .seh_handlerdata
diff --git a/llvm/test/CodeGen/X86/swift-async-win64.ll b/llvm/test/CodeGen/X86/swift-async-win64.ll
index 843118ba435583..56c1c5945b0476 100644
--- a/llvm/test/CodeGen/X86/swift-async-win64.ll
+++ b/llvm/test/CodeGen/X86/swift-async-win64.ll
@@ -35,9 +35,11 @@ define void @more_csrs(ptr swiftasync %context) "frame-pointer"="all" {
 ; CHECK64: .seh_endprologue
 ; CHECK64: movq    %r14, (%rbp)
 ; [...]
+; CHECK64: .seh_beginepilogue
 ; CHECK64: addq    $8, %rsp
 ; CHECK64: popq    %r15
 ; CHECK64: popq    %rbp
+; CHECK64: .seh_endepilogue
 ; CHECK64: retq
 
 declare void @f(ptr)
diff --git a/llvm/test/CodeGen/X86/tailcc-ssp.ll b/llvm/test/CodeGen/X86/tailcc-ssp.ll
index 81b6c9882fd995..8a104e88224f44 100644
--- a/llvm/test/CodeGen/X86/tailcc-ssp.ll
+++ b/llvm/test/CodeGen/X86/tailcc-ssp.ll
@@ -21,7 +21,9 @@ define tailcc void @tailcall_frame(ptr %0, i64 %1) sspreq {
 ; WINDOWS-NEXT:    xorl %ecx, %ecx
 ; WINDOWS-NEXT:    xorl %edx, %edx
 ; WINDOWS-NEXT:    xorl %r8d, %r8d
+; WINDOWS-NEXT:    .seh_beginepilogue
 ; WINDOWS-NEXT:    addq $56, %rsp
+; WINDOWS-NEXT:    .seh_endepilogue
 ; WINDOWS-NEXT:    jmp h # TAILCALL
 ; WINDOWS-NEXT:  .LBB0_1:
 ; WINDOWS-NEXT:    callq __security_check_cookie
@@ -68,7 +70,9 @@ define void @tailcall_unrelated_frame() sspreq {
 ; WINDOWS-NEXT:    cmpq __security_cookie(%rip), %rcx
 ; WINDOWS-NEXT:    jne .LBB1_1
 ; WINDOWS-NEXT:  # %bb.2:
+; WINDOWS-NEXT:    .seh_beginepilogue
 ; WINDOWS-NEXT:    addq $40, %rsp
+; WINDOWS-NEXT:    .seh_endepilogue
 ; WINDOWS-NEXT:    jmp bar # TAILCALL
 ; WINDOWS-NEXT:  .LBB1_1:
 ; WINDOWS-NEXT:    callq __security_check_cookie
diff --git a/llvm/test/CodeGen/X86/taildup-callsiteinfo.mir b/llvm/test/CodeGen/X86/taildup-callsiteinfo.mir
index def9e2e1eee0df..93991799aeb2a9 100644
--- a/llvm/test/CodeGen/X86/taildup-callsiteinfo.mir
+++ b/llvm/test/CodeGen/X86/taildup-callsiteinfo.mir
@@ -68,8 +68,9 @@ body:             |
     liveins: $ecx
 
     CALL64pcrel32 @alloc, csr_win64, implicit $rsp, implicit $ssp, implicit $ecx, implicit-def $rsp, implicit-def $ssp, implicit-def dead $rax
-    SEH_Epilogue
+    SEH_BeginEpilogue
     $rsp = frame-destroy ADD64ri8 $rsp, 40, implicit-def dead $eflags
+    SEH_EndEpilogue
     TAILJMPd64 @f2, csr_win64, implicit $rsp, implicit $ssp, implicit $rsp, implicit $ssp
 
 ...
diff --git a/llvm/test/CodeGen/X86/win-catchpad-csrs.ll b/llvm/test/CodeGen/X86/win-catchpad-csrs.ll
index 49f02197fede62..3148960ba33b9a 100644
--- a/llvm/test/CodeGen/X86/win-catchpad-csrs.ll
+++ b/llvm/test/CodeGen/X86/win-catchpad-csrs.ll
@@ -109,8 +109,10 @@ handler1:
 ; X64: callq f
 ; X64: [[contbb:\.LBB0_[0-9]+]]: # Block address taken
 ; X64-NEXT:                      # %try.cont
+; X64: .seh_beginepilogue
 ; X64: addq $40, %rsp
 ; X64: popq %rbp
+; X64: .seh_endepilogue
 ; X64: retq
 
 ; X64: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch at 4HA":
@@ -131,11 +133,13 @@ handler1:
 ; X64: movl $2, %ecx
 ; X64: callq f
 ; X64: leaq [[contbb]](%rip), %rax
+; X64: .seh_beginepilogue
 ; X64: addq $40, %rsp
 ; X64: popq %rbx
 ; X64: popq %rdi
 ; X64: popq %rsi
 ; X64: popq %rbp
+; X64: .seh_endepilogue
 ; X64: retq
 
 ; X64: $handlerMap$0$try_catch_catch:
@@ -182,10 +186,12 @@ try.cont:
 ; X64: callq f
 ; X64: [[contbb:\.LBB1_[0-9]+]]: # Block address taken
 ; X64-NEXT:                      # %try.cont
+; X64: .seh_beginepilogue
 ; X64: addq $40, %rsp
 ; X64-NOT: popq
 ; X64: popq %rsi
 ; X64: popq %rbp
+; X64: .seh_endepilogue
 ; X64: retq
 
 ; X64: "?catch$[[catch1bb:[0-9]+]]@?0?try_one_csr at 4HA":
@@ -200,9 +206,11 @@ try.cont:
 ; X64: leaq 32(%rdx), %rbp
 ; X64: .seh_endprologue
 ; X64: leaq [[contbb]](%rip), %rax
+; X64: .seh_beginepilogue
 ; X64: addq $40, %rsp
 ; X64: popq %rsi
 ; X64: popq %rbp
+; X64: .seh_endepilogue
 ; X64: retq
 
 ; X64: $handlerMap$0$try_one_csr:
@@ -241,9 +249,11 @@ try.cont:
 ; X64: callq f
 ; X64: [[contbb:\.LBB2_[0-9]+]]: # Block address taken
 ; X64-NEXT:                      # %try.cont
+; X64: .seh_beginepilogue
 ; X64: addq $48, %rsp
 ; X64-NOT: popq
 ; X64: popq %rbp
+; X64: .seh_endepilogue
 ; X64: retq
 
 ; X64: "?catch$[[catch1bb:[0-9]+]]@?0?try_no_csr at 4HA":
@@ -256,8 +266,10 @@ try.cont:
 ; X64: leaq 48(%rdx), %rbp
 ; X64: .seh_endprologue
 ; X64: leaq [[contbb]](%rip), %rax
+; X64: .seh_beginepilogue
 ; X64: addq $32, %rsp
 ; X64: popq %rbp
+; X64: .seh_endepilogue
 ; X64: retq
 
 ; X64: $handlerMap$0$try_no_csr:
diff --git a/llvm/test/CodeGen/X86/win-catchpad.ll b/llvm/test/CodeGen/X86/win-catchpad.ll
index d2067dd4e51c24..f8217d178f5a93 100644
--- a/llvm/test/CodeGen/X86/win-catchpad.ll
+++ b/llvm/test/CodeGen/X86/win-catchpad.ll
@@ -136,8 +136,10 @@ try.cont:
 ; X64: callq f
 ; X64: [[contbb:\.LBB0_[0-9]+]]: # Block address taken
 ; X64-NEXT:                      # %try.cont
+; X64: .seh_beginepilogue
 ; X64: addq $[[STCK_ALLOC]], %rsp
 ; X64: popq %rbp
+; X64: .seh_endepilogue
 ; X64: retq
 
 ; X64: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch at 4HA":
@@ -153,8 +155,10 @@ try.cont:
 ; X64-DAG: movl -4(%rbp), %ecx
 ; X64: callq f
 ; X64: leaq [[contbb]](%rip), %rax
+; X64-NEXT: .seh_beginepilogue
 ; X64-NEXT: addq $32, %rsp
 ; X64-NEXT: popq %rbp
+; X64-NEXT: .seh_endepilogue
 ; X64-NEXT: retq
 
 ; X64: "?catch$[[catch2bb:[0-9]+]]@?0?try_catch_catch at 4HA":
@@ -170,8 +174,10 @@ try.cont:
 ; X64-DAG: movl $3, %ecx
 ; X64: callq f
 ; X64: leaq [[contbb]](%rip), %rax
+; X64-NEXT: .seh_beginepilogue
 ; X64-NEXT: addq $32, %rsp
 ; X64-NEXT: popq %rbp
+; X64-NEXT: .seh_endepilogue
 ; X64-NEXT: retq
 
 ; X64: $cppxdata$try_catch_catch:
@@ -289,8 +295,10 @@ try.cont:
 ; X64: .Ltmp[[after_call:[0-9]+]]:
 ; X64: [[contbb:\.LBB1_[0-9]+]]: # Block address taken
 ; X64-NEXT:                      # %try.cont
+; X64: .seh_beginepilogue
 ; X64: addq $48, %rsp
 ; X64: popq %rbp
+; X64: .seh_endepilogue
 ; X64: retq
 
 ; X64: "?catch$[[catchbb:[0-9]+]]@?0?branch_to_normal_dest at 4HA":
@@ -308,8 +316,10 @@ try.cont:
 ; X64: jne     .LBB1_[[normal_dest_bb]]
 ; X64: # %catch.done
 ; X64: leaq [[contbb]](%rip), %rax
+; X64-NEXT: .seh_beginepilogue
 ; X64-NEXT: addq $32, %rsp
 ; X64-NEXT: popq %rbp
+; X64-NEXT: .seh_endepilogue
 ; X64-NEXT: retq
 
 ; X64-LABEL: $cppxdata$branch_to_normal_dest:
diff --git a/llvm/test/CodeGen/X86/win-funclet-cfi.ll b/llvm/test/CodeGen/X86/win-funclet-cfi.ll
index 7ae82e26601cd0..2e68139389f5ae 100644
--- a/llvm/test/CodeGen/X86/win-funclet-cfi.ll
+++ b/llvm/test/CodeGen/X86/win-funclet-cfi.ll
@@ -57,6 +57,7 @@ declare i32 @__CxxFrameHandler3(...)
 ; Make sure there is a nop after a call if the call precedes the epilogue.
 ; CHECK: callq g
 ; CHECK-NEXT: nop
+; CHECK-NEXT: .seh_beginepilogue
 
 ; Don't emit a reference to the LSDA.
 ; CHECK: .seh_handlerdata
@@ -87,6 +88,7 @@ declare i32 @__CxxFrameHandler3(...)
 ; Make sure there is at least one instruction after a call before the epilogue.
 ; CHECK: callq g
 ; CHECK-NEXT: leaq    .LBB0_{{[0-9]+}}(%rip), %rax
+; CHECK-NEXT: .seh_beginepilogue
 
 ; Emit a reference to the LSDA.
 ; CHECK: .seh_handlerdata
diff --git a/llvm/test/CodeGen/X86/win-smallparams.ll b/llvm/test/CodeGen/X86/win-smallparams.ll
index 5ca8f6705479fd..882d2b9e1db8d0 100644
--- a/llvm/test/CodeGen/X86/win-smallparams.ll
+++ b/llvm/test/CodeGen/X86/win-smallparams.ll
@@ -21,7 +21,9 @@ define void @call() {
 ; WIN64-NEXT:    movw $4, %r9w
 ; WIN64-NEXT:    callq manyargs
 ; WIN64-NEXT:    nop
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    addq $56, %rsp
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 ;
diff --git a/llvm/test/CodeGen/X86/win64-byval.ll b/llvm/test/CodeGen/X86/win64-byval.ll
index 6f48ce160cb6bb..d275baf06bd0a5 100644
--- a/llvm/test/CodeGen/X86/win64-byval.ll
+++ b/llvm/test/CodeGen/X86/win64-byval.ll
@@ -20,7 +20,9 @@ define void @bar() {
 ; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
 ; CHECK-NEXT:    callq foo
 ; CHECK-NEXT:    nop
+; CHECK-NEXT:    .seh_beginepilogue
 ; CHECK-NEXT:    addq $56, %rsp
+; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    retq
 ; CHECK-NEXT:    .seh_endproc
     call void @foo(ptr byval({ float, double }) @G)
@@ -43,7 +45,9 @@ define void @baz(ptr byval({ float, double }) %arg) {
 ; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
 ; CHECK-NEXT:    callq foo
 ; CHECK-NEXT:    nop
+; CHECK-NEXT:    .seh_beginepilogue
 ; CHECK-NEXT:    addq $56, %rsp
+; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    retq
 ; CHECK-NEXT:    .seh_endproc
     call void @foo(ptr byval({ float, double }) %arg)
@@ -81,7 +85,9 @@ define void @test() {
 ; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %r9
 ; CHECK-NEXT:    callq foo2
 ; CHECK-NEXT:    nop
+; CHECK-NEXT:    .seh_beginepilogue
 ; CHECK-NEXT:    addq $136, %rsp
+; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    retq
 ; CHECK-NEXT:    .seh_endproc
   call void @foo2(ptr byval({ float, double }) @G, ptr byval({ float, double }) @G, ptr byval({ float, double }) @G, ptr byval({ float, double }) @G, ptr byval({ float, double }) @G, i64 10)
diff --git a/llvm/test/CodeGen/X86/win64-eh-empty-block-2.mir b/llvm/test/CodeGen/X86/win64-eh-empty-block-2.mir
index df3eb2f8aed72f..6f2741faa856d1 100644
--- a/llvm/test/CodeGen/X86/win64-eh-empty-block-2.mir
+++ b/llvm/test/CodeGen/X86/win64-eh-empty-block-2.mir
@@ -170,9 +170,10 @@ body:             |
 
   bb.8.return (machine-block-address-taken):
     $eax = MOV32rm $rbp, 1, $noreg, -12, $noreg :: (load (s32) from %stack.0)
-    SEH_Epilogue
+    SEH_BeginEpilogue
     $rsp = frame-destroy ADD64ri8 $rsp, 48, implicit-def dead $eflags
     $rbp = frame-destroy POP64r implicit-def $rsp, implicit $rsp
+    SEH_EndEpilogue
     RET64 $eax
 
   bb.1.if.then:
@@ -215,9 +216,10 @@ body:             |
     frame-setup SEH_EndPrologue
     MOV32mi $rbp, 1, $noreg, -12, $noreg, 1 :: (store (s32) into %stack.0)
     $rax = LEA64r $rip, 0, $noreg, %bb.8, $noreg
-    SEH_Epilogue
+    SEH_BeginEpilogue
     $rsp = frame-destroy ADD64ri8 $rsp, 32, implicit-def dead $eflags
     $rbp = frame-destroy POP64r implicit-def $rsp, implicit $rsp
+    SEH_EndEpilogue
     CATCHRET %bb.8, %bb.0
 
 ...
diff --git a/llvm/test/CodeGen/X86/win64-funclet-savexmm.ll b/llvm/test/CodeGen/X86/win64-funclet-savexmm.ll
index c8a84c15fb06ba..488eafa821d7d6 100644
--- a/llvm/test/CodeGen/X86/win64-funclet-savexmm.ll
+++ b/llvm/test/CodeGen/X86/win64-funclet-savexmm.ll
@@ -97,9 +97,11 @@ try.cont:                                         ; preds = %catchret.dest, %inv
 ; CHECK: vmovaps 48(%rsp), %xmm7
 ; CHECK: vmovaps 32(%rsp), %xmm8
 ; CHECK: leaq    .LBB0_1(%rip), %rax
+; CHECK: .seh_beginepilogue
 ; CHECK: addq    $88, %rsp
 ; CHECK: popq    %rbx
 ; CHECK: popq    %rbp
+; CHECK: .seh_endepilogue
 ; CHECK: retq # CATCHRET
 
 ; CHECK-LABEL: "$handlerMap$0$?foo@@YAXHHHHH at Z":
diff --git a/llvm/test/CodeGen/X86/win64-seh-epilogue-statepoint.ll b/llvm/test/CodeGen/X86/win64-seh-epilogue-statepoint.ll
index 7f487a026fac23..e8b2b423fe5cb7 100644
--- a/llvm/test/CodeGen/X86/win64-seh-epilogue-statepoint.ll
+++ b/llvm/test/CodeGen/X86/win64-seh-epilogue-statepoint.ll
@@ -10,7 +10,9 @@ define i32 @foobar() gc "statepoint-example" personality ptr @__gxx_personality_
 ; CHECK-NEXT:    callq bar
 ; CHECK-NEXT:  .Ltmp0:
 ; CHECK-NEXT:    nop
+; CHECK-NEXT:    .seh_beginepilogue
 ; CHECK-NEXT:    addq $40, %rsp
+; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    retq
 ; CHECK-NEXT:    .seh_endproc
     %statepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(i32 ()) @bar, i32 0, i32 0, i32 0, i32 0)
diff --git a/llvm/test/CodeGen/X86/win64_eh.ll b/llvm/test/CodeGen/X86/win64_eh.ll
index cbddf8c68f1cf7..cdfb920616c20d 100644
--- a/llvm/test/CodeGen/X86/win64_eh.ll
+++ b/llvm/test/CodeGen/X86/win64_eh.ll
@@ -129,7 +129,9 @@ endtryfinally:
 ; ATOM:  leaq -40(%rsp), %rsp
 ; WIN64: .seh_stackalloc 40
 ; WIN64: .seh_endprologue
+; WIN64: .seh_beginepilogue
 ; WIN64: addq $40, %rsp
+; WIN64: .seh_endepilogue
 ; WIN64: ret
 ; WIN64: .seh_handlerdata
 ; WIN64: .seh_endproc
@@ -163,9 +165,11 @@ entry:
 ; WIN64: andq  $-64, %rsp
 ; WIN64: movaps  -32(%rbp), %xmm6        # 16-byte Reload
 ; WIN64: movaps  -16(%rbp), %xmm7        # 16-byte Reload
+; WIN64: .seh_beginepilogue
 ; WIN64: movq  %rbp, %rsp
 ; WIN64: popq  %rbx
 ; WIN64: popq  %rdi
 ; WIN64: popq  %rbp
+; WIN64: .seh_endepilogue
 ; WIN64: retq
 ; WIN64: .seh_endproc
diff --git a/llvm/test/CodeGen/X86/win64_frame.ll b/llvm/test/CodeGen/X86/win64_frame.ll
index 03b3f27705a4e6..e8a4eaa98afa93 100644
--- a/llvm/test/CodeGen/X86/win64_frame.ll
+++ b/llvm/test/CodeGen/X86/win64_frame.ll
@@ -11,7 +11,9 @@ define i32 @f1(i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5) "frame-pointer"="all
 ; CHECK-NEXT:    .seh_setframe %rbp, 0
 ; CHECK-NEXT:    .seh_endprologue
 ; CHECK-NEXT:    movl 48(%rbp), %eax
+; CHECK-NEXT:    .seh_beginepilogue
 ; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    retq
 ; CHECK-NEXT:    .seh_endproc
   ret i32 %p5
@@ -32,8 +34,10 @@ define void @f2(i32 %p, ...) "frame-pointer"="all" {
 ; CHECK-NEXT:    movq %r9, 48(%rbp)
 ; CHECK-NEXT:    leaq 32(%rbp), %rax
 ; CHECK-NEXT:    movq %rax, (%rbp)
+; CHECK-NEXT:    .seh_beginepilogue
 ; CHECK-NEXT:    addq $8, %rsp
 ; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    retq
 ; CHECK-NEXT:    .seh_endproc
   %ap = alloca i8, align 8
@@ -50,7 +54,9 @@ define ptr @f3() "frame-pointer"="all" {
 ; CHECK-NEXT:    .seh_setframe %rbp, 0
 ; CHECK-NEXT:    .seh_endprologue
 ; CHECK-NEXT:    movq 8(%rbp), %rax
+; CHECK-NEXT:    .seh_beginepilogue
 ; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    retq
 ; CHECK-NEXT:    .seh_endproc
   %ra = call ptr @llvm.returnaddress(i32 0)
@@ -68,8 +74,10 @@ define ptr @f4() "frame-pointer"="all" {
 ; CHECK-NEXT:    .seh_setframe %rbp, 128
 ; CHECK-NEXT:    .seh_endprologue
 ; CHECK-NEXT:    movq 184(%rbp), %rax
+; CHECK-NEXT:    .seh_beginepilogue
 ; CHECK-NEXT:    addq $304, %rsp # imm = 0x130
 ; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    retq
 ; CHECK-NEXT:    .seh_endproc
   alloca [300 x i8]
@@ -92,8 +100,10 @@ define void @f5() "frame-pointer"="all" {
 ; CHECK-NEXT:    leaq -92(%rbp), %rcx
 ; CHECK-NEXT:    callq external
 ; CHECK-NEXT:    nop
+; CHECK-NEXT:    .seh_beginepilogue
 ; CHECK-NEXT:    addq $336, %rsp # imm = 0x150
 ; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    retq
 ; CHECK-NEXT:    .seh_endproc
   %a = alloca [300 x i8]
@@ -114,8 +124,10 @@ define void @f6(i32 %p, ...) "frame-pointer"="all" {
 ; CHECK-NEXT:    leaq -92(%rbp), %rcx
 ; CHECK-NEXT:    callq external
 ; CHECK-NEXT:    nop
+; CHECK-NEXT:    .seh_beginepilogue
 ; CHECK-NEXT:    addq $336, %rsp # imm = 0x150
 ; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    retq
 ; CHECK-NEXT:    .seh_endproc
   %a = alloca [300 x i8]
@@ -135,8 +147,10 @@ define i32 @f7(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) "frame-pointer"="all" {
 ; CHECK-NEXT:    .seh_endprologue
 ; CHECK-NEXT:    andq $-64, %rsp
 ; CHECK-NEXT:    movl 224(%rbp), %eax
+; CHECK-NEXT:    .seh_beginepilogue
 ; CHECK-NEXT:    leaq 176(%rbp), %rsp
 ; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    retq
 ; CHECK-NEXT:    .seh_endproc
   alloca [300 x i8], align 64
@@ -170,10 +184,12 @@ define i32 @f8(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) "frame-pointer"="all" {
 ; CHECK-NEXT:    callq external
 ; CHECK-NEXT:    addq $32, %rsp
 ; CHECK-NEXT:    movl %esi, %eax
+; CHECK-NEXT:    .seh_beginepilogue
 ; CHECK-NEXT:    leaq 224(%rbp), %rsp
 ; CHECK-NEXT:    popq %rbx
 ; CHECK-NEXT:    popq %rsi
 ; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    retq
 ; CHECK-NEXT:    .seh_endproc
   %alloca = alloca [300 x i8], align 64
@@ -192,7 +208,9 @@ define i64 @f9() {
 ; CHECK-NEXT:    .seh_endprologue
 ; CHECK-NEXT:    pushfq
 ; CHECK-NEXT:    popq %rax
+; CHECK-NEXT:    .seh_beginepilogue
 ; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    retq
 ; CHECK-NEXT:    .seh_endproc
 entry:
@@ -219,9 +237,11 @@ define i64 @f10(ptr %foo, i64 %bar, i64 %baz) {
 ; CHECK-NEXT:    callq dummy
 ; CHECK-NEXT:    testb %bl, %bl
 ; CHECK-NEXT:    cmoveq %rsi, %rax
+; CHECK-NEXT:    .seh_beginepilogue
 ; CHECK-NEXT:    addq $40, %rsp
 ; CHECK-NEXT:    popq %rbx
 ; CHECK-NEXT:    popq %rsi
+; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    retq
 ; CHECK-NEXT:    .seh_endproc
   %cx = cmpxchg ptr %foo, i64 %bar, i64 %baz seq_cst seq_cst
@@ -241,7 +261,9 @@ define ptr @f11() "frame-pointer"="all" {
 ; CHECK-NEXT:    .seh_setframe %rbp, 0
 ; CHECK-NEXT:    .seh_endprologue
 ; CHECK-NEXT:    leaq 8(%rbp), %rax
+; CHECK-NEXT:    .seh_beginepilogue
 ; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    retq
 ; CHECK-NEXT:    .seh_endproc
   %aora = call ptr @llvm.addressofreturnaddress()
diff --git a/llvm/test/CodeGen/X86/x86-64-flags-intrinsics.ll b/llvm/test/CodeGen/X86/x86-64-flags-intrinsics.ll
index e3bc77d4d5fa28..f368610c68ffdd 100644
--- a/llvm/test/CodeGen/X86/x86-64-flags-intrinsics.ll
+++ b/llvm/test/CodeGen/X86/x86-64-flags-intrinsics.ll
@@ -21,7 +21,9 @@ define i64 @read_flags() {
 ; WIN64-NEXT:    .seh_endprologue
 ; WIN64-NEXT:    pushfq
 ; WIN64-NEXT:    popq %rax
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    popq %rbp
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 entry:
@@ -45,7 +47,9 @@ define void @write_flags(i64 %arg) {
 ; WIN64-NEXT:    .seh_endprologue
 ; WIN64-NEXT:    pushq %rcx
 ; WIN64-NEXT:    popfq
+; WIN64-NEXT:    .seh_beginepilogue
 ; WIN64-NEXT:    popq %rbp
+; WIN64-NEXT:    .seh_endepilogue
 ; WIN64-NEXT:    retq
 ; WIN64-NEXT:    .seh_endproc
 entry:
diff --git a/llvm/test/CodeGen/X86/x86-win64-shrink-wrapping.ll b/llvm/test/CodeGen/X86/x86-win64-shrink-wrapping.ll
index 6ed23b0d770cd4..8d2c2f8db15a26 100644
--- a/llvm/test/CodeGen/X86/x86-win64-shrink-wrapping.ll
+++ b/llvm/test/CodeGen/X86/x86-win64-shrink-wrapping.ll
@@ -17,7 +17,7 @@ define i32 @loopInfoSaveOutsideLoop(i32 %cond, i32 %N) #0 {
 ; ENABLE-NEXT:    .seh_pushreg %rbx
 ; ENABLE-NEXT:    .seh_endprologue
 ; ENABLE-NEXT:    testl %ecx, %ecx
-; ENABLE-NEXT:    je .LBB0_4
+; ENABLE-NEXT:    je .LBB0_5
 ; ENABLE-NEXT:  # %bb.1: # %for.preheader
 ; ENABLE-NEXT:    #APP
 ; ENABLE-NEXT:    nop
@@ -38,12 +38,16 @@ define i32 @loopInfoSaveOutsideLoop(i32 %cond, i32 %N) #0 {
 ; ENABLE-NEXT:    nop
 ; ENABLE-NEXT:    #NO_APP
 ; ENABLE-NEXT:    shll $3, %eax
-; ENABLE-NEXT:    jmp .LBB0_5
-; ENABLE-NEXT:  .LBB0_4: # %if.else
+; ENABLE-NEXT:    .seh_beginepilogue
+; ENABLE-NEXT:    popq %rbx
+; ENABLE-NEXT:    .seh_endepilogue
+; ENABLE-NEXT:    retq
+; ENABLE-NEXT:  .LBB0_5: # %if.else
 ; ENABLE-NEXT:    movl %edx, %eax
 ; ENABLE-NEXT:    addl %edx, %eax
-; ENABLE-NEXT:  .LBB0_5: # %if.end
+; ENABLE-NEXT:    .seh_beginepilogue
 ; ENABLE-NEXT:    popq %rbx
+; ENABLE-NEXT:    .seh_endepilogue
 ; ENABLE-NEXT:    retq
 ; ENABLE-NEXT:    .seh_endproc
 ;
@@ -53,7 +57,7 @@ define i32 @loopInfoSaveOutsideLoop(i32 %cond, i32 %N) #0 {
 ; DISABLE-NEXT:    .seh_pushreg %rbx
 ; DISABLE-NEXT:    .seh_endprologue
 ; DISABLE-NEXT:    testl %ecx, %ecx
-; DISABLE-NEXT:    je .LBB0_4
+; DISABLE-NEXT:    je .LBB0_5
 ; DISABLE-NEXT:  # %bb.1: # %for.preheader
 ; DISABLE-NEXT:    #APP
 ; DISABLE-NEXT:    nop
@@ -74,12 +78,16 @@ define i32 @loopInfoSaveOutsideLoop(i32 %cond, i32 %N) #0 {
 ; DISABLE-NEXT:    nop
 ; DISABLE-NEXT:    #NO_APP
 ; DISABLE-NEXT:    shll $3, %eax
-; DISABLE-NEXT:    jmp .LBB0_5
-; DISABLE-NEXT:  .LBB0_4: # %if.else
+; DISABLE-NEXT:    .seh_beginepilogue
+; DISABLE-NEXT:    popq %rbx
+; DISABLE-NEXT:    .seh_endepilogue
+; DISABLE-NEXT:    retq
+; DISABLE-NEXT:  .LBB0_5: # %if.else
 ; DISABLE-NEXT:    movl %edx, %eax
 ; DISABLE-NEXT:    addl %edx, %eax
-; DISABLE-NEXT:  .LBB0_5: # %if.end
+; DISABLE-NEXT:    .seh_beginepilogue
 ; DISABLE-NEXT:    popq %rbx
+; DISABLE-NEXT:    .seh_endepilogue
 ; DISABLE-NEXT:    retq
 ; DISABLE-NEXT:    .seh_endproc
 entry:
@@ -143,7 +151,9 @@ define i32 @loopInfoSaveOutsideLoop2(i32 %cond, i32 %N) #0 {
 ; ENABLE-NEXT:    nop
 ; ENABLE-NEXT:    #NO_APP
 ; ENABLE-NEXT:    shll $3, %eax
+; ENABLE-NEXT:    .seh_beginepilogue
 ; ENABLE-NEXT:    popq %rbx
+; ENABLE-NEXT:    .seh_endepilogue
 ; ENABLE-NEXT:    retq
 ; ENABLE-NEXT:  .LBB1_4: # %if.else
 ; ENABLE-NEXT:    addl %edx, %edx
@@ -157,7 +167,7 @@ define i32 @loopInfoSaveOutsideLoop2(i32 %cond, i32 %N) #0 {
 ; DISABLE-NEXT:    .seh_pushreg %rbx
 ; DISABLE-NEXT:    .seh_endprologue
 ; DISABLE-NEXT:    testl %ecx, %ecx
-; DISABLE-NEXT:    je .LBB1_4
+; DISABLE-NEXT:    je .LBB1_5
 ; DISABLE-NEXT:  # %bb.1: # %for.preheader
 ; DISABLE-NEXT:    #APP
 ; DISABLE-NEXT:    nop
@@ -178,12 +188,16 @@ define i32 @loopInfoSaveOutsideLoop2(i32 %cond, i32 %N) #0 {
 ; DISABLE-NEXT:    nop
 ; DISABLE-NEXT:    #NO_APP
 ; DISABLE-NEXT:    shll $3, %eax
-; DISABLE-NEXT:    jmp .LBB1_5
-; DISABLE-NEXT:  .LBB1_4: # %if.else
+; DISABLE-NEXT:    .seh_beginepilogue
+; DISABLE-NEXT:    popq %rbx
+; DISABLE-NEXT:    .seh_endepilogue
+; DISABLE-NEXT:    retq
+; DISABLE-NEXT:  .LBB1_5: # %if.else
 ; DISABLE-NEXT:    addl %edx, %edx
 ; DISABLE-NEXT:    movl %edx, %eax
-; DISABLE-NEXT:  .LBB1_5: # %if.end
+; DISABLE-NEXT:    .seh_beginepilogue
 ; DISABLE-NEXT:    popq %rbx
+; DISABLE-NEXT:    .seh_endepilogue
 ; DISABLE-NEXT:    retq
 ; DISABLE-NEXT:    .seh_endproc
 entry:
diff --git a/llvm/test/DebugInfo/COFF/trailing-inlined-function.s b/llvm/test/DebugInfo/COFF/trailing-inlined-function.s
index 133f48e3038aa5..3ef602ad322911 100644
--- a/llvm/test/DebugInfo/COFF/trailing-inlined-function.s
+++ b/llvm/test/DebugInfo/COFF/trailing-inlined-function.s
@@ -94,7 +94,9 @@ add_numbers:
 	addl	4(%rdx), %eax
 .Ltmp4:
 	.cv_loc	0 1 6 0
+	.seh_beginepilogue
 	addq	$40, %rsp
+	.seh_endepilogue
 	retq
 .LBB0_1:
 .Ltmp5:
diff --git a/llvm/test/DebugInfo/MIR/X86/instr-ref-join-def-vphi.mir b/llvm/test/DebugInfo/MIR/X86/instr-ref-join-def-vphi.mir
index a23d80ea64b397..b1531aa8ee8780 100644
--- a/llvm/test/DebugInfo/MIR/X86/instr-ref-join-def-vphi.mir
+++ b/llvm/test/DebugInfo/MIR/X86/instr-ref-join-def-vphi.mir
@@ -233,10 +233,11 @@ body:             |
     liveins: $esi
 
     $eax = MOV32rr killed $esi, debug-location !35
-    SEH_Epilogue debug-location !35
+    SEH_BeginEpilogue debug-location !35
     $rsp = frame-destroy ADD64ri8 $rsp, 40, implicit-def dead $eflags, debug-location !35
     $rdi = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !35
     $rsi = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !35
+    SEH_EndEpilogue debug-location !35
     RET64 $eax, debug-location !35
 
 ...
diff --git a/llvm/test/ExecutionEngine/JITLink/x86-64/COFF_pdata_no_strip.s b/llvm/test/ExecutionEngine/JITLink/x86-64/COFF_pdata_no_strip.s
index 80f4f15afd169b..b82e3d544b6c8a 100644
--- a/llvm/test/ExecutionEngine/JITLink/x86-64/COFF_pdata_no_strip.s
+++ b/llvm/test/ExecutionEngine/JITLink/x86-64/COFF_pdata_no_strip.s
@@ -26,6 +26,8 @@ main:
 	.seh_endprologue
 	movl	$0, 36(%rsp)
 	nop
+	.seh_beginepilogue
 	addq	$40, %rsp
+	.seh_endepilogue
 	retq
 	.seh_endproc
diff --git a/llvm/test/ExecutionEngine/JITLink/x86-64/COFF_pdata_strip.s b/llvm/test/ExecutionEngine/JITLink/x86-64/COFF_pdata_strip.s
index e3a752df471c24..c4089705421626 100644
--- a/llvm/test/ExecutionEngine/JITLink/x86-64/COFF_pdata_strip.s
+++ b/llvm/test/ExecutionEngine/JITLink/x86-64/COFF_pdata_strip.s
@@ -38,6 +38,8 @@ func:
 	.seh_endprologue
 	movl	$0, 36(%rsp)
 	nop
+	.seh_beginepilogue
 	addq	$40, %rsp
+	.seh_endepilogue
 	retq
 	.seh_endproc
diff --git a/llvm/test/MC/AsmParser/directive_seh.s b/llvm/test/MC/AsmParser/directive_seh.s
index f4cd29fb5e954c..38f41356a9a093 100644
--- a/llvm/test/MC/AsmParser/directive_seh.s
+++ b/llvm/test/MC/AsmParser/directive_seh.s
@@ -49,9 +49,13 @@ func:
 # CHECK: .seh_startchained
 # CHECK: .seh_endprologue
 # CHECK: .seh_endchained
+    .seh_beginepilogue
+# CHECK: .seh_beginepilogue
     lea (%rbx), %rsp
     pop %rbx
     addq $24, %rsp
+    .seh_endepilogue
+# CHECK: .seh_endepilogue
     ret
     .seh_endproc
 # CHECK: .seh_endproc
diff --git a/llvm/test/MC/AsmParser/seh-directive-errors.s b/llvm/test/MC/AsmParser/seh-directive-errors.s
index 6d1486916caf3f..bd1a66b97067a8 100644
--- a/llvm/test/MC/AsmParser/seh-directive-errors.s
+++ b/llvm/test/MC/AsmParser/seh-directive-errors.s
@@ -33,10 +33,12 @@ f:                                      # @f
 	.seh_stackalloc 32
 	.seh_endprologue
 	nop
+	.seh_beginepilogue
 	addq	$32, %rsp
 	popq	%rbx
 	popq	%rdi
 	popq	%rsi
+	.seh_endepilogue
 	retq
 	.seh_handlerdata
 	.text
@@ -63,8 +65,10 @@ g:
 	.seh_setframe 3, 128
 	# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: frame register and offset can be set at most once
 	nop
+	.seh_beginepilogue
 	popq %rsi
 	popq %rbp
+	.seh_endepilogue
 	retq
 	.seh_endproc
 
@@ -90,9 +94,11 @@ h:                                      # @h
         addsd   %xmm6, %xmm7
         callq   getdbl
         addsd   %xmm7, %xmm0
+		.seh_beginepilogue
         movaps  32(%rsp), %xmm6         # 16-byte Reload
         movaps  48(%rsp), %xmm7         # 16-byte Reload
         addq    $72, %rsp
+		.seh_endepilogue
         retq
         .seh_handlerdata
         .text
diff --git a/llvm/test/MC/COFF/cv-def-range-align.s b/llvm/test/MC/COFF/cv-def-range-align.s
index 2b6c18ad346b06..7c1d7ceb8237ee 100644
--- a/llvm/test/MC/COFF/cv-def-range-align.s
+++ b/llvm/test/MC/COFF/cv-def-range-align.s
@@ -48,7 +48,9 @@ max:                                    # @max
 .LBB0_2:                                # %cond.false
 	movl	4(%rsp), %eax
 .LBB0_3:                                # %cond.end
+	.seh_beginepilogue
 	popq	%rcx
+	.seh_endepilogue
 	retq
 .Ltmp1:
 .Lfunc_end0:
diff --git a/llvm/test/MC/COFF/cv-inline-linetable-unlikely.s b/llvm/test/MC/COFF/cv-inline-linetable-unlikely.s
index 862615f48fdc60..1057c89dbbafa9 100644
--- a/llvm/test/MC/COFF/cv-inline-linetable-unlikely.s
+++ b/llvm/test/MC/COFF/cv-inline-linetable-unlikely.s
@@ -62,8 +62,10 @@ g:                                      # @g
 	jne	.LBB0_1
 	.cv_loc	0 1 10 17               # t.cpp:10:17
 	movl	$0, unlikely_cond(%rip)
+	.seh_beginepilogue
 	.cv_loc	0 1 11 1                # t.cpp:11:1
 	addq	$40, %rsp
+	.seh_endepilogue
 	retq
 
 .LBB0_1:                                # %if.then.i
diff --git a/llvm/test/MC/COFF/seh-align2.s b/llvm/test/MC/COFF/seh-align2.s
index 7981c18c2c2510..53843f4d80c0c6 100644
--- a/llvm/test/MC/COFF/seh-align2.s
+++ b/llvm/test/MC/COFF/seh-align2.s
@@ -73,6 +73,8 @@
     .text
     .seh_endprologue
 func:
+    .seh_beginepilogue
     addq $24, %rsp
+    .seh_endepilogue
     ret
     .seh_endproc
diff --git a/llvm/test/MC/COFF/seh-align3.s b/llvm/test/MC/COFF/seh-align3.s
index 9b3e39d08a1961..aff408fe043429 100644
--- a/llvm/test/MC/COFF/seh-align3.s
+++ b/llvm/test/MC/COFF/seh-align3.s
@@ -77,7 +77,9 @@
     .text
     .seh_endprologue
 func:
+    .seh_beginepilogue
     pop %r13
     pop %r12
+    .seh_endepilogue
     ret
     .seh_endproc
diff --git a/llvm/test/MC/COFF/seh-linkonce.s b/llvm/test/MC/COFF/seh-linkonce.s
index 52feca020386e9..ad15a7167582b9 100644
--- a/llvm/test/MC/COFF/seh-linkonce.s
+++ b/llvm/test/MC/COFF/seh-linkonce.s
@@ -21,7 +21,9 @@ weak_func:                              # @weak_func
 .Ltmp3:
         .seh_endprologue
         xorl    %eax, %eax
+        .seh_beginepilogue
         popq    %rbp
+        .seh_endepilogue
         retq
 .Leh_func_end0:
 .Ltmp4:
diff --git a/llvm/test/MC/COFF/seh-section-2.s b/llvm/test/MC/COFF/seh-section-2.s
index 390a20b3e4f9c8..d4a63d0c41d528 100644
--- a/llvm/test/MC/COFF/seh-section-2.s
+++ b/llvm/test/MC/COFF/seh-section-2.s
@@ -21,7 +21,9 @@ f:                                      # @f
         .seh_endprologue
         callq   g
         nop
+        .seh_beginepilogue
         addq    $40, %rsp
+        .seh_endepilogue
         retq
         .seh_handlerdata
         .section        .text,"xr",discard,f
diff --git a/llvm/test/MC/COFF/seh-section.s b/llvm/test/MC/COFF/seh-section.s
index 7bdc11e7723a23..41482db11b5d96 100644
--- a/llvm/test/MC/COFF/seh-section.s
+++ b/llvm/test/MC/COFF/seh-section.s
@@ -68,8 +68,10 @@ foo:
     pushq %rbp
     .seh_pushreg %rbp
     .seh_endprologue
+    .seh_beginepilogue
     popq %rbp
     addq $8, %rsp
+    .seh_endepilogue
     ret
     .seh_endproc
 
@@ -83,8 +85,10 @@ bar:
     pushq %rbp
     .seh_pushreg %rbp
     .seh_endprologue
+    .seh_beginepilogue
     popq %rbp
     addq $8, %rsp
+    .seh_endepilogue
     ret
     .seh_endproc
 
@@ -98,8 +102,10 @@ baz:
     pushq %rbp
     .seh_pushreg %rbp
     .seh_endprologue
+    .seh_beginepilogue
     popq %rbp
     addq $8, %rsp
+    .seh_endepilogue
     ret
     .seh_endproc
 
diff --git a/llvm/test/MC/COFF/seh.s b/llvm/test/MC/COFF/seh.s
index 201cdb1d07d1c2..a07e4832fa87dc 100644
--- a/llvm/test/MC/COFF/seh.s
+++ b/llvm/test/MC/COFF/seh.s
@@ -144,9 +144,11 @@ func:
     .seh_startchained
     .seh_endprologue
     .seh_endchained
+    .seh_beginepilogue
     lea (%rbx), %rsp
     pop %rbx
     addq $24, %rsp
+    .seh_endepilogue
     ret
     .seh_endproc
 
diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/x86-basic.ll.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/x86-basic.ll.expected
index e113303f57a37c..7c70b9e5ab08a4 100644
--- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/x86-basic.ll.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/x86-basic.ll.expected
@@ -58,7 +58,9 @@ define dso_local i32 @dsolocal() {
 ; WIN-NEXT:    .seh_endprologue
 ; WIN-NEXT:    callq ext
 ; WIN-NEXT:    movl $2, %eax
+; WIN-NEXT:    .seh_beginepilogue
 ; WIN-NEXT:    addq $40, %rsp
+; WIN-NEXT:    .seh_endepilogue
 ; WIN-NEXT:    retq
 ; WIN-NEXT:    .seh_endproc
 entry:



More information about the llvm-commits mailing list