[clang] [lld] [llvm] Fix Windows EH IP2State tables (remove +1 bias) (PR #144745)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 16 15:49:41 PDT 2025
https://github.com/sivadeilra updated https://github.com/llvm/llvm-project/pull/144745
>From e7ccf87561e090a224021e2223e36599396f6335 Mon Sep 17 00:00:00 2001
From: Arlie Davis <ardavis at microsoft.com>
Date: Fri, 13 Jun 2025 12:45:34 -0700
Subject: [PATCH] Fix IP2State tables
style: revert one change
Adjust tests
adjust another test
fix llvm/test/CodeGen/XCore/exception.ll
PR feedback
PR feedback
update microsoft-abi-eh-async.cpp for tighter NOP handling
PR feedback: use INT3 instead of NOP for noreturn
update win64_frame.ll
Fix bug, plus more accurate NOP optimization
Fix win64-seh-epilogue-statepoint.ll
More accurate optimization for NOP insertion for EH
update tests
update test
---
.../CodeGenCXX/microsoft-abi-eh-async.cpp | 209 +++++++++++++++
.../CodeGenCXX/microsoft-abi-eh-disabled.cpp | 136 ++++++++++
.../CodeGenCXX/microsoft-abi-eh-ip2state.cpp | 241 ++++++++++++++++++
lld/test/COFF/lto-comdat.ll | 4 +-
llvm/include/llvm/CodeGen/AsmPrinter.h | 4 +
llvm/include/llvm/CodeGen/AsmPrinterHandler.h | 4 +
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 4 +
llvm/lib/CodeGen/AsmPrinter/WinException.cpp | 16 +-
llvm/lib/CodeGen/AsmPrinter/WinException.h | 3 +-
llvm/lib/Target/X86/X86AsmPrinter.h | 1 +
llvm/lib/Target/X86/X86MCInstLower.cpp | 199 ++++++++++++---
.../test/CodeGen/WinEH/wineh-noret-cleanup.ll | 14 +-
.../CodeGen/X86/apx/push2-pop2-cfi-seh.ll | 3 -
llvm/test/CodeGen/X86/avx512-intel-ocl.ll | 2 -
llvm/test/CodeGen/X86/avx512-regcall-Mask.ll | 3 -
llvm/test/CodeGen/X86/call-rv-marker.ll | 1 -
.../CodeGen/X86/catchret-empty-fallthrough.ll | 2 +-
.../CodeGen/X86/cfguard-x86-64-vectorcall.ll | 1 -
.../CodeGen/X86/conditional-tailcall-pgso.ll | 1 -
llvm/test/CodeGen/X86/conditional-tailcall.ll | 1 -
llvm/test/CodeGen/X86/mixed-ptr-sizes.ll | 1 -
llvm/test/CodeGen/X86/no-sse-win64.ll | 2 -
llvm/test/CodeGen/X86/noreturn-call-win64.ll | 12 +
.../CodeGen/X86/preserve_nonecc_call_win.ll | 1 -
llvm/test/CodeGen/X86/segmented-stacks.ll | 5 -
llvm/test/CodeGen/X86/seh-catch-all.ll | 2 +-
llvm/test/CodeGen/X86/seh-catchpad.ll | 10 +-
llvm/test/CodeGen/X86/seh-except-finally.ll | 6 +-
llvm/test/CodeGen/X86/seh-finally.ll | 2 +-
llvm/test/CodeGen/X86/seh-safe-div.ll | 5 +-
.../X86/seh-unwind-inline-asm-codegen.ll | 4 +-
llvm/test/CodeGen/X86/stack-coloring-wineh.ll | 6 +-
.../CodeGen/X86/win-catchpad-nested-cxx.ll | 8 +-
llvm/test/CodeGen/X86/win-catchpad.ll | 8 +-
llvm/test/CodeGen/X86/win-cleanuppad.ll | 2 +-
.../X86/win-import-call-optimization.ll | 1 -
llvm/test/CodeGen/X86/win-smallparams.ll | 1 -
llvm/test/CodeGen/X86/win32-eh-states.ll | 14 +-
llvm/test/CodeGen/X86/win64-byval.ll | 3 -
.../X86/win64-seh-epilogue-statepoint.ll | 1 -
llvm/test/CodeGen/X86/win64_call_epi.ll | 2 +-
llvm/test/CodeGen/X86/win64_frame.ll | 2 -
llvm/test/CodeGen/X86/wineh-coreclr.ll | 14 +
llvm/test/CodeGen/X86/wineh-no-ehpads.ll | 1 -
llvm/test/CodeGen/XCore/exception.ll | 2 +-
llvm/test/DebugInfo/COFF/local-variables.ll | 3 +-
.../Inputs/mips64_eh.ll.expected | 6 +-
47 files changed, 841 insertions(+), 132 deletions(-)
create mode 100644 clang/test/CodeGenCXX/microsoft-abi-eh-async.cpp
create mode 100644 clang/test/CodeGenCXX/microsoft-abi-eh-disabled.cpp
create mode 100644 clang/test/CodeGenCXX/microsoft-abi-eh-ip2state.cpp
diff --git a/clang/test/CodeGenCXX/microsoft-abi-eh-async.cpp b/clang/test/CodeGenCXX/microsoft-abi-eh-async.cpp
new file mode 100644
index 0000000000000..b83173742a2a7
--- /dev/null
+++ b/clang/test/CodeGenCXX/microsoft-abi-eh-async.cpp
@@ -0,0 +1,209 @@
+// REQUIRES: x86-registered-target
+
+// RUN: %clang_cl -c --target=x86_64-windows-msvc /EHa -O2 /GS- \
+// RUN: -Xclang=-import-call-optimization \
+// RUN: /clang:-S /clang:-o- -- %s 2>&1 \
+// RUN: | FileCheck %s
+
+#ifdef __clang__
+#define NO_TAIL __attribute((disable_tail_calls))
+#else
+#define NO_TAIL
+#endif
+
+void might_throw();
+void other_func(int x);
+
+void does_not_throw() noexcept(true);
+
+extern "C" void __declspec(dllimport) some_dll_import();
+
+class HasDtor {
+ int x;
+ char foo[40];
+
+public:
+ explicit HasDtor(int x);
+ ~HasDtor();
+};
+
+class BadError {
+public:
+ int errorCode;
+};
+
+void normal_has_regions() {
+ // CHECK-LABEL: .def "?normal_has_regions@@YAXXZ"
+ // CHECK: .seh_endprologue
+
+ // <-- state -1 (none)
+ {
+ HasDtor hd{42};
+
+ // <-- state goes from -1 to 0
+ // because state changes, we expect the HasDtor::HasDtor() call to have a NOP
+ // CHECK: call "??0HasDtor@@QEAA at H@Z"
+ // CHECK-NEXT: nop
+
+ might_throw();
+ // CHECK: call "?might_throw@@YAXXZ"
+ // CHECK-NEXT: nop
+
+ // <-- state goes from 0 to -1 because we're about to call HasDtor::~HasDtor()
+ // CHECK: call "??1HasDtor@@QEAA at XZ"
+ // <-- state -1
+ }
+
+ // <-- state -1
+ other_func(10);
+ // CHECK: call "?other_func@@YAXH at Z"
+ // CHECK-NEXT: nop
+ // CHECK: .seh_startepilogue
+
+ // <-- state -1
+}
+
+// This tests a tail call to a destructor.
+void case_dtor_arg_empty_body(HasDtor x)
+{
+ // CHECK-LABEL: .def "?case_dtor_arg_empty_body@@YAXVHasDtor@@@Z"
+ // CHECK: jmp "??1HasDtor@@QEAA at XZ"
+}
+
+int case_dtor_arg_empty_with_ret(HasDtor x)
+{
+ // CHECK-LABEL: .def "?case_dtor_arg_empty_with_ret@@YAHVHasDtor@@@Z"
+ // CHECK: .seh_endprologue
+
+ // CHECK: call "??1HasDtor@@QEAA at XZ"
+ // CHECK-NOT: nop
+
+ // The call to HasDtor::~HasDtor() should NOT have a NOP because the
+ // following "mov eax, 100" instruction is in the same EH state.
+
+ return 100;
+
+ // CHECK: mov eax, 100
+ // CHECK: .seh_startepilogue
+ // CHECK: .seh_endepilogue
+ // CHECK: .seh_endproc
+}
+
+int case_noexcept_dtor(HasDtor x) noexcept(true)
+{
+ // CHECK: .def "?case_noexcept_dtor@@YAHVHasDtor@@@Z"
+ // CHECK: call "??1HasDtor@@QEAA at XZ"
+ // CHECK-NEXT: mov eax, 100
+ // CHECK: .seh_startepilogue
+ return 100;
+}
+
+void case_except_simple_call() NO_TAIL
+{
+ does_not_throw();
+}
+// CHECK-LABEL: .def "?case_except_simple_call@@YAXXZ"
+// CHECK: .seh_endprologue
+// CHECK-NEXT: call "?does_not_throw@@YAXXZ"
+// CHECK-NEXT: nop
+// CHECK-NEXT: .seh_startepilogue
+// CHECK: .seh_endproc
+
+void case_noexcept_simple_call() noexcept(true) NO_TAIL
+{
+ does_not_throw();
+}
+// CHECK-LABEL: .def "?case_noexcept_simple_call@@YAXXZ"
+// CHECK: .seh_endprologue
+// CHECK-NEXT: call "?does_not_throw@@YAXXZ"
+// CHECK-NEXT: nop
+// CHECK-NEXT: .seh_startepilogue
+// CHECK: .seh_endepilogue
+// CHECK-NEXT: ret
+// CHECK-NEXT: .seh_endproc
+
+// This tests that the destructor is called right before SEH_BeginEpilogue,
+// but in a function that has a return value. Loading the return value
+// counts as a real instruction, so there is no need for a NOP after the
+// dtor call.
+int case_dtor_arg_calls_no_throw(HasDtor x)
+{
+ does_not_throw(); // no NOP expected
+ return 100;
+}
+// CHECK-LABEL: .def "?case_dtor_arg_calls_no_throw@@YAHVHasDtor@@@Z"
+// CHECK: .seh_endprologue
+// CHECK: "?does_not_throw@@YAXXZ"
+// CHECK-NEXT: nop
+// CHECK: "??1HasDtor@@QEAA at XZ"
+// CHECK-NEXT: mov eax, 100
+// CHECK: .seh_startepilogue
+// CHECK: .seh_endproc
+
+// Check the behavior of CALLs that are at the end of MBBs. If a CALL is within
+// a non-null EH state (state -1) and is at the end of an MBB, then we expect
+// to find an EH_LABEL after the CALL. This causes us to insert a NOP, which
+// is the desired result.
+void case_dtor_runs_after_join(int x) {
+ // CHECK-LABEL: .def "?case_dtor_runs_after_join@@YAXH at Z"
+ // CHECK: .seh_endprologue
+
+ // <-- EH state -1
+
+ // ctor call does not need a NOP, because it has real instructions after it
+ HasDtor hd{42};
+ // CHECK: call "??0HasDtor@@QEAA at H@Z"
+ // CHECK-NEXT: nop
+ // CHECK: test
+
+ // <-- EH state transition from -1 0
+ if (x) {
+ might_throw(); // <-- NOP expected (at end of BB w/ EH_LABEL)
+ // CHECK: call "?might_throw@@YAXXZ"
+ // CHECK-NEXT: nop
+ } else {
+ other_func(10); // <-- NOP expected (at end of BB w/ EH_LABEL)
+ // CHECK: call "?other_func@@YAXH at Z"
+ // CHECK-NEXT: nop
+ }
+ does_not_throw();
+ // <-- EH state transition 0 to -1
+ // ~HasDtor() runs
+
+ // CHECK: .seh_endproc
+
+ // CHECK: "$ip2state$?case_dtor_runs_after_join@@YAXH at Z":
+ // CHECK-NEXT: .long [[func_begin:.Lfunc_begin([0-9]+)@IMGREL]]
+ // CHECK-NEXT: .long -1
+ // CHECK-NEXT: .long [[tmp1:.Ltmp([0-9]+)]]@IMGREL
+ // CHECK-NEXT: .long 0
+ // CHECK-NEXT: .long [[tmp2:.Ltmp([0-9]+)]]@IMGREL
+ // CHECK-NEXT: .long -1
+}
+
+
+// Check the behavior of NOP padding around tail calls.
+// We do not expect to insert NOPs around tail calls.
+// However, the first call (to other_func()) does get a NOP
+// because it comes before .seh_startepilogue.
+void case_tail_call_no_eh(bool b) {
+ // tail call; no NOP padding after JMP
+ if (b) {
+ does_not_throw();
+ // <-- no NOP here
+ return;
+ }
+
+ other_func(20);
+ // <-- NOP does get inserted here
+}
+// CHECK-LABEL: .def "?case_tail_call_no_eh@@YAX_N at Z"
+// CHECK: test
+// CHECK-NEXT: je .LBB
+// CHECK: jmp "?does_not_throw@@YAXXZ"
+// CHECK-SAME: TAILCALL
+// CHECK-NEXT: .LBB
+// CHECK-NEXT: mov ecx, 20
+// CHECK-NEXT: jmp "?other_func@@YAXH at Z"
+// CHECK-SAME: TAILCALL
+// CHECK-NEXT: # -- End function
diff --git a/clang/test/CodeGenCXX/microsoft-abi-eh-disabled.cpp b/clang/test/CodeGenCXX/microsoft-abi-eh-disabled.cpp
new file mode 100644
index 0000000000000..04109c8f652bf
--- /dev/null
+++ b/clang/test/CodeGenCXX/microsoft-abi-eh-disabled.cpp
@@ -0,0 +1,136 @@
+// RUN: %clang_cl -c --target=x86_64-windows-msvc /EHs-c- -O2 /GS- \
+// RUN: -Xclang=-import-call-optimization \
+// RUN: /clang:-S /clang:-o- %s 2>&1 \
+// RUN: | FileCheck %s
+
+#ifdef __clang__
+#define NO_TAIL __attribute((disable_tail_calls))
+#else
+#define NO_TAIL
+#endif
+
+void might_throw();
+void other_func(int x);
+
+void does_not_throw() noexcept(true);
+
+extern "C" void __declspec(dllimport) some_dll_import();
+
+class HasDtor {
+ int x;
+ char foo[40];
+
+public:
+ explicit HasDtor(int x);
+ ~HasDtor();
+};
+
+void normal_has_regions() {
+ {
+ HasDtor hd{42};
+
+ // because state changes, we expect the HasDtor::HasDtor() call to have a NOP
+ might_throw();
+ }
+
+ other_func(10);
+}
+// CHECK-LABEL: .def "?normal_has_regions@@YAXXZ"
+// CHECK: .seh_endprologue
+// CHECK: call "??0HasDtor@@QEAA at H@Z"
+// CHECK-NEXT: call "?might_throw@@YAXXZ"
+// CHECK-NEXT: mov
+// CHECK: call "??1HasDtor@@QEAA at XZ"
+// CHECK-NEXT: mov ecx, 10
+// CHECK-NEXT: call "?other_func@@YAXH at Z"
+// CHECK-NEXT: .seh_startepilogue
+// CHECK-NOT: "$ip2state$?normal_has_regions@@YAXXZ"
+
+// This tests a tail call to a destructor.
+void case_dtor_arg_empty_body(HasDtor x)
+{
+}
+// CHECK-LABEL: .def "?case_dtor_arg_empty_body@@YAXVHasDtor@@@Z"
+// CHECK: jmp "??1HasDtor@@QEAA at XZ"
+
+int case_dtor_arg_empty_with_ret(HasDtor x)
+{
+ // The call to HasDtor::~HasDtor() should NOT have a NOP because the
+ // following "mov eax, 100" instruction is in the same EH state.
+ return 100;
+}
+// CHECK-LABEL: .def "?case_dtor_arg_empty_with_ret@@YAHVHasDtor@@@Z"
+// CHECK: .seh_endprologue
+// CHECK: call "??1HasDtor@@QEAA at XZ"
+// CHECK-NOT: nop
+// CHECK: mov eax, 100
+// CHECK: .seh_startepilogue
+// CHECK: .seh_endepilogue
+// CHECK: .seh_endproc
+
+void case_except_simple_call() NO_TAIL
+{
+ does_not_throw();
+}
+
+// This tests that the destructor is called right before SEH_BeginEpilogue,
+// but in a function that has a return value.
+int case_dtor_arg_calls_no_throw(HasDtor x)
+{
+ does_not_throw(); // no NOP expected
+ return 100;
+}
+
+// Check the behavior of CALLs that are at the end of MBBs. If a CALL is within
+// a non-null EH state (state -1) and is at the end of an MBB, then we expect
+// to find an EH_LABEL after the CALL. This causes us to insert a NOP, which
+// is the desired result.
+void case_dtor_runs_after_join(int x) {
+
+ // ctor call does not need a NOP, because it has real instructions after it
+ HasDtor hd{42};
+
+ if (x) {
+ might_throw();
+ } else {
+ other_func(10);
+ }
+ does_not_throw();
+ // ~HasDtor() runs
+}
+
+// CHECK-LABEL: .def "?case_dtor_runs_after_join@@YAXH at Z"
+// CHECK: .seh_endprologue
+// CHECK: call "??0HasDtor@@QEAA at H@Z"
+// CHECK-NEXT: test
+// CHECK: call "?might_throw@@YAXXZ"
+// CHECK-NEXT: jmp
+// CHECK: call "?other_func@@YAXH at Z"
+// CHECK-NEXT: .LBB
+// CHECK: call "?does_not_throw@@YAXXZ"
+// CHECK-NEXT: lea
+// CHECK-NEXT: call "??1HasDtor@@QEAA at XZ"
+// CHECK-NEXT: .seh_startepilogue
+// CHECK-NOT: "$ip2state$?case_dtor_runs_after_join@@YAXH at Z":
+
+
+// Check the behavior of NOP padding around tail calls.
+// We do not expect to insert NOPs around tail calls.
+// However, the first call (to other_func()) does get a NOP
+// because it comes before .seh_startepilogue.
+void case_tail_call_no_eh() {
+ // ordinary call
+ other_func(10);
+
+ // tail call; no NOP padding after JMP
+ does_not_throw();
+}
+
+// CHECK-LABEL: .def "?case_tail_call_no_eh@@YAXXZ"
+// CHECK: .seh_endprologue
+// CHECK: call "?other_func@@YAXH at Z"
+// CHECK-NEXT: .seh_startepilogue
+// CHECK: .seh_endepilogue
+// CHECK: jmp "?does_not_throw@@YAXXZ"
+// CHECK-NOT: nop
+// CHECK: .seh_endproc
diff --git a/clang/test/CodeGenCXX/microsoft-abi-eh-ip2state.cpp b/clang/test/CodeGenCXX/microsoft-abi-eh-ip2state.cpp
new file mode 100644
index 0000000000000..5e3f89c4b4680
--- /dev/null
+++ b/clang/test/CodeGenCXX/microsoft-abi-eh-ip2state.cpp
@@ -0,0 +1,241 @@
+// RUN: %clang_cl -c --target=x86_64-windows-msvc -O2 /EHsc /GS- \
+// RUN: -Xclang=-import-call-optimization \
+// RUN: /clang:-S /clang:-o- %s 2>&1 \
+// RUN: | FileCheck %s
+
+#ifdef __clang__
+#define NO_TAIL __attribute((disable_tail_calls))
+#else
+#define NO_TAIL
+#endif
+
+void might_throw();
+void other_func(int x);
+
+void does_not_throw() noexcept(true);
+
+extern "C" void __declspec(dllimport) some_dll_import();
+
+class HasDtor {
+ int x;
+ char foo[40];
+
+public:
+ explicit HasDtor(int x);
+ ~HasDtor();
+};
+
+class BadError {
+public:
+ int errorCode;
+};
+
+// Verify that when NOP padding for IP2State is active *and* Import Call
+// Optimization is active that we see both forms of NOP padding.
+void case_calls_dll_import() NO_TAIL {
+ some_dll_import();
+}
+// CHECK-LABEL: .def "?case_calls_dll_import@@YAXXZ"
+// CHECK: .seh_endprologue
+// CHECK: .Limpcall{{[0-9]+}}:
+// CHECK-NEXT: rex64
+// CHECK-NEXT: call __imp_some_dll_import
+// CHECK-NEXT: nop dword ptr {{\[.*\]}}
+// CHECK-NEXT: nop
+// CHECK-NEXT: .seh_startepilogue
+
+void normal_has_regions() {
+
+ // <-- state -1 (none)
+ {
+ HasDtor hd{42};
+
+ // <-- state goes from -1 to 0
+ // because state changes, we expect the HasDtor::HasDtor() call to have a NOP
+
+ might_throw();
+
+ // <-- state goes from 0 to -1 because we're about to call HasDtor::~HasDtor()
+ // <-- state -1
+ }
+
+ // <-- state -1
+ other_func(10);
+
+ // <-- state -1
+}
+// CHECK-LABEL: .def "?normal_has_regions@@YAXXZ"
+// CHECK: .seh_endprologue
+// CHECK: call "??0HasDtor@@QEAA at H@Z"
+// CHECK-NEXT: nop
+// CHECK: call "?might_throw@@YAXXZ"
+// CHECK-NEXT: nop
+// CHECK: call "??1HasDtor@@QEAA at XZ"
+// CHECK: call "?other_func@@YAXH at Z"
+// CHECK-NEXT: nop
+// CHECK: .seh_startepilogue
+
+// This tests a tail call to a destructor.
+void case_dtor_arg_empty_body(HasDtor x)
+{
+}
+// CHECK-LABEL: .def "?case_dtor_arg_empty_body@@YAXVHasDtor@@@Z"
+// CHECK: jmp "??1HasDtor@@QEAA at XZ"
+
+int case_dtor_arg_empty_with_ret(HasDtor x)
+{
+ // CHECK-LABEL: .def "?case_dtor_arg_empty_with_ret@@YAHVHasDtor@@@Z"
+ // CHECK: .seh_endprologue
+
+ // CHECK: call "??1HasDtor@@QEAA at XZ"
+ // CHECK-NOT: nop
+
+ // The call to HasDtor::~HasDtor() should NOT have a NOP because the
+ // following "mov eax, 100" instruction is in the same EH state.
+
+ return 100;
+
+ // CHECK: mov eax, 100
+ // CHECK: .seh_startepilogue
+ // CHECK: .seh_endepilogue
+ // CHECK: .seh_endproc
+}
+
+int case_noexcept_dtor(HasDtor x) noexcept(true)
+{
+ // CHECK: .def "?case_noexcept_dtor@@YAHVHasDtor@@@Z"
+ // CHECK: call "??1HasDtor@@QEAA at XZ"
+ // CHECK-NEXT: mov eax, 100
+ // CHECK-NEXT: .seh_startepilogue
+ return 100;
+}
+
+// Simple call of a function that can throw
+void case_except_simple_call() NO_TAIL
+{
+ might_throw();
+}
+// CHECK-LABEL: .def "?case_except_simple_call@@YAXXZ"
+// CHECK: .seh_endprologue
+// CHECK-NEXT: call "?might_throw@@YAXXZ"
+// CHECK-NEXT: nop
+// CHECK-NEXT: .seh_startepilogue
+
+// Simple call of a function that cannot throw, in a noexcept context.
+void case_noexcept_simple_call() noexcept(true) NO_TAIL
+{
+ does_not_throw();
+}
+// CHECK-LABEL: .def "?case_noexcept_simple_call@@YAXXZ"
+// CHECK: .seh_endprologue
+// CHECK-NEXT: call "?does_not_throw@@YAXXZ"
+// CHECK-NEXT: nop
+// CHECK-NEXT: .seh_startepilogue
+
+
+// This tests that the destructor is called right before SEH_BeginEpilogue,
+// but in a function that has a return value.
+int case_dtor_arg_calls_no_throw(HasDtor x)
+{
+ does_not_throw(); // no NOP expected
+ return 100;
+}
+
+// Check the behavior of CALLs that are at the end of MBBs. If a CALL is within
+// a non-null EH state (state -1) and is at the end of an MBB, then we expect
+// to find an EH_LABEL after the CALL. This causes us to insert a NOP, which
+// is the desired result.
+void case_dtor_runs_after_join(int x) {
+ // CHECK-LABEL: .def "?case_dtor_runs_after_join@@YAXH at Z"
+ // CHECK: .seh_endprologue
+
+ // <-- EH state -1
+
+ // ctor call does not need a NOP, because it has real instructions after it
+ HasDtor hd{42};
+ // CHECK: call "??0HasDtor@@QEAA at H@Z"
+ // CHECK-NEXT: test
+
+ // <-- EH state transition from -1 0
+ if (x) {
+ might_throw(); // <-- NOP expected (at end of BB w/ EH_LABEL)
+ // CHECK: call "?might_throw@@YAXXZ"
+ // CHECK-NEXT: nop
+ } else {
+ other_func(10); // <-- NOP expected (at end of BB w/ EH_LABEL)
+ // CHECK: call "?other_func@@YAXH at Z"
+ // CHECK-NEXT: nop
+ }
+ does_not_throw();
+ // <-- EH state transition 0 to -1
+ // ~HasDtor() runs
+
+ // CHECK: .seh_endproc
+
+ // CHECK: "$ip2state$?case_dtor_runs_after_join@@YAXH at Z":
+ // CHECK-NEXT: .long [[func_begin:.Lfunc_begin([0-9]+)@IMGREL]]
+ // CHECK-NEXT: .long -1
+ // CHECK-NEXT: .long [[tmp1:.Ltmp([0-9]+)]]@IMGREL
+ // CHECK-NEXT: .long 0
+ // CHECK-NEXT: .long [[tmp2:.Ltmp([0-9]+)]]@IMGREL
+ // CHECK-NEXT: .long -1
+}
+
+
+// Check the behavior of NOP padding around tail calls.
+// We do not expect to insert NOPs around tail calls.
+// However, the first call (to other_func()) does get a NOP
+// because it comes before .seh_startepilogue.
+void case_tail_call_no_eh() {
+ // CHECK-LABEL: .def "?case_tail_call_no_eh@@YAXXZ"
+ // CHECK: .seh_endprologue
+
+ // ordinary call
+ other_func(10);
+ // CHECK: call "?other_func@@YAXH at Z"
+ // CHECK-NEXT: nop
+
+ // tail call; no NOP padding after JMP
+ does_not_throw();
+
+ // CHECK: .seh_startepilogue
+ // CHECK: .seh_endepilogue
+ // CHECK: jmp "?does_not_throw@@YAXXZ"
+ // CHECK-NOT: nop
+ // CHECK: .seh_endproc
+}
+
+
+// Check the behavior of a try/catch
+int case_try_catch() {
+ // CHECK-LABEL: .def "?case_try_catch@@YAHXZ"
+ // CHECK: .seh_endprologue
+
+ // Because of the EH_LABELs, the ctor and other_func() get NOPs.
+
+ int result = 0;
+ try {
+ // CHECK: call "??0HasDtor@@QEAA at H@Z"
+ // CHECK-NEXT: nop
+ HasDtor hd{20};
+
+ // CHECK: call "?other_func@@YAXH at Z"
+ // CHECK-NEXT: nop
+ other_func(10);
+
+ // CHECK: call "??1HasDtor@@QEAA at XZ"
+ // CHECK: mov
+ } catch (BadError& e) {
+ result = 1;
+ }
+ return result;
+
+ // CHECK: .seh_endproc
+
+ // CHECK: .def "?dtor$4@?0??case_try_catch@@YAHXZ at 4HA"
+ // CHECK: .seh_endprologue
+ // CHECK: call "??1HasDtor@@QEAA at XZ"
+ // CHECK-NEXT: nop
+ // CHECK: .seh_startepilogue
+ // CHECK: .seh_endproc
+}
diff --git a/lld/test/COFF/lto-comdat.ll b/lld/test/COFF/lto-comdat.ll
index 76ef8259695a5..4771f0678f2a7 100644
--- a/lld/test/COFF/lto-comdat.ll
+++ b/lld/test/COFF/lto-comdat.ll
@@ -72,16 +72,16 @@
; TEXT-10-NEXT: <.text>:
; TEXT-10-NEXT: subq $40, %rsp
; TEXT-10-NEXT: callq 0x140001040
-; TEXT-10-NEXT: nop
; TEXT-10-NEXT: addq $40, %rsp
; TEXT-10-NEXT: retq
; TEXT-10-NEXT: int3
+; TEXT-10-NEXT: int3
; TEXT-10-NEXT: subq $40, %rsp
; TEXT-10-NEXT: callq 0x140001040
-; TEXT-10-NEXT: nop
; TEXT-10-NEXT: addq $40, %rsp
; TEXT-10-NEXT: retq
; TEXT-10-NEXT: int3
+; TEXT-10-NEXT: int3
; TEXT-10-NEXT: subq $40, %rsp
; TEXT-10-NEXT: callq 0x140001000
; TEXT-10-NEXT: callq 0x140001010
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index faab2503ced50..37b613e02dfa5 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -168,6 +168,10 @@ class LLVM_ABI AsmPrinter : public MachineFunctionPass {
Debug = 2 ///< Emit .debug_frame
};
+ /// True if using WinEH and the current function has an EH personality
+ /// function.
+ bool ShouldEmitPersonality = false;
+
private:
MCSymbol *CurrentFnEnd = nullptr;
diff --git a/llvm/include/llvm/CodeGen/AsmPrinterHandler.h b/llvm/include/llvm/CodeGen/AsmPrinterHandler.h
index ab737fa00ce14..c81cdac7c12c5 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinterHandler.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinterHandler.h
@@ -81,6 +81,10 @@ class LLVM_ABI AsmPrinterHandler {
virtual void beginFunclet(const MachineBasicBlock &MBB,
MCSymbol *Sym = nullptr) {}
virtual void endFunclet() {}
+
+ /// True if an EH-related handler indicates that the current function
+ /// has an EH personality function.
+ virtual bool hasEHPersonality() const { return false; }
};
} // End of namespace llvm
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 76a1d8c931605..71d1320b6e93c 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1066,6 +1066,7 @@ void AsmPrinter::emitFunctionHeader() {
for (auto &Handler : Handlers) {
Handler->beginFunction(MF);
Handler->beginBasicBlockSection(MF->front());
+ this->ShouldEmitPersonality |= Handler->hasEHPersonality();
}
for (auto &Handler : EHHandlers) {
Handler->beginFunction(MF);
@@ -1787,6 +1788,8 @@ static StringRef getMIMnemonic(const MachineInstr &MI, MCStreamer &Streamer) {
/// EmitFunctionBody - This method emits the body and trailer for a
/// function.
void AsmPrinter::emitFunctionBody() {
+ ShouldEmitPersonality = false;
+
emitFunctionHeader();
// Emit target-specific gunk before the function body.
@@ -1868,6 +1871,7 @@ void AsmPrinter::emitFunctionBody() {
OutStreamer->emitLabel(MI.getOperand(0).getMCSymbol());
break;
case TargetOpcode::EH_LABEL:
+ OutStreamer->AddComment("EH_LABEL");
OutStreamer->emitLabel(MI.getOperand(0).getMCSymbol());
// For AsynchEH, insert a Nop if followed by a trap inst
// Or the exception won't be caught.
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
index dccd71fffe053..13fd270ec7410 100644
--- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
@@ -323,12 +323,6 @@ const MCExpr *WinException::getLabel(const MCSymbol *Label) {
Asm->OutContext);
}
-const MCExpr *WinException::getLabelPlusOne(const MCSymbol *Label) {
- return MCBinaryExpr::createAdd(getLabel(Label),
- MCConstantExpr::create(1, Asm->OutContext),
- Asm->OutContext);
-}
-
const MCExpr *WinException::getOffset(const MCSymbol *OffsetOf,
const MCSymbol *OffsetFrom) {
return MCBinaryExpr::createSub(
@@ -655,7 +649,7 @@ void WinException::emitSEHActionsForRange(const WinEHFuncInfo &FuncInfo,
AddComment("LabelStart");
OS.emitValue(getLabel(BeginLabel), 4);
AddComment("LabelEnd");
- OS.emitValue(getLabelPlusOne(EndLabel), 4);
+ OS.emitValue(getLabel(EndLabel), 4);
AddComment(UME.IsFinally ? "FinallyFunclet" : UME.Filter ? "FilterFunction"
: "CatchAll");
OS.emitValue(FilterOrFinally, 4);
@@ -950,13 +944,7 @@ void WinException::computeIP2StateTable(
if (!ChangeLabel)
ChangeLabel = StateChange.PreviousEndLabel;
// Emit an entry indicating that PCs after 'Label' have this EH state.
- // NOTE: On ARM architectures, the StateFromIp automatically takes into
- // account that the return address is after the call instruction (whose EH
- // state we should be using), but on other platforms we need to +1 to the
- // label so that we are using the correct EH state.
- const MCExpr *LabelExpression = (isAArch64 || isThumb)
- ? getLabel(ChangeLabel)
- : getLabelPlusOne(ChangeLabel);
+ const MCExpr *LabelExpression = getLabel(ChangeLabel);
IPToStateTable.push_back(
std::make_pair(LabelExpression, StateChange.NewState));
// FIXME: assert that NewState is between CatchLow and CatchHigh.
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.h b/llvm/lib/CodeGen/AsmPrinter/WinException.h
index 638589adf0ddc..21a8ce2fc7ad1 100644
--- a/llvm/lib/CodeGen/AsmPrinter/WinException.h
+++ b/llvm/lib/CodeGen/AsmPrinter/WinException.h
@@ -80,7 +80,6 @@ class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer {
const MCExpr *create32bitRef(const MCSymbol *Value);
const MCExpr *create32bitRef(const GlobalValue *GV);
const MCExpr *getLabel(const MCSymbol *Label);
- const MCExpr *getLabelPlusOne(const MCSymbol *Label);
const MCExpr *getOffset(const MCSymbol *OffsetOf, const MCSymbol *OffsetFrom);
const MCExpr *getOffsetPlusOne(const MCSymbol *OffsetOf,
const MCSymbol *OffsetFrom);
@@ -114,6 +113,8 @@ class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer {
/// Emit target-specific EH funclet machinery.
void beginFunclet(const MachineBasicBlock &MBB, MCSymbol *Sym) override;
void endFunclet() override;
+
+ virtual bool hasEHPersonality() const { return shouldEmitPersonality; }
};
}
diff --git a/llvm/lib/Target/X86/X86AsmPrinter.h b/llvm/lib/Target/X86/X86AsmPrinter.h
index efb951b73532f..e02b5562d3b5e 100644
--- a/llvm/lib/Target/X86/X86AsmPrinter.h
+++ b/llvm/lib/Target/X86/X86AsmPrinter.h
@@ -151,6 +151,7 @@ class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter {
MCSymbol *LazyPointer) override;
void emitCallInstruction(const llvm::MCInst &MCI);
+ void maybeEmitNopAfterCallForWindowsEH(const MachineInstr *MI);
// Emits a label to mark the next instruction as being relevant to Import Call
// Optimization.
diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp
index 45d596bb498f6..19d5891bc052c 100644
--- a/llvm/lib/Target/X86/X86MCInstLower.cpp
+++ b/llvm/lib/Target/X86/X86MCInstLower.cpp
@@ -32,6 +32,7 @@
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/StackMaps.h"
+#include "llvm/CodeGen/WinEHFuncInfo.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Mangler.h"
@@ -833,6 +834,7 @@ void X86AsmPrinter::LowerSTATEPOINT(const MachineInstr &MI,
CallInst.setOpcode(CallOpcode);
CallInst.addOperand(CallTargetMCOp);
OutStreamer->emitInstruction(CallInst, getSubtargetInfo());
+ maybeEmitNopAfterCallForWindowsEH(&MI);
}
// Record our statepoint node in the same section used by STACKMAP
@@ -1430,21 +1432,6 @@ void X86AsmPrinter::LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI,
OutStreamer->emitLabel(FallthroughLabel);
}
-// Returns instruction preceding MBBI in MachineFunction.
-// If MBBI is the first instruction of the first basic block, returns null.
-static MachineBasicBlock::const_iterator
-PrevCrossBBInst(MachineBasicBlock::const_iterator MBBI) {
- const MachineBasicBlock *MBB = MBBI->getParent();
- while (MBBI == MBB->begin()) {
- if (MBB == &MBB->getParent()->front())
- return MachineBasicBlock::const_iterator();
- MBB = MBB->getPrevNode();
- MBBI = MBB->end();
- }
- --MBBI;
- return MBBI;
-}
-
static unsigned getSrcIdx(const MachineInstr* MI, unsigned SrcIdx) {
if (X86II::isKMasked(MI->getDesc().TSFlags)) {
// Skip mask operand.
@@ -2271,6 +2258,9 @@ void X86AsmPrinter::emitInstruction(const MachineInstr *MI) {
OutStreamer->AddComment("EVEX TO EVEX Compression ", false);
}
+ // We use this to suppress NOP padding for Windows EH.
+ bool IsTailJump = false;
+
switch (MI->getOpcode()) {
case TargetOpcode::DBG_VALUE:
llvm_unreachable("Should be handled target independently");
@@ -2325,6 +2315,7 @@ void X86AsmPrinter::emitInstruction(const MachineInstr *MI) {
// Lower this as normal, but add a comment.
OutStreamer->AddComment("TAILCALL");
+ IsTailJump = true;
break;
case X86::TAILJMPr:
@@ -2340,6 +2331,7 @@ void X86AsmPrinter::emitInstruction(const MachineInstr *MI) {
// Lower these as normal, but add some comments.
OutStreamer->AddComment("TAILCALL");
+ IsTailJump = true;
break;
case X86::TAILJMPm64_REX:
@@ -2349,6 +2341,7 @@ void X86AsmPrinter::emitInstruction(const MachineInstr *MI) {
}
OutStreamer->AddComment("TAILCALL");
+ IsTailJump = true;
break;
case X86::TAILJMPr64_REX: {
@@ -2361,6 +2354,7 @@ void X86AsmPrinter::emitInstruction(const MachineInstr *MI) {
}
OutStreamer->AddComment("TAILCALL");
+ IsTailJump = true;
break;
}
@@ -2537,26 +2531,6 @@ void X86AsmPrinter::emitInstruction(const MachineInstr *MI) {
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);
- MBBI != MachineBasicBlock::const_iterator();
- MBBI = PrevCrossBBInst(MBBI)) {
- // Pseudo instructions that aren't a call are assumed to not emit any
- // code. If they do, we worst case generate unnecessary noops after a
- // call.
- if (MBBI->isCall() || !MBBI->isPseudo()) {
- if (MBBI->isCall())
- EmitAndCountInstruction(MCInstBuilder(X86::NOOP));
- break;
- }
- }
-
EmitSEHInstruction(MI);
return;
}
@@ -2585,6 +2559,7 @@ void X86AsmPrinter::emitInstruction(const MachineInstr *MI) {
EmitAndCountInstruction(MCInstBuilder(X86::REX64_PREFIX));
emitCallInstruction(TmpInst);
emitNop(*OutStreamer, 5, Subtarget);
+ maybeEmitNopAfterCallForWindowsEH(MI);
return;
}
@@ -2605,6 +2580,7 @@ void X86AsmPrinter::emitInstruction(const MachineInstr *MI) {
// For Import Call Optimization to work, we need a 3-byte nop after the
// call instruction.
emitNop(*OutStreamer, 3, Subtarget);
+ maybeEmitNopAfterCallForWindowsEH(MI);
return;
}
break;
@@ -2638,6 +2614,10 @@ void X86AsmPrinter::emitInstruction(const MachineInstr *MI) {
if (MI->isCall()) {
emitCallInstruction(TmpInst);
+ // Since tail calls transfer control without leaving a stack frame, there is
+ // never a need for NOP padding tail calls.
+ if (!IsTailJump)
+ maybeEmitNopAfterCallForWindowsEH(MI);
return;
}
@@ -2659,6 +2639,155 @@ void X86AsmPrinter::emitCallInstruction(const llvm::MCInst &MCI) {
OutStreamer->emitInstruction(MCI, getSubtargetInfo());
}
+// Determines whether a NOP is required after a CALL, so that Windows EH
+// IP2State tables have the correct information.
+//
+// On most Windows platforms (AMD64, ARM64, ARM32, IA64, but *not* x86-32),
+// exception handling works by looking up instruction pointers in lookup
+// tables. These lookup tables are stored in .xdata sections in executables.
+// One element of the lookup tables are the "IP2State" tables (Instruction
+// Pointer to State).
+//
+// If a function has any instructions that require cleanup during exception
+// unwinding, then it will have an IP2State table. Each entry in the IP2State
+// table describes a range of bytes in the function's instruction stream, and
+// associates an "EH state number" with that range of instructions. A value of
+// -1 means "the null state", which does not require any code to execute.
+// A value other than -1 is an index into the State table.
+//
+// The entries in the IP2State table contain byte offsets within the instruction
+// stream of the function. The Windows ABI requires that these offsets are
+// aligned to instruction boundaries; they are not permitted to point to a byte
+// that is not the first byte of an instruction.
+//
+// Unfortunately, CALL instructions present a problem during unwinding. CALL
+// instructions push the address of the instruction after the CALL instruction,
+// so that execution can resume after the CALL. If the CALL is the last
+// instruction within an IP2State region, then the return address (on the stack)
+// points to the *next* IP2State region. This means that the unwinder will
+// use the wrong cleanup funclet during unwinding.
+//
+// To fix this problem, the Windows AMD64 ABI requires that CALL instructions
+// are never placed at the end of an IP2State region. Stated equivalently, the
+// end of a CALL instruction cannot be aligned to an IP2State boundary. If a
+// CALL instruction would occur at the end of an IP2State region, then the
+// compiler must insert a NOP instruction after the CALL. The NOP instruction
+// is placed in the same EH region as the CALL instruction, so that the return
+// address points to the NOP and the unwinder will locate the correct region.
+//
+// NOP padding is only necessary on Windows AMD64 targets. On ARM64 and ARM32,
+// instructions have a fixed size so the unwinder knows how to "back up" by
+// one instruction.
+//
+// Interaction with Import Call Optimization (ICO):
+//
+// Import Call Optimization (ICO) is a compiler + OS feature on Windows which
+// improves the performance and security of DLL imports. ICO relies on using a
+// specific CALL idiom that can be replaced by the OS DLL loader. This removes
+// a load and indirect CALL and replaces it with a single direct CALL.
+//
+// To achieve this, ICO also inserts NOPs after the CALL instruction. If the
+// end of the CALL is aligned with an EH state transition, we *also* insert
+// a single-byte NOP. **Both forms of NOPs must be preserved.** They cannot
+// be combined into a single larger NOP; nor can the second NOP be removed.
+//
+// This is necessary because, if ICO is active and the call site is modified
+// by the loader, the loader will end up overwriting the NOPs that were inserted
+// for ICO. That means that those NOPs cannot be used for the correct
+// termination of the exception handling region (the IP2State transition),
+// so we still need an additional NOP instruction. The NOPs cannot be combined
+// into a longer NOP (which is ordinarily desirable) because then ICO would
+// split one instruction, producing a malformed instruction after the ICO call.
+void X86AsmPrinter::maybeEmitNopAfterCallForWindowsEH(const MachineInstr *MI) {
+ // We only need to insert NOPs after CALLs when targeting Windows on AMD64.
+ // (Don't let the name fool you: Itanium refers to table-based exception
+ // handling, not the Itanium architecture.)
+ if (MAI->getExceptionHandlingType() != ExceptionHandling::WinEH ||
+ MAI->getWinEHEncodingType() != WinEH::EncodingType::Itanium) {
+ return;
+ }
+
+ // If there is no EH personality function, then WinException will not generate
+ // IP2State tables, and NOP padding is not necessary.
+ if (!this->ShouldEmitPersonality) {
+ return;
+ }
+
+ // Set up MBB iterator, initially positioned on the same MBB as MI.
+ MachineFunction::const_iterator MFI(MI->getParent());
+ MachineFunction::const_iterator MFE(MF->end());
+
+ // Set up instruction iterator, positioned immediately *after* MI.
+ MachineBasicBlock::const_iterator MBBI(MI);
+ MachineBasicBlock::const_iterator MBBE = MI->getParent()->end();
+ ++MBBI; // Step over MI
+
+ // This loop iterates MBBs
+ for (;;) {
+ // This loop iterates instructions
+ for (; MBBI != MBBE; ++MBBI) {
+ // Check the instruction that follows this CALL.
+ const MachineInstr &NextMI = *MBBI;
+
+ // If there is an EH_LABEL after this CALL, then there is an EH state
+ // transition after this CALL. This is exactly the situation which
+ // requires NOP padding.
+ if (NextMI.isEHLabel()) {
+ EmitAndCountInstruction(MCInstBuilder(X86::NOOP));
+ return;
+ }
+
+ // Somewhat similarly, if the CALL is the last instruction before the
+ // SEH prologue, then we also need a NOP. This is necessary because the
+ // Windows stack unwinder will not invoke a function's exception handler
+ // if the instruction pointer is in the function prologue or epilogue.
+ if (NextMI.getOpcode() == X86::SEH_BeginEpilogue) {
+ EmitAndCountInstruction(MCInstBuilder(X86::NOOP));
+ return;
+ }
+
+ if (!NextMI.isPseudo() && !NextMI.isMetaInstruction()) {
+ // We found a real instruction. During the CALL, the return IP will
+ // point to this instruction. Since this instruction has the same EH
+ // state as the call itself (because there is no intervening EH_LABEL),
+ // the IP2State table will be accurate; there is no need to insert a
+ // NOP.
+ return;
+ }
+
+ // The next instruction is a pseudo-op. Ignore it and keep searching.
+ // Because these instructions do not generate any machine code, they
+ // cannot prevent the IP2State table from pointing at the wrong
+ // instruction during a CALL.
+ }
+
+ // We've reached the end of this MBB. Find the next MBB in program order.
+ // MBB order should be finalized by this point, so falling across MBBs is
+ // expected.
+ ++MFI;
+ if (MFI == MFE) {
+ // No more blocks; we've reached the end of the function. This should
+ // only happen with no-return functions, but double-check to be sure.
+ //
+ // If the CALL has no successors, then it is a noreturn function.
+ // Insert an INT3 instead of a NOP. This accomplishes the same purpose,
+ // but is more clear to read. Also, analysis tools will understand
+ // that they should not continue disassembling after the CALL (unless
+ // there are other branches to that label).
+ if (MI->getParent()->succ_empty())
+ EmitAndCountInstruction(MCInstBuilder(X86::INT3));
+ else
+ EmitAndCountInstruction(MCInstBuilder(X86::NOOP));
+ return;
+ }
+
+ // Set up iterator to scan the next basic block.
+ const MachineBasicBlock *NextMBB = &*MFI;
+ MBBI = NextMBB->instr_begin();
+ MBBE = NextMBB->instr_end();
+ }
+}
+
void X86AsmPrinter::emitLabelAndRecordForImportCallOptimization(
ImportCallKind Kind) {
assert(EnableImportCallOptimization);
diff --git a/llvm/test/CodeGen/WinEH/wineh-noret-cleanup.ll b/llvm/test/CodeGen/WinEH/wineh-noret-cleanup.ll
index 3b3a46069509b..ab6672ee5f410 100644
--- a/llvm/test/CodeGen/WinEH/wineh-noret-cleanup.ll
+++ b/llvm/test/CodeGen/WinEH/wineh-noret-cleanup.ll
@@ -1,4 +1,4 @@
-; RUN: sed -e s/.Cxx:// %s | llc -mtriple=x86_64-pc-windows-msvc | FileCheck %s --check-prefixes=CXX,X64CXX
+; RUN: sed -e s/.Cxx:// %s | llc -mtriple=x86_64-pc-windows-msvc | FileCheck %s --check-prefixes=CXX
; RUN: sed -e s/.Seh:// %s | llc -mtriple=x86_64-pc-windows-msvc | FileCheck %s --check-prefixes=SEH
; RUN: %if aarch64-registered-target %{ sed -e s/.Cxx:// %s | llc -mtriple=aarch64-pc-windows-msvc | FileCheck %s --check-prefix=CXX %}
; RUN: %if aarch64-registered-target %{ sed -e s/.Seh:// %s | llc -mtriple=aarch64-pc-windows-msvc | FileCheck %s --check-prefix=SEH %}
@@ -49,18 +49,14 @@ catch.body.2:
; CXX-NEXT: .[[ENTRY:long|word]] .Lfunc_begin0 at IMGREL
; CXX-NEXT: .[[ENTRY]] -1
; CXX-NEXT: .[[ENTRY]] .Ltmp0 at IMGREL
-; X64CXX-SAME: +1
; CXX-NEXT: .[[ENTRY]] 1
; CXX-NEXT: .[[ENTRY]] .Ltmp1 at IMGREL
-; X64CXX-SAME: +1
; CXX-NEXT: .[[ENTRY]] -1
; CXX-NEXT: .[[ENTRY]] "?catch$3@?0?test at 4HA"@IMGREL
; CXX-NEXT: .[[ENTRY]] 2
; CXX-NEXT: .[[ENTRY]] .Ltmp2 at IMGREL
-; X64CXX-SAME: +1
; CXX-NEXT: .[[ENTRY]] 3
; CXX-NEXT: .[[ENTRY]] .Ltmp3 at IMGREL
-; X64CXX-SAME: +1
; CXX-NEXT: .[[ENTRY]] 2
; CXX-NEXT: .[[ENTRY]] "?catch$5@?0?test at 4HA"@IMGREL
; CXX-NEXT: .[[ENTRY]] 4
@@ -70,19 +66,19 @@ catch.body.2:
; SEH: .LBB0_[[CATCH:[0-9]+]]: {{.*}} %catch.body
; SEH-LABEL: .Llsda_begin0:
; SEH-NEXT: .[[ENTRY:long|word]] .Ltmp0 at IMGREL
-; SEH-NEXT: .[[ENTRY]] .Ltmp1 at IMGREL+1
+; SEH-NEXT: .[[ENTRY]] .Ltmp1 at IMGREL
; SEH-NEXT: .[[ENTRY]] dummy_filter at IMGREL
; SEH-NEXT: .[[ENTRY]] .LBB0_[[CATCH]]@IMGREL
; SEH-NEXT: .[[ENTRY]] .Ltmp0 at IMGREL
-; SEH-NEXT: .[[ENTRY]] .Ltmp1 at IMGREL+1
+; SEH-NEXT: .[[ENTRY]] .Ltmp1 at IMGREL
; SEH-NEXT: .[[ENTRY]] dummy_filter at IMGREL
; SEH-NEXT: .[[ENTRY]] .LBB0_[[CATCH2]]@IMGREL
; SEH-NEXT: .[[ENTRY]] .Ltmp2 at IMGREL
-; SEH-NEXT: .[[ENTRY]] .Ltmp3 at IMGREL+1
+; SEH-NEXT: .[[ENTRY]] .Ltmp3 at IMGREL
; SEH-NEXT: .[[ENTRY]] "?dtor$[[DTOR:[0-9]+]]@?0?test at 4HA"@IMGREL
; SEH-NEXT: .[[ENTRY]] 0
; SEH-NEXT: .[[ENTRY]] .Ltmp2 at IMGREL
-; SEH-NEXT: .[[ENTRY]] .Ltmp3 at IMGREL+1
+; SEH-NEXT: .[[ENTRY]] .Ltmp3 at IMGREL
; SEH-NEXT: .[[ENTRY]] dummy_filter at IMGREL
; SEH-NEXT: .[[ENTRY]] .LBB0_[[CATCH2]]@IMGREL
; SEH-NEXT: .Llsda_end0:
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 ad24608d338ad..ab4202ede01ca 100644
--- a/llvm/test/CodeGen/X86/apx/push2-pop2-cfi-seh.ll
+++ b/llvm/test/CodeGen/X86/apx/push2-pop2-cfi-seh.ll
@@ -141,7 +141,6 @@ define i32 @csr6_alloc16(ptr %argv) {
; WIN-REF-NEXT: #NO_APP
; WIN-REF-NEXT: xorl %eax, %eax
; WIN-REF-NEXT: callq *%rax
-; WIN-REF-NEXT: nop
; WIN-REF-NEXT: .seh_startepilogue
; WIN-REF-NEXT: addq $56, %rsp
; WIN-REF-NEXT: popq %rbx
@@ -174,7 +173,6 @@ define i32 @csr6_alloc16(ptr %argv) {
; WIN-NEXT: #NO_APP
; WIN-NEXT: xorl %eax, %eax
; WIN-NEXT: callq *%rax
-; WIN-NEXT: nop
; WIN-NEXT: .seh_startepilogue
; WIN-NEXT: addq $64, %rsp
; WIN-NEXT: pop2 %rbp, %rbx
@@ -205,7 +203,6 @@ define i32 @csr6_alloc16(ptr %argv) {
; WIN-PPX-NEXT: #NO_APP
; WIN-PPX-NEXT: xorl %eax, %eax
; WIN-PPX-NEXT: callq *%rax
-; WIN-PPX-NEXT: nop
; WIN-PPX-NEXT: .seh_startepilogue
; WIN-PPX-NEXT: addq $64, %rsp
; WIN-PPX-NEXT: pop2p %rbp, %rbx
diff --git a/llvm/test/CodeGen/X86/avx512-intel-ocl.ll b/llvm/test/CodeGen/X86/avx512-intel-ocl.ll
index eb8bff26f3b77..6c8f9c0b24aba 100644
--- a/llvm/test/CodeGen/X86/avx512-intel-ocl.ll
+++ b/llvm/test/CodeGen/X86/avx512-intel-ocl.ll
@@ -428,7 +428,6 @@ define <16 x float> @testf16_inp_mask(<16 x float> %a, i16 %mask) {
; WIN64-KNL-NEXT: vmovaps (%rcx), %zmm0
; WIN64-KNL-NEXT: kmovw %edx, %k1
; WIN64-KNL-NEXT: callq func_float16_mask
-; WIN64-KNL-NEXT: nop
; WIN64-KNL-NEXT: .seh_startepilogue
; WIN64-KNL-NEXT: addq $40, %rsp
; WIN64-KNL-NEXT: .seh_endepilogue
@@ -444,7 +443,6 @@ define <16 x float> @testf16_inp_mask(<16 x float> %a, i16 %mask) {
; WIN64-SKX-NEXT: vmovaps (%rcx), %zmm0
; WIN64-SKX-NEXT: kmovd %edx, %k1
; WIN64-SKX-NEXT: callq func_float16_mask
-; WIN64-SKX-NEXT: nop
; WIN64-SKX-NEXT: .seh_startepilogue
; WIN64-SKX-NEXT: addq $40, %rsp
; WIN64-SKX-NEXT: .seh_endepilogue
diff --git a/llvm/test/CodeGen/X86/avx512-regcall-Mask.ll b/llvm/test/CodeGen/X86/avx512-regcall-Mask.ll
index 162f5efd78f6d..75e0bb94abcbf 100644
--- a/llvm/test/CodeGen/X86/avx512-regcall-Mask.ll
+++ b/llvm/test/CodeGen/X86/avx512-regcall-Mask.ll
@@ -337,7 +337,6 @@ define dso_local x86_regcallcc i32 @test_argv32i1(<32 x i1> %x0, <32 x i1> %x1,
; WIN64-NEXT: leaq {{[0-9]+}}(%rsp), %r8
; WIN64-NEXT: vzeroupper
; WIN64-NEXT: callq test_argv32i1helper
-; WIN64-NEXT: nop
; WIN64-NEXT: .seh_startepilogue
; WIN64-NEXT: movq %rbp, %rsp
; WIN64-NEXT: popq %r10
@@ -563,7 +562,6 @@ define dso_local x86_regcallcc i16 @test_argv16i1(<16 x i1> %x0, <16 x i1> %x1,
; WIN64-NEXT: leaq {{[0-9]+}}(%rsp), %r8
; WIN64-NEXT: vzeroupper
; WIN64-NEXT: callq test_argv16i1helper
-; WIN64-NEXT: nop
; WIN64-NEXT: .seh_startepilogue
; WIN64-NEXT: addq $88, %rsp
; WIN64-NEXT: popq %r10
@@ -793,7 +791,6 @@ define dso_local x86_regcallcc i8 @test_argv8i1(<8 x i1> %x0, <8 x i1> %x1, <8 x
; WIN64-NEXT: leaq {{[0-9]+}}(%rsp), %r8
; WIN64-NEXT: vzeroupper
; WIN64-NEXT: callq test_argv8i1helper
-; WIN64-NEXT: nop
; WIN64-NEXT: .seh_startepilogue
; WIN64-NEXT: addq $88, %rsp
; WIN64-NEXT: popq %r10
diff --git a/llvm/test/CodeGen/X86/call-rv-marker.ll b/llvm/test/CodeGen/X86/call-rv-marker.ll
index 6ce7430b52c71..2832e5f01f267 100644
--- a/llvm/test/CodeGen/X86/call-rv-marker.ll
+++ b/llvm/test/CodeGen/X86/call-rv-marker.ll
@@ -38,7 +38,6 @@ define ptr @rv_marker_1_retain() {
; WINABI: callq foo1
; WINABI-NEXT: movq %rax, %rcx
; WINABI-NEXT: callq objc_retainAutoreleasedReturnValue
-; WINABI-NEXT: nop
;
entry:
%call = call ptr @foo1() [ "clang.arc.attachedcall"(ptr @objc_retainAutoreleasedReturnValue) ]
diff --git a/llvm/test/CodeGen/X86/catchret-empty-fallthrough.ll b/llvm/test/CodeGen/X86/catchret-empty-fallthrough.ll
index ab9fa2287ffad..24d3030ea4bdb 100644
--- a/llvm/test/CodeGen/X86/catchret-empty-fallthrough.ll
+++ b/llvm/test/CodeGen/X86/catchret-empty-fallthrough.ll
@@ -48,6 +48,6 @@ return: ; preds = %catch, %entry
; CHECK-NEXT: .long (.Llsda_end0-.Llsda_begin0)/16
; CHECK-NEXT: .Llsda_begin0:
; CHECK-NEXT: .long .Ltmp0 at IMGREL
-; CHECK-NEXT: .long .Ltmp1 at IMGREL+1
+; CHECK-NEXT: .long .Ltmp1 at IMGREL
; CHECK-NEXT: .long 1
; CHECK-NEXT: .long .LBB0_[[catch]]@IMGREL
diff --git a/llvm/test/CodeGen/X86/cfguard-x86-64-vectorcall.ll b/llvm/test/CodeGen/X86/cfguard-x86-64-vectorcall.ll
index 7748f8007c619..03a28cf41cb5f 100644
--- a/llvm/test/CodeGen/X86/cfguard-x86-64-vectorcall.ll
+++ b/llvm/test/CodeGen/X86/cfguard-x86-64-vectorcall.ll
@@ -22,7 +22,6 @@ define void @func_cf_vector_x64(ptr %0, ptr %1) #0 {
; X64-NEXT: movsd {{.*#+}} xmm2 = mem[0],zero
; X64-NEXT: movsd {{.*#+}} xmm3 = mem[0],zero
; X64-NEXT: callq *__guard_dispatch_icall_fptr(%rip)
-; X64-NEXT: nop
; X64-NEXT: .seh_startepilogue
; X64-NEXT: addq $72, %rsp
; X64-NEXT: .seh_endepilogue
diff --git a/llvm/test/CodeGen/X86/conditional-tailcall-pgso.ll b/llvm/test/CodeGen/X86/conditional-tailcall-pgso.ll
index c4c194e139828..7855ff2c7eb83 100644
--- a/llvm/test/CodeGen/X86/conditional-tailcall-pgso.ll
+++ b/llvm/test/CodeGen/X86/conditional-tailcall-pgso.ll
@@ -121,7 +121,6 @@ define void @f_non_leaf(i32 %x, i32 %y) !prof !14 {
; WIN64-NEXT: # encoding: [0xeb,A]
; WIN64-NEXT: # fixup A - offset: 1, value: foo, kind: FK_PCRel_1
; WIN64-NEXT: .LBB1_2: # %bb2
-; WIN64-NEXT: nop # encoding: [0x90]
; WIN64-NEXT: .seh_startepilogue
; WIN64-NEXT: popq %rbx # encoding: [0x5b]
; WIN64-NEXT: .seh_endepilogue
diff --git a/llvm/test/CodeGen/X86/conditional-tailcall.ll b/llvm/test/CodeGen/X86/conditional-tailcall.ll
index 9c1d83037d1f5..2859a87db3d56 100644
--- a/llvm/test/CodeGen/X86/conditional-tailcall.ll
+++ b/llvm/test/CodeGen/X86/conditional-tailcall.ll
@@ -121,7 +121,6 @@ define void @f_non_leaf(i32 %x, i32 %y) optsize {
; WIN64-NEXT: # encoding: [0xeb,A]
; WIN64-NEXT: # fixup A - offset: 1, value: foo, kind: FK_PCRel_1
; WIN64-NEXT: .LBB1_2: # %bb2
-; WIN64-NEXT: nop # encoding: [0x90]
; WIN64-NEXT: .seh_startepilogue
; WIN64-NEXT: popq %rbx # encoding: [0x5b]
; WIN64-NEXT: .seh_endepilogue
diff --git a/llvm/test/CodeGen/X86/mixed-ptr-sizes.ll b/llvm/test/CodeGen/X86/mixed-ptr-sizes.ll
index 48d0ea49b70e6..ffab8d190efa1 100644
--- a/llvm/test/CodeGen/X86/mixed-ptr-sizes.ll
+++ b/llvm/test/CodeGen/X86/mixed-ptr-sizes.ll
@@ -132,7 +132,6 @@ define dso_local void @test_null_arg(ptr %f) {
; ALL-NEXT: .seh_endprologue
; ALL-NEXT: xorl %edx, %edx
; ALL-NEXT: callq test_noop1
-; ALL-NEXT: nop
; ALL-NEXT: .seh_startepilogue
; ALL-NEXT: addq $40, %rsp
; ALL-NEXT: .seh_endepilogue
diff --git a/llvm/test/CodeGen/X86/no-sse-win64.ll b/llvm/test/CodeGen/X86/no-sse-win64.ll
index 4ee2fc6514879..2f8029243ac29 100644
--- a/llvm/test/CodeGen/X86/no-sse-win64.ll
+++ b/llvm/test/CodeGen/X86/no-sse-win64.ll
@@ -51,7 +51,6 @@ define void @pass_double(ptr %p) {
; CHECK-NEXT: .seh_endprologue
; CHECK-NEXT: movq (%rcx), %rcx
; CHECK-NEXT: callq take_double
-; CHECK-NEXT: nop
; CHECK-NEXT: .seh_startepilogue
; CHECK-NEXT: addq $40, %rsp
; CHECK-NEXT: .seh_endepilogue
@@ -70,7 +69,6 @@ define void @pass_float(ptr %p) {
; CHECK-NEXT: .seh_endprologue
; CHECK-NEXT: movl (%rcx), %ecx
; CHECK-NEXT: callq take_float
-; CHECK-NEXT: nop
; CHECK-NEXT: .seh_startepilogue
; CHECK-NEXT: addq $40, %rsp
; CHECK-NEXT: .seh_endepilogue
diff --git a/llvm/test/CodeGen/X86/noreturn-call-win64.ll b/llvm/test/CodeGen/X86/noreturn-call-win64.ll
index 57aa022e89e29..13be1f13cf3dc 100644
--- a/llvm/test/CodeGen/X86/noreturn-call-win64.ll
+++ b/llvm/test/CodeGen/X86/noreturn-call-win64.ll
@@ -111,3 +111,15 @@ declare dso_local void @"??1MakeCleanup@@QEAA at XZ"(ptr)
; CHECK: # %unreachable
; CHECK: int3
; CHECK: .seh_handlerdata
+
+
+define dso_local void @last_call_no_return() {
+ call void @abort1()
+ unreachable
+}
+
+; CHECK-LABEL: last_call_no_return:
+; CHECK: callq abort1
+; CHECK-NEXT: int3
+; CHECK-NEXT: .seh_endproc
+
diff --git a/llvm/test/CodeGen/X86/preserve_nonecc_call_win.ll b/llvm/test/CodeGen/X86/preserve_nonecc_call_win.ll
index 8f933fbfd0568..8cf2fd70b5ca0 100644
--- a/llvm/test/CodeGen/X86/preserve_nonecc_call_win.ll
+++ b/llvm/test/CodeGen/X86/preserve_nonecc_call_win.ll
@@ -11,7 +11,6 @@ define preserve_nonecc void @entry(ptr %r12, ptr %r13, ptr %r14, ptr %r15, ptr %
; CHECK-NEXT: .seh_stackalloc 40
; CHECK-NEXT: .seh_endprologue
; CHECK-NEXT: callq boring
-; CHECK-NEXT: nop
; CHECK-NEXT: .seh_startepilogue
; CHECK-NEXT: addq $40, %rsp
; CHECK-NEXT: .seh_endepilogue
diff --git a/llvm/test/CodeGen/X86/segmented-stacks.ll b/llvm/test/CodeGen/X86/segmented-stacks.ll
index f8627ff56a1f9..f251a1ab4bdb8 100644
--- a/llvm/test/CodeGen/X86/segmented-stacks.ll
+++ b/llvm/test/CodeGen/X86/segmented-stacks.ll
@@ -256,7 +256,6 @@ define void @test_basic() #0 {
; X64-MinGW-NEXT: leaq {{[0-9]+}}(%rsp), %rcx
; X64-MinGW-NEXT: movl $10, %edx
; X64-MinGW-NEXT: callq dummy_use
-; X64-MinGW-NEXT: nop
; X64-MinGW-NEXT: .seh_startepilogue
; X64-MinGW-NEXT: addq $72, %rsp
; X64-MinGW-NEXT: .seh_endepilogue
@@ -862,7 +861,6 @@ define void @test_large() #0 {
; X64-MinGW-NEXT: leaq {{[0-9]+}}(%rsp), %rcx
; X64-MinGW-NEXT: movl $3, %edx
; X64-MinGW-NEXT: callq dummy_use
-; X64-MinGW-NEXT: nop
; X64-MinGW-NEXT: .seh_startepilogue
; X64-MinGW-NEXT: addq $40040, %rsp # imm = 0x9C68
; X64-MinGW-NEXT: .seh_endepilogue
@@ -1101,7 +1099,6 @@ define fastcc void @test_fastcc() #0 {
; X64-MinGW-NEXT: leaq {{[0-9]+}}(%rsp), %rcx
; X64-MinGW-NEXT: movl $10, %edx
; X64-MinGW-NEXT: callq dummy_use
-; X64-MinGW-NEXT: nop
; X64-MinGW-NEXT: .seh_startepilogue
; X64-MinGW-NEXT: addq $72, %rsp
; X64-MinGW-NEXT: .seh_endepilogue
@@ -1354,7 +1351,6 @@ define fastcc void @test_fastcc_large() #0 {
; X64-MinGW-NEXT: leaq {{[0-9]+}}(%rsp), %rcx
; X64-MinGW-NEXT: movl $3, %edx
; X64-MinGW-NEXT: callq dummy_use
-; X64-MinGW-NEXT: nop
; X64-MinGW-NEXT: .seh_startepilogue
; X64-MinGW-NEXT: addq $40040, %rsp # imm = 0x9C68
; X64-MinGW-NEXT: .seh_endepilogue
@@ -1611,7 +1607,6 @@ define fastcc void @test_fastcc_large_with_ecx_arg(i32 %a) #0 {
; X64-MinGW-NEXT: movl %ecx, %edx
; X64-MinGW-NEXT: leaq {{[0-9]+}}(%rsp), %rcx
; X64-MinGW-NEXT: callq dummy_use
-; X64-MinGW-NEXT: nop
; X64-MinGW-NEXT: .seh_startepilogue
; X64-MinGW-NEXT: addq $40040, %rsp # imm = 0x9C68
; X64-MinGW-NEXT: .seh_endepilogue
diff --git a/llvm/test/CodeGen/X86/seh-catch-all.ll b/llvm/test/CodeGen/X86/seh-catch-all.ll
index 5250bb9312b78..4e25aabfeef58 100644
--- a/llvm/test/CodeGen/X86/seh-catch-all.ll
+++ b/llvm/test/CodeGen/X86/seh-catch-all.ll
@@ -40,7 +40,7 @@ catchall:
; CHECK-NEXT: .long (.Llsda_end0-.Llsda_begin0)/16
; CHECK-NEXT: .Llsda_begin0:
; CHECK-NEXT: .long .Ltmp{{[0-9]+}}@IMGREL
-; CHECK-NEXT: .long .Ltmp{{[0-9]+}}@IMGREL+1
+; CHECK-NEXT: .long .Ltmp{{[0-9]+}}@IMGREL
; CHECK-NEXT: .long 1
; CHECK-NEXT: .long .LBB0_2 at IMGREL
; CHECK-NEXT: .Llsda_end0:
diff --git a/llvm/test/CodeGen/X86/seh-catchpad.ll b/llvm/test/CodeGen/X86/seh-catchpad.ll
index d958580e5925b..cb85f39439e02 100644
--- a/llvm/test/CodeGen/X86/seh-catchpad.ll
+++ b/llvm/test/CodeGen/X86/seh-catchpad.ll
@@ -123,23 +123,23 @@ __except.ret: ; preds = %catch.dispatch.7
; CHECK-NEXT: .long (.Llsda_end0-.Llsda_begin0)/16
; CHECK-NEXT: .Llsda_begin0:
; CHECK-NEXT: .long .Ltmp0 at IMGREL
-; CHECK-NEXT: .long .Ltmp1 at IMGREL+1
+; CHECK-NEXT: .long .Ltmp1 at IMGREL
; CHECK-NEXT: .long 1
; CHECK-NEXT: .long .LBB1_[[except1bb]]@IMGREL
; CHECK-NEXT: .long .Ltmp0 at IMGREL
-; CHECK-NEXT: .long .Ltmp1 at IMGREL+1
+; CHECK-NEXT: .long .Ltmp1 at IMGREL
; CHECK-NEXT: .long "?filt$0 at 0@main@@"@IMGREL
; CHECK-NEXT: .long .LBB1_[[except2bb]]@IMGREL
; CHECK-NEXT: .long .Ltmp2 at IMGREL
-; CHECK-NEXT: .long .Ltmp3 at IMGREL+1
+; CHECK-NEXT: .long .Ltmp3 at IMGREL
; CHECK-NEXT: .long "?dtor$[[finbb:[0-9]+]]@?0?main at 4HA"@IMGREL
; CHECK-NEXT: .long 0
; CHECK-NEXT: .long .Ltmp2 at IMGREL
-; CHECK-NEXT: .long .Ltmp3 at IMGREL+1
+; CHECK-NEXT: .long .Ltmp3 at IMGREL
; CHECK-NEXT: .long "?filt$0 at 0@main@@"@IMGREL
; CHECK-NEXT: .long .LBB1_3 at IMGREL
; CHECK-NEXT: .long .Ltmp6 at IMGREL
-; CHECK-NEXT: .long .Ltmp7 at IMGREL+1
+; CHECK-NEXT: .long .Ltmp7 at IMGREL
; CHECK-NEXT: .long "?filt$0 at 0@main@@"@IMGREL
; CHECK-NEXT: .long .LBB1_3 at IMGREL
; CHECK-NEXT: .Llsda_end0:
diff --git a/llvm/test/CodeGen/X86/seh-except-finally.ll b/llvm/test/CodeGen/X86/seh-except-finally.ll
index 7f706552fbd7a..539d776430c76 100644
--- a/llvm/test/CodeGen/X86/seh-except-finally.ll
+++ b/llvm/test/CodeGen/X86/seh-except-finally.ll
@@ -83,15 +83,15 @@ __try.cont: ; preds = %__except, %invoke.c
; CHECK-NEXT: .long (.Llsda_end0-.Llsda_begin0)/16
; CHECK-NEXT: .Llsda_begin0:
; CHECK-NEXT: .long .Ltmp0 at IMGREL
-; CHECK-NEXT: .long .Ltmp1 at IMGREL+1
+; CHECK-NEXT: .long .Ltmp1 at IMGREL
; CHECK-NEXT: .long "?dtor$2@?0?use_both at 4HA"@IMGREL
; CHECK-NEXT: .long 0
; CHECK-NEXT: .long .Ltmp0 at IMGREL
-; CHECK-NEXT: .long .Ltmp1 at IMGREL+1
+; CHECK-NEXT: .long .Ltmp1 at IMGREL
; CHECK-NEXT: .long "?filt$0 at 0@use_both@@"@IMGREL
; CHECK-NEXT: .long .LBB0_{{[0-9]+}}@IMGREL
; CHECK-NEXT: .long .Ltmp4 at IMGREL
-; CHECK-NEXT: .long .Ltmp5 at IMGREL+1
+; CHECK-NEXT: .long .Ltmp5 at IMGREL
; CHECK-NEXT: .long "?filt$0 at 0@use_both@@"@IMGREL
; CHECK-NEXT: .long .LBB0_{{[0-9]+}}@IMGREL
; CHECK-NEXT: .Llsda_end0:
diff --git a/llvm/test/CodeGen/X86/seh-finally.ll b/llvm/test/CodeGen/X86/seh-finally.ll
index 41823dfb38f0a..6093e5e437910 100644
--- a/llvm/test/CodeGen/X86/seh-finally.ll
+++ b/llvm/test/CodeGen/X86/seh-finally.ll
@@ -30,7 +30,7 @@ lpad: ; preds = %entry
; X64-NEXT: .long (.Llsda_end0-.Llsda_begin0)/16 # Number of call sites
; X64-NEXT: .Llsda_begin0:
; X64-NEXT: .long .Ltmp0 at IMGREL # LabelStart
-; X64-NEXT: .long .Ltmp1 at IMGREL+1 # LabelEnd
+; X64-NEXT: .long .Ltmp1 at IMGREL # LabelEnd
; X64-NEXT: .long "?dtor$2@?0?main at 4HA"@IMGREL # FinallyFunclet
; X64-NEXT: .long 0 # Null
; X64-NEXT: .Llsda_end0:
diff --git a/llvm/test/CodeGen/X86/seh-safe-div.ll b/llvm/test/CodeGen/X86/seh-safe-div.ll
index 542d9f67e6126..20169f868a0bf 100644
--- a/llvm/test/CodeGen/X86/seh-safe-div.ll
+++ b/llvm/test/CodeGen/X86/seh-safe-div.ll
@@ -60,6 +60,7 @@ __try.cont:
; CHECK: .Ltmp0:
; CHECK: leaq [[rloc:.*\(%rbp\)]], %rcx
; CHECK: callq try_body
+; CHECK: nop
; CHECK-NEXT: .Ltmp1
; CHECK: [[cont_bb:\.LBB0_[0-9]+]]:
; CHECK: movl [[rloc]], %eax
@@ -82,11 +83,11 @@ __try.cont:
; CHECK-NEXT: .long (.Llsda_end0-.Llsda_begin0)/16
; CHECK-NEXT: .Llsda_begin0:
; CHECK-NEXT: .long .Ltmp0 at IMGREL
-; CHECK-NEXT: .long .Ltmp1 at IMGREL+1
+; CHECK-NEXT: .long .Ltmp1 at IMGREL
; CHECK-NEXT: .long safe_div_filt0 at IMGREL
; CHECK-NEXT: .long [[handler0]]@IMGREL
; CHECK-NEXT: .long .Ltmp0 at IMGREL
-; CHECK-NEXT: .long .Ltmp1 at IMGREL+1
+; CHECK-NEXT: .long .Ltmp1 at IMGREL
; CHECK-NEXT: .long safe_div_filt1 at IMGREL
; CHECK-NEXT: .long [[handler1]]@IMGREL
; CHECK-NEXT: .Llsda_end0:
diff --git a/llvm/test/CodeGen/X86/seh-unwind-inline-asm-codegen.ll b/llvm/test/CodeGen/X86/seh-unwind-inline-asm-codegen.ll
index 2c576df1b7549..5a6aeb6020344 100644
--- a/llvm/test/CodeGen/X86/seh-unwind-inline-asm-codegen.ll
+++ b/llvm/test/CodeGen/X86/seh-unwind-inline-asm-codegen.ll
@@ -56,8 +56,8 @@ declare dso_local void @printf(ptr, ...)
; CHECK-NEXT:$ip2state$test:
; CHECK-NEXT: .long .Lfunc_begin0 at IMGREL # IP
; CHECK-NEXT: .long -1 # ToState
-; CHECK-NEXT: .long .Ltmp0 at IMGREL+1 # IP
+; CHECK-NEXT: .long .Ltmp0 at IMGREL # IP
; CHECK-NEXT: .long 0 # ToState
-; CHECK-NEXT: .long .Ltmp1 at IMGREL+1 # IP
+; CHECK-NEXT: .long .Ltmp1 at IMGREL # IP
; CHECK-NEXT: .long -1 # ToState
diff --git a/llvm/test/CodeGen/X86/stack-coloring-wineh.ll b/llvm/test/CodeGen/X86/stack-coloring-wineh.ll
index e2de2ff4a392e..635a61fb7966a 100644
--- a/llvm/test/CodeGen/X86/stack-coloring-wineh.ll
+++ b/llvm/test/CodeGen/X86/stack-coloring-wineh.ll
@@ -82,14 +82,14 @@ define void @pr66984(ptr %arg) personality ptr @__CxxFrameHandler3 {
; X86_64-NEXT: .seh_endprologue
; X86_64-NEXT: movq $-2, -16(%rbp)
; X86_64-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
-; X86_64-NEXT: .Ltmp0:
+; X86_64-NEXT: .Ltmp0: # EH_LABEL
; X86_64-NEXT: callq throw
-; X86_64-NEXT: .Ltmp1:
+; X86_64-NEXT: nop
+; X86_64-NEXT: .Ltmp1: # EH_LABEL
; X86_64-NEXT: # %bb.1: # %bb14
; X86_64-NEXT: .LBB0_3: # Block address taken
; X86_64-NEXT: # %exit
; X86_64-NEXT: $ehgcr_0_3:
-; X86_64-NEXT: nop
; X86_64-NEXT: .seh_startepilogue
; X86_64-NEXT: addq $64, %rsp
; X86_64-NEXT: popq %rbp
diff --git a/llvm/test/CodeGen/X86/win-catchpad-nested-cxx.ll b/llvm/test/CodeGen/X86/win-catchpad-nested-cxx.ll
index bfb9c43b3fd16..0bf8370fa24fa 100644
--- a/llvm/test/CodeGen/X86/win-catchpad-nested-cxx.ll
+++ b/llvm/test/CodeGen/X86/win-catchpad-nested-cxx.ll
@@ -103,15 +103,15 @@ handler2:
; X64: $ip2state$try_in_catch:
; X64-NEXT: .long .Lfunc_begin0 at IMGREL
; X64-NEXT: .long -1
-; X64-NEXT: .long .Ltmp0 at IMGREL+1
+; X64-NEXT: .long .Ltmp0 at IMGREL
; X64-NEXT: .long 0
-; X64-NEXT: .long .Ltmp1 at IMGREL+1
+; X64-NEXT: .long .Ltmp1 at IMGREL
; X64-NEXT: .long -1
; X64-NEXT: .long "?catch$2@?0?try_in_catch at 4HA"@IMGREL
; X64-NEXT: .long 1
-; X64-NEXT: .long .Ltmp2 at IMGREL+1
+; X64-NEXT: .long .Ltmp2 at IMGREL
; X64-NEXT: .long 2
-; X64-NEXT: .long .Ltmp3 at IMGREL+1
+; X64-NEXT: .long .Ltmp3 at IMGREL
; X64-NEXT: .long 1
; X64-NEXT: .long "?catch$4@?0?try_in_catch at 4HA"@IMGREL
; X64-NEXT: .long 3
diff --git a/llvm/test/CodeGen/X86/win-catchpad.ll b/llvm/test/CodeGen/X86/win-catchpad.ll
index 249194610e9f8..62ea5109f9df2 100644
--- a/llvm/test/CodeGen/X86/win-catchpad.ll
+++ b/llvm/test/CodeGen/X86/win-catchpad.ll
@@ -214,9 +214,9 @@ try.cont:
; X64: $ip2state$try_catch_catch:
; X64-NEXT: .long .Lfunc_begin0 at IMGREL
; X64-NEXT: .long -1
-; X64-NEXT: .long .Ltmp0 at IMGREL+1
+; X64-NEXT: .long .Ltmp0 at IMGREL
; X64-NEXT: .long 0
-; X64-NEXT: .long .Ltmp1 at IMGREL+1
+; X64-NEXT: .long .Ltmp1 at IMGREL
; X64-NEXT: .long -1
; X64-NEXT: .long "?catch$[[catch1bb]]@?0?try_catch_catch at 4HA"@IMGREL
; X64-NEXT: .long 1
@@ -357,9 +357,9 @@ try.cont:
; X64-LABEL: $ip2state$branch_to_normal_dest:
; X64-NEXT: .long .Lfunc_begin1 at IMGREL
; X64-NEXT: .long -1
-; X64-NEXT: .long .Ltmp[[before_call]]@IMGREL+1
+; X64-NEXT: .long .Ltmp[[before_call]]@IMGREL
; X64-NEXT: .long 0
-; X64-NEXT: .long .Ltmp[[after_call]]@IMGREL+1
+; X64-NEXT: .long .Ltmp[[after_call]]@IMGREL
; X64-NEXT: .long -1
; X64-NEXT: .long "?catch$[[catchbb]]@?0?branch_to_normal_dest at 4HA"@IMGREL
; X64-NEXT: .long 1
diff --git a/llvm/test/CodeGen/X86/win-cleanuppad.ll b/llvm/test/CodeGen/X86/win-cleanuppad.ll
index e3f7f5be0049e..e9265a1ed42e3 100644
--- a/llvm/test/CodeGen/X86/win-cleanuppad.ll
+++ b/llvm/test/CodeGen/X86/win-cleanuppad.ll
@@ -191,7 +191,7 @@ cleanup.outer: ; preds = %invoke.cont.1, %c
; X64-NEXT: .long 1
; X64-NEXT: .long .Ltmp6 at IMGREL
; X64-NEXT: .long 0
-; X64-NEXT: .long .Ltmp7 at IMGREL+1
+; X64-NEXT: .long .Ltmp7 at IMGREL
; X64-NEXT: .long -1
attributes #0 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="none" "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" }
diff --git a/llvm/test/CodeGen/X86/win-import-call-optimization.ll b/llvm/test/CodeGen/X86/win-import-call-optimization.ll
index cc7e1a9f81e34..ffcaa18edc7c6 100644
--- a/llvm/test/CodeGen/X86/win-import-call-optimization.ll
+++ b/llvm/test/CodeGen/X86/win-import-call-optimization.ll
@@ -22,7 +22,6 @@ entry:
; CHECK-NEXT: .Limpcall2:
; CHECK-NEXT: callq *%rax
; CHECK-NEXT: nopl (%rax)
-; CHECK-NEXT: nop
define dso_local void @tail_call() local_unnamed_addr section "tc_sect" {
entry:
diff --git a/llvm/test/CodeGen/X86/win-smallparams.ll b/llvm/test/CodeGen/X86/win-smallparams.ll
index ecbc7e907a024..40cd9c7b105ed 100644
--- a/llvm/test/CodeGen/X86/win-smallparams.ll
+++ b/llvm/test/CodeGen/X86/win-smallparams.ll
@@ -20,7 +20,6 @@ define void @call() {
; WIN64-NEXT: movb $3, %r8b
; WIN64-NEXT: movw $4, %r9w
; WIN64-NEXT: callq manyargs
-; WIN64-NEXT: nop
; WIN64-NEXT: .seh_startepilogue
; WIN64-NEXT: addq $56, %rsp
; WIN64-NEXT: .seh_endepilogue
diff --git a/llvm/test/CodeGen/X86/win32-eh-states.ll b/llvm/test/CodeGen/X86/win32-eh-states.ll
index 42ae5b060e6f4..e645199f84602 100644
--- a/llvm/test/CodeGen/X86/win32-eh-states.ll
+++ b/llvm/test/CodeGen/X86/win32-eh-states.ll
@@ -86,11 +86,11 @@ catch.7:
; X64-LABEL: $ip2state$f:
; X64-NEXT: .long .Lfunc_begin0 at IMGREL
; X64-NEXT: .long -1
-; X64-NEXT: .long .Ltmp{{.*}}@IMGREL+1
+; X64-NEXT: .long .Ltmp{{.*}}@IMGREL
; X64-NEXT: .long 0
-; X64-NEXT: .long .Ltmp{{.*}}@IMGREL+1
+; X64-NEXT: .long .Ltmp{{.*}}@IMGREL
; X64-NEXT: .long 1
-; X64-NEXT: .long .Ltmp{{.*}}@IMGREL+1
+; X64-NEXT: .long .Ltmp{{.*}}@IMGREL
; X64-NEXT: .long -1
; X64-NEXT: .long "?catch${{.*}}@?0?f at 4HA"@IMGREL
; X64-NEXT: .long 2
@@ -189,15 +189,15 @@ unreachable: ; preds = %entry
; X64-LABEL: $ip2state$g:
; X64-NEXT: .long .Lfunc_begin1 at IMGREL
; X64-NEXT: .long -1
-; X64-NEXT: .long .Ltmp{{.*}}@IMGREL+1
+; X64-NEXT: .long .Ltmp{{.*}}@IMGREL
; X64-NEXT: .long 1
-; X64-NEXT: .long .Ltmp{{.*}}@IMGREL+1
+; X64-NEXT: .long .Ltmp{{.*}}@IMGREL
; X64-NEXT: .long -1
; X64-NEXT: .long "?catch${{.*}}@?0?g at 4HA"@IMGREL
; X64-NEXT: .long 2
-; X64-NEXT: .long .Ltmp{{.*}}@IMGREL+1
+; X64-NEXT: .long .Ltmp{{.*}}@IMGREL
; X64-NEXT: .long 3
-; X64-NEXT: .long .Ltmp{{.*}}@IMGREL+1
+; X64-NEXT: .long .Ltmp{{.*}}@IMGREL
; X64-NEXT: .long 2
diff --git a/llvm/test/CodeGen/X86/win64-byval.ll b/llvm/test/CodeGen/X86/win64-byval.ll
index 573a0016e8772..72e11f6372340 100644
--- a/llvm/test/CodeGen/X86/win64-byval.ll
+++ b/llvm/test/CodeGen/X86/win64-byval.ll
@@ -19,7 +19,6 @@ define void @bar() {
; CHECK-NEXT: movq %rcx, {{[0-9]+}}(%rsp)
; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rcx
; CHECK-NEXT: callq foo
-; CHECK-NEXT: nop
; CHECK-NEXT: .seh_startepilogue
; CHECK-NEXT: addq $56, %rsp
; CHECK-NEXT: .seh_endepilogue
@@ -44,7 +43,6 @@ define void @baz(ptr byval({ float, double }) %arg) {
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rcx
; CHECK-NEXT: callq foo
-; CHECK-NEXT: nop
; CHECK-NEXT: .seh_startepilogue
; CHECK-NEXT: addq $56, %rsp
; CHECK-NEXT: .seh_endepilogue
@@ -84,7 +82,6 @@ define void @test() {
; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %r8
; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %r9
; CHECK-NEXT: callq foo2
-; CHECK-NEXT: nop
; CHECK-NEXT: .seh_startepilogue
; CHECK-NEXT: addq $136, %rsp
; CHECK-NEXT: .seh_endepilogue
diff --git a/llvm/test/CodeGen/X86/win64-seh-epilogue-statepoint.ll b/llvm/test/CodeGen/X86/win64-seh-epilogue-statepoint.ll
index bc5be7af6c7cf..eec029a0bd89e 100644
--- a/llvm/test/CodeGen/X86/win64-seh-epilogue-statepoint.ll
+++ b/llvm/test/CodeGen/X86/win64-seh-epilogue-statepoint.ll
@@ -9,7 +9,6 @@ define i32 @foobar() gc "statepoint-example" personality ptr @__gxx_personality_
; CHECK-NEXT: .seh_endprologue
; CHECK-NEXT: callq bar
; CHECK-NEXT: .Ltmp0:
-; CHECK-NEXT: nop
; CHECK-NEXT: .seh_startepilogue
; CHECK-NEXT: addq $40, %rsp
; CHECK-NEXT: .seh_endepilogue
diff --git a/llvm/test/CodeGen/X86/win64_call_epi.ll b/llvm/test/CodeGen/X86/win64_call_epi.ll
index 8b5e1f2d0157f..16f427a50b75d 100644
--- a/llvm/test/CodeGen/X86/win64_call_epi.ll
+++ b/llvm/test/CodeGen/X86/win64_call_epi.ll
@@ -31,7 +31,7 @@ catch:
; Check it still works when blocks are reordered.
@something = global i32 0
-define void @foo2(i1 zeroext %cond ) {
+define void @foo2(i1 zeroext %cond ) personality ptr @personality {
br i1 %cond, label %a, label %b, !prof !0
a:
call void @bar()
diff --git a/llvm/test/CodeGen/X86/win64_frame.ll b/llvm/test/CodeGen/X86/win64_frame.ll
index c4b36c5e263c8..6715b7b1894f4 100644
--- a/llvm/test/CodeGen/X86/win64_frame.ll
+++ b/llvm/test/CodeGen/X86/win64_frame.ll
@@ -101,7 +101,6 @@ define void @f5() "frame-pointer"="all" {
; CHECK-NEXT: .seh_endprologue
; CHECK-NEXT: leaq -92(%rbp), %rcx
; CHECK-NEXT: callq external
-; CHECK-NEXT: nop
; CHECK-NEXT: .seh_startepilogue
; CHECK-NEXT: addq $336, %rsp # imm = 0x150
; CHECK-NEXT: popq %rbp
@@ -125,7 +124,6 @@ define void @f6(i32 %p, ...) "frame-pointer"="all" {
; CHECK-NEXT: .seh_endprologue
; CHECK-NEXT: leaq -92(%rbp), %rcx
; CHECK-NEXT: callq external
-; CHECK-NEXT: nop
; CHECK-NEXT: .seh_startepilogue
; CHECK-NEXT: addq $336, %rsp # imm = 0x150
; CHECK-NEXT: popq %rbp
diff --git a/llvm/test/CodeGen/X86/wineh-coreclr.ll b/llvm/test/CodeGen/X86/wineh-coreclr.ll
index baf5eaa29d281..a3d0fde76c458 100644
--- a/llvm/test/CodeGen/X86/wineh-coreclr.ll
+++ b/llvm/test/CodeGen/X86/wineh-coreclr.ll
@@ -38,6 +38,7 @@ entry:
; CHECK: [[test1_before_f1:.+]]:
; CHECK-NEXT: movl $1, %ecx
; CHECK-NEXT: callq f
+; CHECK-NEXT: nop
; CHECK-NEXT: [[test1_after_f1:.+]]:
invoke void @f(i32 1)
to label %inner_try unwind label %finally
@@ -46,6 +47,7 @@ inner_try:
; CHECK: [[test1_before_f2:.+]]:
; CHECK-NEXT: movl $2, %ecx
; CHECK-NEXT: callq f
+; CHECK-NEXT: nop
; CHECK-NEXT: [[test1_after_f2:.+]]:
invoke void @f(i32 2)
to label %finally.clone unwind label %exn.dispatch
@@ -69,6 +71,7 @@ catch1:
; CHECK: [[test1_before_f3:.+]]:
; CHECK-NEXT: movl $3, %ecx
; CHECK-NEXT: callq f
+; CHECK-NEXT: nop
; CHECK-NEXT: [[test1_after_f3:.+]]:
invoke void @f(i32 3) [ "funclet"(token %catch.pad1) ]
to label %catch1.ret unwind label %finally
@@ -92,6 +95,7 @@ catch2:
; CHECK: [[test1_before_f4:.+]]:
; CHECK-NEXT: movl $4, %ecx
; CHECK-NEXT: callq f
+; CHECK-NEXT: nop
; CHECK-NEXT: [[test1_after_f4:.+]]:
invoke void @f(i32 4) [ "funclet"(token %catch.pad2) ]
to label %try_in_catch unwind label %finally
@@ -100,6 +104,7 @@ try_in_catch:
; CHECK: [[test1_before_f5:.+]]:
; CHECK-NEXT: movl $5, %ecx
; CHECK-NEXT: callq f
+; CHECK-NEXT: nop
; CHECK-NEXT: [[test1_after_f5:.+]]:
invoke void @f(i32 5) [ "funclet"(token %catch.pad2) ]
to label %catch2.ret unwind label %fault
@@ -116,6 +121,7 @@ fault:
; CHECK: [[test1_before_f6:.+]]:
; CHECK-NEXT: movl $6, %ecx
; CHECK-NEXT: callq f
+; CHECK-NEXT: nop
; CHECK-NEXT: [[test1_after_f6:.+]]:
invoke void @f(i32 6) [ "funclet"(token %fault.pad) ]
to label %fault.ret unwind label %finally
@@ -312,6 +318,7 @@ unreachable:
; CHECK: [[test2_before_f1:.+]]:
; CHECK-NEXT: movl $1, %ecx
; CHECK-NEXT: callq f
+; CHECK-NEXT: nop
; CHECK-NEXT: [[test2_after_f1:.+]]:
; CHECK: .seh_proc [[test2_catch1:[^ ]+]]
; CHECK: .seh_proc [[test2_catch2:[^ ]+]]
@@ -320,6 +327,7 @@ unreachable:
; CHECK: [[test2_before_f2:.+]]:
; CHECK-NEXT: movl $2, %ecx
; CHECK-NEXT: callq f
+; CHECK-NEXT: nop
; CHECK-NEXT: [[test2_after_f2:.+]]:
; CHECK: int3
; CHECK: [[test2_end:.*func_end.*]]:
@@ -448,6 +456,7 @@ entry:
; CHECK: [[test3_before_f1:.+]]:
; CHECK-NEXT: movl $1, %ecx
; CHECK-NEXT: callq f
+; CHECK-NEXT: nop
; CHECK-NEXT: [[test3_after_f1:.+]]:
invoke void @f(i32 1)
to label %exit unwind label %fault1
@@ -474,6 +483,7 @@ fault4:
; CHECK: [[test3_before_f6:.+]]:
; CHECK-NEXT: movl $6, %ecx
; CHECK-NEXT: callq f
+; CHECK-NEXT: nop
; CHECK-NEXT: [[test3_after_f6:.+]]:
invoke void @f(i32 6) ["funclet"(token %fault.pad4)]
to label %fault4.cont unwind label %exn.dispatch1
@@ -482,6 +492,7 @@ fault4.cont:
; CHECK: [[test3_before_f7:.+]]:
; CHECK-NEXT: movl $7, %ecx
; CHECK-NEXT: callq f
+; CHECK-NEXT: nop
; CHECK-NEXT: [[test3_after_f7:.+]]:
invoke void @f(i32 7) ["funclet"(token %fault.pad4)]
to label %unreachable unwind label %fault5
@@ -512,6 +523,7 @@ unreachable:
; CHECK: [[test3_before_f4:.+]]:
; CHECK-NEXT: movl $4, %ecx
; CHECK-NEXT: callq f
+; CHECK-NEXT: nop
; CHECK-NEXT: [[test3_after_f4:.+]]:
; CHECK: int3
; CHECK: .seh_proc [[test3_fault2:[^ ]+]]
@@ -520,6 +532,7 @@ unreachable:
; CHECK: [[test3_before_f3:.+]]:
; CHECK-NEXT: movl $3, %ecx
; CHECK-NEXT: callq f
+; CHECK-NEXT: nop
; CHECK-NEXT: [[test3_after_f3:.+]]:
; CHECK: int3
; CHECK: .seh_proc [[test3_fault1:[^ ]+]]
@@ -528,6 +541,7 @@ unreachable:
; CHECK: [[test3_before_f2:.+]]:
; CHECK-NEXT: movl $2, %ecx
; CHECK-NEXT: callq f
+; CHECK-NEXT: nop
; CHECK-NEXT: [[test3_after_f2:.+]]:
; CHECK: int3
; CHECK: [[test3_end:.*func_end.*]]:
diff --git a/llvm/test/CodeGen/X86/wineh-no-ehpads.ll b/llvm/test/CodeGen/X86/wineh-no-ehpads.ll
index bc85031555865..bacb01cc3dc4a 100644
--- a/llvm/test/CodeGen/X86/wineh-no-ehpads.ll
+++ b/llvm/test/CodeGen/X86/wineh-no-ehpads.ll
@@ -13,7 +13,6 @@ define void @personality_no_ehpad() personality ptr @__CxxFrameHandler3 {
; CHECK-LABEL: personality_no_ehpad: # @personality_no_ehpad
; CHECK-NOT: movq $-2,
; CHECK: callq g
-; CHECK: nop
; CHECK: retq
; Shouldn't have any LSDA either.
diff --git a/llvm/test/CodeGen/XCore/exception.ll b/llvm/test/CodeGen/XCore/exception.ll
index f222297f452cd..bb5f3f44abc9e 100644
--- a/llvm/test/CodeGen/XCore/exception.ll
+++ b/llvm/test/CodeGen/XCore/exception.ll
@@ -60,7 +60,7 @@ entry:
; CHECK: [[PRE_G:.L[a-zA-Z0-9_]+]]
; CHECK: bl g
; CHECK: [[POST_G:.L[a-zA-Z0-9_]+]]
-; CHECK: [[RETURN:.L[a-zA-Z0-9_]+]]
+; CHECK: [[RETURN:^.L[a-zA-Z0-9_]+]]
; CHECK: ldw r6, sp[1]
; CHECK: ldw r5, sp[2]
; CHECK: ldw r4, sp[3]
diff --git a/llvm/test/DebugInfo/COFF/local-variables.ll b/llvm/test/DebugInfo/COFF/local-variables.ll
index 820f6bd8beaa4..40ab659983760 100644
--- a/llvm/test/DebugInfo/COFF/local-variables.ll
+++ b/llvm/test/DebugInfo/COFF/local-variables.ll
@@ -64,7 +64,6 @@
; ASM: .LBB0_3: # %if.end
; ASM: .cv_loc 0 1 17 1 # t.cpp:17:1
; ASM: callq capture
-; ASM: nop
; ASM: addq $56, %rsp
; ASM: retq
; ASM: [[param_end:\.Ltmp.*]]:
@@ -117,7 +116,7 @@
; OBJ: LocalVariableAddrRange {
; OBJ: OffsetStart: .text+0x8
; OBJ: ISectStart: 0x0
-; OBJ: Range: 0x4F
+; OBJ: Range: 0x4E
; OBJ: }
; OBJ: }
; OBJ: LocalSym {
diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/mips64_eh.ll.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/mips64_eh.ll.expected
index 897209a566149..56058bbc4c402 100644
--- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/mips64_eh.ll.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/mips64_eh.ll.expected
@@ -8,17 +8,17 @@ define i32 @main() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill
; CHECK-NEXT: .cfi_offset 31, -8
-; CHECK-NEXT: .Ltmp0:
+; CHECK-NEXT: .Ltmp0: # EH_LABEL
; CHECK-NEXT: jal foo
; CHECK-NEXT: nop
-; CHECK-NEXT: .Ltmp1:
+; CHECK-NEXT: .Ltmp1: # EH_LABEL
; CHECK-NEXT: # %bb.1: # %good
; CHECK-NEXT: addiu $2, $zero, 5
; CHECK-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload
; CHECK-NEXT: jr $ra
; CHECK-NEXT: daddiu $sp, $sp, 16
; CHECK-NEXT: .LBB0_2: # %bad
-; CHECK-NEXT: .Ltmp2:
+; CHECK-NEXT: .Ltmp2: # EH_LABEL
; CHECK-NEXT: jal _Unwind_Resume
; CHECK-NEXT: nop
%1 = invoke i32 @foo() to label %good unwind label %bad
More information about the llvm-commits
mailing list