llvm-project/llvm/test/CodeGen/X86/win-catchpad-csrs.ll
Daniel Paoliello b3458fdec5
[llvm] Win x64 Unwind V2 1/n: Mark beginning and end of epilogs (#110024)
Windows x64 Unwind V2 adds epilog information to unwind data:
specifically, the length of the epilog and the offset of each epilog.

The first step to do this is to add markers to the beginning and end of
each epilog when generating Windows x64 code. I've modelled this after
how LLVM was marking ARM and AArch64 epilogs in Windows (and unified the
code between the three).
2025-01-30 13:51:30 -08:00

281 lines
6.9 KiB
LLVM

; RUN: llc -verify-machineinstrs -mtriple=i686-pc-windows-msvc < %s | FileCheck --check-prefix=X86 %s
; RUN: llc -verify-machineinstrs -mtriple=x86_64-pc-windows-msvc < %s | FileCheck --check-prefix=X64 %s
%rtti.TypeDescriptor2 = type { ptr, ptr, [3 x i8] }
%eh.CatchableType = type { i32, ptr, i32, i32, i32, i32, ptr }
%eh.CatchableTypeArray.1 = type { i32, [1 x ptr] }
%eh.ThrowInfo = type { i32, ptr, ptr, ptr }
$"\01??_R0H@8" = comdat any
@"\01??_7type_info@@6B@" = external constant ptr
@"\01??_R0H@8" = linkonce_odr global %rtti.TypeDescriptor2 { ptr @"\01??_7type_info@@6B@", ptr null, [3 x i8] c".H\00" }, comdat
declare i32 @getint()
declare void @useints(...)
declare void @f(i32 %p)
declare i32 @__CxxFrameHandler3(...)
define i32 @try_catch_catch() personality ptr @__CxxFrameHandler3 {
entry:
%a = call i32 @getint()
%b = call i32 @getint()
%c = call i32 @getint()
%d = call i32 @getint()
call void (...) @useints(i32 %a, i32 %b, i32 %c, i32 %d)
invoke void @f(i32 1)
to label %try.cont unwind label %catch.dispatch
try.cont:
ret i32 0
catch.dispatch:
%cs = catchswitch within none [label %handler1] unwind to caller
handler1:
%h1 = catchpad within %cs [ptr @"\01??_R0H@8", i32 0, ptr null]
call void @f(i32 2) [ "funclet"(token %h1) ]
catchret from %h1 to label %try.cont
}
; X86-LABEL: _try_catch_catch:
; X86: pushl %ebp
; X86: movl %esp, %ebp
; X86: pushl %ebx
; X86: pushl %edi
; X86: pushl %esi
; X86: subl ${{[0-9]+}}, %esp
; X86: calll _getint
; X86: calll _getint
; X86: calll _getint
; X86: calll _getint
; X86: calll _useints
; X86: movl $0, -{{[0-9]+}}(%ebp)
; X86: pushl $1
; X86: calll _f
; X86: [[contbb:LBB0_[0-9]+]]: # %try.cont
; X86: popl %esi
; X86: popl %edi
; X86: popl %ebx
; X86: popl %ebp
; X86: retl
; X86: [[restorebb:LBB0_[0-9]+]]:
; X86: addl $12, %ebp
; X86: jmp [[contbb]]
; X86: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch@4HA":
; X86: LBB0_[[catch1bb]]: # %handler1{{$}}
; X86: pushl %ebp
; X86-NOT: pushl
; X86: subl $16, %esp
; X86: addl $12, %ebp
; X86: movl $1, -{{[0-9]+}}(%ebp)
; X86: pushl $2
; X86: calll _f
; X86: movl $[[restorebb]], %eax
; X86-NEXT: addl $16, %esp
; X86-NEXT: popl %ebp
; X86-NEXT: retl
; X86: L__ehtable$try_catch_catch:
; X86: $handlerMap$0$try_catch_catch:
; X86: .long 0
; X86: .long "??_R0H@8"
; X86: .long 0
; X86: .long "?catch$[[catch1bb]]@?0?try_catch_catch@4HA"
; X64-LABEL: try_catch_catch:
; X64: pushq %rbp
; X64: .seh_pushreg %rbp
; X64: pushq %rsi
; X64: .seh_pushreg %rsi
; X64: pushq %rdi
; X64: .seh_pushreg %rdi
; X64: pushq %rbx
; X64: .seh_pushreg %rbx
; X64: subq $40, %rsp
; X64: .seh_stackalloc 40
; X64: leaq 32(%rsp), %rbp
; X64: .seh_setframe %rbp, 32
; X64: .seh_endprologue
; X64: movq $-2, (%rbp)
; X64: callq getint
; X64: callq getint
; X64: callq getint
; X64: callq getint
; X64: callq useints
; X64: movl $1, %ecx
; X64: callq f
; X64: [[contbb:\.LBB0_[0-9]+]]: # Block address taken
; X64-NEXT: # %try.cont
; X64: .seh_startepilogue
; X64: addq $40, %rsp
; X64: popq %rbp
; X64: .seh_endepilogue
; X64: retq
; X64: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch@4HA":
; X64: LBB0_[[catch1bb]]: # %handler1{{$}}
; X64: movq %rdx, 16(%rsp)
; X64: pushq %rbp
; X64: .seh_pushreg %rbp
; X64: pushq %rsi
; X64: .seh_pushreg %rsi
; X64: pushq %rdi
; X64: .seh_pushreg %rdi
; X64: pushq %rbx
; X64: .seh_pushreg %rbx
; X64: subq $40, %rsp
; X64: .seh_stackalloc 40
; X64: leaq 32(%rdx), %rbp
; X64: .seh_endprologue
; X64: movl $2, %ecx
; X64: callq f
; X64: leaq [[contbb]](%rip), %rax
; X64: .seh_startepilogue
; X64: addq $40, %rsp
; X64: popq %rbx
; X64: popq %rdi
; X64: popq %rsi
; X64: popq %rbp
; X64: .seh_endepilogue
; X64: retq
; X64: $handlerMap$0$try_catch_catch:
; X64: .long 0
; X64: .long "??_R0H@8"@IMGREL
; X64: .long 0
; X64: .long "?catch$[[catch1bb]]@?0?try_catch_catch@4HA"@IMGREL
; X64: .long 88
define i32 @try_one_csr() personality ptr @__CxxFrameHandler3 {
entry:
%a = call i32 @getint()
%b = call i32 @getint()
call void (...) @useints(i32 %a)
invoke void @f(i32 1)
to label %try.cont unwind label %catch.dispatch
catch.dispatch:
%cs = catchswitch within none [label %handler1] unwind to caller
handler1:
%0 = catchpad within %cs [ptr @"\01??_R0H@8", i32 0, ptr null]
catchret from %0 to label %try.cont
try.cont:
ret i32 0
}
; X64-LABEL: try_one_csr:
; X64: pushq %rbp
; X64: .seh_pushreg %rbp
; X64: pushq %rsi
; X64: .seh_pushreg %rsi
; X64-NOT: pushq
; X64: subq $40, %rsp
; X64: .seh_stackalloc 40
; X64: leaq 32(%rsp), %rbp
; X64: .seh_setframe %rbp, 32
; X64: .seh_endprologue
; X64: callq getint
; X64: callq getint
; X64: callq useints
; X64: movl $1, %ecx
; X64: callq f
; X64: [[contbb:\.LBB1_[0-9]+]]: # Block address taken
; X64-NEXT: # %try.cont
; X64: .seh_startepilogue
; X64: addq $40, %rsp
; X64-NOT: popq
; X64: popq %rsi
; X64: popq %rbp
; X64: .seh_endepilogue
; X64: retq
; X64: "?catch$[[catch1bb:[0-9]+]]@?0?try_one_csr@4HA":
; X64: LBB1_[[catch1bb]]: # %handler1{{$}}
; X64: movq %rdx, 16(%rsp)
; X64: pushq %rbp
; X64: .seh_pushreg %rbp
; X64: pushq %rsi
; X64: .seh_pushreg %rsi
; X64: subq $40, %rsp
; X64: .seh_stackalloc 40
; X64: leaq 32(%rdx), %rbp
; X64: .seh_endprologue
; X64: leaq [[contbb]](%rip), %rax
; X64: .seh_startepilogue
; X64: addq $40, %rsp
; X64: popq %rsi
; X64: popq %rbp
; X64: .seh_endepilogue
; X64: retq
; X64: $handlerMap$0$try_one_csr:
; X64: .long 0
; X64: .long "??_R0H@8"@IMGREL
; X64: .long 0
; X64: .long "?catch$[[catch1bb]]@?0?try_one_csr@4HA"@IMGREL
; X64: .long 72
define i32 @try_no_csr() personality ptr @__CxxFrameHandler3 {
entry:
invoke void @f(i32 1)
to label %try.cont unwind label %catch.dispatch
catch.dispatch:
%cs = catchswitch within none [label %handler1] unwind to caller
handler1:
%cp1 = catchpad within %cs [ptr @"\01??_R0H@8", i32 0, ptr null]
catchret from %cp1 to label %try.cont
try.cont:
ret i32 0
}
; X64-LABEL: try_no_csr:
; X64: pushq %rbp
; X64: .seh_pushreg %rbp
; X64-NOT: pushq
; X64: subq $48, %rsp
; X64: .seh_stackalloc 48
; X64: leaq 48(%rsp), %rbp
; X64: .seh_setframe %rbp, 48
; X64: .seh_endprologue
; X64: movl $1, %ecx
; X64: callq f
; X64: [[contbb:\.LBB2_[0-9]+]]: # Block address taken
; X64-NEXT: # %try.cont
; X64: .seh_startepilogue
; X64: addq $48, %rsp
; X64-NOT: popq
; X64: popq %rbp
; X64: .seh_endepilogue
; X64: retq
; X64: "?catch$[[catch1bb:[0-9]+]]@?0?try_no_csr@4HA":
; X64: LBB2_[[catch1bb]]: # %handler1{{$}}
; X64: movq %rdx, 16(%rsp)
; X64: pushq %rbp
; X64: .seh_pushreg %rbp
; X64: subq $32, %rsp
; X64: .seh_stackalloc 32
; X64: leaq 48(%rdx), %rbp
; X64: .seh_endprologue
; X64: leaq [[contbb]](%rip), %rax
; X64: .seh_startepilogue
; X64: addq $32, %rsp
; X64: popq %rbp
; X64: .seh_endepilogue
; X64: retq
; X64: $handlerMap$0$try_no_csr:
; X64: .long 0
; X64: .long "??_R0H@8"@IMGREL
; X64: .long 0
; X64: .long "?catch$[[catch1bb]]@?0?try_no_csr@4HA"@IMGREL
; X64: .long 56