[SimplifyCFG] Don't DCE catchret because the successor is unreachable
[oota-llvm.git] / test / Transforms / SimplifyCFG / wineh-unreachable.ll
1 ; RUN: opt -S -simplifycfg < %s | FileCheck %s
2
3 declare void @Personality()
4 declare void @f()
5
6 ; CHECK-LABEL: define void @test1()
7 define void @test1() personality i8* bitcast (void ()* @Personality to i8*) {
8 entry:
9   ; CHECK: call void @f()
10   invoke void @f()
11     to label %exit unwind label %unreachable.unwind
12 exit:
13   ret void
14 unreachable.unwind:
15   cleanuppad []
16   unreachable  
17 }
18
19 ; CHECK-LABEL: define void @test2()
20 define void @test2() personality i8* bitcast (void ()* @Personality to i8*) {
21 entry:
22   invoke void @f()
23     to label %exit unwind label %catch.pad
24 catch.pad:
25   ; CHECK: catchpad []
26   ; CHECK-NEXT: to label %catch.body unwind label %catch.end
27   %catch = catchpad []
28     to label %catch.body unwind label %catch.end
29 catch.body:
30   ; CHECK:      catch.body:
31   ; CHECK-NEXT:   call void @f()
32   ; CHECK-NEXT:   unreachable
33   call void @f()
34   catchret %catch to label %unreachable
35 catch.end:
36   ; CHECK: catch.end:
37   ; CHECK-NEXT: catchendpad unwind to caller
38   catchendpad unwind label %unreachable.unwind
39 exit:
40   ret void
41 unreachable.unwind:
42   cleanuppad []
43   unreachable
44 unreachable:
45   unreachable
46 }
47
48 ; CHECK-LABEL: define void @test3()
49 define void @test3() personality i8* bitcast (void ()* @Personality to i8*) {
50 entry:
51   invoke void @f()
52     to label %exit unwind label %cleanup.pad
53 cleanup.pad:
54   ; CHECK: %cleanup = cleanuppad []
55   ; CHECK-NEXT: call void @f()
56   ; CHECK-NEXT: unreachable
57   %cleanup = cleanuppad []
58   invoke void @f()
59     to label %cleanup.ret unwind label %cleanup.end
60 cleanup.ret:
61   ; This cleanupret should be rewritten to unreachable,
62   ; and merged into the pred block.
63   cleanupret %cleanup unwind label %unreachable.unwind
64 cleanup.end:
65   ; This cleanupendpad should be rewritten to unreachable,
66   ; causing the invoke to be rewritten to a call.
67   cleanupendpad %cleanup unwind label %unreachable.unwind
68 exit:
69   ret void
70 unreachable.unwind:
71   cleanuppad []
72   unreachable
73 }
74
75 ; CHECK-LABEL: define void @test4()
76 define void @test4() personality i8* bitcast (void ()* @Personality to i8*) {
77 entry:
78   invoke void @f()
79     to label %exit unwind label %terminate.pad
80 terminate.pad:
81   ; CHECK: terminatepad [] unwind to caller
82   terminatepad [] unwind label %unreachable.unwind
83 exit:
84   ret void
85 unreachable.unwind:
86   cleanuppad []
87   unreachable
88 }
89
90 ; CHECK-LABEL: define void @test5()
91 define void @test5() personality i8* bitcast (void ()* @Personality to i8*) {
92 entry:
93   invoke void @f()
94           to label %exit unwind label %catch.pad
95
96 catch.pad:
97   %catch = catchpad []
98           to label %catch.body unwind label %catch.end
99
100 catch.body:
101   catchret %catch to label %exit
102
103 catch.end:
104   catchendpad unwind to caller
105
106 exit:
107   unreachable
108 }