summaryrefslogtreecommitdiffstats
path: root/llvm/test/CodeGen
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2015-11-05 21:09:49 +0000
committerReid Kleckner <rnk@google.com>2015-11-05 21:09:49 +0000
commit6ddae31045615b4f4e7005427d013e525b73bbd3 (patch)
treeb35d4146ff258ef80cc66b23a0f035679516fd9f /llvm/test/CodeGen
parent484e48e3a3107c8b9827824fc40d5e644e79bf97 (diff)
downloadbcm5719-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.ll77
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
OpenPOWER on IntegriCloud