Home | History | Annotate | Download | only in SimplifyCFG
      1 ; RUN: opt < %s -simplifycfg -S | FileCheck %s
      2 
      3 declare void @f()
      4 declare void @llvm.foo(i32) nounwind
      5 declare void @ProcessCLRException()
      6 
      7 define void @test1() personality void ()* @ProcessCLRException {
      8 entry:
      9   invoke void @f()
     10     to label %exit unwind label %exn.dispatch
     11 exn.dispatch:
     12   %cs = catchswitch within none [label %pad1, label %pad2] unwind to caller
     13 pad1:
     14   %cp1 = catchpad within %cs [i32 1]
     15   call void @llvm.foo(i32 1)
     16   catchret from %cp1 to label %exit
     17 pad2:
     18   %cp2 = catchpad within %cs [i32 2]
     19   unreachable
     20 exit:
     21   ret void
     22 }
     23 ; Remove unreachble catch2, leave catch1 as-is
     24 ; CHECK-LABEL: define void @test1()
     25 ; CHECK: %cs = catchswitch within none [label %pad1] unwind to caller
     26 ; CHECK-NOT: catchpad
     27 ; CHECK: %cp1 = catchpad within %cs [i32 1]
     28 ; CHECK-NOT: catchpad
     29 
     30 ; Remove both catchpads and the catchswitch from exn.dispatch
     31 ; CHECK-LABEL: define void @test2()
     32 define void @test2() personality void ()* @ProcessCLRException {
     33 entry:
     34   invoke void @f()
     35     to label %via.cleanup unwind label %exn.dispatch
     36   ; CHECK-NOT: invoke
     37   ; CHECK: call void @f()
     38 via.cleanup:
     39   invoke void @f()
     40     to label %via.catchswitch unwind label %cleanup.inner
     41 cleanup.inner:
     42   %cp.inner = cleanuppad within none []
     43   call void @llvm.foo(i32 0)
     44   cleanupret from %cp.inner unwind label %exn.dispatch
     45   ; CHECK: cleanupret from %cp.inner unwind to caller
     46 via.catchswitch:
     47   invoke void @f()
     48     to label %exit unwind label %dispatch.inner
     49 dispatch.inner:
     50   %cs.inner = catchswitch within none [label %pad.inner] unwind label %exn.dispatch
     51   ; CHECK: %cs.inner = catchswitch within none [label %pad.inner] unwind to caller
     52 pad.inner:
     53   %catch.inner = catchpad within %cs.inner [i32 0]
     54   ; CHECK: %catch.inner = catchpad within %cs.inner
     55   call void @llvm.foo(i32 1)
     56   catchret from %catch.inner to label %exit
     57 exn.dispatch:
     58   %cs = catchswitch within none [label %pad1, label %pad2] unwind to caller
     59   ; CHECK-NOT: catchswitch within
     60   ; CHECK-NOT: catchpad
     61 pad1:
     62   catchpad within %cs [i32 1]
     63   unreachable
     64 pad2:
     65   catchpad within %cs [i32 2]
     66   unreachable
     67 exit:
     68   ret void
     69 }
     70 
     71 ; Same as @test2, but exn.dispatch catchswitch has an unwind dest that
     72 ; preds need to be reidrected to
     73 ; CHECK-LABEL: define void @test3()
     74 define void @test3() personality void ()* @ProcessCLRException {
     75 entry:
     76   invoke void @f()
     77     to label %via.cleanup unwind label %exn.dispatch
     78   ; CHECK: invoke void @f()
     79   ; CHECK-NEXT: to label %via.cleanup unwind label %cleanup
     80 via.cleanup:
     81   invoke void @f()
     82     to label %via.catchswitch unwind label %cleanup.inner
     83 cleanup.inner:
     84   %cp.inner = cleanuppad within none []
     85   call void @llvm.foo(i32 0)
     86   cleanupret from %cp.inner unwind label %exn.dispatch
     87   ; CHECK: cleanupret from %cp.inner unwind label %cleanup
     88 via.catchswitch:
     89   invoke void @f()
     90     to label %exit unwind label %dispatch.inner
     91 dispatch.inner:
     92   %cs.inner = catchswitch within none [label %pad.inner] unwind label %exn.dispatch
     93   ; CHECK: %cs.inner = catchswitch within none [label %pad.inner] unwind label %cleanup
     94 pad.inner:
     95   %catch.inner = catchpad within %cs.inner [i32 0]
     96   ; CHECK: %catch.inner = catchpad within %cs.inner
     97   call void @llvm.foo(i32 1)
     98   catchret from %catch.inner to label %exit
     99 exn.dispatch:
    100   %cs = catchswitch within none [label %pad1, label %pad2] unwind label %cleanup
    101   ; CHECK-NOT: catchswitch within
    102   ; CHECK-NOT: catchpad
    103 pad1:
    104   catchpad within %cs [i32 1]
    105   unreachable
    106 pad2:
    107   catchpad within %cs [i32 2]
    108   unreachable
    109 cleanup:
    110   %cp = cleanuppad within none []
    111   call void @llvm.foo(i32 0)
    112   cleanupret from %cp unwind to caller
    113 exit:
    114   ret void
    115 }
    116