[WinEH] Verify consistent funclet unwind exits
[oota-llvm.git] / test / CodeGen / WinEH / wineh-no-demotion.ll
1 ; RUN: opt -mtriple=x86_x64-pc-windows-msvc -S -winehprepare -disable-demotion -disable-cleanups < %s | FileCheck %s
2
3 declare i32 @__CxxFrameHandler3(...)
4
5 declare i32 @__C_specific_handler(...)
6
7 declare void @f()
8
9 declare i32 @g()
10
11 declare void @h(i32)
12
13 ; CHECK-LABEL: @test1(
14 define void @test1(i1 %bool) personality i32 (...)* @__C_specific_handler {
15 entry:
16   invoke void @f()
17           to label %invoke.cont unwind label %left
18
19 invoke.cont:
20   invoke void @f()
21           to label %exit unwind label %inner
22
23 left:
24   %0 = cleanuppad within none []
25   br i1 %bool, label %shared, label %cleanupret
26
27 cleanupret:
28   cleanupret from %0 unwind label %right
29
30 right:
31   %1 = cleanuppad within none []
32   br label %shared
33
34 shared:
35   %x = call i32 @g()
36   invoke void @f()
37           to label %shared.cont unwind label %inner
38
39 shared.cont:
40   unreachable
41
42 inner:
43   %phi = phi i32 [ %x, %shared ], [ 0, %invoke.cont ]
44   %i = cleanuppad within none []
45   call void @h(i32 %phi)
46   unreachable
47
48 ; CHECK: %phi = phi i32 [ %x, %shared ], [ 0, %invoke.cont ], [ %x.for.left, %shared.for.left ]
49 ; CHECK: %i = cleanuppad within none []
50 ; CHECK: call void @h(i32 %phi)
51
52 exit:
53   unreachable
54 }
55
56 ; CHECK-LABEL: @test2(
57 define void @test2(i1 %bool) personality i32 (...)* @__C_specific_handler {
58 entry:
59   invoke void @f()
60           to label %shared.cont unwind label %left
61
62 left:
63   %0 = cleanuppad within none []
64   br i1 %bool, label %shared, label %cleanupret
65
66 cleanupret:
67   cleanupret from %0 unwind label %right
68
69 right:
70   %1 = cleanuppad within none []
71   br label %shared
72
73 shared:
74   %x = call i32 @g()
75   invoke void @f()
76           to label %shared.cont unwind label %inner
77
78 shared.cont:
79   unreachable
80
81 inner:
82   %i = cleanuppad within none []
83   call void @h(i32 %x)
84   unreachable
85
86 ; CHECK: %x1 = phi i32 [ %x.for.left, %shared.for.left ], [ %x, %shared ]
87 ; CHECK: %i = cleanuppad within none []
88 ; CHECK: call void @h(i32 %x1)
89
90 exit:
91   unreachable
92 }
93
94 ; CHECK-LABEL: @test4(
95 define void @test4(i1 %x) personality i32 (...)* @__CxxFrameHandler3 {
96 entry:
97   invoke void @f()
98           to label %invoke.cont1 unwind label %left
99
100 invoke.cont1:
101   invoke void @f()
102           to label %exit unwind label %right
103
104 left:
105   %0 = cleanuppad within none []
106   br label %shared
107
108 right:
109   %1 = cleanuppad within none []
110   br i1 %x, label %shared, label %right.other
111
112 right.other:
113   br label %shared
114
115 shared:
116   %phi = phi i32 [ 1, %left ], [ 0, %right ], [ -1, %right.other ]
117   call void @h(i32 %phi)
118   unreachable
119
120 ; CHECK: %phi = phi i32 [ 0, %right ], [ -1, %right.other ]
121 ; CHECK: call void @h(i32 %phi)
122
123 ; CHECK: %phi.for.left = phi i32 [ 1, %left ]
124 ; CHECK: call void @h(i32 %phi.for.left)
125
126 exit:
127   unreachable
128 }
129
130 declare void @__std_terminate()