1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S < %s | FileCheck %s
4 define i32 @basic(i1 %cond_0, ptr %p) {
7 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
8 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
9 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]]
11 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
12 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
14 ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P:%.*]], align 4
15 ; CHECK-NEXT: [[COND_1:%.*]] = icmp eq i32 [[V]], 0
16 ; CHECK-NEXT: br i1 [[COND_1]], label [[RETURN:%.*]], label [[DEOPT]], !prof [[PROF0]]
18 ; CHECK-NEXT: ret i32 0
21 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
22 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
23 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
26 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
31 %cond_1 = icmp eq i32 %v, 0
32 br i1 %cond_1, label %return, label %deopt2, !prof !0
35 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
42 define i32 @mergeable(i1 %cond_0, i1 %cond_1) {
43 ; CHECK-LABEL: @mergeable(
45 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
46 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
47 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND_NOT:%.*]] = xor i1 [[EXIPLICIT_GUARD_COND]], true
48 ; CHECK-NEXT: [[COND_1_NOT:%.*]] = xor i1 [[COND_1:%.*]], true
49 ; CHECK-NEXT: [[BRMERGE:%.*]] = select i1 [[EXIPLICIT_GUARD_COND_NOT]], i1 true, i1 [[COND_1_NOT]]
50 ; CHECK-NEXT: br i1 [[BRMERGE]], label [[DEOPT:%.*]], label [[RETURN:%.*]], !prof [[PROF1:![0-9]+]]
52 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
53 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
55 ; CHECK-NEXT: ret i32 0
58 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
59 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
60 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
63 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
67 br i1 %cond_1, label %return, label %deopt2, !prof !0
70 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
77 define i32 @basic_swapped_branch(i1 %cond_0, ptr %p) {
78 ; CHECK-LABEL: @basic_swapped_branch(
80 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
81 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
82 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
84 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
85 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
87 ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P:%.*]], align 4
88 ; CHECK-NEXT: [[COND_1:%.*]] = icmp eq i32 [[V]], 0
89 ; CHECK-NEXT: br i1 [[COND_1]], label [[DEOPT]], label [[RETURN:%.*]], !prof [[PROF0]]
91 ; CHECK-NEXT: ret i32 0
94 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
95 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
96 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
99 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
103 %v = load i32, ptr %p
104 %cond_1 = icmp eq i32 %v, 0
105 br i1 %cond_1, label %deopt2, label %return, !prof !0
108 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
115 define i32 @todo_sink_side_effect(i1 %cond_0, i1 %cond_1) {
116 ; CHECK-LABEL: @todo_sink_side_effect(
118 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
119 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
120 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
122 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
123 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
125 ; CHECK-NEXT: call void @unknown()
126 ; CHECK-NEXT: br i1 [[COND_1:%.*]], label [[RETURN:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
128 ; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
129 ; CHECK-NEXT: ret i32 [[DEOPTRET2]]
131 ; CHECK-NEXT: ret i32 0
134 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
135 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
136 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
139 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
144 br i1 %cond_1, label %return, label %deopt2, !prof !0
147 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
154 define i32 @neg_unsinkable_side_effect(i1 %cond_0) {
155 ; CHECK-LABEL: @neg_unsinkable_side_effect(
157 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
158 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
159 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
161 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
162 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
164 ; CHECK-NEXT: [[V:%.*]] = call i32 @unknown_i32()
165 ; CHECK-NEXT: [[COND_1:%.*]] = icmp eq i32 [[V]], 0
166 ; CHECK-NEXT: br i1 [[COND_1]], label [[RETURN:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
168 ; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
169 ; CHECK-NEXT: ret i32 [[DEOPTRET2]]
171 ; CHECK-NEXT: ret i32 0
174 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
175 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
176 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
179 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
183 %v = call i32 @unknown_i32()
184 %cond_1 = icmp eq i32 %v, 0
185 br i1 %cond_1, label %return, label %deopt2, !prof !0
188 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
196 define i32 @neg_inf_loop(i1 %cond_0, i1 %cond_1) {
197 ; CHECK-LABEL: @neg_inf_loop(
199 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
200 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
201 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
203 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
204 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
206 ; CHECK-NEXT: call void @unknown()
207 ; CHECK-NEXT: br i1 [[COND_1:%.*]], label [[RETURN:%.*]], label [[DEOPT]], !prof [[PROF0]]
209 ; CHECK-NEXT: ret i32 0
212 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
213 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
214 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
217 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
222 br i1 %cond_1, label %return, label %deopt, !prof !0
229 define i32 @todo_phi(i1 %cond_0, i1 %cond_1) {
230 ; CHECK-LABEL: @todo_phi(
232 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
233 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
234 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
236 ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ]
237 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[PHI]]) ]
238 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
240 ; CHECK-NEXT: br i1 [[COND_1:%.*]], label [[RETURN:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
242 ; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
243 ; CHECK-NEXT: ret i32 [[DEOPTRET2]]
245 ; CHECK-NEXT: ret i32 0
248 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
249 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
250 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
253 %phi = phi i32 [0, %entry]
254 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %phi) ]
258 br i1 %cond_1, label %return, label %deopt2, !prof !0
261 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
269 define i32 @neg_loop(i1 %cond_0, i1 %cond_1) {
270 ; CHECK-LABEL: @neg_loop(
272 ; CHECK-NEXT: br label [[GUARDED:%.*]]
274 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
275 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
276 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
278 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
279 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
281 ; CHECK-NEXT: call void @unknown()
282 ; CHECK-NEXT: br i1 [[COND_1:%.*]], label [[LOOP:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
284 ; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
285 ; CHECK-NEXT: ret i32 [[DEOPTRET2]]
291 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
292 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
293 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
296 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
301 br i1 %cond_1, label %loop, label %deopt2, !prof !0
304 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
308 ; This one is subtle - We can't widen only one branch use of the
309 ; widenable condition as two branches are correlated. We'd have to
311 define i32 @neg_correlated(i1 %cond_0, i1 %cond_1, ptr %p) {
312 ; CHECK-LABEL: @neg_correlated(
314 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
315 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
316 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
318 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
319 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
321 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND2:%.*]] = and i1 [[COND_1:%.*]], [[WIDENABLE_COND]]
322 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND2]], label [[GUARDED2:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
324 ; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
325 ; CHECK-NEXT: ret i32 [[DEOPTRET2]]
327 ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P:%.*]], align 4
328 ; CHECK-NEXT: [[COND_2:%.*]] = icmp eq i32 [[V]], 0
329 ; CHECK-NEXT: br i1 [[COND_2]], label [[RETURN:%.*]], label [[DEOPT3:%.*]], !prof [[PROF0]]
331 ; CHECK-NEXT: [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
332 ; CHECK-NEXT: ret i32 [[DEOPTRET3]]
334 ; CHECK-NEXT: ret i32 0
337 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
338 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
339 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
342 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
346 %exiplicit_guard_cond2 = and i1 %cond_1, %widenable_cond
347 br i1 %exiplicit_guard_cond2, label %guarded2, label %deopt2, !prof !0
350 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
354 %v = load i32, ptr %p
355 %cond_2 = icmp eq i32 %v, 0
356 br i1 %cond_2, label %return, label %deopt3, !prof !0
359 %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
366 define i32 @trivial_wb(i1 %cond_0, ptr %p) {
367 ; CHECK-LABEL: @trivial_wb(
369 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
370 ; CHECK-NEXT: br i1 [[WIDENABLE_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
372 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
373 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
375 ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P:%.*]], align 4
376 ; CHECK-NEXT: [[COND_1:%.*]] = icmp eq i32 [[V]], 0
377 ; CHECK-NEXT: br i1 [[COND_1]], label [[RETURN:%.*]], label [[DEOPT]], !prof [[PROF0]]
379 ; CHECK-NEXT: ret i32 0
382 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
383 br i1 %widenable_cond, label %guarded, label %deopt, !prof !0
386 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
390 %v = load i32, ptr %p
391 %cond_1 = icmp eq i32 %v, 0
392 br i1 %cond_1, label %return, label %deopt2, !prof !0
395 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
403 define i32 @swapped_wb(i1 %cond_0, ptr %p) {
404 ; CHECK-LABEL: @swapped_wb(
406 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
407 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDENABLE_COND]], [[COND_0:%.*]]
408 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
410 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
411 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
413 ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P:%.*]], align 4
414 ; CHECK-NEXT: [[COND_1:%.*]] = icmp eq i32 [[V]], 0
415 ; CHECK-NEXT: br i1 [[COND_1]], label [[RETURN:%.*]], label [[DEOPT]], !prof [[PROF0]]
417 ; CHECK-NEXT: ret i32 0
420 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
421 %exiplicit_guard_cond = and i1 %widenable_cond, %cond_0
422 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
425 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
429 %v = load i32, ptr %p
430 %cond_1 = icmp eq i32 %v, 0
431 br i1 %cond_1, label %return, label %deopt2, !prof !0
434 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
444 declare void @unknown()
445 declare i32 @unknown_i32()
447 declare i1 @llvm.experimental.widenable.condition()
448 declare i32 @llvm.experimental.deoptimize.i32(...)
450 !0 = !{!"branch_weights", i32 1048576, i32 1}
451 !1 = !{i32 1, i32 -2147483648}