diff options
| author | Reid Kleckner <rnk@google.com> | 2015-11-05 21:09:49 +0000 |
|---|---|---|
| committer | Reid Kleckner <rnk@google.com> | 2015-11-05 21:09:49 +0000 |
| commit | 6ddae31045615b4f4e7005427d013e525b73bbd3 (patch) | |
| tree | b35d4146ff258ef80cc66b23a0f035679516fd9f /llvm/test/CodeGen | |
| parent | 484e48e3a3107c8b9827824fc40d5e644e79bf97 (diff) | |
| download | bcm5719-llvm-6ddae31045615b4f4e7005427d013e525b73bbd3.tar.gz bcm5719-llvm-6ddae31045615b4f4e7005427d013e525b73bbd3.zip | |
[WinEH] Fix funclet prologues with stack realignment
We already had a test for this for 32-bit SEH catchpads, but those don't
actually create funclets. We had a bug that only appeared in funclet
prologues, where we would establish EBP and ESI as our FP and BP, and
then downstream prologue code would overwrite them.
While I was at it, I fixed Win64+funclets+stackrealign. This issue
doesn't come up as often there due to the ABI requring 16 byte stack
alignment, but now we can rest easy that AVX and WinEH will work well
together =P.
llvm-svn: 252210
Diffstat (limited to 'llvm/test/CodeGen')
| -rw-r--r-- | llvm/test/CodeGen/X86/cleanuppad-realign.ll | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/X86/cleanuppad-realign.ll b/llvm/test/CodeGen/X86/cleanuppad-realign.ll new file mode 100644 index 00000000000..c80077e80c6 --- /dev/null +++ b/llvm/test/CodeGen/X86/cleanuppad-realign.ll @@ -0,0 +1,77 @@ +; RUN: llc -mtriple=i686-pc-windows-msvc < %s | FileCheck --check-prefix=X86 %s +; RUN: llc -mtriple=x86_64-pc-windows-msvc < %s | FileCheck --check-prefix=X64 %s + +declare i32 @__CxxFrameHandler3(...) +declare void @Dtor(i64* %o) +declare void @f(i32) + +define void @realigned_cleanup() personality i32 (...)* @__CxxFrameHandler3 { +entry: + ; Overalign %o to cause stack realignment. + %o = alloca i64, align 32 + invoke void @f(i32 1) + to label %invoke.cont unwind label %ehcleanup + +invoke.cont: ; preds = %entry + call void @Dtor(i64* %o) + ret void + +ehcleanup: ; preds = %entry + %0 = cleanuppad [] + call void @Dtor(i64* %o) + cleanupret %0 unwind to caller +} + +; X86-LABEL: _realigned_cleanup: # @realigned_cleanup +; X86: pushl %ebp +; X86: movl %esp, %ebp +; X86: pushl %ebx +; X86: pushl %edi +; X86: pushl %esi +; X86: andl $-32, %esp +; X86: subl $96, %esp +; X86: movl %esp, %esi +; EBP will reload from this offset. +; X86: movl %ebp, 28(%esi) +; The last EH reg field is the state number, so dtor adjust is this +4. +; X86: movl $-1, 72(%esi) + +; X86-LABEL: "?dtor$2@?0?realigned_cleanup@4HA": +; X86: pushl %ebp +; X86: leal -76(%ebp), %esi +; X86: movl 28(%esi), %ebp +; We used to have a bug where we clobbered ESI after the prologue. +; X86-NOT: movl {{.*}}, %esi +; X86: popl %ebp +; X86: retl # CLEANUPRET + +; X64-LABEL: realigned_cleanup: # @realigned_cleanup +; X64: pushq %rbp +; X64: .seh_pushreg 5 +; X64: pushq %rbx +; X64: .seh_pushreg 3 +; X64: subq $72, %rsp +; X64: .seh_stackalloc 72 +; X64: leaq 64(%rsp), %rbp +; X64: .seh_setframe 5, 64 +; X64: .seh_endprologue +; X64: andq $-32, %rsp +; X64: movq %rsp, %rbx +; RBP will reload from this offset. +; X64: movq %rbp, 48(%rbx) + +; X64-LABEL: "?dtor$2@?0?realigned_cleanup@4HA": +; X64: movq %rdx, 16(%rsp) +; X64: pushq %rbp +; X64: .seh_pushreg 5 +; X64: pushq %rbx +; X64: .seh_pushreg 3 +; X64: subq $40, %rsp +; X64: .seh_stackalloc 40 +; X64: leaq 64(%rdx), %rbp +; X64: .seh_endprologue +; X64: andq $-32, %rdx +; X64: movq %rdx, %rbx +; X64-NOT: mov{{.*}}, %rbx +; X64: popq %rbp +; X64: retq # CLEANUPRET |

