1 ; RUN: llc -verify-machineinstrs -mtriple=i686-pc-windows-msvc < %s | FileCheck --check-prefix=X86 %s 2 ; RUN: llc -verify-machineinstrs -mtriple=x86_64-pc-windows-msvc < %s | FileCheck --check-prefix=X64 %s 3 4 %struct.Dtor = type { i8 } 5 6 define void @simple_cleanup() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { 7 entry: 8 %o = alloca %struct.Dtor, align 1 9 invoke void @f(i32 1) 10 to label %invoke.cont unwind label %ehcleanup 11 12 invoke.cont: ; preds = %entry 13 call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o) #2 14 ret void 15 16 ehcleanup: ; preds = %entry 17 %0 = cleanuppad within none [] 18 call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o) #2 [ "funclet"(token %0) ] 19 cleanupret from %0 unwind to caller 20 } 21 22 ; CHECK: simple_cleanup: # @simple_cleanup 23 ; CHECK: pushq %rbp 24 ; CHECK: subq $48, %rsp 25 ; CHECK: leaq 48(%rsp), %rbp 26 ; CHECK: movq $-2, -8(%rbp) 27 ; CHECK: movl $1, %ecx 28 ; CHECK: callq f 29 ; CHECK: callq "??1Dtor@@QAE@XZ" 30 ; CHECK: nop 31 ; CHECK: addq $48, %rsp 32 ; CHECK: popq %rbp 33 ; CHECK: retq 34 35 ; CHECK: "?dtor$2@?0?simple_cleanup@4HA": 36 ; CHECK: callq "??1Dtor@@QAE@XZ" 37 ; CHECK: retq 38 39 ; CHECK: $cppxdata$simple_cleanup: 40 ; CHECK-NEXT: .long 429065506 41 ; CHECK-NEXT: .long 1 42 ; CHECK-NEXT: .long ($stateUnwindMap$simple_cleanup)@IMGREL 43 ; CHECK-NEXT: .long 0 44 ; CHECK-NEXT: .long 0 45 ; CHECK-NEXT: .long 3 46 ; CHECK-NEXT: .long ($ip2state$simple_cleanup)@IMGREL 47 ; UnwindHelp offset should match the -2 store above 48 ; CHECK-NEXT: .long 40 49 ; CHECK-NEXT: .long 0 50 ; CHECK-NEXT: .long 1 51 52 declare void @f(i32) #0 53 54 declare i32 @__CxxFrameHandler3(...) 55 56 ; Function Attrs: nounwind 57 declare x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor*) #1 58 59 define void @nested_cleanup() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { 60 entry: 61 %o1 = alloca %struct.Dtor, align 1 62 %o2 = alloca %struct.Dtor, align 1 63 invoke void @f(i32 1) 64 to label %invoke.cont unwind label %cleanup.outer 65 66 invoke.cont: ; preds = %entry 67 invoke void @f(i32 2) 68 to label %invoke.cont.1 unwind label %cleanup.inner 69 70 invoke.cont.1: ; preds = %invoke.cont 71 call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o2) #2 72 invoke void @f(i32 3) 73 to label %invoke.cont.2 unwind label %cleanup.outer 74 75 invoke.cont.2: ; preds = %invoke.cont.1 76 call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o1) #2 77 ret void 78 79 cleanup.inner: ; preds = %invoke.cont 80 %0 = cleanuppad within none [] 81 call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o2) #2 [ "funclet"(token %0) ] 82 cleanupret from %0 unwind label %cleanup.outer 83 84 cleanup.outer: ; preds = %invoke.cont.1, %cleanup.inner, %entry 85 %1 = cleanuppad within none [] 86 call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o1) #2 [ "funclet"(token %1) ] 87 cleanupret from %1 unwind to caller 88 } 89 90 ; X86-LABEL: _nested_cleanup: 91 ; X86: movl $1, (%esp) 92 ; X86: calll _f 93 ; X86: movl $2, (%esp) 94 ; X86: calll _f 95 ; X86: movl $3, (%esp) 96 ; X86: calll _f 97 98 ; X86: "?dtor$[[cleanup_inner:[0-9]+]]@?0?nested_cleanup@4HA": 99 ; X86: LBB1_[[cleanup_inner]]: # %cleanup.inner{{$}} 100 ; X86: pushl %ebp 101 ; X86: leal {{.*}}(%ebp), %ecx 102 ; X86: calll "??1Dtor@@QAE@XZ" 103 ; X86: popl %ebp 104 ; X86: retl 105 106 ; X86: "?dtor$[[cleanup_outer:[0-9]+]]@?0?nested_cleanup@4HA": 107 ; X86: LBB1_[[cleanup_outer]]: # %cleanup.outer{{$}} 108 ; X86: pushl %ebp 109 ; X86: leal {{.*}}(%ebp), %ecx 110 ; X86: calll "??1Dtor@@QAE@XZ" 111 ; X86: popl %ebp 112 ; X86: retl 113 114 ; X86: L__ehtable$nested_cleanup: 115 ; X86: .long 429065506 116 ; X86: .long 2 117 ; X86: .long ($stateUnwindMap$nested_cleanup) 118 ; X86: .long 0 119 ; X86: .long 0 120 ; X86: .long 0 121 ; X86: .long 0 122 ; X86: .long 0 123 ; X86: .long 1 124 ; X86: $stateUnwindMap$nested_cleanup: 125 ; X86: .long -1 126 ; X86: .long "?dtor$[[cleanup_outer]]@?0?nested_cleanup@4HA" 127 ; X86: .long 0 128 ; X86: .long "?dtor$[[cleanup_inner]]@?0?nested_cleanup@4HA" 129 130 ; X64-LABEL: nested_cleanup: 131 ; X64: .Lfunc_begin1: 132 ; X64: .Ltmp13: 133 ; X64: movl $1, %ecx 134 ; X64: callq f 135 ; X64: .Ltmp15: 136 ; X64: movl $2, %ecx 137 ; X64: callq f 138 ; X64: .Ltmp16: 139 ; X64: callq "??1Dtor@@QAE@XZ" 140 ; X64: .Ltmp17: 141 ; X64: movl $3, %ecx 142 ; X64: callq f 143 ; X64: .Ltmp18: 144 145 ; X64: "?dtor$[[cleanup_inner:[0-9]+]]@?0?nested_cleanup@4HA": 146 ; X64: LBB1_[[cleanup_inner]]: # %cleanup.inner{{$}} 147 ; X64: pushq %rbp 148 ; X64: leaq {{.*}}(%rbp), %rcx 149 ; X64: callq "??1Dtor@@QAE@XZ" 150 ; X64: popq %rbp 151 ; X64: retq 152 153 ; X64: .seh_handlerdata 154 ; X64: .text 155 ; X64: .seh_endproc 156 157 ; X64: "?dtor$[[cleanup_outer:[0-9]+]]@?0?nested_cleanup@4HA": 158 ; X64: LBB1_[[cleanup_outer]]: # %cleanup.outer{{$}} 159 ; X64: pushq %rbp 160 ; X64: leaq {{.*}}(%rbp), %rcx 161 ; X64: callq "??1Dtor@@QAE@XZ" 162 ; X64: popq %rbp 163 ; X64: retq 164 165 ; X64: .section .xdata,"dr" 166 ; X64-NEXT: .align 4 167 ; X64: $cppxdata$nested_cleanup: 168 ; X64-NEXT: .long 429065506 169 ; X64-NEXT: .long 2 170 ; X64-NEXT: .long ($stateUnwindMap$nested_cleanup)@IMGREL 171 ; X64-NEXT: .long 0 172 ; X64-NEXT: .long 0 173 ; X64-NEXT: .long 5 174 ; X64-NEXT: .long ($ip2state$nested_cleanup)@IMGREL 175 ; X64-NEXT: .long 56 176 ; X64-NEXT: .long 0 177 ; X64-NEXT: .long 1 178 179 ; X64: $stateUnwindMap$nested_cleanup: 180 ; X64-NEXT: .long -1 181 ; X64-NEXT: .long "?dtor$[[cleanup_outer]]@?0?nested_cleanup@4HA"@IMGREL 182 ; X64-NEXT: .long 0 183 ; X64-NEXT: .long "?dtor$[[cleanup_inner]]@?0?nested_cleanup@4HA"@IMGREL 184 185 ; X64: $ip2state$nested_cleanup: 186 ; X64-NEXT: .long .Lfunc_begin1@IMGREL 187 ; X64-NEXT: .long -1 188 ; X64-NEXT: .long .Ltmp13@IMGREL 189 ; X64-NEXT: .long 0 190 ; X64-NEXT: .long .Ltmp15@IMGREL 191 ; X64-NEXT: .long 1 192 ; X64-NEXT: .long .Ltmp17@IMGREL 193 ; X64-NEXT: .long 0 194 ; X64-NEXT: .long .Ltmp18@IMGREL+1 195 ; X64-NEXT: .long -1 196 197 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" } 198 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" } 199 attributes #2 = { nounwind } 200