1; RUN: opt -mtriple=x86_64-pc-windows-msvc -S -winehprepare -disable-demotion -disable-cleanups < %s | FileCheck %s
2
3declare i32 @__CxxFrameHandler3(...)
4
5declare i32 @__C_specific_handler(...)
6
7declare void @f()
8
9declare i32 @g()
10
11declare void @h(i32)
12
13; CHECK-LABEL: @test1(
14define void @test1(i1 %bool) personality i32 (...)* @__C_specific_handler {
15entry:
16  invoke void @f()
17          to label %invoke.cont unwind label %left
18
19invoke.cont:
20  invoke void @f()
21          to label %exit unwind label %inner
22
23left:
24  %0 = cleanuppad within none []
25  br i1 %bool, label %shared, label %cleanupret
26
27cleanupret:
28  cleanupret from %0 unwind label %right
29
30right:
31  %1 = cleanuppad within none []
32  br label %shared
33
34shared:
35  %x = call i32 @g()
36  invoke void @f()
37          to label %shared.cont unwind label %inner
38
39shared.cont:
40  unreachable
41
42inner:
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
52exit:
53  unreachable
54}
55
56; CHECK-LABEL: @test2(
57define void @test2(i1 %bool) personality i32 (...)* @__C_specific_handler {
58entry:
59  invoke void @f()
60          to label %shared.cont unwind label %left
61
62left:
63  %0 = cleanuppad within none []
64  br i1 %bool, label %shared, label %cleanupret
65
66cleanupret:
67  cleanupret from %0 unwind label %right
68
69right:
70  %1 = cleanuppad within none []
71  br label %shared
72
73shared:
74  %x = call i32 @g()
75  invoke void @f()
76          to label %shared.cont unwind label %inner
77
78shared.cont:
79  unreachable
80
81inner:
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
90exit:
91  unreachable
92}
93
94; CHECK-LABEL: @test4(
95define void @test4(i1 %x) personality i32 (...)* @__CxxFrameHandler3 {
96entry:
97  invoke void @f()
98          to label %invoke.cont1 unwind label %left
99
100invoke.cont1:
101  invoke void @f()
102          to label %exit unwind label %right
103
104left:
105  %0 = cleanuppad within none []
106  br label %shared
107
108right:
109  %1 = cleanuppad within none []
110  br i1 %x, label %shared, label %right.other
111
112right.other:
113  br label %shared
114
115shared:
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
126exit:
127  unreachable
128}
129
130declare void @__std_terminate()
131