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