| ; RUN: llc -verify-machineinstrs -mtriple=i686-pc-windows-msvc < %s \ |
| ; RUN: | FileCheck --check-prefix=CHECK --check-prefix=X86 %s |
| ; RUN: llc -verify-machineinstrs -mtriple=x86_64-pc-windows-msvc < %s \ |
| ; RUN: | FileCheck --check-prefix=CHECK --check-prefix=X64 %s |
| |
| ; Loosely based on IR for this C++ source code: |
| ; void f(int p); |
| ; void try_in_catch() { |
| ; try { |
| ; f(1); |
| ; } catch (...) { |
| ; try { |
| ; f(2); |
| ; } catch (...) { |
| ; f(3); |
| ; } |
| ; } |
| ; } |
| |
| declare void @f(i32 %p) |
| declare i32 @__CxxFrameHandler3(...) |
| |
| define i32 @try_in_catch() personality i32 (...)* @__CxxFrameHandler3 { |
| entry: |
| invoke void @f(i32 1) |
| to label %try.cont unwind label %catch.dispatch.1 |
| try.cont: |
| ret i32 0 |
| |
| catch.dispatch.1: |
| %cs1 = catchswitch within none [label %handler1] unwind to caller |
| handler1: |
| %h1 = catchpad within %cs1 [i8* null, i32 64, i8* null] |
| invoke void @f(i32 2) [ "funclet"(token %h1) ] |
| to label %catchret1 unwind label %catch.dispatch.2 |
| catchret1: |
| catchret from %h1 to label %try.cont |
| |
| catch.dispatch.2: |
| %cs2 = catchswitch within %h1 [label %handler2] unwind to caller |
| handler2: |
| %h2 = catchpad within %cs2 [i8* null, i32 64, i8* null] |
| call void @f(i32 3) |
| catchret from %h2 to label %catchret1 |
| } |
| |
| ; X86-LABEL: L__ehtable$try_in_catch: |
| ; X64-LABEL: $cppxdata$try_in_catch: |
| ; CHECK-NEXT: .long 429065506 |
| ; CHECK-NEXT: .long 4 |
| ; CHECK-NEXT: .long ($stateUnwindMap$try_in_catch) |
| ; CHECK-NEXT: .long 2 |
| ; CHECK-NEXT: .long ($tryMap$try_in_catch) |
| ; ip2state num + ptr |
| ; X86-NEXT: .long 0 |
| ; X86-NEXT: .long 0 |
| ; X64-NEXT: .long 7 |
| ; X64-NEXT: .long ($ip2state$try_in_catch) |
| ; unwindhelp offset |
| ; X64-NEXT: .long 40 |
| ; CHECK-NEXT: .long 0 |
| ; EHFlags |
| ; CHECK-NEXT: .long 1 |
| |
| ; CHECK: $tryMap$try_in_catch: |
| ; CHECK-NEXT: .long 2 |
| ; CHECK-NEXT: .long 2 |
| ; CHECK-NEXT: .long 3 |
| ; CHECK-NEXT: .long 1 |
| ; CHECK-NEXT: .long ($handlerMap$0$try_in_catch) |
| ; CHECK-NEXT: .long 0 |
| ; CHECK-NEXT: .long 0 |
| ; CHECK-NEXT: .long 3 |
| ; CHECK-NEXT: .long 1 |
| ; CHECK-NEXT: .long ($handlerMap$1$try_in_catch) |
| |
| ; CHECK: $handlerMap$0$try_in_catch: |
| ; CHECK-NEXT: .long 64 |
| ; CHECK-NEXT: .long 0 |
| ; CHECK-NEXT: .long 0 |
| ; CHECK-NEXT: .long "?catch${{[0-9]+}}@?0?try_in_catch@4HA" |
| ; X64-NEXT: .long 56 |
| |
| ; CHECK: $handlerMap$1$try_in_catch: |
| ; CHECK-NEXT: .long 64 |
| ; CHECK-NEXT: .long 0 |
| ; CHECK-NEXT: .long 0 |
| ; CHECK-NEXT: .long "?catch${{[0-9]+}}@?0?try_in_catch@4HA" |
| ; X64-NEXT: .long 56 |
| |
| ; X64: $ip2state$try_in_catch: |
| ; X64-NEXT: .long .Lfunc_begin0@IMGREL |
| ; X64-NEXT: .long -1 |
| ; X64-NEXT: .long .Ltmp0@IMGREL+1 |
| ; X64-NEXT: .long 0 |
| ; X64-NEXT: .long .Ltmp1@IMGREL+1 |
| ; X64-NEXT: .long -1 |
| ; X64-NEXT: .long "?catch$2@?0?try_in_catch@4HA"@IMGREL |
| ; X64-NEXT: .long 1 |
| ; X64-NEXT: .long .Ltmp2@IMGREL+1 |
| ; X64-NEXT: .long 2 |
| ; X64-NEXT: .long .Ltmp3@IMGREL+1 |
| ; X64-NEXT: .long 1 |
| ; X64-NEXT: .long "?catch$4@?0?try_in_catch@4HA"@IMGREL |
| ; X64-NEXT: .long 3 |