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 6define void @simple_cleanup() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { 7entry: 8 %o = alloca %struct.Dtor, align 1 9 invoke void @f(i32 1) 10 to label %invoke.cont unwind label %ehcleanup 11 12invoke.cont: ; preds = %entry 13 call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o) #2 14 ret void 15 16ehcleanup: ; 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 52declare void @f(i32) #0 53 54declare i32 @__CxxFrameHandler3(...) 55 56; Function Attrs: nounwind 57declare x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor*) #1 58 59define void @nested_cleanup() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { 60entry: 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 66invoke.cont: ; preds = %entry 67 invoke void @f(i32 2) 68 to label %invoke.cont.1 unwind label %cleanup.inner 69 70invoke.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 75invoke.cont.2: ; preds = %invoke.cont.1 76 call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o1) #2 77 ret void 78 79cleanup.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 84cleanup.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: pushl $1 92; X86: calll _f 93; X86: pushl $2 94; X86: calll _f 95; X86: pushl $3 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: .Ltmp2: 133; X64: movl $1, %ecx 134; X64: callq f 135; X64: .Ltmp4: 136; X64: movl $2, %ecx 137; X64: callq f 138; X64: .Ltmp5: 139; X64: callq "??1Dtor@@QAE@XZ" 140; X64: .Ltmp6: 141; X64: movl $3, %ecx 142; X64: callq f 143; X64: .Ltmp7: 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: .p2align 2 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 .Ltmp2@IMGREL 189; X64-NEXT: .long 0 190; X64-NEXT: .long .Ltmp4@IMGREL 191; X64-NEXT: .long 1 192; X64-NEXT: .long .Ltmp6@IMGREL 193; X64-NEXT: .long 0 194; X64-NEXT: .long .Ltmp7@IMGREL+1 195; X64-NEXT: .long -1 196 197attributes #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" } 198attributes #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" } 199attributes #2 = { nounwind } 200