[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / GuardWidening / basic_widenable_condition_guards.ll
blob40d22e07ebaec08dae7be6c7221ab878acb28d16
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:    [[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
14 ; CHECK:       deopt:
15 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
16 ; CHECK-NEXT:    ret void
17 ; CHECK:       guarded:
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
21 ; CHECK:       deopt2:
22 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
23 ; CHECK-NEXT:    ret void
24 ; CHECK:       guarded1:
25 ; CHECK-NEXT:    ret void
27 entry:
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"() ]
34   ret void
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"() ]
43   ret void
45 guarded1:                                         ; preds = %guarded
46   ret void
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) {
51 ; CHECK-LABEL: @f_1(
52 ; CHECK-NEXT:  entry:
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
57 ; CHECK:       deopt:
58 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
59 ; CHECK-NEXT:    ret void
60 ; CHECK:       guarded:
61 ; CHECK-NEXT:    br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
62 ; CHECK:       left:
63 ; CHECK-NEXT:    br label [[MERGE:%.*]]
64 ; CHECK:       right:
65 ; CHECK-NEXT:    br label [[MERGE]]
66 ; CHECK:       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
70 ; CHECK:       deopt2:
71 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
72 ; CHECK-NEXT:    ret void
73 ; CHECK:       guarded1:
74 ; CHECK-NEXT:    ret void
76 entry:
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"() ]
83   ret void
85 guarded:                                          ; preds = %entry
86   br i1 undef, label %left, label %right
88 left:                                             ; preds = %guarded
89   br label %merge
91 right:                                            ; preds = %guarded
92   br label %merge
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"() ]
101   ret void
103 guarded1:                                         ; preds = %merge
104   ret void
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) {
110 ; CHECK-LABEL: @f_2(
111 ; CHECK-NEXT:  entry:
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
118 ; CHECK:       deopt:
119 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
120 ; CHECK-NEXT:    ret void
121 ; CHECK:       guarded:
122 ; CHECK-NEXT:    br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
123 ; CHECK:       left:
124 ; CHECK-NEXT:    br label [[MERGE:%.*]]
125 ; CHECK:       right:
126 ; CHECK-NEXT:    br label [[MERGE]]
127 ; CHECK:       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
131 ; CHECK:       deopt2:
132 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
133 ; CHECK-NEXT:    ret void
134 ; CHECK:       guarded1:
135 ; CHECK-NEXT:    ret void
137 entry:
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"() ]
145   ret void
147 guarded:                                          ; preds = %entry
148   br i1 undef, label %left, label %right
150 left:                                             ; preds = %guarded
151   br label %merge
153 right:                                            ; preds = %guarded
154   br label %merge
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"() ]
164   ret void
166 guarded1:                                         ; preds = %merge
167   ret void
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) {
173 ; CHECK-LABEL: @f_3(
174 ; CHECK-NEXT:  entry:
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
179 ; CHECK:       deopt:
180 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
181 ; CHECK-NEXT:    ret void
182 ; CHECK:       guarded:
183 ; CHECK-NEXT:    br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
184 ; CHECK:       left:
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
189 ; CHECK:       deopt2:
190 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
191 ; CHECK-NEXT:    ret void
192 ; CHECK:       guarded1:
193 ; CHECK-NEXT:    ret void
194 ; CHECK:       right:
195 ; CHECK-NEXT:    ret void
197 entry:
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"() ]
205   ret void
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"() ]
218   ret void
220 guarded1:                                         ; preds = %left
221   ret void
223 right:                                            ; preds = %guarded
224   ret void
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
229 ; the future.
230 define void @f_4(i32 %a, i32 %b) {
231 ; CHECK-LABEL: @f_4(
232 ; CHECK-NEXT:  entry:
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
239 ; CHECK:       deopt:
240 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
241 ; CHECK-NEXT:    ret void
242 ; CHECK:       guarded:
243 ; CHECK-NEXT:    br i1 undef, label [[LOOP:%.*]], label [[LEAVE:%.*]]
244 ; CHECK:       loop:
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
248 ; CHECK:       deopt2:
249 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
250 ; CHECK-NEXT:    ret void
251 ; CHECK:       guarded1:
252 ; CHECK-NEXT:    br i1 undef, label [[LOOP]], label [[LEAVE]]
253 ; CHECK:       leave:
254 ; CHECK-NEXT:    ret void
256 entry:
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"() ]
264   ret void
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"() ]
277   ret void
279 guarded1:                                         ; preds = %loop
280   br i1 undef, label %loop, label %leave
282 leave:                                            ; preds = %guarded1, %guarded
283   ret void
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) {
289 ; CHECK-LABEL: @f_5(
290 ; CHECK-NEXT:  entry:
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
296 ; CHECK:       deopt:
297 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
298 ; CHECK-NEXT:    ret void
299 ; CHECK:       guarded:
300 ; CHECK-NEXT:    br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
301 ; CHECK:       left:
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
306 ; CHECK:       deopt2:
307 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
308 ; CHECK-NEXT:    ret void
309 ; CHECK:       guarded1:
310 ; CHECK-NEXT:    ret void
311 ; CHECK:       right:
312 ; CHECK-NEXT:    ret void
314 entry:
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"() ]
322   ret void
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"() ]
335   ret void
337 guarded1:                                         ; preds = %left
338   ret void
340 right:                                            ; preds = %guarded
341   ret void
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
346 ; same value.
347 define void @f_6(i1* dereferenceable(32) %a, i1* %b, i1 %unknown) {
348 ; CHECK-LABEL: @f_6(
349 ; CHECK-NEXT:  entry:
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
354 ; CHECK:       deopt:
355 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
356 ; CHECK-NEXT:    ret void
357 ; CHECK:       guarded:
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
363 ; CHECK:       deopt2:
364 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
365 ; CHECK-NEXT:    ret void
366 ; CHECK:       guarded1:
367 ; CHECK-NEXT:    ret void
369 entry:
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"() ]
377   ret void
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"() ]
388   ret void
390 guarded1:                                         ; preds = %guarded
391   ret void
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) {
397 ; CHECK-LABEL: @f_7(
398 ; CHECK-NEXT:  entry:
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
405 ; CHECK:       deopt:
406 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
407 ; CHECK-NEXT:    ret void
408 ; CHECK:       guarded:
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
413 ; CHECK:       deopt2:
414 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
415 ; CHECK-NEXT:    ret void
416 ; CHECK:       guarded1:
417 ; CHECK-NEXT:    br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
418 ; CHECK:       left:
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
422 ; CHECK:       deopt6:
423 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
424 ; CHECK-NEXT:    ret void
425 ; CHECK:       guarded5:
426 ; CHECK-NEXT:    br label [[LEFT]]
427 ; CHECK:       right:
428 ; CHECK-NEXT:    ret void
430 entry:
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"() ]
438   ret void
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"() ]
448   ret void
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"() ]
461   ret void
463 guarded5:                                         ; preds = %left
464   br label %left
466 right:                                            ; preds = %guarded1
467   ret void
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
472 ; tuning.
473 define void @f_8(i32 %a, i1 %cond_1, i1 %cond_2) {
474 ; CHECK-LABEL: @f_8(
475 ; CHECK-NEXT:  entry:
476 ; CHECK-NEXT:    br label [[LOOP:%.*]]
477 ; CHECK:       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
481 ; CHECK:       deopt:
482 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
483 ; CHECK-NEXT:    ret void
484 ; CHECK:       guarded:
485 ; CHECK-NEXT:    br i1 undef, label [[LOOP]], label [[LEAVE:%.*]]
486 ; CHECK:       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
492 ; CHECK:       deopt2:
493 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
494 ; CHECK-NEXT:    ret void
495 ; CHECK:       guarded1:
496 ; CHECK-NEXT:    br i1 undef, label [[LOOP2:%.*]], label [[LEAVE2:%.*]]
497 ; CHECK:       loop2:
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
501 ; CHECK:       deopt6:
502 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
503 ; CHECK-NEXT:    ret void
504 ; CHECK:       guarded5:
505 ; CHECK-NEXT:    br label [[LOOP2]]
506 ; CHECK:       leave2:
507 ; CHECK-NEXT:    ret void
509 entry:
510   br label %loop
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"() ]
519   ret void
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"() ]
531   ret void
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"() ]
544   ret void
546 guarded5:                                         ; preds = %loop2
547   br label %loop2
549 leave2:                                           ; preds = %guarded1
550   ret void
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) {
556 ; CHECK-LABEL: @f_9(
557 ; CHECK-NEXT:  entry:
558 ; CHECK-NEXT:    br label [[FIRST_LOOP:%.*]]
559 ; CHECK:       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
563 ; CHECK:       deopt:
564 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
565 ; CHECK-NEXT:    ret void
566 ; CHECK:       guarded:
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
572 ; CHECK:       deopt2:
573 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
574 ; CHECK-NEXT:    ret void
575 ; CHECK:       guarded1:
576 ; CHECK-NEXT:    br label [[SECOND_LOOP]]
578 entry:
579   br label %first_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"() ]
588   ret void
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"() ]
600   ret void
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(
610 ; CHECK-NEXT:  entry:
611 ; CHECK-NEXT:    br label [[LOOP:%.*]]
612 ; CHECK:       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
616 ; CHECK:       deopt:
617 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
618 ; CHECK-NEXT:    ret void
619 ; CHECK:       guarded:
620 ; CHECK-NEXT:    br i1 undef, label [[LOOP]], label [[NO_LOOP:%.*]]
621 ; CHECK:       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
625 ; CHECK:       deopt2:
626 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
627 ; CHECK-NEXT:    ret void
628 ; CHECK:       guarded1:
629 ; CHECK-NEXT:    ret void
631 entry:
632   br label %loop
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"() ]
641   ret void
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"() ]
653   ret void
655 guarded1:                                         ; preds = %no_loop
656   ret void
659 ; With guards in loops, we're okay hoisting out the guard into the
660 ; containing loop.
661 define void @f_11(i32 %a, i1 %cond_0, i1 %cond_1) {
662 ; CHECK-LABEL: @f_11(
663 ; CHECK-NEXT:  entry:
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
670 ; CHECK:       deopt:
671 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
672 ; CHECK-NEXT:    ret void
673 ; CHECK:       guarded:
674 ; CHECK-NEXT:    br label [[INNER:%.*]]
675 ; CHECK:       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
679 ; CHECK:       deopt2:
680 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
681 ; CHECK-NEXT:    ret void
682 ; CHECK:       guarded1:
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:%.*]]
686 ; CHECK:       exit:
687 ; CHECK-NEXT:    ret void
689 entry:
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"() ]
699   ret void
701 guarded:                                          ; preds = %outer_header
702   br label %inner
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"() ]
711   ret void
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
720   ret void
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(
727 ; CHECK-NEXT:  entry:
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
763 ; CHECK:       deopt:
764 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
765 ; CHECK-NEXT:    ret void
766 ; CHECK:       guarded:
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
770 ; CHECK:       deopt2:
771 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
772 ; CHECK-NEXT:    ret void
773 ; CHECK:       guarded1:
774 ; CHECK-NEXT:    ret void
776 entry:
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"() ]
783   ret void
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"() ]
823   ret void
825 guarded1:                                         ; preds = %guarded
826   ret void
829 define void @f_13(i32 %a) {
830 ; CHECK-LABEL: @f_13(
831 ; CHECK-NEXT:  entry:
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
837 ; CHECK:       deopt:
838 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
839 ; CHECK-NEXT:    ret void
840 ; CHECK:       guarded:
841 ; CHECK-NEXT:    br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
842 ; CHECK:       left:
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
847 ; CHECK:       deopt2:
848 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
849 ; CHECK-NEXT:    ret void
850 ; CHECK:       guarded1:
851 ; CHECK-NEXT:    ret void
852 ; CHECK:       right:
853 ; CHECK-NEXT:    ret void
855 entry:
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"() ]
863   ret void
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"() ]
876   ret void
878 guarded1:                                         ; preds = %left
879   ret void
881 right:                                            ; preds = %guarded
882   ret void
885 define void @f_14(i32 %a) {
886 ; CHECK-LABEL: @f_14(
887 ; CHECK-NEXT:  entry:
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
892 ; CHECK:       deopt:
893 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
894 ; CHECK-NEXT:    ret void
895 ; CHECK:       guarded:
896 ; CHECK-NEXT:    br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
897 ; CHECK:       left:
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
902 ; CHECK:       deopt2:
903 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
904 ; CHECK-NEXT:    ret void
905 ; CHECK:       guarded1:
906 ; CHECK-NEXT:    ret void
907 ; CHECK:       right:
908 ; CHECK-NEXT:    ret void
910 entry:
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"() ]
918   ret void
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"() ]
931   ret void
933 guarded1:                                         ; preds = %left
934   ret void
936 right:                                            ; preds = %guarded
937   ret void
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(
943 ; CHECK-NEXT:  entry:
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
947 ; CHECK:       deopt:
948 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
949 ; CHECK-NEXT:    ret void
950 ; CHECK:       guarded:
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
954 ; CHECK:       deopt2:
955 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
956 ; CHECK-NEXT:    ret void
957 ; CHECK:       guarded1:
958 ; CHECK-NEXT:    ret void
960 entry:
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"() ]
967   ret void
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"() ]
976   ret void
978 guarded1:                                         ; preds = %guarded
979   ret void
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(
985 ; CHECK-NEXT:  entry:
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
989 ; CHECK:       deopt:
990 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
991 ; CHECK-NEXT:    ret void
992 ; CHECK:       guarded:
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
996 ; CHECK:       deopt2:
997 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
998 ; CHECK-NEXT:    ret void
999 ; CHECK:       guarded1:
1000 ; CHECK-NEXT:    ret void
1002 entry:
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"() ]
1009   ret void
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"() ]
1018   ret void
1020 guarded1:                                         ; preds = %guarded
1021   ret void
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
1032 ; CHECK:       deopt:
1033 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1034 ; CHECK-NEXT:    ret void
1035 ; CHECK:       guarded:
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
1039 ; CHECK:       deopt2:
1040 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1041 ; CHECK-NEXT:    ret void
1042 ; CHECK:       guarded1:
1043 ; CHECK-NEXT:    ret void
1045 entry:
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"() ]
1052   ret void
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"() ]
1061   ret void
1063 guarded1:                                         ; preds = %guarded
1064   ret void
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
1074 ; CHECK:       deopt:
1075 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1076 ; CHECK-NEXT:    ret void
1077 ; CHECK:       guarded:
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
1081 ; CHECK:       deopt2:
1082 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1083 ; CHECK-NEXT:    ret void
1084 ; CHECK:       guarded1:
1085 ; CHECK-NEXT:    ret void
1087 entry:
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"() ]
1093   ret void
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"() ]
1102   ret void
1104 guarded1:                                         ; preds = %guarded
1105   ret void
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}