1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -guard-widening-widen-branch-guards=true -guard-widening < %s | FileCheck %s
3 ; RUN: opt -S -guard-widening-widen-branch-guards=true -passes=guard-widening < %s | FileCheck %s
5 ; Basic test case: we wide the first check to check both the
7 define void @f_0(i1 %cond_0, i1 %cond_1) {
10 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
11 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]]
12 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
13 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
15 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
16 ; CHECK-NEXT: ret void
18 ; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
19 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
20 ; CHECK-NEXT: br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
22 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
23 ; CHECK-NEXT: ret void
25 ; CHECK-NEXT: ret void
28 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
29 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
30 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
32 deopt: ; preds = %entry
33 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
36 guarded: ; preds = %entry
37 %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
38 %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
39 br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
41 deopt2: ; preds = %guarded
42 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
45 guarded1: ; preds = %guarded
49 ; Same as @f_0, but with using a more general notion of postdominance.
50 define void @f_1(i1 %cond_0, i1 %cond_1) {
53 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
54 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]]
55 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
56 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
58 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
59 ; CHECK-NEXT: ret void
61 ; CHECK-NEXT: br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
63 ; CHECK-NEXT: br label [[MERGE:%.*]]
65 ; CHECK-NEXT: br label [[MERGE]]
67 ; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
68 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
69 ; CHECK-NEXT: br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
71 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
72 ; CHECK-NEXT: ret void
74 ; CHECK-NEXT: ret void
77 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
78 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
79 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
81 deopt: ; preds = %entry
82 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
85 guarded: ; preds = %entry
86 br i1 undef, label %left, label %right
88 left: ; preds = %guarded
91 right: ; preds = %guarded
94 merge: ; preds = %right, %left
95 %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
96 %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
97 br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
99 deopt2: ; preds = %merge
100 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
103 guarded1: ; preds = %merge
107 ; Like @f_1, but we have some code we need to hoist before we can
108 ; widen a dominanting check.
109 define void @f_2(i32 %a, i32 %b) {
112 ; CHECK-NEXT: [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 10
113 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
114 ; CHECK-NEXT: [[COND_1:%.*]] = icmp ult i32 [[B:%.*]], 10
115 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0]], [[COND_1]]
116 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
117 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
119 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
120 ; CHECK-NEXT: ret void
122 ; CHECK-NEXT: br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
124 ; CHECK-NEXT: br label [[MERGE:%.*]]
126 ; CHECK-NEXT: br label [[MERGE]]
128 ; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
129 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
130 ; CHECK-NEXT: br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
132 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
133 ; CHECK-NEXT: ret void
135 ; CHECK-NEXT: ret void
138 %cond_0 = icmp ult i32 %a, 10
139 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
140 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
141 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
143 deopt: ; preds = %entry
144 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
147 guarded: ; preds = %entry
148 br i1 undef, label %left, label %right
150 left: ; preds = %guarded
153 right: ; preds = %guarded
156 merge: ; preds = %right, %left
157 %cond_1 = icmp ult i32 %b, 10
158 %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
159 %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
160 br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
162 deopt2: ; preds = %merge
163 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
166 guarded1: ; preds = %merge
170 ; Negative test: don't hoist stuff out of control flow
171 ; indiscriminately, since that can make us do more work than needed.
172 define void @f_3(i32 %a, i32 %b) {
175 ; CHECK-NEXT: [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 10
176 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
177 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0]], [[WIDENABLE_COND]]
178 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
180 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
181 ; CHECK-NEXT: ret void
183 ; CHECK-NEXT: br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
185 ; CHECK-NEXT: [[COND_1:%.*]] = icmp ult i32 [[B:%.*]], 10
186 ; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
187 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
188 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
190 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
191 ; CHECK-NEXT: ret void
193 ; CHECK-NEXT: ret void
195 ; CHECK-NEXT: ret void
198 %cond_0 = icmp ult i32 %a, 10
199 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
200 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
201 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
203 deopt: ; preds = %entry
204 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
207 guarded: ; preds = %entry
208 br i1 undef, label %left, label %right
210 left: ; preds = %guarded
211 %cond_1 = icmp ult i32 %b, 10
212 %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
213 %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
214 br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
216 deopt2: ; preds = %left
217 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
220 guarded1: ; preds = %left
223 right: ; preds = %guarded
227 ; But hoisting out of control flow is fine if it makes a loop computed
228 ; condition loop invariant. This behavior may require some tuning in
230 define void @f_4(i32 %a, i32 %b) {
233 ; CHECK-NEXT: [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 10
234 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
235 ; CHECK-NEXT: [[COND_1:%.*]] = icmp ult i32 [[B:%.*]], 10
236 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0]], [[COND_1]]
237 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
238 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
240 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
241 ; CHECK-NEXT: ret void
243 ; CHECK-NEXT: br i1 undef, label [[LOOP:%.*]], label [[LEAVE:%.*]]
245 ; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
246 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
247 ; CHECK-NEXT: br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
249 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
250 ; CHECK-NEXT: ret void
252 ; CHECK-NEXT: br i1 undef, label [[LOOP]], label [[LEAVE]]
254 ; CHECK-NEXT: ret void
257 %cond_0 = icmp ult i32 %a, 10
258 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
259 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
260 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
262 deopt: ; preds = %entry
263 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
266 guarded: ; preds = %entry
267 br i1 undef, label %loop, label %leave
269 loop: ; preds = %guarded1, %guarded
270 %cond_1 = icmp ult i32 %b, 10
271 %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
272 %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
273 br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
275 deopt2: ; preds = %loop
276 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
279 guarded1: ; preds = %loop
280 br i1 undef, label %loop, label %leave
282 leave: ; preds = %guarded1, %guarded
286 ; Hoisting out of control flow is also fine if we can widen the
287 ; dominating check without doing any extra work.
288 define void @f_5(i32 %a) {
291 ; CHECK-NEXT: [[COND_0:%.*]] = icmp ugt i32 [[A:%.*]], 7
292 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
293 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = icmp uge i32 [[A]], 11
294 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
295 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
297 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
298 ; CHECK-NEXT: ret void
300 ; CHECK-NEXT: br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
302 ; CHECK-NEXT: [[COND_1:%.*]] = icmp ugt i32 [[A]], 10
303 ; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
304 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
305 ; CHECK-NEXT: br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
307 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
308 ; CHECK-NEXT: ret void
310 ; CHECK-NEXT: ret void
312 ; CHECK-NEXT: ret void
315 %cond_0 = icmp ugt i32 %a, 7
316 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
317 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
318 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
320 deopt: ; preds = %entry
321 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
324 guarded: ; preds = %entry
325 br i1 undef, label %left, label %right
327 left: ; preds = %guarded
328 %cond_1 = icmp ugt i32 %a, 10
329 %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
330 %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
331 br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
333 deopt2: ; preds = %left
334 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
337 guarded1: ; preds = %left
340 right: ; preds = %guarded
344 ; Negative test: the load from %a can be safely speculated to before
345 ; the first guard, but there is no guarantee that it will produce the
347 define void @f_6(i1* dereferenceable(32) %a, i1* %b, i1 %unknown) {
350 ; CHECK-NEXT: [[COND_0:%.*]] = load i1, i1* [[A:%.*]]
351 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
352 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0]], [[WIDENABLE_COND]]
353 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
355 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
356 ; CHECK-NEXT: ret void
358 ; CHECK-NEXT: store i1 [[UNKNOWN:%.*]], i1* [[B:%.*]]
359 ; CHECK-NEXT: [[COND_1:%.*]] = load i1, i1* [[A]]
360 ; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
361 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
362 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
364 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
365 ; CHECK-NEXT: ret void
367 ; CHECK-NEXT: ret void
370 %cond_0 = load i1, i1* %a
371 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
372 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
373 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
375 deopt: ; preds = %entry
376 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
379 guarded: ; preds = %entry
380 store i1 %unknown, i1* %b
381 %cond_1 = load i1, i1* %a
382 %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
383 %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
384 br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
386 deopt2: ; preds = %guarded
387 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
390 guarded1: ; preds = %guarded
394 ; All else equal, we try to widen the earliest guard we can. This
395 ; heuristic can use some tuning.
396 define void @f_7(i32 %a, i1* %cond_buf) {
399 ; CHECK-NEXT: [[COND_1:%.*]] = load volatile i1, i1* [[COND_BUF:%.*]]
400 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
401 ; CHECK-NEXT: [[COND_3:%.*]] = icmp ult i32 [[A:%.*]], 7
402 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_1]], [[COND_3]]
403 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
404 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
406 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
407 ; CHECK-NEXT: ret void
409 ; CHECK-NEXT: [[COND_2:%.*]] = load volatile i1, i1* [[COND_BUF]]
410 ; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
411 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_2]], [[WIDENABLE_COND3]]
412 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
414 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
415 ; CHECK-NEXT: ret void
417 ; CHECK-NEXT: br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
419 ; CHECK-NEXT: [[WIDENABLE_COND7:%.*]] = call i1 @llvm.experimental.widenable.condition()
420 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND8:%.*]] = and i1 [[COND_3]], [[WIDENABLE_COND7]]
421 ; CHECK-NEXT: br i1 true, label [[GUARDED5:%.*]], label [[DEOPT6:%.*]], !prof !0
423 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
424 ; CHECK-NEXT: ret void
426 ; CHECK-NEXT: br label [[LEFT]]
428 ; CHECK-NEXT: ret void
431 %cond_1 = load volatile i1, i1* %cond_buf
432 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
433 %exiplicit_guard_cond = and i1 %cond_1, %widenable_cond
434 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
436 deopt: ; preds = %entry
437 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
440 guarded: ; preds = %entry
441 %cond_2 = load volatile i1, i1* %cond_buf
442 %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
443 %exiplicit_guard_cond4 = and i1 %cond_2, %widenable_cond3
444 br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
446 deopt2: ; preds = %guarded
447 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
450 guarded1: ; preds = %guarded
451 br i1 undef, label %left, label %right
453 left: ; preds = %guarded5, %guarded1
454 %cond_3 = icmp ult i32 %a, 7
455 %widenable_cond7 = call i1 @llvm.experimental.widenable.condition()
456 %exiplicit_guard_cond8 = and i1 %cond_3, %widenable_cond7
457 br i1 %exiplicit_guard_cond8, label %guarded5, label %deopt6, !prof !0
459 deopt6: ; preds = %left
460 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
463 guarded5: ; preds = %left
466 right: ; preds = %guarded1
470 ; In this case the earliest dominating guard is in a loop, and we
471 ; don't want to put extra work in there. This heuristic can use some
473 define void @f_8(i32 %a, i1 %cond_1, i1 %cond_2) {
476 ; CHECK-NEXT: br label [[LOOP:%.*]]
478 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
479 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_1:%.*]], [[WIDENABLE_COND]]
480 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
482 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
483 ; CHECK-NEXT: ret void
485 ; CHECK-NEXT: br i1 undef, label [[LOOP]], label [[LEAVE:%.*]]
487 ; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
488 ; CHECK-NEXT: [[COND_3:%.*]] = icmp ult i32 [[A:%.*]], 7
489 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_2:%.*]], [[COND_3]]
490 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND3]]
491 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
493 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
494 ; CHECK-NEXT: ret void
496 ; CHECK-NEXT: br i1 undef, label [[LOOP2:%.*]], label [[LEAVE2:%.*]]
498 ; CHECK-NEXT: [[WIDENABLE_COND7:%.*]] = call i1 @llvm.experimental.widenable.condition()
499 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND8:%.*]] = and i1 [[COND_3]], [[WIDENABLE_COND7]]
500 ; CHECK-NEXT: br i1 true, label [[GUARDED5:%.*]], label [[DEOPT6:%.*]], !prof !0
502 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
503 ; CHECK-NEXT: ret void
505 ; CHECK-NEXT: br label [[LOOP2]]
507 ; CHECK-NEXT: ret void
512 loop: ; preds = %guarded, %entry
513 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
514 %exiplicit_guard_cond = and i1 %cond_1, %widenable_cond
515 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
517 deopt: ; preds = %loop
518 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
521 guarded: ; preds = %loop
522 br i1 undef, label %loop, label %leave
524 leave: ; preds = %guarded
525 %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
526 %exiplicit_guard_cond4 = and i1 %cond_2, %widenable_cond3
527 br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
529 deopt2: ; preds = %leave
530 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
533 guarded1: ; preds = %leave
534 br i1 undef, label %loop2, label %leave2
536 loop2: ; preds = %guarded5, %guarded1
537 %cond_3 = icmp ult i32 %a, 7
538 %widenable_cond7 = call i1 @llvm.experimental.widenable.condition()
539 %exiplicit_guard_cond8 = and i1 %cond_3, %widenable_cond7
540 br i1 %exiplicit_guard_cond8, label %guarded5, label %deopt6, !prof !0
542 deopt6: ; preds = %loop2
543 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
546 guarded5: ; preds = %loop2
549 leave2: ; preds = %guarded1
553 ; In cases like these where there isn't any "obviously profitable"
554 ; widening sites, we refuse to do anything.
555 define void @f_9(i32 %a, i1 %cond_0, i1 %cond_1) {
558 ; CHECK-NEXT: br label [[FIRST_LOOP:%.*]]
560 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
561 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
562 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
564 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
565 ; CHECK-NEXT: ret void
567 ; CHECK-NEXT: br i1 undef, label [[FIRST_LOOP]], label [[SECOND_LOOP:%.*]]
568 ; CHECK: second_loop:
569 ; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
570 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1:%.*]], [[WIDENABLE_COND3]]
571 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
573 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
574 ; CHECK-NEXT: ret void
576 ; CHECK-NEXT: br label [[SECOND_LOOP]]
581 first_loop: ; preds = %guarded, %entry
582 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
583 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
584 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
586 deopt: ; preds = %first_loop
587 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
590 guarded: ; preds = %first_loop
591 br i1 undef, label %first_loop, label %second_loop
593 second_loop: ; preds = %guarded1, %guarded
594 %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
595 %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
596 br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
598 deopt2: ; preds = %second_loop
599 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
602 guarded1: ; preds = %second_loop
603 br label %second_loop
606 ; Same situation as in @f_9: no "obviously profitable" widening sites,
607 ; so we refuse to do anything.
608 define void @f_10(i32 %a, i1 %cond_0, i1 %cond_1) {
609 ; CHECK-LABEL: @f_10(
611 ; CHECK-NEXT: br label [[LOOP:%.*]]
613 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
614 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
615 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
617 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
618 ; CHECK-NEXT: ret void
620 ; CHECK-NEXT: br i1 undef, label [[LOOP]], label [[NO_LOOP:%.*]]
622 ; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
623 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1:%.*]], [[WIDENABLE_COND3]]
624 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
626 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
627 ; CHECK-NEXT: ret void
629 ; CHECK-NEXT: ret void
634 loop: ; preds = %guarded, %entry
635 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
636 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
637 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
639 deopt: ; preds = %loop
640 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
643 guarded: ; preds = %loop
644 br i1 undef, label %loop, label %no_loop
646 no_loop: ; preds = %guarded
647 %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
648 %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
649 br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
651 deopt2: ; preds = %no_loop
652 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
655 guarded1: ; preds = %no_loop
659 ; With guards in loops, we're okay hoisting out the guard into the
661 define void @f_11(i32 %a, i1 %cond_0, i1 %cond_1) {
662 ; CHECK-LABEL: @f_11(
664 ; CHECK-NEXT: br label [[OUTER_HEADER:%.*]]
665 ; CHECK: outer_header:
666 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
667 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]]
668 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
669 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
671 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
672 ; CHECK-NEXT: ret void
674 ; CHECK-NEXT: br label [[INNER:%.*]]
676 ; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
677 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
678 ; CHECK-NEXT: br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
680 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
681 ; CHECK-NEXT: ret void
683 ; CHECK-NEXT: br i1 undef, label [[INNER]], label [[OUTER_LATCH:%.*]]
684 ; CHECK: outer_latch:
685 ; CHECK-NEXT: br i1 undef, label [[OUTER_HEADER]], label [[EXIT:%.*]]
687 ; CHECK-NEXT: ret void
690 br label %outer_header
692 outer_header: ; preds = %outer_latch, %entry
693 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
694 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
695 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
697 deopt: ; preds = %outer_header
698 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
701 guarded: ; preds = %outer_header
704 inner: ; preds = %guarded1, %guarded
705 %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
706 %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
707 br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
709 deopt2: ; preds = %inner
710 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
713 guarded1: ; preds = %inner
714 br i1 undef, label %inner, label %outer_latch
716 outer_latch: ; preds = %guarded1
717 br i1 undef, label %outer_header, label %exit
719 exit: ; preds = %outer_latch
723 ; Checks that we are adequately guarded against exponential-time
724 ; behavior when hoisting code.
725 define void @f_12(i32 %a0) {
726 ; CHECK-LABEL: @f_12(
728 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
729 ; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A0:%.*]], [[A0]]
730 ; CHECK-NEXT: [[A2:%.*]] = mul i32 [[A1]], [[A1]]
731 ; CHECK-NEXT: [[A3:%.*]] = mul i32 [[A2]], [[A2]]
732 ; CHECK-NEXT: [[A4:%.*]] = mul i32 [[A3]], [[A3]]
733 ; CHECK-NEXT: [[A5:%.*]] = mul i32 [[A4]], [[A4]]
734 ; CHECK-NEXT: [[A6:%.*]] = mul i32 [[A5]], [[A5]]
735 ; CHECK-NEXT: [[A7:%.*]] = mul i32 [[A6]], [[A6]]
736 ; CHECK-NEXT: [[A8:%.*]] = mul i32 [[A7]], [[A7]]
737 ; CHECK-NEXT: [[A9:%.*]] = mul i32 [[A8]], [[A8]]
738 ; CHECK-NEXT: [[A10:%.*]] = mul i32 [[A9]], [[A9]]
739 ; CHECK-NEXT: [[A11:%.*]] = mul i32 [[A10]], [[A10]]
740 ; CHECK-NEXT: [[A12:%.*]] = mul i32 [[A11]], [[A11]]
741 ; CHECK-NEXT: [[A13:%.*]] = mul i32 [[A12]], [[A12]]
742 ; CHECK-NEXT: [[A14:%.*]] = mul i32 [[A13]], [[A13]]
743 ; CHECK-NEXT: [[A15:%.*]] = mul i32 [[A14]], [[A14]]
744 ; CHECK-NEXT: [[A16:%.*]] = mul i32 [[A15]], [[A15]]
745 ; CHECK-NEXT: [[A17:%.*]] = mul i32 [[A16]], [[A16]]
746 ; CHECK-NEXT: [[A18:%.*]] = mul i32 [[A17]], [[A17]]
747 ; CHECK-NEXT: [[A19:%.*]] = mul i32 [[A18]], [[A18]]
748 ; CHECK-NEXT: [[A20:%.*]] = mul i32 [[A19]], [[A19]]
749 ; CHECK-NEXT: [[A21:%.*]] = mul i32 [[A20]], [[A20]]
750 ; CHECK-NEXT: [[A22:%.*]] = mul i32 [[A21]], [[A21]]
751 ; CHECK-NEXT: [[A23:%.*]] = mul i32 [[A22]], [[A22]]
752 ; CHECK-NEXT: [[A24:%.*]] = mul i32 [[A23]], [[A23]]
753 ; CHECK-NEXT: [[A25:%.*]] = mul i32 [[A24]], [[A24]]
754 ; CHECK-NEXT: [[A26:%.*]] = mul i32 [[A25]], [[A25]]
755 ; CHECK-NEXT: [[A27:%.*]] = mul i32 [[A26]], [[A26]]
756 ; CHECK-NEXT: [[A28:%.*]] = mul i32 [[A27]], [[A27]]
757 ; CHECK-NEXT: [[A29:%.*]] = mul i32 [[A28]], [[A28]]
758 ; CHECK-NEXT: [[A30:%.*]] = mul i32 [[A29]], [[A29]]
759 ; CHECK-NEXT: [[COND:%.*]] = trunc i32 [[A30]] to i1
760 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 true, [[COND]]
761 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
762 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
764 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
765 ; CHECK-NEXT: ret void
767 ; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
768 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND]], [[WIDENABLE_COND3]]
769 ; CHECK-NEXT: br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
771 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
772 ; CHECK-NEXT: ret void
774 ; CHECK-NEXT: ret void
777 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
778 %exiplicit_guard_cond = and i1 true, %widenable_cond
779 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
781 deopt: ; preds = %entry
782 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
785 guarded: ; preds = %entry
786 %a1 = mul i32 %a0, %a0
787 %a2 = mul i32 %a1, %a1
788 %a3 = mul i32 %a2, %a2
789 %a4 = mul i32 %a3, %a3
790 %a5 = mul i32 %a4, %a4
791 %a6 = mul i32 %a5, %a5
792 %a7 = mul i32 %a6, %a6
793 %a8 = mul i32 %a7, %a7
794 %a9 = mul i32 %a8, %a8
795 %a10 = mul i32 %a9, %a9
796 %a11 = mul i32 %a10, %a10
797 %a12 = mul i32 %a11, %a11
798 %a13 = mul i32 %a12, %a12
799 %a14 = mul i32 %a13, %a13
800 %a15 = mul i32 %a14, %a14
801 %a16 = mul i32 %a15, %a15
802 %a17 = mul i32 %a16, %a16
803 %a18 = mul i32 %a17, %a17
804 %a19 = mul i32 %a18, %a18
805 %a20 = mul i32 %a19, %a19
806 %a21 = mul i32 %a20, %a20
807 %a22 = mul i32 %a21, %a21
808 %a23 = mul i32 %a22, %a22
809 %a24 = mul i32 %a23, %a23
810 %a25 = mul i32 %a24, %a24
811 %a26 = mul i32 %a25, %a25
812 %a27 = mul i32 %a26, %a26
813 %a28 = mul i32 %a27, %a27
814 %a29 = mul i32 %a28, %a28
815 %a30 = mul i32 %a29, %a29
816 %cond = trunc i32 %a30 to i1
817 %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
818 %exiplicit_guard_cond4 = and i1 %cond, %widenable_cond3
819 br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
821 deopt2: ; preds = %guarded
822 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
825 guarded1: ; preds = %guarded
829 define void @f_13(i32 %a) {
830 ; CHECK-LABEL: @f_13(
832 ; CHECK-NEXT: [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 14
833 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
834 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = icmp ult i32 [[A]], 10
835 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
836 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
838 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
839 ; CHECK-NEXT: ret void
841 ; CHECK-NEXT: br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
843 ; CHECK-NEXT: [[COND_1:%.*]] = icmp slt i32 [[A]], 10
844 ; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
845 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
846 ; CHECK-NEXT: br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
848 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
849 ; CHECK-NEXT: ret void
851 ; CHECK-NEXT: ret void
853 ; CHECK-NEXT: ret void
856 %cond_0 = icmp ult i32 %a, 14
857 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
858 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
859 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
861 deopt: ; preds = %entry
862 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
865 guarded: ; preds = %entry
866 br i1 undef, label %left, label %right
868 left: ; preds = %guarded
869 %cond_1 = icmp slt i32 %a, 10
870 %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
871 %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
872 br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
874 deopt2: ; preds = %left
875 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
878 guarded1: ; preds = %left
881 right: ; preds = %guarded
885 define void @f_14(i32 %a) {
886 ; CHECK-LABEL: @f_14(
888 ; CHECK-NEXT: [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 14
889 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
890 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0]], [[WIDENABLE_COND]]
891 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
893 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
894 ; CHECK-NEXT: ret void
896 ; CHECK-NEXT: br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
898 ; CHECK-NEXT: [[COND_1:%.*]] = icmp sgt i32 [[A]], 10
899 ; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
900 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
901 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
903 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
904 ; CHECK-NEXT: ret void
906 ; CHECK-NEXT: ret void
908 ; CHECK-NEXT: ret void
911 %cond_0 = icmp ult i32 %a, 14
912 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
913 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
914 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
916 deopt: ; preds = %entry
917 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
920 guarded: ; preds = %entry
921 br i1 undef, label %left, label %right
923 left: ; preds = %guarded
924 %cond_1 = icmp sgt i32 %a, 10
925 %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
926 %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
927 br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
929 deopt2: ; preds = %left
930 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
933 guarded1: ; preds = %left
936 right: ; preds = %guarded
940 ; Make sure we do not widen guard by trivial true conditions into something.
941 define void @f_15(i1 %cond_0, i1 %cond_1) {
942 ; CHECK-LABEL: @f_15(
944 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
945 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
946 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
948 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
949 ; CHECK-NEXT: ret void
951 ; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
952 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 true, [[WIDENABLE_COND3]]
953 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
955 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
956 ; CHECK-NEXT: ret void
958 ; CHECK-NEXT: ret void
961 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
962 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
963 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
965 deopt: ; preds = %entry
966 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
969 guarded: ; preds = %entry
970 %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
971 %exiplicit_guard_cond4 = and i1 true, %widenable_cond3
972 br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
974 deopt2: ; preds = %guarded
975 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
978 guarded1: ; preds = %guarded
982 ; Make sure we do not widen guard by trivial false conditions into something.
983 define void @f_16(i1 %cond_0, i1 %cond_1) {
984 ; CHECK-LABEL: @f_16(
986 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
987 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
988 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
990 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
991 ; CHECK-NEXT: ret void
993 ; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
994 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 false, [[WIDENABLE_COND3]]
995 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
997 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
998 ; CHECK-NEXT: ret void
1000 ; CHECK-NEXT: ret void
1003 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1004 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
1005 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1007 deopt: ; preds = %entry
1008 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1011 guarded: ; preds = %entry
1012 %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
1013 %exiplicit_guard_cond4 = and i1 false, %widenable_cond3
1014 br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
1016 deopt2: ; preds = %guarded
1017 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1020 guarded1: ; preds = %guarded
1025 define void @swapped_wb(i1 %cond_0, i1 %cond_1) {
1026 ; CHECK-LABEL: @swapped_wb(
1027 ; CHECK-NEXT: entry:
1028 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1029 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]]
1030 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDENABLE_COND]], [[WIDE_CHK]]
1031 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
1033 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1034 ; CHECK-NEXT: ret void
1036 ; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
1037 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
1038 ; CHECK-NEXT: br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
1040 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1041 ; CHECK-NEXT: ret void
1043 ; CHECK-NEXT: ret void
1046 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1047 %exiplicit_guard_cond = and i1 %widenable_cond, %cond_0
1048 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1050 deopt: ; preds = %entry
1051 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1054 guarded: ; preds = %entry
1055 %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
1056 %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
1057 br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
1059 deopt2: ; preds = %guarded
1060 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1063 guarded1: ; preds = %guarded
1067 define void @trivial_wb(i1 %cond_0) {
1068 ; CHECK-LABEL: @trivial_wb(
1069 ; CHECK-NEXT: entry:
1070 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1071 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 true, [[COND_0:%.*]]
1072 ; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
1073 ; CHECK-NEXT: br i1 [[TMP0]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
1075 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1076 ; CHECK-NEXT: ret void
1078 ; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
1079 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_0]], [[WIDENABLE_COND3]]
1080 ; CHECK-NEXT: br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
1082 ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1083 ; CHECK-NEXT: ret void
1085 ; CHECK-NEXT: ret void
1088 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1089 br i1 %widenable_cond, label %guarded, label %deopt, !prof !0
1091 deopt: ; preds = %entry
1092 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1095 guarded: ; preds = %entry
1096 %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
1097 %exiplicit_guard_cond4 = and i1 %cond_0, %widenable_cond3
1098 br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
1100 deopt2: ; preds = %guarded
1101 call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1104 guarded1: ; preds = %guarded
1109 declare void @llvm.experimental.deoptimize.isVoid(...)
1111 ; Function Attrs: inaccessiblememonly nounwind
1112 declare i1 @llvm.experimental.widenable.condition() #0
1114 attributes #0 = { inaccessiblememonly nounwind }
1116 !0 = !{!"branch_weights", i32 1048576, i32 1}