Choosing a "cfi" name makes the intend a bit clearer in an assembly dump and more importantly the assembly dumps are slightly more stable as the numbers don't move around anymore when unrelated code calls createTempSymbol() more or less often. As they are temp labels the name doesn't influence the generated object code. Differential Revision: https://reviews.llvm.org/D27244 llvm-svn: 288290
200 lines
6.7 KiB
LLVM
200 lines
6.7 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
|
|
|
|
%struct.Dtor = type { i8 }
|
|
|
|
define void @simple_cleanup() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
|
|
entry:
|
|
%o = alloca %struct.Dtor, align 1
|
|
invoke void @f(i32 1)
|
|
to label %invoke.cont unwind label %ehcleanup
|
|
|
|
invoke.cont: ; preds = %entry
|
|
call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o) #2
|
|
ret void
|
|
|
|
ehcleanup: ; preds = %entry
|
|
%0 = cleanuppad within none []
|
|
call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o) #2 [ "funclet"(token %0) ]
|
|
cleanupret from %0 unwind to caller
|
|
}
|
|
|
|
; CHECK: simple_cleanup: # @simple_cleanup
|
|
; CHECK: pushq %rbp
|
|
; CHECK: subq $48, %rsp
|
|
; CHECK: leaq 48(%rsp), %rbp
|
|
; CHECK: movq $-2, -8(%rbp)
|
|
; CHECK: movl $1, %ecx
|
|
; CHECK: callq f
|
|
; CHECK: callq "??1Dtor@@QAE@XZ"
|
|
; CHECK: nop
|
|
; CHECK: addq $48, %rsp
|
|
; CHECK: popq %rbp
|
|
; CHECK: retq
|
|
|
|
; CHECK: "?dtor$2@?0?simple_cleanup@4HA":
|
|
; CHECK: callq "??1Dtor@@QAE@XZ"
|
|
; CHECK: retq
|
|
|
|
; CHECK: $cppxdata$simple_cleanup:
|
|
; CHECK-NEXT: .long 429065506
|
|
; CHECK-NEXT: .long 1
|
|
; CHECK-NEXT: .long ($stateUnwindMap$simple_cleanup)@IMGREL
|
|
; CHECK-NEXT: .long 0
|
|
; CHECK-NEXT: .long 0
|
|
; CHECK-NEXT: .long 3
|
|
; CHECK-NEXT: .long ($ip2state$simple_cleanup)@IMGREL
|
|
; UnwindHelp offset should match the -2 store above
|
|
; CHECK-NEXT: .long 40
|
|
; CHECK-NEXT: .long 0
|
|
; CHECK-NEXT: .long 1
|
|
|
|
declare void @f(i32) #0
|
|
|
|
declare i32 @__CxxFrameHandler3(...)
|
|
|
|
; Function Attrs: nounwind
|
|
declare x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor*) #1
|
|
|
|
define void @nested_cleanup() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
|
|
entry:
|
|
%o1 = alloca %struct.Dtor, align 1
|
|
%o2 = alloca %struct.Dtor, align 1
|
|
invoke void @f(i32 1)
|
|
to label %invoke.cont unwind label %cleanup.outer
|
|
|
|
invoke.cont: ; preds = %entry
|
|
invoke void @f(i32 2)
|
|
to label %invoke.cont.1 unwind label %cleanup.inner
|
|
|
|
invoke.cont.1: ; preds = %invoke.cont
|
|
call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o2) #2
|
|
invoke void @f(i32 3)
|
|
to label %invoke.cont.2 unwind label %cleanup.outer
|
|
|
|
invoke.cont.2: ; preds = %invoke.cont.1
|
|
call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o1) #2
|
|
ret void
|
|
|
|
cleanup.inner: ; preds = %invoke.cont
|
|
%0 = cleanuppad within none []
|
|
call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o2) #2 [ "funclet"(token %0) ]
|
|
cleanupret from %0 unwind label %cleanup.outer
|
|
|
|
cleanup.outer: ; preds = %invoke.cont.1, %cleanup.inner, %entry
|
|
%1 = cleanuppad within none []
|
|
call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o1) #2 [ "funclet"(token %1) ]
|
|
cleanupret from %1 unwind to caller
|
|
}
|
|
|
|
; X86-LABEL: _nested_cleanup:
|
|
; X86: pushl $1
|
|
; X86: calll _f
|
|
; X86: pushl $2
|
|
; X86: calll _f
|
|
; X86: pushl $3
|
|
; X86: calll _f
|
|
|
|
; X86: "?dtor$[[cleanup_inner:[0-9]+]]@?0?nested_cleanup@4HA":
|
|
; X86: LBB1_[[cleanup_inner]]: # %cleanup.inner{{$}}
|
|
; X86: pushl %ebp
|
|
; X86: leal {{.*}}(%ebp), %ecx
|
|
; X86: calll "??1Dtor@@QAE@XZ"
|
|
; X86: popl %ebp
|
|
; X86: retl
|
|
|
|
; X86: "?dtor$[[cleanup_outer:[0-9]+]]@?0?nested_cleanup@4HA":
|
|
; X86: LBB1_[[cleanup_outer]]: # %cleanup.outer{{$}}
|
|
; X86: pushl %ebp
|
|
; X86: leal {{.*}}(%ebp), %ecx
|
|
; X86: calll "??1Dtor@@QAE@XZ"
|
|
; X86: popl %ebp
|
|
; X86: retl
|
|
|
|
; X86: L__ehtable$nested_cleanup:
|
|
; X86: .long 429065506
|
|
; X86: .long 2
|
|
; X86: .long ($stateUnwindMap$nested_cleanup)
|
|
; X86: .long 0
|
|
; X86: .long 0
|
|
; X86: .long 0
|
|
; X86: .long 0
|
|
; X86: .long 0
|
|
; X86: .long 1
|
|
; X86: $stateUnwindMap$nested_cleanup:
|
|
; X86: .long -1
|
|
; X86: .long "?dtor$[[cleanup_outer]]@?0?nested_cleanup@4HA"
|
|
; X86: .long 0
|
|
; X86: .long "?dtor$[[cleanup_inner]]@?0?nested_cleanup@4HA"
|
|
|
|
; X64-LABEL: nested_cleanup:
|
|
; X64: .Lfunc_begin1:
|
|
; X64: .Ltmp2:
|
|
; X64: movl $1, %ecx
|
|
; X64: callq f
|
|
; X64: .Ltmp4:
|
|
; X64: movl $2, %ecx
|
|
; X64: callq f
|
|
; X64: .Ltmp5:
|
|
; X64: callq "??1Dtor@@QAE@XZ"
|
|
; X64: .Ltmp6:
|
|
; X64: movl $3, %ecx
|
|
; X64: callq f
|
|
; X64: .Ltmp7:
|
|
|
|
; X64: "?dtor$[[cleanup_inner:[0-9]+]]@?0?nested_cleanup@4HA":
|
|
; X64: LBB1_[[cleanup_inner]]: # %cleanup.inner{{$}}
|
|
; X64: pushq %rbp
|
|
; X64: leaq {{.*}}(%rbp), %rcx
|
|
; X64: callq "??1Dtor@@QAE@XZ"
|
|
; X64: popq %rbp
|
|
; X64: retq
|
|
|
|
; X64: .seh_handlerdata
|
|
; X64: .text
|
|
; X64: .seh_endproc
|
|
|
|
; X64: "?dtor$[[cleanup_outer:[0-9]+]]@?0?nested_cleanup@4HA":
|
|
; X64: LBB1_[[cleanup_outer]]: # %cleanup.outer{{$}}
|
|
; X64: pushq %rbp
|
|
; X64: leaq {{.*}}(%rbp), %rcx
|
|
; X64: callq "??1Dtor@@QAE@XZ"
|
|
; X64: popq %rbp
|
|
; X64: retq
|
|
|
|
; X64: .section .xdata,"dr"
|
|
; X64-NEXT: .p2align 2
|
|
; X64: $cppxdata$nested_cleanup:
|
|
; X64-NEXT: .long 429065506
|
|
; X64-NEXT: .long 2
|
|
; X64-NEXT: .long ($stateUnwindMap$nested_cleanup)@IMGREL
|
|
; X64-NEXT: .long 0
|
|
; X64-NEXT: .long 0
|
|
; X64-NEXT: .long 5
|
|
; X64-NEXT: .long ($ip2state$nested_cleanup)@IMGREL
|
|
; X64-NEXT: .long 56
|
|
; X64-NEXT: .long 0
|
|
; X64-NEXT: .long 1
|
|
|
|
; X64: $stateUnwindMap$nested_cleanup:
|
|
; X64-NEXT: .long -1
|
|
; X64-NEXT: .long "?dtor$[[cleanup_outer]]@?0?nested_cleanup@4HA"@IMGREL
|
|
; X64-NEXT: .long 0
|
|
; X64-NEXT: .long "?dtor$[[cleanup_inner]]@?0?nested_cleanup@4HA"@IMGREL
|
|
|
|
; X64: $ip2state$nested_cleanup:
|
|
; X64-NEXT: .long .Lfunc_begin1@IMGREL
|
|
; X64-NEXT: .long -1
|
|
; X64-NEXT: .long .Ltmp2@IMGREL
|
|
; X64-NEXT: .long 0
|
|
; X64-NEXT: .long .Ltmp4@IMGREL
|
|
; X64-NEXT: .long 1
|
|
; X64-NEXT: .long .Ltmp6@IMGREL
|
|
; X64-NEXT: .long 0
|
|
; X64-NEXT: .long .Ltmp7@IMGREL+1
|
|
; X64-NEXT: .long -1
|
|
|
|
attributes #0 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
|
attributes #1 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
|
attributes #2 = { nounwind }
|