1*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=i686-pc-windows-msvc < %s | FileCheck %s --check-prefix=X86 2*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=x86_64-pc-windows-msvc < %s | FileCheck %s --check-prefix=X64 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Worker; Based on this source: 5*9880d681SAndroid Build Coastguard Worker; extern "C" void may_throw(int); 6*9880d681SAndroid Build Coastguard Worker; void f() { 7*9880d681SAndroid Build Coastguard Worker; try { 8*9880d681SAndroid Build Coastguard Worker; may_throw(1); 9*9880d681SAndroid Build Coastguard Worker; try { 10*9880d681SAndroid Build Coastguard Worker; may_throw(2); 11*9880d681SAndroid Build Coastguard Worker; } catch (int) { 12*9880d681SAndroid Build Coastguard Worker; may_throw(3); 13*9880d681SAndroid Build Coastguard Worker; } 14*9880d681SAndroid Build Coastguard Worker; } catch (int) { 15*9880d681SAndroid Build Coastguard Worker; may_throw(4); 16*9880d681SAndroid Build Coastguard Worker; } 17*9880d681SAndroid Build Coastguard Worker; } 18*9880d681SAndroid Build Coastguard Worker 19*9880d681SAndroid Build Coastguard Worker%rtti.TypeDescriptor2 = type { i8**, i8*, [3 x i8] } 20*9880d681SAndroid Build Coastguard Worker%eh.CatchHandlerType = type { i32, i8* } 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard Workerdeclare void @may_throw(i32) 23*9880d681SAndroid Build Coastguard Workerdeclare i32 @__CxxFrameHandler3(...) 24*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.eh.begincatch(i8*, i8*) 25*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.eh.endcatch() 26*9880d681SAndroid Build Coastguard Workerdeclare i32 @llvm.eh.typeid.for(i8*) 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Worker$"\01??_R0H@8" = comdat any 29*9880d681SAndroid Build Coastguard Worker 30*9880d681SAndroid Build Coastguard Worker@"\01??_7type_info@@6B@" = external constant i8* 31*9880d681SAndroid Build Coastguard Worker@"\01??_R0H@8" = linkonce_odr global %rtti.TypeDescriptor2 { i8** @"\01??_7type_info@@6B@", i8* null, [3 x i8] c".H\00" }, comdat 32*9880d681SAndroid Build Coastguard Worker@llvm.eh.handlertype.H.0 = private unnamed_addr constant %eh.CatchHandlerType { i32 0, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*) }, section "llvm.metadata" 33*9880d681SAndroid Build Coastguard Worker 34*9880d681SAndroid Build Coastguard Workerdefine void @f() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { 35*9880d681SAndroid Build Coastguard Workerentry: 36*9880d681SAndroid Build Coastguard Worker invoke void @may_throw(i32 1) 37*9880d681SAndroid Build Coastguard Worker to label %invoke.cont unwind label %lpad.1 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Workerinvoke.cont: ; preds = %entry 40*9880d681SAndroid Build Coastguard Worker invoke void @may_throw(i32 2) 41*9880d681SAndroid Build Coastguard Worker to label %try.cont.9 unwind label %lpad 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Workertry.cont.9: ; preds = %invoke.cont.3, %invoke.cont, %catch.7 44*9880d681SAndroid Build Coastguard Worker ret void 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Workerlpad: ; preds = %catch, %entry 47*9880d681SAndroid Build Coastguard Worker %cs1 = catchswitch within none [label %catch] unwind label %lpad.1 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Workercatch: ; preds = %lpad.1 50*9880d681SAndroid Build Coastguard Worker %p1 = catchpad within %cs1 [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] 51*9880d681SAndroid Build Coastguard Worker invoke void @may_throw(i32 3) [ "funclet"(token %p1) ] 52*9880d681SAndroid Build Coastguard Worker to label %invoke.cont.3 unwind label %lpad.1 53*9880d681SAndroid Build Coastguard Worker 54*9880d681SAndroid Build Coastguard Workerinvoke.cont.3: ; preds = %catch 55*9880d681SAndroid Build Coastguard Worker catchret from %p1 to label %try.cont.9 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Workerlpad.1: ; preds = %invoke.cont 58*9880d681SAndroid Build Coastguard Worker %cs2 = catchswitch within none [label %catch.7] unwind to caller 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Workercatch.7: 61*9880d681SAndroid Build Coastguard Worker %p2 = catchpad within %cs2 [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] 62*9880d681SAndroid Build Coastguard Worker call void @may_throw(i32 4) [ "funclet"(token %p2) ] 63*9880d681SAndroid Build Coastguard Worker catchret from %p2 to label %try.cont.9 64*9880d681SAndroid Build Coastguard Worker} 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Worker; X86-LABEL: _f: 67*9880d681SAndroid Build Coastguard Worker; X86: movl $-1, [[state:[-0-9]+]](%ebp) 68*9880d681SAndroid Build Coastguard Worker; X86: movl $___ehhandler$f, {{.*}} 69*9880d681SAndroid Build Coastguard Worker; 70*9880d681SAndroid Build Coastguard Worker; X86: movl $0, [[state]](%ebp) 71*9880d681SAndroid Build Coastguard Worker; X86: pushl $1 72*9880d681SAndroid Build Coastguard Worker; X86: calll _may_throw 73*9880d681SAndroid Build Coastguard Worker; 74*9880d681SAndroid Build Coastguard Worker; X86: movl $1, [[state]](%ebp) 75*9880d681SAndroid Build Coastguard Worker; X86: pushl $2 76*9880d681SAndroid Build Coastguard Worker; X86: calll _may_throw 77*9880d681SAndroid Build Coastguard Worker; 78*9880d681SAndroid Build Coastguard Worker; X86: movl $2, [[state]](%ebp) 79*9880d681SAndroid Build Coastguard Worker; X86: pushl $3 80*9880d681SAndroid Build Coastguard Worker; X86: calll _may_throw 81*9880d681SAndroid Build Coastguard Worker; 82*9880d681SAndroid Build Coastguard Worker; X86: movl $3, [[state]](%ebp) 83*9880d681SAndroid Build Coastguard Worker; X86: pushl $4 84*9880d681SAndroid Build Coastguard Worker; X86: calll _may_throw 85*9880d681SAndroid Build Coastguard Worker 86*9880d681SAndroid Build Coastguard Worker 87*9880d681SAndroid Build Coastguard Worker; X64-LABEL: f: 88*9880d681SAndroid Build Coastguard Worker; X64-LABEL: $ip2state$f: 89*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long .Lfunc_begin0@IMGREL 90*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long -1 91*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long .Ltmp{{.*}}@IMGREL+1 92*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long 0 93*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long .Ltmp{{.*}}@IMGREL+1 94*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long 1 95*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long .Ltmp{{.*}}@IMGREL+1 96*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long -1 97*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long "?catch${{.*}}@?0?f@4HA"@IMGREL 98*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long 2 99*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long "?catch${{.*}}@?0?f@4HA"@IMGREL 100*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long 3 101*9880d681SAndroid Build Coastguard Worker 102*9880d681SAndroid Build Coastguard Worker; Based on this source: 103*9880d681SAndroid Build Coastguard Worker; extern "C" void may_throw(int); 104*9880d681SAndroid Build Coastguard Worker; struct S { ~S(); }; 105*9880d681SAndroid Build Coastguard Worker; void g() { 106*9880d681SAndroid Build Coastguard Worker; S x; 107*9880d681SAndroid Build Coastguard Worker; try { 108*9880d681SAndroid Build Coastguard Worker; may_throw(-1); 109*9880d681SAndroid Build Coastguard Worker; } catch (...) { 110*9880d681SAndroid Build Coastguard Worker; may_throw(0); 111*9880d681SAndroid Build Coastguard Worker; { 112*9880d681SAndroid Build Coastguard Worker; S y; 113*9880d681SAndroid Build Coastguard Worker; may_throw(1); 114*9880d681SAndroid Build Coastguard Worker; } 115*9880d681SAndroid Build Coastguard Worker; may_throw(2); 116*9880d681SAndroid Build Coastguard Worker; } 117*9880d681SAndroid Build Coastguard Worker; } 118*9880d681SAndroid Build Coastguard Worker 119*9880d681SAndroid Build Coastguard Worker%struct.S = type { i8 } 120*9880d681SAndroid Build Coastguard Workerdeclare void @"\01??1S@@QEAA@XZ"(%struct.S*) 121*9880d681SAndroid Build Coastguard Worker 122*9880d681SAndroid Build Coastguard Workerdefine void @g() personality i32 (...)* @__CxxFrameHandler3 { 123*9880d681SAndroid Build Coastguard Workerentry: 124*9880d681SAndroid Build Coastguard Worker %x = alloca %struct.S, align 1 125*9880d681SAndroid Build Coastguard Worker %y = alloca %struct.S, align 1 126*9880d681SAndroid Build Coastguard Worker invoke void @may_throw(i32 -1) 127*9880d681SAndroid Build Coastguard Worker to label %unreachable unwind label %catch.dispatch 128*9880d681SAndroid Build Coastguard Worker 129*9880d681SAndroid Build Coastguard Workercatch.dispatch: ; preds = %entry 130*9880d681SAndroid Build Coastguard Worker %0 = catchswitch within none [label %catch] unwind label %ehcleanup5 131*9880d681SAndroid Build Coastguard Worker 132*9880d681SAndroid Build Coastguard Workercatch: ; preds = %catch.dispatch 133*9880d681SAndroid Build Coastguard Worker %1 = catchpad within %0 [i8* null, i32 64, i8* null] 134*9880d681SAndroid Build Coastguard Worker invoke void @may_throw(i32 0) [ "funclet"(token %1) ] 135*9880d681SAndroid Build Coastguard Worker to label %invoke.cont unwind label %ehcleanup5 136*9880d681SAndroid Build Coastguard Worker 137*9880d681SAndroid Build Coastguard Workerinvoke.cont: ; preds = %catch 138*9880d681SAndroid Build Coastguard Worker invoke void @may_throw(i32 1) [ "funclet"(token %1) ] 139*9880d681SAndroid Build Coastguard Worker to label %invoke.cont2 unwind label %ehcleanup 140*9880d681SAndroid Build Coastguard Worker 141*9880d681SAndroid Build Coastguard Workerinvoke.cont2: ; preds = %invoke.cont 142*9880d681SAndroid Build Coastguard Worker invoke void @"\01??1S@@QEAA@XZ"(%struct.S* nonnull %y) [ "funclet"(token %1) ] 143*9880d681SAndroid Build Coastguard Worker to label %invoke.cont3 unwind label %ehcleanup5 144*9880d681SAndroid Build Coastguard Worker 145*9880d681SAndroid Build Coastguard Workerinvoke.cont3: ; preds = %invoke.cont2 146*9880d681SAndroid Build Coastguard Worker invoke void @may_throw(i32 2) [ "funclet"(token %1) ] 147*9880d681SAndroid Build Coastguard Worker to label %invoke.cont4 unwind label %ehcleanup5 148*9880d681SAndroid Build Coastguard Worker 149*9880d681SAndroid Build Coastguard Workerinvoke.cont4: ; preds = %invoke.cont3 150*9880d681SAndroid Build Coastguard Worker catchret from %1 to label %try.cont 151*9880d681SAndroid Build Coastguard Worker 152*9880d681SAndroid Build Coastguard Workertry.cont: ; preds = %invoke.cont4 153*9880d681SAndroid Build Coastguard Worker call void @"\01??1S@@QEAA@XZ"(%struct.S* nonnull %x) 154*9880d681SAndroid Build Coastguard Worker ret void 155*9880d681SAndroid Build Coastguard Worker 156*9880d681SAndroid Build Coastguard Workerehcleanup: ; preds = %invoke.cont 157*9880d681SAndroid Build Coastguard Worker %2 = cleanuppad within %1 [] 158*9880d681SAndroid Build Coastguard Worker call void @"\01??1S@@QEAA@XZ"(%struct.S* nonnull %y) [ "funclet"(token %2) ] 159*9880d681SAndroid Build Coastguard Worker cleanupret from %2 unwind label %ehcleanup5 160*9880d681SAndroid Build Coastguard Worker 161*9880d681SAndroid Build Coastguard Workerehcleanup5: ; preds = %invoke.cont2, %invoke.cont3, %ehcleanup, %catch, %catch.dispatch 162*9880d681SAndroid Build Coastguard Worker %3 = cleanuppad within none [] 163*9880d681SAndroid Build Coastguard Worker call void @"\01??1S@@QEAA@XZ"(%struct.S* nonnull %x) [ "funclet"(token %3) ] 164*9880d681SAndroid Build Coastguard Worker cleanupret from %3 unwind to caller 165*9880d681SAndroid Build Coastguard Worker 166*9880d681SAndroid Build Coastguard Workerunreachable: ; preds = %entry 167*9880d681SAndroid Build Coastguard Worker unreachable 168*9880d681SAndroid Build Coastguard Worker} 169*9880d681SAndroid Build Coastguard Worker 170*9880d681SAndroid Build Coastguard Worker; X86-LABEL: _g: 171*9880d681SAndroid Build Coastguard Worker; X86: movl $-1, [[state:[-0-9]+]](%ebp) 172*9880d681SAndroid Build Coastguard Worker; X86: movl $___ehhandler$g, {{.*}} 173*9880d681SAndroid Build Coastguard Worker; 174*9880d681SAndroid Build Coastguard Worker; X86: movl $1, [[state]](%ebp) 175*9880d681SAndroid Build Coastguard Worker; X86: pushl $-1 176*9880d681SAndroid Build Coastguard Worker; X86: calll _may_throw 177*9880d681SAndroid Build Coastguard Worker; 178*9880d681SAndroid Build Coastguard Worker; X86: movl $2, [[state]](%ebp) 179*9880d681SAndroid Build Coastguard Worker; X86: pushl $0 180*9880d681SAndroid Build Coastguard Worker; X86: calll _may_throw 181*9880d681SAndroid Build Coastguard Worker; 182*9880d681SAndroid Build Coastguard Worker; X86: movl $3, [[state]](%ebp) 183*9880d681SAndroid Build Coastguard Worker; X86: pushl $1 184*9880d681SAndroid Build Coastguard Worker; X86: calll _may_throw 185*9880d681SAndroid Build Coastguard Worker; 186*9880d681SAndroid Build Coastguard Worker; X86: movl $2, [[state]](%ebp) 187*9880d681SAndroid Build Coastguard Worker; X86: pushl $2 188*9880d681SAndroid Build Coastguard Worker; X86: calll _may_throw 189*9880d681SAndroid Build Coastguard Worker 190*9880d681SAndroid Build Coastguard Worker; X64-LABEL: g: 191*9880d681SAndroid Build Coastguard Worker; X64-LABEL: $ip2state$g: 192*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long .Lfunc_begin1@IMGREL 193*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long -1 194*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long .Ltmp{{.*}}@IMGREL+1 195*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long 1 196*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long .Ltmp{{.*}}@IMGREL+1 197*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long -1 198*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long "?catch${{.*}}@?0?g@4HA"@IMGREL 199*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long 2 200*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long .Ltmp{{.*}}@IMGREL+1 201*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long 3 202*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long .Ltmp{{.*}}@IMGREL+1 203*9880d681SAndroid Build Coastguard Worker; X64-NEXT: .long 2 204*9880d681SAndroid Build Coastguard Worker 205*9880d681SAndroid Build Coastguard Worker 206*9880d681SAndroid Build Coastguard Worker; X86: .safeseh ___ehhandler$f 207*9880d681SAndroid Build Coastguard Worker; X86: .safeseh ___ehhandler$g 208