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
4
5; Basic test case: we wide the first check to check both the
6; conditions.
7define 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 [[PROF0:![0-9]+]]
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 [[PROF0]]
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
26;
27entry:
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
31
32deopt:                                            ; preds = %entry
33  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
34  ret void
35
36guarded:                                          ; 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
40
41deopt2:                                           ; preds = %guarded
42  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
43  ret void
44
45guarded1:                                         ; preds = %guarded
46  ret void
47}
48
49; Same as @f_0, but with using a more general notion of postdominance.
50define 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 [[PROF0]]
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 [[PROF0]]
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
75;
76entry:
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
80
81deopt:                                            ; preds = %entry
82  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
83  ret void
84
85guarded:                                          ; preds = %entry
86  br i1 undef, label %left, label %right
87
88left:                                             ; preds = %guarded
89  br label %merge
90
91right:                                            ; preds = %guarded
92  br label %merge
93
94merge:                                            ; 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
98
99deopt2:                                           ; preds = %merge
100  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
101  ret void
102
103guarded1:                                         ; preds = %merge
104  ret void
105}
106
107; Like @f_1, but we have some code we need to hoist before we can
108; widen a dominanting check.
109define 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 [[PROF0]]
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 [[PROF0]]
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
136;
137entry:
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
142
143deopt:                                            ; preds = %entry
144  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
145  ret void
146
147guarded:                                          ; preds = %entry
148  br i1 undef, label %left, label %right
149
150left:                                             ; preds = %guarded
151  br label %merge
152
153right:                                            ; preds = %guarded
154  br label %merge
155
156merge:                                            ; 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
161
162deopt2:                                           ; preds = %merge
163  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
164  ret void
165
166guarded1:                                         ; preds = %merge
167  ret void
168}
169
170; Negative test: don't hoist stuff out of control flow
171; indiscriminately, since that can make us do more work than needed.
172define 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 [[PROF0]]
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 [[PROF0]]
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
196;
197entry:
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
202
203deopt:                                            ; preds = %entry
204  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
205  ret void
206
207guarded:                                          ; preds = %entry
208  br i1 undef, label %left, label %right
209
210left:                                             ; 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
215
216deopt2:                                           ; preds = %left
217  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
218  ret void
219
220guarded1:                                         ; preds = %left
221  ret void
222
223right:                                            ; preds = %guarded
224  ret void
225}
226
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.
230define 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 [[PROF0]]
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 [[PROF0]]
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
255;
256entry:
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
261
262deopt:                                            ; preds = %entry
263  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
264  ret void
265
266guarded:                                          ; preds = %entry
267  br i1 undef, label %loop, label %leave
268
269loop:                                             ; 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
274
275deopt2:                                           ; preds = %loop
276  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
277  ret void
278
279guarded1:                                         ; preds = %loop
280  br i1 undef, label %loop, label %leave
281
282leave:                                            ; preds = %guarded1, %guarded
283  ret void
284}
285
286; Hoisting out of control flow is also fine if we can widen the
287; dominating check without doing any extra work.
288define 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 [[PROF0]]
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 [[PROF0]]
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
313;
314entry:
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
319
320deopt:                                            ; preds = %entry
321  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
322  ret void
323
324guarded:                                          ; preds = %entry
325  br i1 undef, label %left, label %right
326
327left:                                             ; 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
332
333deopt2:                                           ; preds = %left
334  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
335  ret void
336
337guarded1:                                         ; preds = %left
338  ret void
339
340right:                                            ; preds = %guarded
341  ret void
342}
343
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.
347define 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:%.*]], align 1
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 [[PROF0]]
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:%.*]], align 1
359; CHECK-NEXT:    [[COND_1:%.*]] = load i1, i1* [[A]], align 1
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 [[PROF0]]
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
368;
369entry:
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
374
375deopt:                                            ; preds = %entry
376  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
377  ret void
378
379guarded:                                          ; 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
385
386deopt2:                                           ; preds = %guarded
387  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
388  ret void
389
390guarded1:                                         ; preds = %guarded
391  ret void
392}
393
394; All else equal, we try to widen the earliest guard we can.  This
395; heuristic can use some tuning.
396define 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:%.*]], align 1
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 [[PROF0]]
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]], align 1
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 [[PROF0]]
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 [[PROF0]]
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
429;
430entry:
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
435
436deopt:                                            ; preds = %entry
437  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
438  ret void
439
440guarded:                                          ; 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
445
446deopt2:                                           ; preds = %guarded
447  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
448  ret void
449
450guarded1:                                         ; preds = %guarded
451  br i1 undef, label %left, label %right
452
453left:                                             ; 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
458
459deopt6:                                           ; preds = %left
460  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
461  ret void
462
463guarded5:                                         ; preds = %left
464  br label %left
465
466right:                                            ; preds = %guarded1
467  ret void
468}
469
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.
473define 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 [[PROF0]]
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 [[PROF0]]
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 [[PROF0]]
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
508;
509entry:
510  br label %loop
511
512loop:                                             ; 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
516
517deopt:                                            ; preds = %loop
518  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
519  ret void
520
521guarded:                                          ; preds = %loop
522  br i1 undef, label %loop, label %leave
523
524leave:                                            ; 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
528
529deopt2:                                           ; preds = %leave
530  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
531  ret void
532
533guarded1:                                         ; preds = %leave
534  br i1 undef, label %loop2, label %leave2
535
536loop2:                                            ; 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
541
542deopt6:                                           ; preds = %loop2
543  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
544  ret void
545
546guarded5:                                         ; preds = %loop2
547  br label %loop2
548
549leave2:                                           ; preds = %guarded1
550  ret void
551}
552
553; In cases like these where there isn't any "obviously profitable"
554; widening sites, we refuse to do anything.
555define 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 [[PROF0]]
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 [[PROF0]]
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]]
577;
578entry:
579  br label %first_loop
580
581first_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
585
586deopt:                                            ; preds = %first_loop
587  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
588  ret void
589
590guarded:                                          ; preds = %first_loop
591  br i1 undef, label %first_loop, label %second_loop
592
593second_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
597
598deopt2:                                           ; preds = %second_loop
599  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
600  ret void
601
602guarded1:                                         ; preds = %second_loop
603  br label %second_loop
604}
605
606; Same situation as in @f_9: no "obviously profitable" widening sites,
607; so we refuse to do anything.
608define 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 [[PROF0]]
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 [[PROF0]]
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
630;
631entry:
632  br label %loop
633
634loop:                                             ; 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
638
639deopt:                                            ; preds = %loop
640  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
641  ret void
642
643guarded:                                          ; preds = %loop
644  br i1 undef, label %loop, label %no_loop
645
646no_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
650
651deopt2:                                           ; preds = %no_loop
652  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
653  ret void
654
655guarded1:                                         ; preds = %no_loop
656  ret void
657}
658
659; With guards in loops, we're okay hoisting out the guard into the
660; containing loop.
661define 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 [[PROF0]]
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 [[PROF0]]
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
688;
689entry:
690  br label %outer_header
691
692outer_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
696
697deopt:                                            ; preds = %outer_header
698  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
699  ret void
700
701guarded:                                          ; preds = %outer_header
702  br label %inner
703
704inner:                                            ; 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
708
709deopt2:                                           ; preds = %inner
710  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
711  ret void
712
713guarded1:                                         ; preds = %inner
714  br i1 undef, label %inner, label %outer_latch
715
716outer_latch:                                      ; preds = %guarded1
717  br i1 undef, label %outer_header, label %exit
718
719exit:                                             ; preds = %outer_latch
720  ret void
721}
722
723; Checks that we are adequately guarded against exponential-time
724; behavior when hoisting code.
725define 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 [[PROF0]]
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 [[PROF0]]
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
775;
776entry:
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
780
781deopt:                                            ; preds = %entry
782  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
783  ret void
784
785guarded:                                          ; 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
820
821deopt2:                                           ; preds = %guarded
822  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
823  ret void
824
825guarded1:                                         ; preds = %guarded
826  ret void
827}
828
829define 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 [[PROF0]]
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 [[PROF0]]
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
854;
855entry:
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
860
861deopt:                                            ; preds = %entry
862  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
863  ret void
864
865guarded:                                          ; preds = %entry
866  br i1 undef, label %left, label %right
867
868left:                                             ; 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
873
874deopt2:                                           ; preds = %left
875  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
876  ret void
877
878guarded1:                                         ; preds = %left
879  ret void
880
881right:                                            ; preds = %guarded
882  ret void
883}
884
885define 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 [[PROF0]]
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 [[PROF0]]
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
909;
910entry:
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
915
916deopt:                                            ; preds = %entry
917  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
918  ret void
919
920guarded:                                          ; preds = %entry
921  br i1 undef, label %left, label %right
922
923left:                                             ; 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
928
929deopt2:                                           ; preds = %left
930  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
931  ret void
932
933guarded1:                                         ; preds = %left
934  ret void
935
936right:                                            ; preds = %guarded
937  ret void
938}
939
940; Make sure we do not widen guard by trivial true conditions into something.
941define 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 [[PROF0]]
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 [[PROF0]]
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
959;
960entry:
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
964
965deopt:                                            ; preds = %entry
966  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
967  ret void
968
969guarded:                                          ; 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
973
974deopt2:                                           ; preds = %guarded
975  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
976  ret void
977
978guarded1:                                         ; preds = %guarded
979  ret void
980}
981
982; Make sure we do not widen guard by trivial false conditions into something.
983define 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 [[PROF0]]
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 [[PROF0]]
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
1001;
1002entry:
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
1006
1007deopt:                                            ; preds = %entry
1008  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1009  ret void
1010
1011guarded:                                          ; 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
1015
1016deopt2:                                           ; preds = %guarded
1017  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1018  ret void
1019
1020guarded1:                                         ; preds = %guarded
1021  ret void
1022}
1023
1024
1025define 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 [[PROF0]]
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 [[PROF0]]
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
1044;
1045entry:
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
1049
1050deopt:                                            ; preds = %entry
1051  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1052  ret void
1053
1054guarded:                                          ; 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
1058
1059deopt2:                                           ; preds = %guarded
1060  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1061  ret void
1062
1063guarded1:                                         ; preds = %guarded
1064  ret void
1065}
1066
1067define 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 [[PROF0]]
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 [[PROF0]]
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
1086;
1087entry:
1088  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1089  br i1 %widenable_cond, label %guarded, label %deopt, !prof !0
1090
1091deopt:                                            ; preds = %entry
1092  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1093  ret void
1094
1095guarded:                                          ; 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
1099
1100deopt2:                                           ; preds = %guarded
1101  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
1102  ret void
1103
1104guarded1:                                         ; preds = %guarded
1105  ret void
1106}
1107
1108
1109declare void @llvm.experimental.deoptimize.isVoid(...)
1110
1111; Function Attrs: inaccessiblememonly nounwind
1112declare i1 @llvm.experimental.widenable.condition() #0
1113
1114attributes #0 = { inaccessiblememonly nounwind }
1115
1116!0 = !{!"branch_weights", i32 1048576, i32 1}
1117