David Majnemer | 8a1c45d | 2015-12-12 05:38:55 +0000 | [diff] [blame] | 1 | ; RUN: llc -verify-machineinstrs -mtriple=i686-pc-windows-msvc < %s \ |
| 2 | ; RUN: | FileCheck --check-prefix=CHECK --check-prefix=X86 %s |
| 3 | ; RUN: llc -verify-machineinstrs -mtriple=x86_64-pc-windows-msvc < %s \ |
| 4 | ; RUN: | FileCheck --check-prefix=CHECK --check-prefix=X64 %s |
| 5 | |
| 6 | ; Loosely based on IR for this C++ source code: |
| 7 | ; void f(int p); |
| 8 | ; void try_in_catch() { |
| 9 | ; try { |
| 10 | ; f(1); |
| 11 | ; } catch (...) { |
| 12 | ; try { |
| 13 | ; f(2); |
| 14 | ; } catch (...) { |
| 15 | ; f(3); |
| 16 | ; } |
| 17 | ; } |
| 18 | ; } |
| 19 | |
| 20 | declare void @f(i32 %p) |
| 21 | declare i32 @__CxxFrameHandler3(...) |
| 22 | |
| 23 | define i32 @try_in_catch() personality i32 (...)* @__CxxFrameHandler3 { |
| 24 | entry: |
| 25 | invoke void @f(i32 1) |
| 26 | to label %try.cont unwind label %catch.dispatch.1 |
| 27 | try.cont: |
| 28 | ret i32 0 |
| 29 | |
| 30 | catch.dispatch.1: |
| 31 | %cs1 = catchswitch within none [label %handler1] unwind to caller |
| 32 | handler1: |
| 33 | %h1 = catchpad within %cs1 [i8* null, i32 64, i8* null] |
David Majnemer | 3bb88c0 | 2015-12-15 21:27:27 +0000 | [diff] [blame] | 34 | invoke void @f(i32 2) [ "funclet"(token %h1) ] |
David Majnemer | 8a1c45d | 2015-12-12 05:38:55 +0000 | [diff] [blame] | 35 | to label %catchret1 unwind label %catch.dispatch.2 |
| 36 | catchret1: |
| 37 | catchret from %h1 to label %try.cont |
| 38 | |
| 39 | catch.dispatch.2: |
| 40 | %cs2 = catchswitch within %h1 [label %handler2] unwind to caller |
| 41 | handler2: |
| 42 | %h2 = catchpad within %cs2 [i8* null, i32 64, i8* null] |
| 43 | call void @f(i32 3) |
| 44 | catchret from %h2 to label %catchret1 |
| 45 | } |
| 46 | |
| 47 | ; X86-LABEL: L__ehtable$try_in_catch: |
| 48 | ; X64-LABEL: $cppxdata$try_in_catch: |
| 49 | ; CHECK-NEXT: .long 429065506 |
| 50 | ; CHECK-NEXT: .long 4 |
| 51 | ; CHECK-NEXT: .long ($stateUnwindMap$try_in_catch) |
| 52 | ; CHECK-NEXT: .long 2 |
| 53 | ; CHECK-NEXT: .long ($tryMap$try_in_catch) |
| 54 | ; ip2state num + ptr |
| 55 | ; X86-NEXT: .long 0 |
| 56 | ; X86-NEXT: .long 0 |
| 57 | ; X64-NEXT: .long 7 |
| 58 | ; X64-NEXT: .long ($ip2state$try_in_catch) |
| 59 | ; unwindhelp offset |
| 60 | ; X64-NEXT: .long 40 |
| 61 | ; CHECK-NEXT: .long 0 |
| 62 | ; EHFlags |
| 63 | ; CHECK-NEXT: .long 1 |
| 64 | |
| 65 | ; CHECK: $tryMap$try_in_catch: |
| 66 | ; CHECK-NEXT: .long 2 |
| 67 | ; CHECK-NEXT: .long 2 |
| 68 | ; CHECK-NEXT: .long 3 |
| 69 | ; CHECK-NEXT: .long 1 |
| 70 | ; CHECK-NEXT: .long ($handlerMap$0$try_in_catch) |
| 71 | ; CHECK-NEXT: .long 0 |
| 72 | ; CHECK-NEXT: .long 0 |
| 73 | ; CHECK-NEXT: .long 3 |
| 74 | ; CHECK-NEXT: .long 1 |
| 75 | ; CHECK-NEXT: .long ($handlerMap$1$try_in_catch) |
| 76 | |
| 77 | ; CHECK: $handlerMap$0$try_in_catch: |
| 78 | ; CHECK-NEXT: .long 64 |
| 79 | ; CHECK-NEXT: .long 0 |
| 80 | ; CHECK-NEXT: .long 0 |
| 81 | ; CHECK-NEXT: .long "?catch${{[0-9]+}}@?0?try_in_catch@4HA" |
| 82 | ; X64-NEXT: .long 56 |
| 83 | |
| 84 | ; CHECK: $handlerMap$1$try_in_catch: |
| 85 | ; CHECK-NEXT: .long 64 |
| 86 | ; CHECK-NEXT: .long 0 |
| 87 | ; CHECK-NEXT: .long 0 |
| 88 | ; CHECK-NEXT: .long "?catch${{[0-9]+}}@?0?try_in_catch@4HA" |
| 89 | ; X64-NEXT: .long 56 |
| 90 | |
| 91 | ; X64: $ip2state$try_in_catch: |
| 92 | ; X64-NEXT: .long .Lfunc_begin0@IMGREL |
| 93 | ; X64-NEXT: .long -1 |
| 94 | ; X64-NEXT: .long .Ltmp0@IMGREL+1 |
| 95 | ; X64-NEXT: .long 0 |
| 96 | ; X64-NEXT: .long .Ltmp1@IMGREL+1 |
| 97 | ; X64-NEXT: .long -1 |
| 98 | ; X64-NEXT: .long "?catch$2@?0?try_in_catch@4HA"@IMGREL |
| 99 | ; X64-NEXT: .long 1 |
| 100 | ; X64-NEXT: .long .Ltmp2@IMGREL+1 |
| 101 | ; X64-NEXT: .long 2 |
| 102 | ; X64-NEXT: .long .Ltmp3@IMGREL+1 |
| 103 | ; X64-NEXT: .long 1 |
| 104 | ; X64-NEXT: .long "?catch$4@?0?try_in_catch@4HA"@IMGREL |
| 105 | ; X64-NEXT: .long 3 |