Revert "[InstCombine] Support gep nuw in icmp folds" (#118698)
[llvm-project.git] / llvm / test / Transforms / GuardWidening / basic_widenable_condition_guards.ll
blob310c4a820c8a938cfbcbc1da518a6210a4682480
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -guard-widening-widen-branch-guards=true -passes=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:    [[COND_1_GW_FR:%.*]] = freeze i1 [[COND_1:%.*]]
11 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1_GW_FR]]
12 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
13 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
14 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]]
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_GW_FR]], [[WIDENABLE_COND3]]
21 ; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
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, i1 %arg) {
52 ; CHECK-LABEL: @f_1(
53 ; CHECK-NEXT:  entry:
54 ; CHECK-NEXT:    [[COND_1_GW_FR:%.*]] = freeze i1 [[COND_1:%.*]]
55 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1_GW_FR]]
56 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
57 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
58 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
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 %arg, 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_GW_FR]], [[WIDENABLE_COND3]]
71 ; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
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 %arg, 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, i1 %arg) {
112 ; CHECK-LABEL: @f_2(
113 ; CHECK-NEXT:  entry:
114 ; CHECK-NEXT:    [[B_GW_FR:%.*]] = freeze i32 [[B:%.*]]
115 ; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 10
116 ; CHECK-NEXT:    [[COND_1:%.*]] = icmp ult i32 [[B_GW_FR]], 10
117 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0]], [[COND_1]]
118 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
119 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
120 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
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 %arg, 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 [[PROF0]]
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 %arg, 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, i1 %arg) {
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 [[PROF0]]
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 %arg, 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 [[PROF0]]
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 %arg, 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, i1 %arg) {
234 ; CHECK-LABEL: @f_4(
235 ; CHECK-NEXT:  entry:
236 ; CHECK-NEXT:    [[B_GW_FR:%.*]] = freeze i32 [[B:%.*]]
237 ; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 10
238 ; CHECK-NEXT:    [[COND_1:%.*]] = icmp ult i32 [[B_GW_FR]], 10
239 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0]], [[COND_1]]
240 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
241 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
242 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
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 %arg, 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 [[PROF0]]
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 %arg, 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 %arg, 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 %arg, 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, i1 %arg) {
293 ; CHECK-LABEL: @f_5(
294 ; CHECK-NEXT:  entry:
295 ; CHECK-NEXT:    [[COND_0:%.*]] = icmp ugt i32 [[A:%.*]], 7
296 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = icmp uge i32 [[A]], 11
297 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
298 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
299 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
300 ; CHECK:       deopt:
301 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
302 ; CHECK-NEXT:    ret void
303 ; CHECK:       guarded:
304 ; CHECK-NEXT:    br i1 %arg, label [[LEFT:%.*]], label [[RIGHT:%.*]]
305 ; CHECK:       left:
306 ; CHECK-NEXT:    [[COND_1:%.*]] = icmp ugt i32 [[A]], 10
307 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
308 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
309 ; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
310 ; CHECK:       deopt2:
311 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
312 ; CHECK-NEXT:    ret void
313 ; CHECK:       guarded1:
314 ; CHECK-NEXT:    ret void
315 ; CHECK:       right:
316 ; CHECK-NEXT:    ret void
318 entry:
319   %cond_0 = icmp ugt i32 %a, 7
320   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
321   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
322   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
324 deopt:                                            ; preds = %entry
325   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
326   ret void
328 guarded:                                          ; preds = %entry
329   br i1 %arg, label %left, label %right
331 left:                                             ; preds = %guarded
332   %cond_1 = icmp ugt i32 %a, 10
333   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
334   %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
335   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
337 deopt2:                                           ; preds = %left
338   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
339   ret void
341 guarded1:                                         ; preds = %left
342   ret void
344 right:                                            ; preds = %guarded
345   ret void
348 ; Negative test: the load from %a can be safely speculated to before
349 ; the first guard, but there is no guarantee that it will produce the
350 ; same value.
351 define void @f_6(ptr dereferenceable(32) %a, ptr %b, i1 %unknown) {
352 ; CHECK-LABEL: @f_6(
353 ; CHECK-NEXT:  entry:
354 ; CHECK-NEXT:    [[COND_0:%.*]] = load i1, ptr [[A:%.*]], align 1
355 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
356 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0]], [[WIDENABLE_COND]]
357 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
358 ; CHECK:       deopt:
359 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
360 ; CHECK-NEXT:    ret void
361 ; CHECK:       guarded:
362 ; CHECK-NEXT:    store i1 [[UNKNOWN:%.*]], ptr [[B:%.*]], align 1
363 ; CHECK-NEXT:    [[COND_1:%.*]] = load i1, ptr [[A]], align 1
364 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
365 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
366 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
367 ; CHECK:       deopt2:
368 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
369 ; CHECK-NEXT:    ret void
370 ; CHECK:       guarded1:
371 ; CHECK-NEXT:    ret void
373 entry:
374   %cond_0 = load i1, ptr %a
375   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
376   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
377   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
379 deopt:                                            ; preds = %entry
380   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
381   ret void
383 guarded:                                          ; preds = %entry
384   store i1 %unknown, ptr %b
385   %cond_1 = load i1, ptr %a
386   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
387   %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
388   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
390 deopt2:                                           ; preds = %guarded
391   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
392   ret void
394 guarded1:                                         ; preds = %guarded
395   ret void
398 ; All else equal, we try to widen the earliest guard we can.  This
399 ; heuristic can use some tuning.
400 define void @f_7(i32 %a, ptr %cond_buf, i1 %arg) {
401 ; CHECK-LABEL: @f_7(
402 ; CHECK-NEXT:  entry:
403 ; CHECK-NEXT:    [[A_GW_FR:%.*]] = freeze i32 [[A:%.*]]
404 ; CHECK-NEXT:    [[COND_1:%.*]] = load volatile i1, ptr [[COND_BUF:%.*]], align 1
405 ; CHECK-NEXT:    [[COND_3:%.*]] = icmp ult i32 [[A_GW_FR]], 7
406 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_1]], [[COND_3]]
407 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
408 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
409 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
410 ; CHECK:       deopt:
411 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
412 ; CHECK-NEXT:    ret void
413 ; CHECK:       guarded:
414 ; CHECK-NEXT:    [[COND_2:%.*]] = load volatile i1, ptr [[COND_BUF]], align 1
415 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
416 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_2]], [[WIDENABLE_COND3]]
417 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
418 ; CHECK:       deopt2:
419 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
420 ; CHECK-NEXT:    ret void
421 ; CHECK:       guarded1:
422 ; CHECK-NEXT:    br i1 %arg, label [[LEFT:%.*]], label [[RIGHT:%.*]]
423 ; CHECK:       left:
424 ; CHECK-NEXT:    [[WIDENABLE_COND7:%.*]] = call i1 @llvm.experimental.widenable.condition()
425 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND8:%.*]] = and i1 [[COND_3]], [[WIDENABLE_COND7]]
426 ; CHECK-NEXT:    br i1 true, label [[GUARDED5:%.*]], label [[DEOPT6:%.*]], !prof [[PROF0]]
427 ; CHECK:       deopt6:
428 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
429 ; CHECK-NEXT:    ret void
430 ; CHECK:       guarded5:
431 ; CHECK-NEXT:    br label [[LEFT]]
432 ; CHECK:       right:
433 ; CHECK-NEXT:    ret void
435 entry:
436   %cond_1 = load volatile i1, ptr %cond_buf
437   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
438   %exiplicit_guard_cond = and i1 %cond_1, %widenable_cond
439   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
441 deopt:                                            ; preds = %entry
442   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
443   ret void
445 guarded:                                          ; preds = %entry
446   %cond_2 = load volatile i1, ptr %cond_buf
447   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
448   %exiplicit_guard_cond4 = and i1 %cond_2, %widenable_cond3
449   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
451 deopt2:                                           ; preds = %guarded
452   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
453   ret void
455 guarded1:                                         ; preds = %guarded
456   br i1 %arg, label %left, label %right
458 left:                                             ; preds = %guarded5, %guarded1
459   %cond_3 = icmp ult i32 %a, 7
460   %widenable_cond7 = call i1 @llvm.experimental.widenable.condition()
461   %exiplicit_guard_cond8 = and i1 %cond_3, %widenable_cond7
462   br i1 %exiplicit_guard_cond8, label %guarded5, label %deopt6, !prof !0
464 deopt6:                                           ; preds = %left
465   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
466   ret void
468 guarded5:                                         ; preds = %left
469   br label %left
471 right:                                            ; preds = %guarded1
472   ret void
475 ; In this case the earliest dominating guard is in a loop, and we
476 ; don't want to put extra work in there.  This heuristic can use some
477 ; tuning.
478 define void @f_8(i32 %a, i1 %cond_1, i1 %cond_2, i1 %arg) {
479 ; CHECK-LABEL: @f_8(
480 ; CHECK-NEXT:  entry:
481 ; CHECK-NEXT:    [[A_GW_FR:%.*]] = freeze i32 [[A:%.*]]
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 [[PROF0]]
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 %arg, label [[LOOP]], label [[LEAVE:%.*]]
492 ; CHECK:       leave:
493 ; CHECK-NEXT:    [[COND_3:%.*]] = icmp ult i32 [[A_GW_FR]], 7
494 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_2:%.*]], [[COND_3]]
495 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
496 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND3]]
497 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
498 ; CHECK:       deopt2:
499 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
500 ; CHECK-NEXT:    ret void
501 ; CHECK:       guarded1:
502 ; CHECK-NEXT:    br i1 %arg, label [[LOOP2:%.*]], label [[LEAVE2:%.*]]
503 ; CHECK:       loop2:
504 ; CHECK-NEXT:    [[WIDENABLE_COND7:%.*]] = call i1 @llvm.experimental.widenable.condition()
505 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND8:%.*]] = and i1 [[COND_3]], [[WIDENABLE_COND7]]
506 ; CHECK-NEXT:    br i1 true, label [[GUARDED5:%.*]], label [[DEOPT6:%.*]], !prof [[PROF0]]
507 ; CHECK:       deopt6:
508 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
509 ; CHECK-NEXT:    ret void
510 ; CHECK:       guarded5:
511 ; CHECK-NEXT:    br label [[LOOP2]]
512 ; CHECK:       leave2:
513 ; CHECK-NEXT:    ret void
515 entry:
516   br label %loop
518 loop:                                             ; preds = %guarded, %entry
519   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
520   %exiplicit_guard_cond = and i1 %cond_1, %widenable_cond
521   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
523 deopt:                                            ; preds = %loop
524   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
525   ret void
527 guarded:                                          ; preds = %loop
528   br i1 %arg, label %loop, label %leave
530 leave:                                            ; preds = %guarded
531   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
532   %exiplicit_guard_cond4 = and i1 %cond_2, %widenable_cond3
533   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
535 deopt2:                                           ; preds = %leave
536   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
537   ret void
539 guarded1:                                         ; preds = %leave
540   br i1 %arg, label %loop2, label %leave2
542 loop2:                                            ; preds = %guarded5, %guarded1
543   %cond_3 = icmp ult i32 %a, 7
544   %widenable_cond7 = call i1 @llvm.experimental.widenable.condition()
545   %exiplicit_guard_cond8 = and i1 %cond_3, %widenable_cond7
546   br i1 %exiplicit_guard_cond8, label %guarded5, label %deopt6, !prof !0
548 deopt6:                                           ; preds = %loop2
549   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
550   ret void
552 guarded5:                                         ; preds = %loop2
553   br label %loop2
555 leave2:                                           ; preds = %guarded1
556   ret void
559 ; In cases like these where there isn't any "obviously profitable"
560 ; widening sites, we refuse to do anything.
561 define void @f_9(i32 %a, i1 %cond_0, i1 %cond_1, i1 %arg) {
562 ; CHECK-LABEL: @f_9(
563 ; CHECK-NEXT:  entry:
564 ; CHECK-NEXT:    br label [[FIRST_LOOP:%.*]]
565 ; CHECK:       first_loop:
566 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
567 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
568 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
569 ; CHECK:       deopt:
570 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
571 ; CHECK-NEXT:    ret void
572 ; CHECK:       guarded:
573 ; CHECK-NEXT:    br i1 %arg, label [[FIRST_LOOP]], label [[SECOND_LOOP:%.*]]
574 ; CHECK:       second_loop:
575 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
576 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1:%.*]], [[WIDENABLE_COND3]]
577 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
578 ; CHECK:       deopt2:
579 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
580 ; CHECK-NEXT:    ret void
581 ; CHECK:       guarded1:
582 ; CHECK-NEXT:    br label [[SECOND_LOOP]]
584 entry:
585   br label %first_loop
587 first_loop:                                       ; preds = %guarded, %entry
588   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
589   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
590   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
592 deopt:                                            ; preds = %first_loop
593   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
594   ret void
596 guarded:                                          ; preds = %first_loop
597   br i1 %arg, label %first_loop, label %second_loop
599 second_loop:                                      ; preds = %guarded1, %guarded
600   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
601   %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
602   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
604 deopt2:                                           ; preds = %second_loop
605   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
606   ret void
608 guarded1:                                         ; preds = %second_loop
609   br label %second_loop
612 ; Same situation as in @f_9: no "obviously profitable" widening sites,
613 ; so we refuse to do anything.
614 define void @f_10(i32 %a, i1 %cond_0, i1 %cond_1, i1 %arg) {
615 ; CHECK-LABEL: @f_10(
616 ; CHECK-NEXT:  entry:
617 ; CHECK-NEXT:    br label [[LOOP:%.*]]
618 ; CHECK:       loop:
619 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
620 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
621 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
622 ; CHECK:       deopt:
623 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
624 ; CHECK-NEXT:    ret void
625 ; CHECK:       guarded:
626 ; CHECK-NEXT:    br i1 %arg, label [[LOOP]], label [[NO_LOOP:%.*]]
627 ; CHECK:       no_loop:
628 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
629 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1:%.*]], [[WIDENABLE_COND3]]
630 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
631 ; CHECK:       deopt2:
632 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
633 ; CHECK-NEXT:    ret void
634 ; CHECK:       guarded1:
635 ; CHECK-NEXT:    ret void
637 entry:
638   br label %loop
640 loop:                                             ; preds = %guarded, %entry
641   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
642   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
643   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
645 deopt:                                            ; preds = %loop
646   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
647   ret void
649 guarded:                                          ; preds = %loop
650   br i1 %arg, label %loop, label %no_loop
652 no_loop:                                          ; preds = %guarded
653   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
654   %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
655   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
657 deopt2:                                           ; preds = %no_loop
658   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
659   ret void
661 guarded1:                                         ; preds = %no_loop
662   ret void
665 ; With guards in loops, we're okay hoisting out the guard into the
666 ; containing loop.
667 define void @f_11(i32 %a, i1 %cond_0, i1 %cond_1, i1 %arg) {
668 ; CHECK-LABEL: @f_11(
669 ; CHECK-NEXT:  entry:
670 ; CHECK-NEXT:    [[COND_1_GW_FR:%.*]] = freeze i1 [[COND_1:%.*]]
671 ; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]
672 ; CHECK:       outer_header:
673 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1_GW_FR]]
674 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
675 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
676 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
677 ; CHECK:       deopt:
678 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
679 ; CHECK-NEXT:    ret void
680 ; CHECK:       guarded:
681 ; CHECK-NEXT:    br label [[INNER:%.*]]
682 ; CHECK:       inner:
683 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
684 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1_GW_FR]], [[WIDENABLE_COND3]]
685 ; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
686 ; CHECK:       deopt2:
687 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
688 ; CHECK-NEXT:    ret void
689 ; CHECK:       guarded1:
690 ; CHECK-NEXT:    br i1 %arg, label [[INNER]], label [[OUTER_LATCH:%.*]]
691 ; CHECK:       outer_latch:
692 ; CHECK-NEXT:    br i1 %arg, label [[OUTER_HEADER]], label [[EXIT:%.*]]
693 ; CHECK:       exit:
694 ; CHECK-NEXT:    ret void
696 entry:
697   br label %outer_header
699 outer_header:                                     ; preds = %outer_latch, %entry
700   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
701   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
702   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
704 deopt:                                            ; preds = %outer_header
705   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
706   ret void
708 guarded:                                          ; preds = %outer_header
709   br label %inner
711 inner:                                            ; preds = %guarded1, %guarded
712   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
713   %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
714   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
716 deopt2:                                           ; preds = %inner
717   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
718   ret void
720 guarded1:                                         ; preds = %inner
721   br i1 %arg, label %inner, label %outer_latch
723 outer_latch:                                      ; preds = %guarded1
724   br i1 %arg, label %outer_header, label %exit
726 exit:                                             ; preds = %outer_latch
727   ret void
730 ; Checks that we are adequately guarded against exponential-time
731 ; behavior when hoisting code.
732 define void @f_12(i32 %a0) {
733 ; CHECK-LABEL: @f_12(
734 ; CHECK-NEXT:  entry:
735 ; CHECK-NEXT:    [[A0_GW_FR:%.*]] = freeze i32 [[A0:%.*]]
736 ; CHECK-NEXT:    [[A1:%.*]] = mul i32 [[A0_GW_FR]], [[A0_GW_FR]]
737 ; CHECK-NEXT:    [[A2:%.*]] = mul i32 [[A1]], [[A1]]
738 ; CHECK-NEXT:    [[A3:%.*]] = mul i32 [[A2]], [[A2]]
739 ; CHECK-NEXT:    [[A4:%.*]] = mul i32 [[A3]], [[A3]]
740 ; CHECK-NEXT:    [[A5:%.*]] = mul i32 [[A4]], [[A4]]
741 ; CHECK-NEXT:    [[A6:%.*]] = mul i32 [[A5]], [[A5]]
742 ; CHECK-NEXT:    [[A7:%.*]] = mul i32 [[A6]], [[A6]]
743 ; CHECK-NEXT:    [[A8:%.*]] = mul i32 [[A7]], [[A7]]
744 ; CHECK-NEXT:    [[A9:%.*]] = mul i32 [[A8]], [[A8]]
745 ; CHECK-NEXT:    [[A10:%.*]] = mul i32 [[A9]], [[A9]]
746 ; CHECK-NEXT:    [[A11:%.*]] = mul i32 [[A10]], [[A10]]
747 ; CHECK-NEXT:    [[A12:%.*]] = mul i32 [[A11]], [[A11]]
748 ; CHECK-NEXT:    [[A13:%.*]] = mul i32 [[A12]], [[A12]]
749 ; CHECK-NEXT:    [[A14:%.*]] = mul i32 [[A13]], [[A13]]
750 ; CHECK-NEXT:    [[A15:%.*]] = mul i32 [[A14]], [[A14]]
751 ; CHECK-NEXT:    [[A16:%.*]] = mul i32 [[A15]], [[A15]]
752 ; CHECK-NEXT:    [[A17:%.*]] = mul i32 [[A16]], [[A16]]
753 ; CHECK-NEXT:    [[A18:%.*]] = mul i32 [[A17]], [[A17]]
754 ; CHECK-NEXT:    [[A19:%.*]] = mul i32 [[A18]], [[A18]]
755 ; CHECK-NEXT:    [[A20:%.*]] = mul i32 [[A19]], [[A19]]
756 ; CHECK-NEXT:    [[A21:%.*]] = mul i32 [[A20]], [[A20]]
757 ; CHECK-NEXT:    [[A22:%.*]] = mul i32 [[A21]], [[A21]]
758 ; CHECK-NEXT:    [[A23:%.*]] = mul i32 [[A22]], [[A22]]
759 ; CHECK-NEXT:    [[A24:%.*]] = mul i32 [[A23]], [[A23]]
760 ; CHECK-NEXT:    [[A25:%.*]] = mul i32 [[A24]], [[A24]]
761 ; CHECK-NEXT:    [[A26:%.*]] = mul i32 [[A25]], [[A25]]
762 ; CHECK-NEXT:    [[A27:%.*]] = mul i32 [[A26]], [[A26]]
763 ; CHECK-NEXT:    [[A28:%.*]] = mul i32 [[A27]], [[A27]]
764 ; CHECK-NEXT:    [[A29:%.*]] = mul i32 [[A28]], [[A28]]
765 ; CHECK-NEXT:    [[A30:%.*]] = mul i32 [[A29]], [[A29]]
766 ; CHECK-NEXT:    [[COND:%.*]] = trunc i32 [[A30]] to i1
767 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 true, [[COND]]
768 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
769 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
770 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
771 ; CHECK:       deopt:
772 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
773 ; CHECK-NEXT:    ret void
774 ; CHECK:       guarded:
775 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
776 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND]], [[WIDENABLE_COND3]]
777 ; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
778 ; CHECK:       deopt2:
779 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
780 ; CHECK-NEXT:    ret void
781 ; CHECK:       guarded1:
782 ; CHECK-NEXT:    ret void
784 entry:
785   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
786   %exiplicit_guard_cond = and i1 true, %widenable_cond
787   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
789 deopt:                                            ; preds = %entry
790   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
791   ret void
793 guarded:                                          ; preds = %entry
794   %a1 = mul i32 %a0, %a0
795   %a2 = mul i32 %a1, %a1
796   %a3 = mul i32 %a2, %a2
797   %a4 = mul i32 %a3, %a3
798   %a5 = mul i32 %a4, %a4
799   %a6 = mul i32 %a5, %a5
800   %a7 = mul i32 %a6, %a6
801   %a8 = mul i32 %a7, %a7
802   %a9 = mul i32 %a8, %a8
803   %a10 = mul i32 %a9, %a9
804   %a11 = mul i32 %a10, %a10
805   %a12 = mul i32 %a11, %a11
806   %a13 = mul i32 %a12, %a12
807   %a14 = mul i32 %a13, %a13
808   %a15 = mul i32 %a14, %a14
809   %a16 = mul i32 %a15, %a15
810   %a17 = mul i32 %a16, %a16
811   %a18 = mul i32 %a17, %a17
812   %a19 = mul i32 %a18, %a18
813   %a20 = mul i32 %a19, %a19
814   %a21 = mul i32 %a20, %a20
815   %a22 = mul i32 %a21, %a21
816   %a23 = mul i32 %a22, %a22
817   %a24 = mul i32 %a23, %a23
818   %a25 = mul i32 %a24, %a24
819   %a26 = mul i32 %a25, %a25
820   %a27 = mul i32 %a26, %a26
821   %a28 = mul i32 %a27, %a27
822   %a29 = mul i32 %a28, %a28
823   %a30 = mul i32 %a29, %a29
824   %cond = trunc i32 %a30 to i1
825   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
826   %exiplicit_guard_cond4 = and i1 %cond, %widenable_cond3
827   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
829 deopt2:                                           ; preds = %guarded
830   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
831   ret void
833 guarded1:                                         ; preds = %guarded
834   ret void
837 define void @f_13(i32 %a, i1 %arg) {
838 ; CHECK-LABEL: @f_13(
839 ; CHECK-NEXT:  entry:
840 ; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 14
841 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = icmp ult i32 [[A]], 10
842 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
843 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
844 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
845 ; CHECK:       deopt:
846 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
847 ; CHECK-NEXT:    ret void
848 ; CHECK:       guarded:
849 ; CHECK-NEXT:    br i1 %arg, label [[LEFT:%.*]], label [[RIGHT:%.*]]
850 ; CHECK:       left:
851 ; CHECK-NEXT:    [[COND_1:%.*]] = icmp slt i32 [[A]], 10
852 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
853 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
854 ; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
855 ; CHECK:       deopt2:
856 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
857 ; CHECK-NEXT:    ret void
858 ; CHECK:       guarded1:
859 ; CHECK-NEXT:    ret void
860 ; CHECK:       right:
861 ; CHECK-NEXT:    ret void
863 entry:
864   %cond_0 = icmp ult i32 %a, 14
865   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
866   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
867   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
869 deopt:                                            ; preds = %entry
870   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
871   ret void
873 guarded:                                          ; preds = %entry
874   br i1 %arg, label %left, label %right
876 left:                                             ; preds = %guarded
877   %cond_1 = icmp slt i32 %a, 10
878   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
879   %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
880   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
882 deopt2:                                           ; preds = %left
883   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
884   ret void
886 guarded1:                                         ; preds = %left
887   ret void
889 right:                                            ; preds = %guarded
890   ret void
893 define void @f_14(i32 %a, i1 %arg) {
894 ; CHECK-LABEL: @f_14(
895 ; CHECK-NEXT:  entry:
896 ; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 14
897 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
898 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0]], [[WIDENABLE_COND]]
899 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
900 ; CHECK:       deopt:
901 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
902 ; CHECK-NEXT:    ret void
903 ; CHECK:       guarded:
904 ; CHECK-NEXT:    br i1 %arg, label [[LEFT:%.*]], label [[RIGHT:%.*]]
905 ; CHECK:       left:
906 ; CHECK-NEXT:    [[COND_1:%.*]] = icmp sgt i32 [[A]], 10
907 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
908 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1]], [[WIDENABLE_COND3]]
909 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
910 ; CHECK:       deopt2:
911 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
912 ; CHECK-NEXT:    ret void
913 ; CHECK:       guarded1:
914 ; CHECK-NEXT:    ret void
915 ; CHECK:       right:
916 ; CHECK-NEXT:    ret void
918 entry:
919   %cond_0 = icmp ult i32 %a, 14
920   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
921   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
922   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
924 deopt:                                            ; preds = %entry
925   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
926   ret void
928 guarded:                                          ; preds = %entry
929   br i1 %arg, label %left, label %right
931 left:                                             ; preds = %guarded
932   %cond_1 = icmp sgt i32 %a, 10
933   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
934   %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
935   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
937 deopt2:                                           ; preds = %left
938   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
939   ret void
941 guarded1:                                         ; preds = %left
942   ret void
944 right:                                            ; preds = %guarded
945   ret void
948 ; Make sure we do not widen guard by trivial true conditions into something.
949 define void @f_15(i1 %cond_0, i1 %cond_1) {
950 ; CHECK-LABEL: @f_15(
951 ; CHECK-NEXT:  entry:
952 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
953 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
954 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
955 ; CHECK:       deopt:
956 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
957 ; CHECK-NEXT:    ret void
958 ; CHECK:       guarded:
959 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
960 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 true, [[WIDENABLE_COND3]]
961 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
962 ; CHECK:       deopt2:
963 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
964 ; CHECK-NEXT:    ret void
965 ; CHECK:       guarded1:
966 ; CHECK-NEXT:    ret void
968 entry:
969   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
970   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
971   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
973 deopt:                                            ; preds = %entry
974   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
975   ret void
977 guarded:                                          ; preds = %entry
978   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
979   %exiplicit_guard_cond4 = and i1 true, %widenable_cond3
980   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
982 deopt2:                                           ; preds = %guarded
983   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
984   ret void
986 guarded1:                                         ; preds = %guarded
987   ret void
990 ; Make sure we do not widen guard by trivial false conditions into something.
991 define void @f_16(i1 %cond_0, i1 %cond_1) {
992 ; CHECK-LABEL: @f_16(
993 ; CHECK-NEXT:  entry:
994 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
995 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
996 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
997 ; CHECK:       deopt:
998 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
999 ; CHECK-NEXT:    ret void
1000 ; CHECK:       guarded:
1001 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
1002 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 false, [[WIDENABLE_COND3]]
1003 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
1004 ; CHECK:       deopt2:
1005 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1006 ; CHECK-NEXT:    ret void
1007 ; CHECK:       guarded1:
1008 ; CHECK-NEXT:    ret void
1010 entry:
1011   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1012   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
1013   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1015 deopt:                                            ; preds = %entry
1016   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1017   ret void
1019 guarded:                                          ; preds = %entry
1020   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
1021   %exiplicit_guard_cond4 = and i1 false, %widenable_cond3
1022   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
1024 deopt2:                                           ; preds = %guarded
1025   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1026   ret void
1028 guarded1:                                         ; preds = %guarded
1029   ret void
1033 define void @swapped_wb(i1 %cond_0, i1 %cond_1) {
1034 ; CHECK-LABEL: @swapped_wb(
1035 ; CHECK-NEXT:  entry:
1036 ; CHECK-NEXT:    [[COND_1_GW_FR:%.*]] = freeze i1 [[COND_1:%.*]]
1037 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1_GW_FR]]
1038 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1039 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDENABLE_COND]], [[WIDE_CHK]]
1040 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
1041 ; CHECK:       deopt:
1042 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1043 ; CHECK-NEXT:    ret void
1044 ; CHECK:       guarded:
1045 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
1046 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_1_GW_FR]], [[WIDENABLE_COND3]]
1047 ; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
1048 ; CHECK:       deopt2:
1049 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1050 ; CHECK-NEXT:    ret void
1051 ; CHECK:       guarded1:
1052 ; CHECK-NEXT:    ret void
1054 entry:
1055   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1056   %exiplicit_guard_cond = and i1 %widenable_cond, %cond_0
1057   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1059 deopt:                                            ; preds = %entry
1060   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1061   ret void
1063 guarded:                                          ; preds = %entry
1064   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
1065   %exiplicit_guard_cond4 = and i1 %cond_1, %widenable_cond3
1066   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
1068 deopt2:                                           ; preds = %guarded
1069   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1070   ret void
1072 guarded1:                                         ; preds = %guarded
1073   ret void
1076 define void @trivial_wb(i1 %cond_0) {
1077 ; CHECK-LABEL: @trivial_wb(
1078 ; CHECK-NEXT:  entry:
1079 ; CHECK-NEXT:    [[COND_0_GW_FR:%.*]] = freeze i1 [[COND_0:%.*]]
1080 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 true, [[COND_0_GW_FR]]
1081 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1082 ; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]]
1083 ; CHECK-NEXT:    br i1 [[TMP0]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
1084 ; CHECK:       deopt:
1085 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1086 ; CHECK-NEXT:    ret void
1087 ; CHECK:       guarded:
1088 ; CHECK-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
1089 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND_0_GW_FR]], [[WIDENABLE_COND3]]
1090 ; CHECK-NEXT:    br i1 true, label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
1091 ; CHECK:       deopt2:
1092 ; CHECK-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1093 ; CHECK-NEXT:    ret void
1094 ; CHECK:       guarded1:
1095 ; CHECK-NEXT:    ret void
1097 entry:
1098   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1099   br i1 %widenable_cond, label %guarded, label %deopt, !prof !0
1101 deopt:                                            ; preds = %entry
1102   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1103   ret void
1105 guarded:                                          ; preds = %entry
1106   %widenable_cond3 = call i1 @llvm.experimental.widenable.condition()
1107   %exiplicit_guard_cond4 = and i1 %cond_0, %widenable_cond3
1108   br i1 %exiplicit_guard_cond4, label %guarded1, label %deopt2, !prof !0
1110 deopt2:                                           ; preds = %guarded
1111   call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1112   ret void
1114 guarded1:                                         ; preds = %guarded
1115   ret void
1119 declare void @llvm.experimental.deoptimize.isVoid(...)
1121 ; Function Attrs: inaccessiblememonly nounwind
1122 declare i1 @llvm.experimental.widenable.condition() #0
1124 attributes #0 = { inaccessiblememonly nounwind }
1126 !0 = !{!"branch_weights", i32 1048576, i32 1}