Home | History | Annotate | Download | only in X86
      1 ; RUN: llc -mtriple=x86_64-pc-windows-msvc < %s | FileCheck %s
      2 
      3 declare i32 @__CxxFrameHandler3(...)
      4 
      5 declare void @throw()
      6 declare i16 @f()
      7 
      8 define i16 @test1(i16 %a, i8* %b) personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
      9 entry:
     10   %cmp = icmp eq i16 %a, 10
     11   br i1 %cmp, label %if.then, label %if.else
     12 
     13 if.then:
     14   %call1 = invoke i16 @f()
     15           to label %cleanup unwind label %catch.dispatch
     16 
     17 if.else:
     18   %call2 = invoke i16 @f()
     19           to label %cleanup unwind label %catch.dispatch
     20 
     21 catch.dispatch:
     22   %cs = catchswitch within none [ label %catch, label %catch.2 ] unwind to caller
     23 
     24 catch:
     25   catchpad within %cs [i8* null, i32 8, i8* null]
     26   call void @throw() noreturn
     27   br label %unreachable
     28 
     29 catch.2:
     30   catchpad within %cs [i8* null, i32 64, i8* null]
     31   store i8 1, i8* %b
     32   call void @throw() noreturn
     33   br label %unreachable
     34 
     35 cleanup:
     36   %retval = phi i16 [ %call1, %if.then ], [ %call2, %if.else ]
     37   ret i16 %retval
     38 
     39 unreachable:
     40   unreachable
     41 }
     42 
     43 ; This test verifies the case where two funclet blocks meet the old criteria
     44 ; to be placed at the end.  The order of the blocks is not important for the
     45 ; purposes of this test.  The failure mode is an infinite loop during
     46 ; compilation.
     47 ;
     48 ; CHECK-LABEL: .def     test1;
     49 
     50 define i16 @test2(i16 %a, i8* %b) personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
     51 entry:
     52   %cmp = icmp eq i16 %a, 10
     53   br i1 %cmp, label %if.then, label %if.else
     54 
     55 if.then:
     56   %call1 = invoke i16 @f()
     57           to label %cleanup unwind label %catch.dispatch
     58 
     59 if.else:
     60   %call2 = invoke i16 @f()
     61           to label %cleanup unwind label %catch.dispatch
     62 
     63 catch.dispatch:
     64   %cs = catchswitch within none [ label %catch, label %catch.2, label %catch.3 ] unwind to caller
     65 
     66 catch:
     67   catchpad within %cs [i8* null, i32 8, i8* null]
     68   call void @throw() noreturn
     69   br label %unreachable
     70 
     71 catch.2:
     72   %c2 = catchpad within %cs [i8* null, i32 32, i8* null]
     73   store i8 1, i8* %b
     74   catchret from %c2 to label %cleanup
     75 
     76 catch.3:
     77   %c3 = catchpad within %cs [i8* null, i32 64, i8* null]
     78   store i8 2, i8* %b
     79   catchret from %c3 to label %cleanup
     80 
     81 cleanup:
     82   %retval = phi i16 [ %call1, %if.then ], [ %call2, %if.else ], [ -1, %catch.2 ], [ -1, %catch.3 ]
     83   ret i16 %retval
     84 
     85 unreachable:
     86   unreachable
     87 }
     88 
     89 ; This test verifies the case where three funclet blocks all meet the old
     90 ; criteria to be placed at the end.  The order of the blocks is not important
     91 ; for the purposes of this test.  The failure mode is an infinite loop during
     92 ; compilation.
     93 ;
     94 ; CHECK-LABEL: .def     test2;
     95 
     96