Use "isa" since the variable isn't used.
[llvm-complete.git] / test / Transforms / GuardWidening / basic_widenable_condition_guards.ll
blob605178a7868bbc45517e7a09a787bb61e61ae9dd
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
6 ; conditions.
7 define void @f_0(i1 %cond_0, i1 %cond_1) {
8 ; CHECK-LABEL: @f_0(
9 ; CHECK-NEXT:  entry:
10 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
11 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
12 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0]], [[COND_1:%.*]]
13 ; CHECK-NEXT:    [[GUARD_CHK:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
14 ; CHECK-NEXT:    br i1 [[GUARD_CHK]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
15 ; CHECK:       deopt:
16 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
17 ; CHECK-NEXT:    ret void
18 ; CHECK:       guarded:
19 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
20 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
21 ; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
22 ; CHECK:       deopt2:
23 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
24 ; CHECK-NEXT:    ret void
25 ; CHECK:       guarded1:
26 ; CHECK-NEXT:    ret void
28 entry:
29   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
30   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
31   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
33 deopt:                                            ; preds = %entry
34   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
35   ret void
37 guarded:                                          ; preds = %entry
38   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
39   %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
40   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
42 deopt2:                                           ; preds = %guarded
43   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
44   ret void
46 guarded1:                                         ; preds = %guarded
47   ret void
50 ; Same as @f_0, but with using a more general notion of postdominance.
51 define void @f_1(i1 %cond_0, i1 %cond_1) {
52 ; CHECK-LABEL: @f_1(
53 ; CHECK-NEXT:  entry:
54 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
55 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
56 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0]], [[COND_1:%.*]]
57 ; CHECK-NEXT:    [[GUARD_CHK:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
58 ; CHECK-NEXT:    br i1 [[GUARD_CHK]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
59 ; CHECK:       deopt:
60 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
61 ; CHECK-NEXT:    ret void
62 ; CHECK:       guarded:
63 ; CHECK-NEXT:    br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
64 ; CHECK:       left:
65 ; CHECK-NEXT:    br label [[MERGE:%.*]]
66 ; CHECK:       right:
67 ; CHECK-NEXT:    br label [[MERGE]]
68 ; CHECK:       merge:
69 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
70 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
71 ; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
72 ; CHECK:       deopt2:
73 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
74 ; CHECK-NEXT:    ret void
75 ; CHECK:       guarded1:
76 ; CHECK-NEXT:    ret void
78 entry:
79   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
80   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
81   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
83 deopt:                                            ; preds = %entry
84   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
85   ret void
87 guarded:                                          ; preds = %entry
88   br i1 undef, label %left, label %right
90 left:                                             ; preds = %guarded
91   br label %merge
93 right:                                            ; preds = %guarded
94   br label %merge
96 merge:                                            ; preds = %right, %left
97   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
98   %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
99   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
101 deopt2:                                           ; preds = %merge
102   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
103   ret void
105 guarded1:                                         ; preds = %merge
106   ret void
109 ; Like @f_1, but we have some code we need to hoist before we can
110 ; widen a dominanting check.
111 define void @f_2(i32 %a, i32 %b) {
112 ; CHECK-LABEL: @f_2(
113 ; CHECK-NEXT:  entry:
114 ; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 10
115 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
116 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0]], [[WIDENABLE_COND]]
117 ; CHECK-NEXT:    [[COND_1:%.*]] = icmp ult i32 [[B:%.*]], 10
118 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0]], [[COND_1]]
119 ; CHECK-NEXT:    [[GUARD_CHK:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
120 ; CHECK-NEXT:    br i1 [[GUARD_CHK]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
121 ; CHECK:       deopt:
122 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
123 ; CHECK-NEXT:    ret void
124 ; CHECK:       guarded:
125 ; CHECK-NEXT:    br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
126 ; CHECK:       left:
127 ; CHECK-NEXT:    br label [[MERGE:%.*]]
128 ; CHECK:       right:
129 ; CHECK-NEXT:    br label [[MERGE]]
130 ; CHECK:       merge:
131 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
132 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
133 ; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
134 ; CHECK:       deopt2:
135 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
136 ; CHECK-NEXT:    ret void
137 ; CHECK:       guarded1:
138 ; CHECK-NEXT:    ret void
140 entry:
141   %cond_0 = icmp ult i32 %a, 10
142   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
143   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
144   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
146 deopt:                                            ; preds = %entry
147   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
148   ret void
150 guarded:                                          ; preds = %entry
151   br i1 undef, label %left, label %right
153 left:                                             ; preds = %guarded
154   br label %merge
156 right:                                            ; preds = %guarded
157   br label %merge
159 merge:                                            ; preds = %right, %left
160   %cond_1 = icmp ult i32 %b, 10
161   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
162   %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
163   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
165 deopt2:                                           ; preds = %merge
166   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
167   ret void
169 guarded1:                                         ; preds = %merge
170   ret void
173 ; Negative test: don't hoist stuff out of control flow
174 ; indiscriminately, since that can make us do more work than needed.
175 define void @f_3(i32 %a, i32 %b) {
176 ; CHECK-LABEL: @f_3(
177 ; CHECK-NEXT:  entry:
178 ; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 10
179 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
180 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0]], [[WIDENABLE_COND]]
181 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
182 ; CHECK:       deopt:
183 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
184 ; CHECK-NEXT:    ret void
185 ; CHECK:       guarded:
186 ; CHECK-NEXT:    br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
187 ; CHECK:       left:
188 ; CHECK-NEXT:    [[COND_1:%.*]] = icmp ult i32 [[B:%.*]], 10
189 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
190 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
191 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
192 ; CHECK:       deopt2:
193 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
194 ; CHECK-NEXT:    ret void
195 ; CHECK:       guarded1:
196 ; CHECK-NEXT:    ret void
197 ; CHECK:       right:
198 ; CHECK-NEXT:    ret void
200 entry:
201   %cond_0 = icmp ult i32 %a, 10
202   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
203   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
204   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
206 deopt:                                            ; preds = %entry
207   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
208   ret void
210 guarded:                                          ; preds = %entry
211   br i1 undef, label %left, label %right
213 left:                                             ; preds = %guarded
214   %cond_1 = icmp ult i32 %b, 10
215   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
216   %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
217   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
219 deopt2:                                           ; preds = %left
220   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
221   ret void
223 guarded1:                                         ; preds = %left
224   ret void
226 right:                                            ; preds = %guarded
227   ret void
230 ; But hoisting out of control flow is fine if it makes a loop computed
231 ; condition loop invariant.  This behavior may require some tuning in
232 ; the future.
233 define void @f_4(i32 %a, i32 %b) {
234 ; CHECK-LABEL: @f_4(
235 ; CHECK-NEXT:  entry:
236 ; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 10
237 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
238 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0]], [[WIDENABLE_COND]]
239 ; CHECK-NEXT:    [[COND_1:%.*]] = icmp ult i32 [[B:%.*]], 10
240 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0]], [[COND_1]]
241 ; CHECK-NEXT:    [[GUARD_CHK:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
242 ; CHECK-NEXT:    br i1 [[GUARD_CHK]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
243 ; CHECK:       deopt:
244 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
245 ; CHECK-NEXT:    ret void
246 ; CHECK:       guarded:
247 ; CHECK-NEXT:    br i1 undef, label [[LOOP:%.*]], label [[LEAVE:%.*]]
248 ; CHECK:       loop:
249 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
250 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
251 ; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
252 ; CHECK:       deopt2:
253 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
254 ; CHECK-NEXT:    ret void
255 ; CHECK:       guarded1:
256 ; CHECK-NEXT:    br i1 undef, label [[LOOP]], label [[LEAVE]]
257 ; CHECK:       leave:
258 ; CHECK-NEXT:    ret void
260 entry:
261   %cond_0 = icmp ult i32 %a, 10
262   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
263   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
264   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
266 deopt:                                            ; preds = %entry
267   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
268   ret void
270 guarded:                                          ; preds = %entry
271   br i1 undef, label %loop, label %leave
273 loop:                                             ; preds = %guarded1, %guarded
274   %cond_1 = icmp ult i32 %b, 10
275   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
276   %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
277   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
279 deopt2:                                           ; preds = %loop
280   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
281   ret void
283 guarded1:                                         ; preds = %loop
284   br i1 undef, label %loop, label %leave
286 leave:                                            ; preds = %guarded1, %guarded
287   ret void
290 ; Hoisting out of control flow is also fine if we can widen the
291 ; dominating check without doing any extra work.
292 define void @f_5(i32 %a) {
293 ; CHECK-LABEL: @f_5(
294 ; CHECK-NEXT:  entry:
295 ; CHECK-NEXT:    [[COND_0:%.*]] = icmp ugt i32 [[A:%.*]], 7
296 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
297 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0]], [[WIDENABLE_COND]]
298 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = icmp uge i32 [[A]], 11
299 ; CHECK-NEXT:    [[GUARD_CHK:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
300 ; CHECK-NEXT:    br i1 [[GUARD_CHK]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
301 ; CHECK:       deopt:
302 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
303 ; CHECK-NEXT:    ret void
304 ; CHECK:       guarded:
305 ; CHECK-NEXT:    br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
306 ; CHECK:       left:
307 ; CHECK-NEXT:    [[COND_1:%.*]] = icmp ugt i32 [[A]], 10
308 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
309 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
310 ; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
311 ; CHECK:       deopt2:
312 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
313 ; CHECK-NEXT:    ret void
314 ; CHECK:       guarded1:
315 ; CHECK-NEXT:    ret void
316 ; CHECK:       right:
317 ; CHECK-NEXT:    ret void
319 entry:
320   %cond_0 = icmp ugt i32 %a, 7
321   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
322   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
323   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
325 deopt:                                            ; preds = %entry
326   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
327   ret void
329 guarded:                                          ; preds = %entry
330   br i1 undef, label %left, label %right
332 left:                                             ; preds = %guarded
333   %cond_1 = icmp ugt i32 %a, 10
334   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
335   %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
336   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
338 deopt2:                                           ; preds = %left
339   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
340   ret void
342 guarded1:                                         ; preds = %left
343   ret void
345 right:                                            ; preds = %guarded
346   ret void
349 ; Negative test: the load from %a can be safely speculated to before
350 ; the first guard, but there is no guarantee that it will produce the
351 ; same value.
352 define void @f_6(i1* dereferenceable(32) %a, i1* %b, i1 %unknown) {
353 ; CHECK-LABEL: @f_6(
354 ; CHECK-NEXT:  entry:
355 ; CHECK-NEXT:    [[COND_0:%.*]] = load i1, i1* [[A:%.*]]
356 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
357 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0]], [[WIDENABLE_COND]]
358 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
359 ; CHECK:       deopt:
360 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
361 ; CHECK-NEXT:    ret void
362 ; CHECK:       guarded:
363 ; CHECK-NEXT:    store i1 [[UNKNOWN:%.*]], i1* [[B:%.*]]
364 ; CHECK-NEXT:    [[COND_1:%.*]] = load i1, i1* [[A]]
365 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
366 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
367 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
368 ; CHECK:       deopt2:
369 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
370 ; CHECK-NEXT:    ret void
371 ; CHECK:       guarded1:
372 ; CHECK-NEXT:    ret void
374 entry:
375   %cond_0 = load i1, i1* %a
376   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
377   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
378   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
380 deopt:                                            ; preds = %entry
381   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
382   ret void
384 guarded:                                          ; preds = %entry
385   store i1 %unknown, i1* %b
386   %cond_1 = load i1, i1* %a
387   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
388   %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
389   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
391 deopt2:                                           ; preds = %guarded
392   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
393   ret void
395 guarded1:                                         ; preds = %guarded
396   ret void
399 ; All else equal, we try to widen the earliest guard we can.  This
400 ; heuristic can use some tuning.
401 define void @f_7(i32 %a, i1* %cond_buf) {
402 ; CHECK-LABEL: @f_7(
403 ; CHECK-NEXT:  entry:
404 ; CHECK-NEXT:    [[COND_1:%.*]] = load volatile i1, i1* [[COND_BUF:%.*]]
405 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
406 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND]]
407 ; CHECK-NEXT:    [[COND_3:%.*]] = icmp ult i32 [[A:%.*]], 7
408 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_1]], [[COND_3]]
409 ; CHECK-NEXT:    [[GUARD_CHK:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
410 ; CHECK-NEXT:    br i1 [[GUARD_CHK]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
411 ; CHECK:       deopt:
412 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
413 ; CHECK-NEXT:    ret void
414 ; CHECK:       guarded:
415 ; CHECK-NEXT:    [[COND_2:%.*]] = load volatile i1, i1* [[COND_BUF]]
416 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
417 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_2]], [[WIDENABLE_COND3]]
418 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
419 ; CHECK:       deopt2:
420 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
421 ; CHECK-NEXT:    ret void
422 ; CHECK:       guarded1:
423 ; CHECK-NEXT:    br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
424 ; CHECK:       left:
425 ; CHECK-NEXT:    [[WIDENABLE_COND7:%.*]] = call i1 @llvm.experimental.widenable.condition()
426 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND8:%.*]] = and i1 [[COND_3]], [[WIDENABLE_COND7]]
427 ; CHECK-NEXT:    br i1 true, label [[GUARDED5:%.*]], label [[DEOPT6:%.*]], !prof !0
428 ; CHECK:       deopt6:
429 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
430 ; CHECK-NEXT:    ret void
431 ; CHECK:       guarded5:
432 ; CHECK-NEXT:    br label [[LEFT]]
433 ; CHECK:       right:
434 ; CHECK-NEXT:    ret void
436 entry:
437   %cond_1 = load volatile i1, i1* %cond_buf
438   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
439   %exiplicit_guard_cond = and i1 %cond_1, %widenable_cond
440   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
442 deopt:                                            ; preds = %entry
443   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
444   ret void
446 guarded:                                          ; preds = %entry
447   %cond_2 = load volatile i1, i1* %cond_buf
448   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
449   %exiplicit_guard_cond4 = and i1 %cond_2, %widenable_cond3
450   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
452 deopt2:                                           ; preds = %guarded
453   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
454   ret void
456 guarded1:                                         ; preds = %guarded
457   br i1 undef, label %left, label %right
459 left:                                             ; preds = %guarded5, %guarded1
460   %cond_3 = icmp ult i32 %a, 7
461   %widenable_cond7 = call i1 @llvm.experimental.widenable.condition()
462   %exiplicit_guard_cond8 = and i1 %cond_3, %widenable_cond7
463   br i1 %exiplicit_guard_cond8, label %guarded5, label %deopt6, !prof !0
465 deopt6:                                           ; preds = %left
466   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
467   ret void
469 guarded5:                                         ; preds = %left
470   br label %left
472 right:                                            ; preds = %guarded1
473   ret void
476 ; In this case the earliest dominating guard is in a loop, and we
477 ; don't want to put extra work in there.  This heuristic can use some
478 ; tuning.
479 define void @f_8(i32 %a, i1 %cond_1, i1 %cond_2) {
480 ; CHECK-LABEL: @f_8(
481 ; CHECK-NEXT:  entry:
482 ; CHECK-NEXT:    br label [[LOOP:%.*]]
483 ; CHECK:       loop:
484 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
485 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_1:%.*]], [[WIDENABLE_COND]]
486 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
487 ; CHECK:       deopt:
488 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
489 ; CHECK-NEXT:    ret void
490 ; CHECK:       guarded:
491 ; CHECK-NEXT:    br i1 undef, label [[LOOP]], label [[LEAVE:%.*]]
492 ; CHECK:       leave:
493 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
494 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_2:%.*]], [[WIDENABLE_COND3]]
495 ; CHECK-NEXT:    [[COND_3:%.*]] = icmp ult i32 [[A:%.*]], 7
496 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_2]], [[COND_3]]
497 ; CHECK-NEXT:    [[GUARD_CHK:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND3]]
498 ; CHECK-NEXT:    br i1 [[GUARD_CHK]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
499 ; CHECK:       deopt2:
500 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
501 ; CHECK-NEXT:    ret void
502 ; CHECK:       guarded1:
503 ; CHECK-NEXT:    br i1 undef, label [[LOOP2:%.*]], label [[LEAVE2:%.*]]
504 ; CHECK:       loop2:
505 ; CHECK-NEXT:    [[WIDENABLE_COND7:%.*]] = call i1 @llvm.experimental.widenable.condition()
506 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND8:%.*]] = and i1 [[COND_3]], [[WIDENABLE_COND7]]
507 ; CHECK-NEXT:    br i1 true, label [[GUARDED5:%.*]], label [[DEOPT6:%.*]], !prof !0
508 ; CHECK:       deopt6:
509 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
510 ; CHECK-NEXT:    ret void
511 ; CHECK:       guarded5:
512 ; CHECK-NEXT:    br label [[LOOP2]]
513 ; CHECK:       leave2:
514 ; CHECK-NEXT:    ret void
516 entry:
517   br label %loop
519 loop:                                             ; preds = %guarded, %entry
520   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
521   %exiplicit_guard_cond = and i1 %cond_1, %widenable_cond
522   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
524 deopt:                                            ; preds = %loop
525   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
526   ret void
528 guarded:                                          ; preds = %loop
529   br i1 undef, label %loop, label %leave
531 leave:                                            ; preds = %guarded
532   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
533   %exiplicit_guard_cond4 = and i1 %cond_2, %widenable_cond3
534   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
536 deopt2:                                           ; preds = %leave
537   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
538   ret void
540 guarded1:                                         ; preds = %leave
541   br i1 undef, label %loop2, label %leave2
543 loop2:                                            ; preds = %guarded5, %guarded1
544   %cond_3 = icmp ult i32 %a, 7
545   %widenable_cond7 = call i1 @llvm.experimental.widenable.condition()
546   %exiplicit_guard_cond8 = and i1 %cond_3, %widenable_cond7
547   br i1 %exiplicit_guard_cond8, label %guarded5, label %deopt6, !prof !0
549 deopt6:                                           ; preds = %loop2
550   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
551   ret void
553 guarded5:                                         ; preds = %loop2
554   br label %loop2
556 leave2:                                           ; preds = %guarded1
557   ret void
560 ; In cases like these where there isn't any "obviously profitable"
561 ; widening sites, we refuse to do anything.
562 define void @f_9(i32 %a, i1 %cond_0, i1 %cond_1) {
563 ; CHECK-LABEL: @f_9(
564 ; CHECK-NEXT:  entry:
565 ; CHECK-NEXT:    br label [[FIRST_LOOP:%.*]]
566 ; CHECK:       first_loop:
567 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
568 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
569 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
570 ; CHECK:       deopt:
571 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
572 ; CHECK-NEXT:    ret void
573 ; CHECK:       guarded:
574 ; CHECK-NEXT:    br i1 undef, label [[FIRST_LOOP]], label [[SECOND_LOOP:%.*]]
575 ; CHECK:       second_loop:
576 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
577 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1:%.*]], [[WIDENABLE_COND3]]
578 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
579 ; CHECK:       deopt2:
580 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
581 ; CHECK-NEXT:    ret void
582 ; CHECK:       guarded1:
583 ; CHECK-NEXT:    br label [[SECOND_LOOP]]
585 entry:
586   br label %first_loop
588 first_loop:                                       ; preds = %guarded, %entry
589   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
590   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
591   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
593 deopt:                                            ; preds = %first_loop
594   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
595   ret void
597 guarded:                                          ; preds = %first_loop
598   br i1 undef, label %first_loop, label %second_loop
600 second_loop:                                      ; preds = %guarded1, %guarded
601   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
602   %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
603   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
605 deopt2:                                           ; preds = %second_loop
606   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
607   ret void
609 guarded1:                                         ; preds = %second_loop
610   br label %second_loop
613 ; Same situation as in @f_9: no "obviously profitable" widening sites,
614 ; so we refuse to do anything.
615 define void @f_10(i32 %a, i1 %cond_0, i1 %cond_1) {
616 ; CHECK-LABEL: @f_10(
617 ; CHECK-NEXT:  entry:
618 ; CHECK-NEXT:    br label [[LOOP:%.*]]
619 ; CHECK:       loop:
620 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
621 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
622 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
623 ; CHECK:       deopt:
624 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
625 ; CHECK-NEXT:    ret void
626 ; CHECK:       guarded:
627 ; CHECK-NEXT:    br i1 undef, label [[LOOP]], label [[NO_LOOP:%.*]]
628 ; CHECK:       no_loop:
629 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
630 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1:%.*]], [[WIDENABLE_COND3]]
631 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
632 ; CHECK:       deopt2:
633 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
634 ; CHECK-NEXT:    ret void
635 ; CHECK:       guarded1:
636 ; CHECK-NEXT:    ret void
638 entry:
639   br label %loop
641 loop:                                             ; preds = %guarded, %entry
642   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
643   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
644   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
646 deopt:                                            ; preds = %loop
647   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
648   ret void
650 guarded:                                          ; preds = %loop
651   br i1 undef, label %loop, label %no_loop
653 no_loop:                                          ; preds = %guarded
654   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
655   %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
656   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
658 deopt2:                                           ; preds = %no_loop
659   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
660   ret void
662 guarded1:                                         ; preds = %no_loop
663   ret void
666 ; With guards in loops, we're okay hoisting out the guard into the
667 ; containing loop.
668 define void @f_11(i32 %a, i1 %cond_0, i1 %cond_1) {
669 ; CHECK-LABEL: @f_11(
670 ; CHECK-NEXT:  entry:
671 ; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]
672 ; CHECK:       outer_header:
673 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
674 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
675 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0]], [[COND_1:%.*]]
676 ; CHECK-NEXT:    [[GUARD_CHK:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
677 ; CHECK-NEXT:    br i1 [[GUARD_CHK]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
678 ; CHECK:       deopt:
679 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
680 ; CHECK-NEXT:    ret void
681 ; CHECK:       guarded:
682 ; CHECK-NEXT:    br label [[INNER:%.*]]
683 ; CHECK:       inner:
684 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
685 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
686 ; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
687 ; CHECK:       deopt2:
688 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
689 ; CHECK-NEXT:    ret void
690 ; CHECK:       guarded1:
691 ; CHECK-NEXT:    br i1 undef, label [[INNER]], label [[OUTER_LATCH:%.*]]
692 ; CHECK:       outer_latch:
693 ; CHECK-NEXT:    br i1 undef, label [[OUTER_HEADER]], label [[EXIT:%.*]]
694 ; CHECK:       exit:
695 ; CHECK-NEXT:    ret void
697 entry:
698   br label %outer_header
700 outer_header:                                     ; preds = %outer_latch, %entry
701   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
702   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
703   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
705 deopt:                                            ; preds = %outer_header
706   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
707   ret void
709 guarded:                                          ; preds = %outer_header
710   br label %inner
712 inner:                                            ; preds = %guarded1, %guarded
713   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
714   %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
715   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
717 deopt2:                                           ; preds = %inner
718   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
719   ret void
721 guarded1:                                         ; preds = %inner
722   br i1 undef, label %inner, label %outer_latch
724 outer_latch:                                      ; preds = %guarded1
725   br i1 undef, label %outer_header, label %exit
727 exit:                                             ; preds = %outer_latch
728   ret void
731 ; Checks that we are adequately guarded against exponential-time
732 ; behavior when hoisting code.
733 define void @f_12(i32 %a0) {
734 ; CHECK-LABEL: @f_12(
735 ; CHECK-NEXT:  entry:
736 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
737 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 true, [[WIDENABLE_COND]]
738 ; CHECK-NEXT:    [[A1:%.*]] = mul i32 [[A0:%.*]], [[A0]]
739 ; CHECK-NEXT:    [[A2:%.*]] = mul i32 [[A1]], [[A1]]
740 ; CHECK-NEXT:    [[A3:%.*]] = mul i32 [[A2]], [[A2]]
741 ; CHECK-NEXT:    [[A4:%.*]] = mul i32 [[A3]], [[A3]]
742 ; CHECK-NEXT:    [[A5:%.*]] = mul i32 [[A4]], [[A4]]
743 ; CHECK-NEXT:    [[A6:%.*]] = mul i32 [[A5]], [[A5]]
744 ; CHECK-NEXT:    [[A7:%.*]] = mul i32 [[A6]], [[A6]]
745 ; CHECK-NEXT:    [[A8:%.*]] = mul i32 [[A7]], [[A7]]
746 ; CHECK-NEXT:    [[A9:%.*]] = mul i32 [[A8]], [[A8]]
747 ; CHECK-NEXT:    [[A10:%.*]] = mul i32 [[A9]], [[A9]]
748 ; CHECK-NEXT:    [[A11:%.*]] = mul i32 [[A10]], [[A10]]
749 ; CHECK-NEXT:    [[A12:%.*]] = mul i32 [[A11]], [[A11]]
750 ; CHECK-NEXT:    [[A13:%.*]] = mul i32 [[A12]], [[A12]]
751 ; CHECK-NEXT:    [[A14:%.*]] = mul i32 [[A13]], [[A13]]
752 ; CHECK-NEXT:    [[A15:%.*]] = mul i32 [[A14]], [[A14]]
753 ; CHECK-NEXT:    [[A16:%.*]] = mul i32 [[A15]], [[A15]]
754 ; CHECK-NEXT:    [[A17:%.*]] = mul i32 [[A16]], [[A16]]
755 ; CHECK-NEXT:    [[A18:%.*]] = mul i32 [[A17]], [[A17]]
756 ; CHECK-NEXT:    [[A19:%.*]] = mul i32 [[A18]], [[A18]]
757 ; CHECK-NEXT:    [[A20:%.*]] = mul i32 [[A19]], [[A19]]
758 ; CHECK-NEXT:    [[A21:%.*]] = mul i32 [[A20]], [[A20]]
759 ; CHECK-NEXT:    [[A22:%.*]] = mul i32 [[A21]], [[A21]]
760 ; CHECK-NEXT:    [[A23:%.*]] = mul i32 [[A22]], [[A22]]
761 ; CHECK-NEXT:    [[A24:%.*]] = mul i32 [[A23]], [[A23]]
762 ; CHECK-NEXT:    [[A25:%.*]] = mul i32 [[A24]], [[A24]]
763 ; CHECK-NEXT:    [[A26:%.*]] = mul i32 [[A25]], [[A25]]
764 ; CHECK-NEXT:    [[A27:%.*]] = mul i32 [[A26]], [[A26]]
765 ; CHECK-NEXT:    [[A28:%.*]] = mul i32 [[A27]], [[A27]]
766 ; CHECK-NEXT:    [[A29:%.*]] = mul i32 [[A28]], [[A28]]
767 ; CHECK-NEXT:    [[A30:%.*]] = mul i32 [[A29]], [[A29]]
768 ; CHECK-NEXT:    [[COND:%.*]] = trunc i32 [[A30]] to i1
769 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 true, [[COND]]
770 ; CHECK-NEXT:    [[GUARD_CHK:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
771 ; CHECK-NEXT:    br i1 [[GUARD_CHK]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
772 ; CHECK:       deopt:
773 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
774 ; CHECK-NEXT:    ret void
775 ; CHECK:       guarded:
776 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
777 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND]], [[WIDENABLE_COND3]]
778 ; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
779 ; CHECK:       deopt2:
780 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
781 ; CHECK-NEXT:    ret void
782 ; CHECK:       guarded1:
783 ; CHECK-NEXT:    ret void
785 entry:
786   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
787   %exiplicit_guard_cond = and i1 true, %widenable_cond
788   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
790 deopt:                                            ; preds = %entry
791   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
792   ret void
794 guarded:                                          ; preds = %entry
795   %a1 = mul i32 %a0, %a0
796   %a2 = mul i32 %a1, %a1
797   %a3 = mul i32 %a2, %a2
798   %a4 = mul i32 %a3, %a3
799   %a5 = mul i32 %a4, %a4
800   %a6 = mul i32 %a5, %a5
801   %a7 = mul i32 %a6, %a6
802   %a8 = mul i32 %a7, %a7
803   %a9 = mul i32 %a8, %a8
804   %a10 = mul i32 %a9, %a9
805   %a11 = mul i32 %a10, %a10
806   %a12 = mul i32 %a11, %a11
807   %a13 = mul i32 %a12, %a12
808   %a14 = mul i32 %a13, %a13
809   %a15 = mul i32 %a14, %a14
810   %a16 = mul i32 %a15, %a15
811   %a17 = mul i32 %a16, %a16
812   %a18 = mul i32 %a17, %a17
813   %a19 = mul i32 %a18, %a18
814   %a20 = mul i32 %a19, %a19
815   %a21 = mul i32 %a20, %a20
816   %a22 = mul i32 %a21, %a21
817   %a23 = mul i32 %a22, %a22
818   %a24 = mul i32 %a23, %a23
819   %a25 = mul i32 %a24, %a24
820   %a26 = mul i32 %a25, %a25
821   %a27 = mul i32 %a26, %a26
822   %a28 = mul i32 %a27, %a27
823   %a29 = mul i32 %a28, %a28
824   %a30 = mul i32 %a29, %a29
825   %cond = trunc i32 %a30 to i1
826   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
827   %exiplicit_guard_cond4 = and i1 %cond, %widenable_cond3
828   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
830 deopt2:                                           ; preds = %guarded
831   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
832   ret void
834 guarded1:                                         ; preds = %guarded
835   ret void
838 define void @f_13(i32 %a) {
839 ; CHECK-LABEL: @f_13(
840 ; CHECK-NEXT:  entry:
841 ; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 14
842 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
843 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0]], [[WIDENABLE_COND]]
844 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = icmp ult i32 [[A]], 10
845 ; CHECK-NEXT:    [[GUARD_CHK:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
846 ; CHECK-NEXT:    br i1 [[GUARD_CHK]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
847 ; CHECK:       deopt:
848 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
849 ; CHECK-NEXT:    ret void
850 ; CHECK:       guarded:
851 ; CHECK-NEXT:    br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
852 ; CHECK:       left:
853 ; CHECK-NEXT:    [[COND_1:%.*]] = icmp slt i32 [[A]], 10
854 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
855 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
856 ; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
857 ; CHECK:       deopt2:
858 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
859 ; CHECK-NEXT:    ret void
860 ; CHECK:       guarded1:
861 ; CHECK-NEXT:    ret void
862 ; CHECK:       right:
863 ; CHECK-NEXT:    ret void
865 entry:
866   %cond_0 = icmp ult i32 %a, 14
867   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
868   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
869   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
871 deopt:                                            ; preds = %entry
872   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
873   ret void
875 guarded:                                          ; preds = %entry
876   br i1 undef, label %left, label %right
878 left:                                             ; preds = %guarded
879   %cond_1 = icmp slt i32 %a, 10
880   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
881   %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
882   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
884 deopt2:                                           ; preds = %left
885   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
886   ret void
888 guarded1:                                         ; preds = %left
889   ret void
891 right:                                            ; preds = %guarded
892   ret void
895 define void @f_14(i32 %a) {
896 ; CHECK-LABEL: @f_14(
897 ; CHECK-NEXT:  entry:
898 ; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 14
899 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
900 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0]], [[WIDENABLE_COND]]
901 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
902 ; CHECK:       deopt:
903 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
904 ; CHECK-NEXT:    ret void
905 ; CHECK:       guarded:
906 ; CHECK-NEXT:    br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
907 ; CHECK:       left:
908 ; CHECK-NEXT:    [[COND_1:%.*]] = icmp sgt i32 [[A]], 10
909 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
910 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
911 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
912 ; CHECK:       deopt2:
913 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
914 ; CHECK-NEXT:    ret void
915 ; CHECK:       guarded1:
916 ; CHECK-NEXT:    ret void
917 ; CHECK:       right:
918 ; CHECK-NEXT:    ret void
920 entry:
921   %cond_0 = icmp ult i32 %a, 14
922   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
923   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
924   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
926 deopt:                                            ; preds = %entry
927   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
928   ret void
930 guarded:                                          ; preds = %entry
931   br i1 undef, label %left, label %right
933 left:                                             ; preds = %guarded
934   %cond_1 = icmp sgt i32 %a, 10
935   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
936   %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
937   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
939 deopt2:                                           ; preds = %left
940   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
941   ret void
943 guarded1:                                         ; preds = %left
944   ret void
946 right:                                            ; preds = %guarded
947   ret void
950 ; Make sure we do not widen guard by trivial true conditions into something.
951 define void @f_15(i1 %cond_0, i1 %cond_1) {
952 ; CHECK-LABEL: @f_15(
953 ; CHECK-NEXT:  entry:
954 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
955 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
956 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
957 ; CHECK:       deopt:
958 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
959 ; CHECK-NEXT:    ret void
960 ; CHECK:       guarded:
961 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
962 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 true, [[WIDENABLE_COND3]]
963 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
964 ; CHECK:       deopt2:
965 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
966 ; CHECK-NEXT:    ret void
967 ; CHECK:       guarded1:
968 ; CHECK-NEXT:    ret void
970 entry:
971   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
972   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
973   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
975 deopt:                                            ; preds = %entry
976   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
977   ret void
979 guarded:                                          ; preds = %entry
980   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
981   %exiplicit_guard_cond4 = and i1 true, %widenable_cond3
982   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
984 deopt2:                                           ; preds = %guarded
985   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
986   ret void
988 guarded1:                                         ; preds = %guarded
989   ret void
992 ; Make sure we do not widen guard by trivial false conditions into something.
993 define void @f_16(i1 %cond_0, i1 %cond_1) {
994 ; CHECK-LABEL: @f_16(
995 ; CHECK-NEXT:  entry:
996 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
997 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
998 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
999 ; CHECK:       deopt:
1000 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1001 ; CHECK-NEXT:    ret void
1002 ; CHECK:       guarded:
1003 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
1004 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 false, [[WIDENABLE_COND3]]
1005 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
1006 ; CHECK:       deopt2:
1007 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1008 ; CHECK-NEXT:    ret void
1009 ; CHECK:       guarded1:
1010 ; CHECK-NEXT:    ret void
1012 entry:
1013   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1014   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
1015   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1017 deopt:                                            ; preds = %entry
1018   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1019   ret void
1021 guarded:                                          ; preds = %entry
1022   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
1023   %exiplicit_guard_cond4 = and i1 false, %widenable_cond3
1024   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
1026 deopt2:                                           ; preds = %guarded
1027   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1028   ret void
1030 guarded1:                                         ; preds = %guarded
1031   ret void
1034 declare void @llvm.experimental.deoptimize.isVoid(...)
1036 ; Function Attrs: inaccessiblememonly nounwind
1037 declare i1 @llvm.experimental.widenable.condition() #0
1039 attributes #0 = { inaccessiblememonly nounwind }
1041 !0 = !{!"branch_weights", i32 1048576, i32 1}