1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -simplifycfg < %s | FileCheck %s
3
4declare void @foo()
5declare void @bar()
6declare void @use.i1(i1)
7
8define void @test_phi_simple(i1 %c) {
9; CHECK-LABEL: @test_phi_simple(
10; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
11; CHECK:       if:
12; CHECK-NEXT:    call void @foo()
13; CHECK-NEXT:    call void @foo()
14; CHECK-NEXT:    br label [[JOIN2:%.*]]
15; CHECK:       else:
16; CHECK-NEXT:    call void @bar()
17; CHECK-NEXT:    call void @bar()
18; CHECK-NEXT:    br label [[JOIN2]]
19; CHECK:       join2:
20; CHECK-NEXT:    ret void
21;
22  br i1 %c, label %if, label %else
23
24if:
25  call void @foo()
26  br label %join
27
28else:
29  call void @bar()
30  br label %join
31
32join:
33  %c2 = phi i1 [ true, %if ], [ false, %else ]
34  br i1 %c2, label %if2, label %else2
35
36if2:
37  call void @foo()
38  br label %join2
39
40else2:
41  call void @bar()
42  br label %join2
43
44join2:
45  ret void
46}
47
48define void @test_phi_extra_use(i1 %c) {
49; CHECK-LABEL: @test_phi_extra_use(
50; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
51; CHECK:       if:
52; CHECK-NEXT:    call void @foo()
53; CHECK-NEXT:    call void @use.i1(i1 true)
54; CHECK-NEXT:    call void @foo()
55; CHECK-NEXT:    br label [[JOIN2:%.*]]
56; CHECK:       else:
57; CHECK-NEXT:    call void @bar()
58; CHECK-NEXT:    call void @use.i1(i1 false)
59; CHECK-NEXT:    call void @bar()
60; CHECK-NEXT:    br label [[JOIN2]]
61; CHECK:       join2:
62; CHECK-NEXT:    ret void
63;
64  br i1 %c, label %if, label %else
65
66if:
67  call void @foo()
68  br label %join
69
70else:
71  call void @bar()
72  br label %join
73
74join:
75  %c2 = phi i1 [ true, %if ], [ false, %else ]
76  call void @use.i1(i1 %c2)
77  br i1 %c2, label %if2, label %else2
78
79if2:
80  call void @foo()
81  br label %join2
82
83else2:
84  call void @bar()
85  br label %join2
86
87join2:
88  ret void
89}
90
91define void @test_phi_extra_use_different_block(i1 %c) {
92; CHECK-LABEL: @test_phi_extra_use_different_block(
93; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
94; CHECK:       if:
95; CHECK-NEXT:    call void @foo()
96; CHECK-NEXT:    br label [[JOIN:%.*]]
97; CHECK:       else:
98; CHECK-NEXT:    call void @bar()
99; CHECK-NEXT:    br label [[JOIN]]
100; CHECK:       join:
101; CHECK-NEXT:    [[C2:%.*]] = phi i1 [ true, [[IF]] ], [ false, [[ELSE]] ]
102; CHECK-NEXT:    br i1 [[C2]], label [[IF2:%.*]], label [[ELSE2:%.*]]
103; CHECK:       if2:
104; CHECK-NEXT:    call void @use.i1(i1 [[C2]])
105; CHECK-NEXT:    call void @foo()
106; CHECK-NEXT:    br label [[JOIN2:%.*]]
107; CHECK:       else2:
108; CHECK-NEXT:    call void @use.i1(i1 [[C2]])
109; CHECK-NEXT:    call void @bar()
110; CHECK-NEXT:    br label [[JOIN2]]
111; CHECK:       join2:
112; CHECK-NEXT:    ret void
113;
114  br i1 %c, label %if, label %else
115
116if:
117  call void @foo()
118  br label %join
119
120else:
121  call void @bar()
122  br label %join
123
124join:
125  %c2 = phi i1 [ true, %if ], [ false, %else ]
126  br i1 %c2, label %if2, label %else2
127
128if2:
129  call void @use.i1(i1 %c2)
130  call void @foo()
131  br label %join2
132
133else2:
134  call void @use.i1(i1 %c2)
135  call void @bar()
136  br label %join2
137
138join2:
139  ret void
140}
141
142define void @test_same_cond_simple(i1 %c) {
143; CHECK-LABEL: @test_same_cond_simple(
144; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
145; CHECK:       if:
146; CHECK-NEXT:    call void @foo()
147; CHECK-NEXT:    br label [[JOIN:%.*]]
148; CHECK:       else:
149; CHECK-NEXT:    call void @bar()
150; CHECK-NEXT:    br label [[JOIN]]
151; CHECK:       join:
152; CHECK-NEXT:    br i1 [[C]], label [[IF2:%.*]], label [[ELSE2:%.*]]
153; CHECK:       if2:
154; CHECK-NEXT:    call void @foo()
155; CHECK-NEXT:    br label [[JOIN2:%.*]]
156; CHECK:       else2:
157; CHECK-NEXT:    call void @bar()
158; CHECK-NEXT:    br label [[JOIN2]]
159; CHECK:       join2:
160; CHECK-NEXT:    ret void
161;
162  br i1 %c, label %if, label %else
163
164if:
165  call void @foo()
166  br label %join
167
168else:
169  call void @bar()
170  br label %join
171
172join:
173  br i1 %c, label %if2, label %else2
174
175if2:
176  call void @foo()
177  br label %join2
178
179else2:
180  call void @bar()
181  br label %join2
182
183join2:
184  ret void
185}
186
187define void @test_same_cond_extra_use(i1 %c) {
188; CHECK-LABEL: @test_same_cond_extra_use(
189; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
190; CHECK:       if:
191; CHECK-NEXT:    call void @foo()
192; CHECK-NEXT:    br label [[JOIN:%.*]]
193; CHECK:       else:
194; CHECK-NEXT:    call void @bar()
195; CHECK-NEXT:    br label [[JOIN]]
196; CHECK:       join:
197; CHECK-NEXT:    call void @use.i1(i1 [[C]])
198; CHECK-NEXT:    br i1 [[C]], label [[IF2:%.*]], label [[ELSE2:%.*]]
199; CHECK:       if2:
200; CHECK-NEXT:    call void @foo()
201; CHECK-NEXT:    br label [[JOIN2:%.*]]
202; CHECK:       else2:
203; CHECK-NEXT:    call void @bar()
204; CHECK-NEXT:    br label [[JOIN2]]
205; CHECK:       join2:
206; CHECK-NEXT:    ret void
207;
208  br i1 %c, label %if, label %else
209
210if:
211  call void @foo()
212  br label %join
213
214else:
215  call void @bar()
216  br label %join
217
218join:
219  call void @use.i1(i1 %c)
220  br i1 %c, label %if2, label %else2
221
222if2:
223  call void @foo()
224  br label %join2
225
226else2:
227  call void @bar()
228  br label %join2
229
230join2:
231  ret void
232}
233
234define void @test_same_cond_extra_use_different_block(i1 %c) {
235; CHECK-LABEL: @test_same_cond_extra_use_different_block(
236; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
237; CHECK:       if:
238; CHECK-NEXT:    call void @foo()
239; CHECK-NEXT:    br label [[JOIN:%.*]]
240; CHECK:       else:
241; CHECK-NEXT:    call void @bar()
242; CHECK-NEXT:    br label [[JOIN]]
243; CHECK:       join:
244; CHECK-NEXT:    br i1 [[C]], label [[IF2:%.*]], label [[ELSE2:%.*]]
245; CHECK:       if2:
246; CHECK-NEXT:    call void @use.i1(i1 [[C]])
247; CHECK-NEXT:    call void @foo()
248; CHECK-NEXT:    br label [[JOIN2:%.*]]
249; CHECK:       else2:
250; CHECK-NEXT:    call void @use.i1(i1 [[C]])
251; CHECK-NEXT:    call void @bar()
252; CHECK-NEXT:    br label [[JOIN2]]
253; CHECK:       join2:
254; CHECK-NEXT:    ret void
255;
256  br i1 %c, label %if, label %else
257
258if:
259  call void @foo()
260  br label %join
261
262else:
263  call void @bar()
264  br label %join
265
266join:
267  br i1 %c, label %if2, label %else2
268
269if2:
270  call void @use.i1(i1 %c)
271  call void @foo()
272  br label %join2
273
274else2:
275  call void @use.i1(i1 %c)
276  call void @bar()
277  br label %join2
278
279join2:
280  ret void
281}
282