1 ; RUN: llc -mtriple=i686-pc-windows-msvc -stack-symbol-ordering=0 < %s | FileCheck --check-prefix=X86 %s
2 ; RUN: llc -mtriple=x86_64-pc-windows-msvc -stack-symbol-ordering=0 < %s | FileCheck --check-prefix=X64 %s
4 declare i32 @__CxxFrameHandler3(...)
5 declare void @Dtor(i64* %o)
8 define void @realigned_cleanup() personality i32 (...)* @__CxxFrameHandler3 {
10 ; Overalign %o to cause stack realignment.
11 %o = alloca i64, align 32
13 to label %invoke.cont unwind label %ehcleanup
15 invoke.cont: ; preds = %entry
16 call void @Dtor(i64* %o)
19 ehcleanup: ; preds = %entry
20 %0 = cleanuppad within none []
21 call void @Dtor(i64* %o) [ "funclet"(token %0) ]
22 cleanupret from %0 unwind to caller
25 ; X86-LABEL: _realigned_cleanup: # @realigned_cleanup
27 ; X86: movl %esp, %ebp
31 ; X86: andl $-32, %esp
33 ; X86: movl %esp, %esi
34 ; EBP will reload from this offset.
35 ; X86: movl %ebp, 28(%esi)
36 ; The last EH reg field is the state number, so dtor adjust is this +4.
37 ; X86: movl $-1, 72(%esi)
39 ; X86-LABEL: "?dtor$2@?0?realigned_cleanup@4HA":
41 ; X86: leal -76(%ebp), %esi
42 ; X86: movl 28(%esi), %ebp
43 ; We used to have a bug where we clobbered ESI after the prologue.
44 ; X86-NOT: movl {{.*}}, %esi
46 ; X86: retl # CLEANUPRET
48 ; X64-LABEL: realigned_cleanup: # @realigned_cleanup
50 ; X64: .seh_pushreg %rbp
52 ; X64: .seh_pushreg %rbx
53 ; X64: subq $104, %rsp
54 ; X64: .seh_stackalloc 104
55 ; X64: leaq 96(%rsp), %rbp
56 ; X64: .seh_setframe %rbp, 96
57 ; X64: .seh_endprologue
58 ; X64: andq $-32, %rsp
59 ; X64: movq %rsp, %rbx
60 ; RBP will reload from this offset.
61 ; X64: movq %rbp, 56(%rbx)
62 ; X64: movq $-2, (%rbp)
64 ; X64-LABEL: "?dtor$2@?0?realigned_cleanup@4HA":
65 ; X64: movq %rdx, 16(%rsp)
67 ; X64: .seh_pushreg %rbp
69 ; X64: .seh_pushreg %rbx
71 ; X64: .seh_stackalloc 40
72 ; X64: leaq 96(%rdx), %rbp
73 ; X64: .seh_endprologue
74 ; X64: andq $-32, %rdx
75 ; X64: movq %rdx, %rbx
76 ; X64-NOT: mov{{.*}}, %rbx
78 ; X64: retq # CLEANUPRET