[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / LoopPredication / predicate-exits.ll
blob01c78580ca9e63c0f5fb58119555112a892feb19
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -loop-predication -S | FileCheck %s
4 declare void @prevent_merging()
6 ; Base case - with side effects in loop
7 define i32 @test1(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
8 ; CHECK-LABEL: @test1(
9 ; CHECK-NEXT:  entry:
10 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
11 ; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
12 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
13 ; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])
14 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
15 ; CHECK-NEXT:    [[TMP2:%.*]] = freeze i1 [[TMP1]]
16 ; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]
17 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
18 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
19 ; CHECK:       deopt:
20 ; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
21 ; CHECK-NEXT:    ret i32 [[DEOPTRET]]
22 ; CHECK:       loop.preheader:
23 ; CHECK-NEXT:    br label [[LOOP:%.*]]
24 ; CHECK:       loop:
25 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
26 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
27 ; CHECK-NEXT:    call void @unknown()
28 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
29 ; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
30 ; CHECK:       deopt2:
31 ; CHECK-NEXT:    call void @unknown()
32 ; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
33 ; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
34 ; CHECK:       guarded:
35 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
36 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
37 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
38 ; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
39 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
40 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
41 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
42 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
43 ; CHECK:       exit:
44 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
45 ; CHECK-NEXT:    ret i32 [[RESULT]]
47 entry:
48   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
49   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
50   br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
52 deopt:
53   %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
54   ret i32 %deoptret
56 loop.preheader:
57   br label %loop
59 loop:
60   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
61   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
62   call void @unknown()
63   %within.bounds = icmp ult i32 %i, %length
64   br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
66 deopt2:
67   call void @unknown()
68   %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
69   ret i32 %deoptret2
71 guarded:
72   %i.i64 = zext i32 %i to i64
73   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
74   %array.i = load i32, i32* %array.i.ptr, align 4
75   store i32 0, i32* %array.i.ptr
76   %loop.acc.next = add i32 %loop.acc, %array.i
77   %i.next = add nuw i32 %i, 1
78   %continue = icmp ult i32 %i.next, %n
79   br i1 %continue, label %loop, label %exit
81 exit:
82   %result = phi i32 [ %loop.acc.next, %guarded ]
83   ret i32 %result
88 define i32 @test_non_canonical(i32* %array, i32 %length, i1 %cond_0) {
89 ; CHECK-LABEL: @test_non_canonical(
90 ; CHECK-NEXT:  entry:
91 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
92 ; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[LENGTH:%.*]], i32 1)
93 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
94 ; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH]], i32 [[TMP0]])
95 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
96 ; CHECK-NEXT:    [[TMP2:%.*]] = freeze i1 [[TMP1]]
97 ; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]
98 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
99 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
100 ; CHECK:       deopt:
101 ; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
102 ; CHECK-NEXT:    ret i32 [[DEOPTRET]]
103 ; CHECK:       loop.preheader:
104 ; CHECK-NEXT:    br label [[LOOP:%.*]]
105 ; CHECK:       loop:
106 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
107 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
108 ; CHECK-NEXT:    call void @unknown()
109 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
110 ; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
111 ; CHECK:       deopt2:
112 ; CHECK-NEXT:    call void @unknown()
113 ; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
114 ; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
115 ; CHECK:       guarded:
116 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
117 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
118 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
119 ; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
120 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
121 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
122 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[LENGTH]]
123 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
124 ; CHECK:       exit:
125 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
126 ; CHECK-NEXT:    ret i32 [[RESULT]]
128 entry:
129   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
130   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
131   br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
133 deopt:
134   %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
135   ret i32 %deoptret
137 loop.preheader:
138   br label %loop
140 loop:
141   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
142   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
143   call void @unknown()
144   %within.bounds = icmp ult i32 %i, %length
145   br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
147 deopt2:
148   call void @unknown()
149   %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
150   ret i32 %deoptret2
152 guarded:
153   %i.i64 = zext i32 %i to i64
154   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
155   %array.i = load i32, i32* %array.i.ptr, align 4
156   store i32 0, i32* %array.i.ptr
157   %loop.acc.next = add i32 %loop.acc, %array.i
158   %i.next = add nuw i32 %i, 1
159   %continue = icmp ult i32 %i.next, %length
160   br i1 %continue, label %loop, label %exit
162 exit:
163   %result = phi i32 [ %loop.acc.next, %guarded ]
164   ret i32 %result
168 define i32 @test_two_range_checks(i32* %array, i32 %length.1, i32 %length.2, i32 %n, i1 %cond_0) {
169 ; CHECK-LABEL: @test_two_range_checks(
170 ; CHECK-NEXT:  entry:
171 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
172 ; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH_2:%.*]], i32 [[LENGTH_1:%.*]])
173 ; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
174 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
175 ; CHECK-NEXT:    [[UMIN1:%.*]] = call i32 @llvm.umin.i32(i32 [[UMIN]], i32 [[TMP0]])
176 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[LENGTH_1]], [[UMIN1]]
177 ; CHECK-NEXT:    [[TMP2:%.*]] = freeze i1 [[TMP1]]
178 ; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]
179 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp ugt i32 [[LENGTH_2]], [[UMIN1]]
180 ; CHECK-NEXT:    [[TMP5:%.*]] = freeze i1 [[TMP4]]
181 ; CHECK-NEXT:    [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP3]]
182 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP6]], [[WIDENABLE_COND]]
183 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
184 ; CHECK:       deopt:
185 ; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
186 ; CHECK-NEXT:    ret i32 [[DEOPTRET]]
187 ; CHECK:       loop.preheader:
188 ; CHECK-NEXT:    br label [[LOOP:%.*]]
189 ; CHECK:       loop:
190 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
191 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]
192 ; CHECK-NEXT:    call void @unknown()
193 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]]
194 ; CHECK-NEXT:    br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof !0
195 ; CHECK:       deopt2:
196 ; CHECK-NEXT:    call void @unknown()
197 ; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
198 ; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
199 ; CHECK:       guarded:
200 ; CHECK-NEXT:    [[WITHIN_BOUNDS2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]]
201 ; CHECK-NEXT:    br i1 true, label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0
202 ; CHECK:       deopt3:
203 ; CHECK-NEXT:    call void @unknown()
204 ; CHECK-NEXT:    [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
205 ; CHECK-NEXT:    ret i32 [[DEOPTRET3]]
206 ; CHECK:       guarded2:
207 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
208 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
209 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
210 ; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
211 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
212 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
213 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
214 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
215 ; CHECK:       exit:
216 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
217 ; CHECK-NEXT:    ret i32 [[RESULT]]
219 entry:
220   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
221   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
222   br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
224 deopt:
225   %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
226   ret i32 %deoptret
228 loop.preheader:
229   br label %loop
231 loop:
232   %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]
233   %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
234   call void @unknown()
235   %within.bounds = icmp ult i32 %i, %length.1
236   br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
238 deopt2:
239   call void @unknown()
240   %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
241   ret i32 %deoptret2
243 guarded:
244   %within.bounds2 = icmp ult i32 %i, %length.2
245   br i1 %within.bounds2, label %guarded2, label %deopt3, !prof !0
247 deopt3:
248   call void @unknown()
249   %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
250   ret i32 %deoptret3
252 guarded2:
253   %i.i64 = zext i32 %i to i64
254   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
255   %array.i = load i32, i32* %array.i.ptr, align 4
256   store i32 0, i32* %array.i.ptr
257   %loop.acc.next = add i32 %loop.acc, %array.i
258   %i.next = add nuw i32 %i, 1
259   %continue = icmp ult i32 %i.next, %n
260   br i1 %continue, label %loop, label %exit
262 exit:
263   %result = phi i32 [ %loop.acc.next, %guarded2 ]
264   ret i32 %result
267 @G = external global i32
269 define i32 @test_unanalyzeable_exit(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
270 ; CHECK-LABEL: @test_unanalyzeable_exit(
271 ; CHECK-NEXT:  entry:
272 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
273 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
274 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
275 ; CHECK:       deopt:
276 ; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
277 ; CHECK-NEXT:    ret i32 [[DEOPTRET]]
278 ; CHECK:       loop.preheader:
279 ; CHECK-NEXT:    br label [[LOOP:%.*]]
280 ; CHECK:       loop:
281 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
282 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]
283 ; CHECK-NEXT:    call void @unknown()
284 ; CHECK-NEXT:    [[VOL:%.*]] = load volatile i32, i32* @G, align 4
285 ; CHECK-NEXT:    [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0
286 ; CHECK-NEXT:    br i1 [[UNKNOWN]], label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0
287 ; CHECK:       deopt3:
288 ; CHECK-NEXT:    call void @unknown()
289 ; CHECK-NEXT:    [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
290 ; CHECK-NEXT:    ret i32 [[DEOPTRET3]]
291 ; CHECK:       guarded2:
292 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
293 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
294 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
295 ; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
296 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
297 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
298 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N:%.*]]
299 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
300 ; CHECK:       exit:
301 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
302 ; CHECK-NEXT:    ret i32 [[RESULT]]
304 entry:
305   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
306   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
307   br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
309 deopt:
310   %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
311   ret i32 %deoptret
313 loop.preheader:
314   br label %loop
316 loop:
317   %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]
318   %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
319   call void @unknown()
320   %vol = load volatile i32, i32* @G
321   %unknown = icmp eq i32 %vol, 0
322   br i1 %unknown, label %guarded2, label %deopt3, !prof !0
324 deopt3:
325   call void @unknown()
326   %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
327   ret i32 %deoptret3
329 guarded2:
330   %i.i64 = zext i32 %i to i64
331   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
332   %array.i = load i32, i32* %array.i.ptr, align 4
333   store i32 0, i32* %array.i.ptr
334   %loop.acc.next = add i32 %loop.acc, %array.i
335   %i.next = add nuw i32 %i, 1
336   %continue = icmp ult i32 %i.next, %n
337   br i1 %continue, label %loop, label %exit
339 exit:
340   %result = phi i32 [ %loop.acc.next, %guarded2 ]
341   ret i32 %result
344 define i32 @test_unanalyzeable_exit2(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
345 ; CHECK-LABEL: @test_unanalyzeable_exit2(
346 ; CHECK-NEXT:  entry:
347 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
348 ; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
349 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
350 ; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])
351 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
352 ; CHECK-NEXT:    [[TMP2:%.*]] = freeze i1 [[TMP1]]
353 ; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]
354 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
355 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
356 ; CHECK:       deopt:
357 ; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
358 ; CHECK-NEXT:    ret i32 [[DEOPTRET]]
359 ; CHECK:       loop.preheader:
360 ; CHECK-NEXT:    br label [[LOOP:%.*]]
361 ; CHECK:       loop:
362 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
363 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]
364 ; CHECK-NEXT:    call void @unknown()
365 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
366 ; CHECK-NEXT:    br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof !0
367 ; CHECK:       deopt2:
368 ; CHECK-NEXT:    call void @unknown()
369 ; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
370 ; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
371 ; CHECK:       guarded:
372 ; CHECK-NEXT:    [[VOL:%.*]] = load volatile i32, i32* @G, align 4
373 ; CHECK-NEXT:    [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0
374 ; CHECK-NEXT:    br i1 [[UNKNOWN]], label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0
375 ; CHECK:       deopt3:
376 ; CHECK-NEXT:    call void @unknown()
377 ; CHECK-NEXT:    [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
378 ; CHECK-NEXT:    ret i32 [[DEOPTRET3]]
379 ; CHECK:       guarded2:
380 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
381 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
382 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
383 ; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
384 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
385 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
386 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
387 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
388 ; CHECK:       exit:
389 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
390 ; CHECK-NEXT:    ret i32 [[RESULT]]
392 entry:
393   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
394   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
395   br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
397 deopt:
398   %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
399   ret i32 %deoptret
401 loop.preheader:
402   br label %loop
404 loop:
405   %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]
406   %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
407   call void @unknown()
408   %within.bounds = icmp ult i32 %i, %length
409   br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
411 deopt2:
412   call void @unknown()
413   %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
414   ret i32 %deoptret2
416 guarded:
417   %vol = load volatile i32, i32* @G
418   %unknown = icmp eq i32 %vol, 0
419   br i1 %unknown, label %guarded2, label %deopt3, !prof !0
421 deopt3:
422   call void @unknown()
423   %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
424   ret i32 %deoptret3
426 guarded2:
427   %i.i64 = zext i32 %i to i64
428   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
429   %array.i = load i32, i32* %array.i.ptr, align 4
430   store i32 0, i32* %array.i.ptr
431   %loop.acc.next = add i32 %loop.acc, %array.i
432   %i.next = add nuw i32 %i, 1
433   %continue = icmp ult i32 %i.next, %n
434   br i1 %continue, label %loop, label %exit
436 exit:
437   %result = phi i32 [ %loop.acc.next, %guarded2 ]
438   ret i32 %result
442 define i32 @test_unanalyzeable_latch(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
443 ; CHECK-LABEL: @test_unanalyzeable_latch(
444 ; CHECK-NEXT:  entry:
445 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
446 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
447 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
448 ; CHECK:       deopt:
449 ; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
450 ; CHECK-NEXT:    ret i32 [[DEOPTRET]]
451 ; CHECK:       loop.preheader:
452 ; CHECK-NEXT:    br label [[LOOP:%.*]]
453 ; CHECK:       loop:
454 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
455 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
456 ; CHECK-NEXT:    call void @unknown()
457 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
458 ; CHECK-NEXT:    br i1 [[WITHIN_BOUNDS]], label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
459 ; CHECK:       deopt2:
460 ; CHECK-NEXT:    call void @unknown()
461 ; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
462 ; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
463 ; CHECK:       guarded:
464 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
465 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
466 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
467 ; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
468 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
469 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
470 ; CHECK-NEXT:    [[VOL:%.*]] = load volatile i32, i32* @G, align 4
471 ; CHECK-NEXT:    [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0
472 ; CHECK-NEXT:    br i1 [[UNKNOWN]], label [[LOOP]], label [[EXIT:%.*]]
473 ; CHECK:       exit:
474 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
475 ; CHECK-NEXT:    ret i32 [[RESULT]]
477 entry:
478   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
479   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
480   br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
482 deopt:
483   %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
484   ret i32 %deoptret
486 loop.preheader:
487   br label %loop
489 loop:
490   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
491   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
492   call void @unknown()
493   %within.bounds = icmp ult i32 %i, %length
494   br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
496 deopt2:
497   call void @unknown()
498   %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
499   ret i32 %deoptret2
501 guarded:
502   %i.i64 = zext i32 %i to i64
503   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
504   %array.i = load i32, i32* %array.i.ptr, align 4
505   store i32 0, i32* %array.i.ptr
506   %loop.acc.next = add i32 %loop.acc, %array.i
507   %i.next = add nuw i32 %i, 1
508   %vol = load volatile i32, i32* @G
509   %unknown = icmp eq i32 %vol, 0
510   br i1 %unknown, label %loop, label %exit
512 exit:
513   %result = phi i32 [ %loop.acc.next, %guarded ]
514   ret i32 %result
518 define i32 @provably_taken(i32* %array, i1 %cond_0) {
519 ; CHECK-LABEL: @provably_taken(
520 ; CHECK-NEXT:  entry:
521 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
522 ; CHECK-NEXT:    [[TMP0:%.*]] = freeze i1 false
523 ; CHECK-NEXT:    [[TMP1:%.*]] = and i1 [[TMP0]], [[COND_0:%.*]]
524 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]]
525 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
526 ; CHECK:       deopt:
527 ; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
528 ; CHECK-NEXT:    ret i32 [[DEOPTRET]]
529 ; CHECK:       loop.preheader:
530 ; CHECK-NEXT:    br label [[LOOP:%.*]]
531 ; CHECK:       loop:
532 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
533 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
534 ; CHECK-NEXT:    call void @unknown()
535 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], 198
536 ; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
537 ; CHECK:       deopt2:
538 ; CHECK-NEXT:    call void @unknown()
539 ; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
540 ; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
541 ; CHECK:       guarded:
542 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
543 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
544 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
545 ; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
546 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
547 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
548 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], 200
549 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
550 ; CHECK:       exit:
551 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
552 ; CHECK-NEXT:    ret i32 [[RESULT]]
554 entry:
555   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
556   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
557   br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
559 deopt:
560   %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
561   ret i32 %deoptret
563 loop.preheader:
564   br label %loop
566 loop:
567   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
568   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
569   call void @unknown()
570   %within.bounds = icmp ult i32 %i, 198
571   br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
573 deopt2:
574   call void @unknown()
575   %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
576   ret i32 %deoptret2
578 guarded:
579   %i.i64 = zext i32 %i to i64
580   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
581   %array.i = load i32, i32* %array.i.ptr, align 4
582   store i32 0, i32* %array.i.ptr
583   %loop.acc.next = add i32 %loop.acc, %array.i
584   %i.next = add nuw i32 %i, 1
585   %continue = icmp ult i32 %i.next, 200
586   br i1 %continue, label %loop, label %exit
588 exit:
589   %result = phi i32 [ %loop.acc.next, %guarded ]
590   ret i32 %result
593 define i32 @provably_not_taken(i32* %array, i1 %cond_0) {
594 ; CHECK-LABEL: @provably_not_taken(
595 ; CHECK-NEXT:  entry:
596 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
597 ; CHECK-NEXT:    [[TMP0:%.*]] = freeze i1 true
598 ; CHECK-NEXT:    [[TMP1:%.*]] = and i1 [[TMP0]], [[COND_0:%.*]]
599 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]]
600 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
601 ; CHECK:       deopt:
602 ; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
603 ; CHECK-NEXT:    ret i32 [[DEOPTRET]]
604 ; CHECK:       loop.preheader:
605 ; CHECK-NEXT:    br label [[LOOP:%.*]]
606 ; CHECK:       loop:
607 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
608 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
609 ; CHECK-NEXT:    call void @unknown()
610 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], 205
611 ; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
612 ; CHECK:       deopt2:
613 ; CHECK-NEXT:    call void @unknown()
614 ; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
615 ; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
616 ; CHECK:       guarded:
617 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
618 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
619 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
620 ; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
621 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
622 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
623 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], 200
624 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
625 ; CHECK:       exit:
626 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
627 ; CHECK-NEXT:    ret i32 [[RESULT]]
629 entry:
630   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
631   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
632   br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
634 deopt:
635   %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
636   ret i32 %deoptret
638 loop.preheader:
639   br label %loop
641 loop:
642   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
643   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
644   call void @unknown()
645   %within.bounds = icmp ult i32 %i, 205
646   br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
648 deopt2:
649   call void @unknown()
650   %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
651   ret i32 %deoptret2
653 guarded:
654   %i.i64 = zext i32 %i to i64
655   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
656   %array.i = load i32, i32* %array.i.ptr, align 4
657   store i32 0, i32* %array.i.ptr
658   %loop.acc.next = add i32 %loop.acc, %array.i
659   %i.next = add nuw i32 %i, 1
660   %continue = icmp ult i32 %i.next, 200
661   br i1 %continue, label %loop, label %exit
663 exit:
664   %result = phi i32 [ %loop.acc.next, %guarded ]
665   ret i32 %result
669 ;; Unswitch likes to produce some ugly exit blocks without simplifications
670 ;; being applied.  Make sure we can handle that form.
671 define i32 @unswitch_exit_form(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
672 ; CHECK-LABEL: @unswitch_exit_form(
673 ; CHECK-NEXT:  entry:
674 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
675 ; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
676 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
677 ; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])
678 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
679 ; CHECK-NEXT:    [[TMP2:%.*]] = freeze i1 [[TMP1]]
680 ; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]
681 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
682 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
683 ; CHECK:       deopt.loopexit:
684 ; CHECK-NEXT:    br label [[DEOPT]]
685 ; CHECK:       deopt:
686 ; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[DEOPT_LOOPEXIT:%.*]] ]
687 ; CHECK-NEXT:    call void @unknown()
688 ; CHECK-NEXT:    br label [[ACTUAL_DEOPT:%.*]]
689 ; CHECK:       actual_deopt:
690 ; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[PHI]]) ]
691 ; CHECK-NEXT:    ret i32 [[DEOPTRET]]
692 ; CHECK:       loop.preheader:
693 ; CHECK-NEXT:    br label [[LOOP:%.*]]
694 ; CHECK:       loop:
695 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
696 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
697 ; CHECK-NEXT:    call void @unknown()
698 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
699 ; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT_LOOPEXIT]], !prof !0
700 ; CHECK:       guarded:
701 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
702 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
703 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
704 ; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
705 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
706 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
707 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
708 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
709 ; CHECK:       exit:
710 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
711 ; CHECK-NEXT:    ret i32 [[RESULT]]
713 entry:
714   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
715   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
716   br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
718 deopt:
719   ;; This is written to look like an unsimplified loop exit after unswitch
720   ;; (i.e. phis, merge, and branch to actual block)
721   %phi = phi i32 [0, %entry], [1, %loop]
722   call void @unknown() ;; it's okay to skip possible throws
723   br label %actual_deopt
725 actual_deopt:
726   %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %phi) ]
727   ret i32 %deoptret
729 loop.preheader:
730   br label %loop
732 loop:
733   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
734   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
735   call void @unknown()
736   %within.bounds = icmp ult i32 %i, %length
737   br i1 %within.bounds, label %guarded, label %deopt, !prof !0
739 guarded:
740   %i.i64 = zext i32 %i to i64
741   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
742   %array.i = load i32, i32* %array.i.ptr, align 4
743   store i32 0, i32* %array.i.ptr
744   %loop.acc.next = add i32 %loop.acc, %array.i
745   %i.next = add nuw i32 %i, 1
746   %continue = icmp ult i32 %i.next, %n
747   br i1 %continue, label %loop, label %exit
749 exit:
750   %result = phi i32 [ %loop.acc.next, %guarded ]
751   ret i32 %result
754 define i32 @swapped_wb(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
755 ; CHECK-LABEL: @swapped_wb(
756 ; CHECK-NEXT:  entry:
757 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
758 ; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
759 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
760 ; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])
761 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
762 ; CHECK-NEXT:    [[TMP2:%.*]] = freeze i1 [[TMP1]]
763 ; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]
764 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP3]]
765 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
766 ; CHECK:       deopt:
767 ; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
768 ; CHECK-NEXT:    ret i32 [[DEOPTRET]]
769 ; CHECK:       loop.preheader:
770 ; CHECK-NEXT:    br label [[LOOP:%.*]]
771 ; CHECK:       loop:
772 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
773 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
774 ; CHECK-NEXT:    call void @unknown()
775 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
776 ; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
777 ; CHECK:       deopt2:
778 ; CHECK-NEXT:    call void @unknown()
779 ; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
780 ; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
781 ; CHECK:       guarded:
782 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
783 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
784 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
785 ; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
786 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
787 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
788 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
789 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
790 ; CHECK:       exit:
791 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
792 ; CHECK-NEXT:    ret i32 [[RESULT]]
794 entry:
795   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
796   %exiplicit_guard_cond = and i1 %widenable_cond, %cond_0
797   br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
799 deopt:
800   %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
801   ret i32 %deoptret
803 loop.preheader:
804   br label %loop
806 loop:
807   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
808   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
809   call void @unknown()
810   %within.bounds = icmp ult i32 %i, %length
811   br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
813 deopt2:
814   call void @unknown()
815   %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
816   ret i32 %deoptret2
818 guarded:
819   %i.i64 = zext i32 %i to i64
820   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
821   %array.i = load i32, i32* %array.i.ptr, align 4
822   store i32 0, i32* %array.i.ptr
823   %loop.acc.next = add i32 %loop.acc, %array.i
824   %i.next = add nuw i32 %i, 1
825   %continue = icmp ult i32 %i.next, %n
826   br i1 %continue, label %loop, label %exit
828 exit:
829   %result = phi i32 [ %loop.acc.next, %guarded ]
830   ret i32 %result
833 define i32 @trivial_wb(i32* %array, i32 %length, i32 %n) {
834 ; CHECK-LABEL: @trivial_wb(
835 ; CHECK-NEXT:  entry:
836 ; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
837 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
838 ; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])
839 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
840 ; CHECK-NEXT:    [[TMP2:%.*]] = freeze i1 [[TMP1]]
841 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
842 ; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
843 ; CHECK-NEXT:    br i1 [[TMP3]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
844 ; CHECK:       deopt:
845 ; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
846 ; CHECK-NEXT:    ret i32 [[DEOPTRET]]
847 ; CHECK:       loop.preheader:
848 ; CHECK-NEXT:    br label [[LOOP:%.*]]
849 ; CHECK:       loop:
850 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
851 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
852 ; CHECK-NEXT:    call void @unknown()
853 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
854 ; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
855 ; CHECK:       deopt2:
856 ; CHECK-NEXT:    call void @unknown()
857 ; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
858 ; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
859 ; CHECK:       guarded:
860 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
861 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
862 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
863 ; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
864 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
865 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
866 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
867 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
868 ; CHECK:       exit:
869 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
870 ; CHECK-NEXT:    ret i32 [[RESULT]]
872 entry:
873   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
874   br i1 %widenable_cond, label %loop.preheader, label %deopt, !prof !0
876 deopt:
877   %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
878   ret i32 %deoptret
880 loop.preheader:
881   br label %loop
883 loop:
884   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
885   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
886   call void @unknown()
887   %within.bounds = icmp ult i32 %i, %length
888   br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
890 deopt2:
891   call void @unknown()
892   %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
893   ret i32 %deoptret2
895 guarded:
896   %i.i64 = zext i32 %i to i64
897   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
898   %array.i = load i32, i32* %array.i.ptr, align 4
899   store i32 0, i32* %array.i.ptr
900   %loop.acc.next = add i32 %loop.acc, %array.i
901   %i.next = add nuw i32 %i, 1
902   %continue = icmp ult i32 %i.next, %n
903   br i1 %continue, label %loop, label %exit
905 exit:
906   %result = phi i32 [ %loop.acc.next, %guarded ]
907   ret i32 %result
910 ; TODO: Non-latch exits can still be predicated
911 ; This is currently prevented by an overly restrictive profitability check.
912 define i32 @todo_unconditional_latch(i32* %array, i32 %length, i1 %cond_0) {
913 ; CHECK-LABEL: @todo_unconditional_latch(
914 ; CHECK-NEXT:  entry:
915 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
916 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
917 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
918 ; CHECK:       deopt:
919 ; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
920 ; CHECK-NEXT:    ret i32 [[DEOPTRET]]
921 ; CHECK:       loop.preheader:
922 ; CHECK-NEXT:    br label [[LOOP:%.*]]
923 ; CHECK:       loop:
924 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
925 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
926 ; CHECK-NEXT:    call void @unknown()
927 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
928 ; CHECK-NEXT:    br i1 [[WITHIN_BOUNDS]], label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
929 ; CHECK:       deopt2:
930 ; CHECK-NEXT:    call void @unknown()
931 ; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
932 ; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
933 ; CHECK:       guarded:
934 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
935 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
936 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
937 ; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
938 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
939 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
940 ; CHECK-NEXT:    br label [[LOOP]]
942 entry:
943   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
944   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
945   br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
947 deopt:
948   %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
949   ret i32 %deoptret
951 loop.preheader:
952   br label %loop
954 loop:
955   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
956   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
957   call void @unknown()
958   %within.bounds = icmp ult i32 %i, %length
959   br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
961 deopt2:
962   call void @unknown()
963   %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
964   ret i32 %deoptret2
966 guarded:
967   %i.i64 = zext i32 %i to i64
968   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
969   %array.i = load i32, i32* %array.i.ptr, align 4
970   store i32 0, i32* %array.i.ptr
971   %loop.acc.next = add i32 %loop.acc, %array.i
972   %i.next = add nuw i32 %i, 1
973   br label %loop
977 ; If we have a stray widenable branch in the loop, we should still be able to
978 ; run.  This can happen when unswitching's cost model avoids unswitching some
979 ; branches.
980 define i32 @wb_in_loop(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
981 ; CHECK-LABEL: @wb_in_loop(
982 ; CHECK-NEXT:  entry:
983 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
984 ; CHECK-NEXT:    [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition()
985 ; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
986 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
987 ; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])
988 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
989 ; CHECK-NEXT:    [[TMP2:%.*]] = freeze i1 [[TMP1]]
990 ; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]
991 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
992 ; CHECK-NEXT:    [[TMP5:%.*]] = freeze i1 [[TMP4]]
993 ; CHECK-NEXT:    [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP3]]
994 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP6]], [[WIDENABLE_COND]]
995 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
996 ; CHECK:       deopt:
997 ; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
998 ; CHECK-NEXT:    ret i32 [[DEOPTRET]]
999 ; CHECK:       loop.preheader:
1000 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1001 ; CHECK:       loop:
1002 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1003 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]
1004 ; CHECK-NEXT:    call void @unknown()
1005 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
1006 ; CHECK-NEXT:    br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof !0
1007 ; CHECK:       deopt2:
1008 ; CHECK-NEXT:    call void @unknown()
1009 ; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1010 ; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
1011 ; CHECK:       guarded:
1012 ; CHECK-NEXT:    call void @unknown()
1013 ; CHECK-NEXT:    [[WITHIN_BOUNDS2:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
1014 ; CHECK-NEXT:    [[WB_COND:%.*]] = and i1 [[WITHIN_BOUNDS2]], true
1015 ; CHECK-NEXT:    br i1 true, label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0
1016 ; CHECK:       deopt3:
1017 ; CHECK-NEXT:    call void @unknown()
1018 ; CHECK-NEXT:    [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1019 ; CHECK-NEXT:    ret i32 [[DEOPTRET3]]
1020 ; CHECK:       guarded2:
1021 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1022 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1023 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1024 ; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
1025 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1026 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1027 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1028 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
1029 ; CHECK:       exit:
1030 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
1031 ; CHECK-NEXT:    ret i32 [[RESULT]]
1033 entry:
1034   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1035   %wc2 = call i1 @llvm.experimental.widenable.condition()
1036   %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
1037   br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
1039 deopt:
1040   %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1041   ret i32 %deoptret
1043 loop.preheader:
1044   br label %loop
1046 loop:
1047   %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]
1048   %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
1049   call void @unknown()
1050   %within.bounds = icmp ult i32 %i, %length
1051   br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
1053 deopt2:
1054   call void @unknown()
1055   %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1056   ret i32 %deoptret2
1058 guarded:
1059   call void @unknown()
1060   %within.bounds2 = icmp ult i32 %i, %length
1061   %wb_cond = and i1 %within.bounds2, %wc2
1062   br i1 %wb_cond, label %guarded2, label %deopt3, !prof !0
1064 deopt3:
1065   call void @unknown()
1066   %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1067   ret i32 %deoptret3
1069 guarded2:
1070   %i.i64 = zext i32 %i to i64
1071   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1072   %array.i = load i32, i32* %array.i.ptr, align 4
1073   store i32 0, i32* %array.i.ptr
1074   %loop.acc.next = add i32 %loop.acc, %array.i
1075   %i.next = add nuw i32 %i, 1
1076   %continue = icmp ult i32 %i.next, %n
1077   br i1 %continue, label %loop, label %exit
1079 exit:
1080   %result = phi i32 [ %loop.acc.next, %guarded2 ]
1081   ret i32 %result
1086 declare void @unknown()
1088 declare i1 @llvm.experimental.widenable.condition()
1089 declare i32 @llvm.experimental.deoptimize.i32(...)
1091 !0 = !{!"branch_weights", i32 1048576, i32 1}
1092 !1 = !{i32 1, i32 -2147483648}
1093 !2 = !{i32 0, i32 50}