Home | History | Annotate | Download | only in X86
      1 ; RUN: llc < %s | FileCheck %s
      2 
      3 ; Based on the source:
      4 ; extern "C" int puts(const char *);
      5 ; extern "C" int printf(const char *, ...);
      6 ; extern "C" int do_div(int a, int b) { return a / b; }
      7 ; extern "C" int filt();
      8 ; int main() {
      9 ;   __try {
     10 ;     __try {
     11 ;       do_div(1, 0);
     12 ;     } __except (1) {
     13 ;       __try {
     14 ;         do_div(1, 0);
     15 ;       } __finally {
     16 ;         puts("finally");
     17 ;       }
     18 ;     }
     19 ;   } __except (filt()) {
     20 ;     puts("caught");
     21 ;   }
     22 ;   return 0;
     23 ; }
     24 
     25 ; ModuleID = 't.cpp'
     26 target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
     27 target triple = "x86_64-pc-windows-msvc"
     28 
     29 $"\01??_C@_07MKBLAIAL@finally?$AA@" = comdat any
     30 
     31 $"\01??_C@_06IBDBCMGJ@caught?$AA@" = comdat any
     32 
     33 @"\01??_C@_07MKBLAIAL@finally?$AA@" = linkonce_odr unnamed_addr constant [8 x i8] c"finally\00", comdat, align 1
     34 @"\01??_C@_06IBDBCMGJ@caught?$AA@" = linkonce_odr unnamed_addr constant [7 x i8] c"caught\00", comdat, align 1
     35 
     36 ; Function Attrs: nounwind readnone
     37 define i32 @do_div(i32 %a, i32 %b) #0 {
     38 entry:
     39   %div = sdiv i32 %a, %b
     40   ret i32 %div
     41 }
     42 
     43 define i32 @main() #1 personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) {
     44 entry:
     45   %call = invoke i32 @do_div(i32 1, i32 0) #4
     46           to label %__try.cont.12 unwind label %catch.dispatch
     47 
     48 __except.2:                                       ; preds = %__except
     49   %call4 = invoke i32 @do_div(i32 1, i32 0) #4
     50           to label %invoke.cont.3 unwind label %ehcleanup
     51 
     52 invoke.cont.3:                                    ; preds = %__except.2
     53   invoke fastcc void @"\01?fin$0@0@main@@"() #4
     54           to label %__try.cont.12 unwind label %catch.dispatch.7
     55 
     56 __except.9:                                       ; preds = %__except.ret
     57   %call11 = tail call i32 @puts(i8* nonnull getelementptr inbounds ([7 x i8], [7 x i8]* @"\01??_C@_06IBDBCMGJ@caught?$AA@", i64 0, i64 0))
     58   br label %__try.cont.12
     59 
     60 __try.cont.12:                                    ; preds = %invoke.cont.3, %entry, %__except.9
     61   ret i32 0
     62 
     63 catch.dispatch:                                   ; preds = %entry
     64   %cs1 = catchswitch within none [label %__except] unwind label %catch.dispatch.7
     65 
     66 __except:                                         ; preds = %catch.dispatch
     67   %cp1 = catchpad within %cs1 [i8* null]
     68   catchret from %cp1 to label %__except.2
     69 
     70 ehcleanup:                                        ; preds = %__except.2
     71   %cp2 = cleanuppad within none []
     72   invoke fastcc void @"\01?fin$0@0@main@@"() #4 [ "funclet"(token %cp2) ]
     73           to label %invoke.cont.6 unwind label %catch.dispatch.7
     74 
     75 invoke.cont.6:                                    ; preds = %ehcleanup
     76   cleanupret from %cp2 unwind label %catch.dispatch.7
     77 
     78 catch.dispatch.7:
     79   %cs2 = catchswitch within none [label %__except.ret] unwind to caller
     80 
     81 __except.ret:                                     ; preds = %catch.dispatch.7
     82   %cp3 = catchpad within %cs2 [i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@main@@" to i8*)]
     83   catchret from %cp3 to label %__except.9
     84 }
     85 
     86 ; CHECK: main:                                   # @main
     87 ; CHECK: .seh_proc main
     88 ; CHECK:         .seh_handler __C_specific_handler, @unwind, @except
     89 ; CHECK:         pushq   %rbp
     90 ; CHECK:         .seh_pushreg 5
     91 ; CHECK:         subq    $32, %rsp
     92 ; CHECK:         .seh_stackalloc 32
     93 ; CHECK:         leaq    32(%rsp), %rbp
     94 ; CHECK:         .seh_setframe 5, 32
     95 ; CHECK:         .seh_endprologue
     96 ; CHECK: .Ltmp0:
     97 ; CHECK:         movl    $1, %ecx
     98 ; CHECK:         xorl    %edx, %edx
     99 ; CHECK:         callq   do_div
    100 ; CHECK: .Ltmp1:
    101 ; CHECK: .LBB1_[[epilogue:[0-9]+]]:                                # %__try.cont.12
    102 ; CHECK:         xorl    %eax, %eax
    103 ; CHECK:         addq    $32, %rsp
    104 ; CHECK:         popq    %rbp
    105 ; CHECK:         retq
    106 ; CHECK: .LBB1_[[except1bb:[0-9]+]]:                                # %__except
    107 ; CHECK: .Ltmp2:
    108 ; CHECK:         movl    $1, %ecx
    109 ; CHECK:         xorl    %edx, %edx
    110 ; CHECK:         callq   do_div
    111 ; CHECK: .Ltmp3:
    112 ; CHECK:         callq   "?fin$0@0@main@@"
    113 ; CHECK:         jmp     .LBB1_[[epilogue]]
    114 ; CHECK: .LBB1_[[except2bb:[0-9]+]]:                                # %__except.ret
    115 ; CHECK:         leaq    "??_C@_06IBDBCMGJ@caught?$AA@"(%rip), %rcx
    116 ; CHECK:         callq   puts
    117 ; CHECK:         jmp     .LBB1_[[epilogue]]
    118 
    119 ; CHECK:         .seh_handlerdata
    120 ; CHECK-NEXT:         .Lmain$parent_frame_offset = 32
    121 ; CHECK-NEXT:         .long   (.Llsda_end0-.Llsda_begin0)/16
    122 ; CHECK-NEXT: .Llsda_begin0:
    123 ; CHECK-NEXT:         .long   .Ltmp0@IMGREL+1
    124 ; CHECK-NEXT:         .long   .Ltmp1@IMGREL+1
    125 ; CHECK-NEXT:         .long   1
    126 ; CHECK-NEXT:         .long   .LBB1_[[except1bb]]@IMGREL
    127 ; CHECK-NEXT:         .long   .Ltmp0@IMGREL+1
    128 ; CHECK-NEXT:         .long   .Ltmp1@IMGREL+1
    129 ; CHECK-NEXT:         .long   "?filt$0@0@main@@"@IMGREL
    130 ; CHECK-NEXT:         .long   .LBB1_[[except2bb]]@IMGREL
    131 ; CHECK-NEXT:         .long   .Ltmp2@IMGREL+1
    132 ; CHECK-NEXT:         .long   .Ltmp3@IMGREL+1
    133 ; CHECK-NEXT:         .long   "?dtor$[[finbb:[0-9]+]]@?0?main@4HA"@IMGREL
    134 ; CHECK-NEXT:         .long   0
    135 ; CHECK-NEXT:         .long   .Ltmp2@IMGREL+1
    136 ; CHECK-NEXT:         .long   .Ltmp3@IMGREL+1
    137 ; CHECK-NEXT:         .long   "?filt$0@0@main@@"@IMGREL
    138 ; CHECK-NEXT:         .long   .LBB1_3@IMGREL
    139 ; CHECK-NEXT:         .long   .Ltmp6@IMGREL+1
    140 ; CHECK-NEXT:         .long   .Ltmp7@IMGREL+1
    141 ; CHECK-NEXT:         .long   "?filt$0@0@main@@"@IMGREL
    142 ; CHECK-NEXT:         .long   .LBB1_3@IMGREL
    143 ; CHECK-NEXT: .Llsda_end0:
    144 
    145 ; CHECK:         .text
    146 ; CHECK:         .seh_endproc
    147 
    148 ; CHECK: "?dtor$[[finbb]]@?0?main@4HA":
    149 ; CHECK: .seh_proc "?dtor$[[finbb]]@?0?main@4HA"
    150 ; CHECK:         .seh_handler __C_specific_handler, @unwind, @except
    151 ; CHECK: .LBB1_[[finbb]]:                                # %ehcleanup
    152 ; CHECK:         movq    %rdx, 16(%rsp)
    153 ; CHECK:         pushq   %rbp
    154 ; CHECK:         .seh_pushreg 5
    155 ; CHECK:         subq    $32, %rsp
    156 ; CHECK:         .seh_stackalloc 32
    157 ; CHECK:         leaq    32(%rdx), %rbp
    158 ; CHECK:         .seh_endprologue
    159 ; CHECK:         callq   "?fin$0@0@main@@"
    160 ; CHECK:         nop
    161 ; CHECK:         addq    $32, %rsp
    162 ; CHECK:         popq    %rbp
    163 ; CHECK:         retq
    164 ; CHECK:         .seh_handlerdata
    165 ; CHECK:         .seh_endproc
    166 
    167 define internal i32 @"\01?filt$0@0@main@@"(i8* nocapture readnone %exception_pointers, i8* nocapture readnone %frame_pointer) #1 {
    168 entry:
    169   %call = tail call i32 @filt()
    170   ret i32 %call
    171 }
    172 
    173 ; CHECK: "?filt$0@0@main@@":                     # @"\01?filt$0@0@main@@"
    174 ; CHECK: .seh_proc "?filt$0@0@main@@"
    175 ; CHECK:         .seh_endprologue
    176 ; CHECK:         rex64 jmp       filt  # TAILCALL
    177 ; CHECK:         .seh_handlerdata
    178 
    179 declare i32 @filt() #1
    180 
    181 declare i32 @__C_specific_handler(...)
    182 
    183 ; Function Attrs: noinline nounwind
    184 define internal fastcc void @"\01?fin$0@0@main@@"() #2 {
    185 entry:
    186   %call = tail call i32 @puts(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @"\01??_C@_07MKBLAIAL@finally?$AA@", i64 0, i64 0)) #5
    187   ret void
    188 }
    189 
    190 ; Function Attrs: nounwind
    191 declare i32 @puts(i8* nocapture readonly) #3
    192 
    193 attributes #0 = { nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
    194 attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
    195 attributes #2 = { noinline nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
    196 attributes #3 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
    197 attributes #4 = { noinline }
    198 attributes #5 = { nounwind }
    199