1; RUN: llc < %s -mtriple=x86_64-pc-mingw32 | FileCheck %s -check-prefix=WIN64
2
3declare void @bar()
4declare void @baz()
5declare i32 @personality(...)
6
7; Check for 'nop' between the last call and the epilogue.
8define void @foo1() {
9
10    invoke void @bar()
11        to label %normal
12        unwind label %catch
13
14normal:
15    ret void
16
17catch:
18    %1 = landingpad { i8*, i32 } personality i32 (...)* @personality cleanup
19    resume { i8*, i32 } %1
20}
21; WIN64-LABEL: foo1:
22; WIN64: .seh_proc foo1
23; WIN64: callq bar
24; WIN64: nop
25; WIN64: addq ${{[0-9]+}}, %rsp
26; WIN64: retq
27; Check for 'ud2' after noreturn call
28; WIN64: callq _Unwind_Resume
29; WIN64-NEXT: ud2
30; WIN64: .seh_endproc
31
32
33; Check it still works when blocks are reordered.
34@something = global i32 0
35define void @foo2(i1 zeroext %cond ) {
36    br i1 %cond, label %a, label %b, !prof !0
37a:
38    call void @bar()
39    br label %done
40b:
41    call void @baz()
42    store i32 0, i32* @something
43    br label %done
44done:
45    ret void
46}
47!0 = !{!"branch_weights", i32 100, i32 0}
48; WIN64-LABEL: foo2:
49; WIN64: callq bar
50; WIN64: nop
51; WIN64: addq ${{[0-9]+}}, %rsp
52; WIN64: retq
53
54
55; Check nop is not emitted when call is not adjacent to epilogue.
56define i32 @foo3() {
57    call void @bar()
58    ret i32 0
59}
60; WIN64-LABEL: foo3:
61; WIN64: callq bar
62; WIN64: xorl
63; WIN64-NOT: nop
64; WIN64: addq ${{[0-9]+}}, %rsp
65; WIN64: retq
66