[win/asan] GetInstructionSize: Fix `83 E4 XX` to return 3. (#119644)
[llvm-project.git] / llvm / test / Transforms / LoopPredication / basic_widenable_branch_guards.ll
blobb8f7c61f6c31b8f72db62efd366a421bec71bc1b
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=loop-predication -loop-predication-predicate-widenable-branches-to-deopt=true < %s 2>&1 | FileCheck %s
3 ; RUN: opt -S -passes='require<scalar-evolution>,loop-mssa(loop-predication)'  -verify-memoryssa -loop-predication-predicate-widenable-branches-to-deopt=true < %s 2>&1 | FileCheck %s
4 ; RUN: opt -S -passes='require<scalar-evolution>,require<branch-prob>,loop-mssa(loop-predication)' -verify-memoryssa -loop-predication-predicate-widenable-branches-to-deopt=true < %s 2>&1 | FileCheck %s
6 declare void @llvm.experimental.guard(i1, ...)
8 define i32 @unsigned_loop_0_to_n_ult_check(ptr %array, i32 %length, i32 %n) {
9 ; CHECK-LABEL: @unsigned_loop_0_to_n_ult_check(
10 ; CHECK-NEXT:  entry:
11 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
12 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
13 ; CHECK:       loop.preheader:
14 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
15 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
16 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
17 ; CHECK-NEXT:    [[TMP3:%.*]] = freeze i1 [[TMP2]]
18 ; CHECK-NEXT:    br label [[LOOP:%.*]]
19 ; CHECK:       loop:
20 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
21 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
22 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
23 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
24 ; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
25 ; CHECK-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]]
26 ; CHECK:       deopt:
27 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
28 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
29 ; CHECK:       guarded:
30 ; CHECK-NEXT:    call void @llvm.assume(i1 [[WITHIN_BOUNDS]])
31 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
32 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
33 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
34 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
35 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
36 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
37 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1:![0-9]+]]
38 ; CHECK:       exit.loopexit:
39 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
40 ; CHECK-NEXT:    br label [[EXIT]]
41 ; CHECK:       exit:
42 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
43 ; CHECK-NEXT:    ret i32 [[RESULT]]
45 entry:
46   %tmp5 = icmp eq i32 %n, 0
47   br i1 %tmp5, label %exit, label %loop.preheader
49 loop.preheader:                                   ; preds = %entry
50   br label %loop
52 loop:                                             ; preds = %guarded, %loop.preheader
53   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
54   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
55   %within.bounds = icmp ult i32 %i, %length
56   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
57   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
58   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
60 deopt:                                            ; preds = %loop
61   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
62   ret i32 %deoptcall
64 guarded:                                          ; preds = %loop
65   %i.i64 = zext i32 %i to i64
66   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
67   %array.i = load i32, ptr %array.i.ptr, align 4
68   %loop.acc.next = add i32 %loop.acc, %array.i
69   %i.next = add nuw i32 %i, 1
70   %continue = icmp ult i32 %i.next, %n
71   br i1 %continue, label %loop, label %exit, !prof !2
73 exit:                                             ; preds = %guarded, %entry
74   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
75   ret i32 %result
78 define i32 @unsigned_loop_0_to_n_ule_latch_ult_check(ptr %array, i32 %length, i32 %n) {
79 ; CHECK-LABEL: @unsigned_loop_0_to_n_ule_latch_ult_check(
80 ; CHECK-NEXT:  entry:
81 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
82 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
83 ; CHECK:       loop.preheader:
84 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 [[N]], [[LENGTH:%.*]]
85 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
86 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
87 ; CHECK-NEXT:    [[TMP3:%.*]] = freeze i1 [[TMP2]]
88 ; CHECK-NEXT:    br label [[LOOP:%.*]]
89 ; CHECK:       loop:
90 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
91 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
92 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
93 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
94 ; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
95 ; CHECK-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
96 ; CHECK:       deopt:
97 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
98 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
99 ; CHECK:       guarded:
100 ; CHECK-NEXT:    call void @llvm.assume(i1 [[WITHIN_BOUNDS]])
101 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
102 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
103 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
104 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
105 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
106 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ule i32 [[I_NEXT]], [[N]]
107 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
108 ; CHECK:       exit.loopexit:
109 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
110 ; CHECK-NEXT:    br label [[EXIT]]
111 ; CHECK:       exit:
112 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
113 ; CHECK-NEXT:    ret i32 [[RESULT]]
115 entry:
116   %tmp5 = icmp eq i32 %n, 0
117   br i1 %tmp5, label %exit, label %loop.preheader
119 loop.preheader:                                   ; preds = %entry
120   br label %loop
122 loop:                                             ; preds = %guarded, %loop.preheader
123   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
124   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
125   %within.bounds = icmp ult i32 %i, %length
126   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
127   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
128   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
130 deopt:                                            ; preds = %loop
131   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
132   ret i32 %deoptcall
134 guarded:                                          ; preds = %loop
135   %i.i64 = zext i32 %i to i64
136   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
137   %array.i = load i32, ptr %array.i.ptr, align 4
138   %loop.acc.next = add i32 %loop.acc, %array.i
139   %i.next = add nuw i32 %i, 1
140   %continue = icmp ule i32 %i.next, %n
141   br i1 %continue, label %loop, label %exit, !prof !2
143 exit:                                             ; preds = %guarded, %entry
144   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
145   ret i32 %result
148 define i32 @unsigned_loop_0_to_n_ugt_check(ptr %array, i32 %length, i32 %n) {
149 ; CHECK-LABEL: @unsigned_loop_0_to_n_ugt_check(
150 ; CHECK-NEXT:  entry:
151 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
152 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
153 ; CHECK:       loop.preheader:
154 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
155 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
156 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
157 ; CHECK-NEXT:    [[TMP3:%.*]] = freeze i1 [[TMP2]]
158 ; CHECK-NEXT:    br label [[LOOP:%.*]]
159 ; CHECK:       loop:
160 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
161 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
162 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ugt i32 [[LENGTH]], [[I]]
163 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
164 ; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
165 ; CHECK-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
166 ; CHECK:       deopt:
167 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
168 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
169 ; CHECK:       guarded:
170 ; CHECK-NEXT:    call void @llvm.assume(i1 [[WITHIN_BOUNDS]])
171 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
172 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
173 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
174 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
175 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
176 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
177 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
178 ; CHECK:       exit.loopexit:
179 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
180 ; CHECK-NEXT:    br label [[EXIT]]
181 ; CHECK:       exit:
182 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
183 ; CHECK-NEXT:    ret i32 [[RESULT]]
185 entry:
186   %tmp5 = icmp eq i32 %n, 0
187   br i1 %tmp5, label %exit, label %loop.preheader
189 loop.preheader:                                   ; preds = %entry
190   br label %loop
192 loop:                                             ; preds = %guarded, %loop.preheader
193   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
194   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
195   %within.bounds = icmp ugt i32 %length, %i
196   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
197   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
198   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
200 deopt:                                            ; preds = %loop
201   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
202   ret i32 %deoptcall
204 guarded:                                          ; preds = %loop
205   %i.i64 = zext i32 %i to i64
206   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
207   %array.i = load i32, ptr %array.i.ptr, align 4
208   %loop.acc.next = add i32 %loop.acc, %array.i
209   %i.next = add nuw i32 %i, 1
210   %continue = icmp ult i32 %i.next, %n
211   br i1 %continue, label %loop, label %exit, !prof !2
213 exit:                                             ; preds = %guarded, %entry
214   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
215   ret i32 %result
218 define i32 @signed_loop_0_to_n_ult_check(ptr %array, i32 %length, i32 %n) {
219 ; CHECK-LABEL: @signed_loop_0_to_n_ult_check(
220 ; CHECK-NEXT:  entry:
221 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
222 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
223 ; CHECK:       loop.preheader:
224 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]]
225 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
226 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
227 ; CHECK-NEXT:    [[TMP3:%.*]] = freeze i1 [[TMP2]]
228 ; CHECK-NEXT:    br label [[LOOP:%.*]]
229 ; CHECK:       loop:
230 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
231 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
232 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
233 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
234 ; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
235 ; CHECK-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
236 ; CHECK:       deopt:
237 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
238 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
239 ; CHECK:       guarded:
240 ; CHECK-NEXT:    call void @llvm.assume(i1 [[WITHIN_BOUNDS]])
241 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
242 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
243 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
244 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
245 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
246 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
247 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
248 ; CHECK:       exit.loopexit:
249 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
250 ; CHECK-NEXT:    br label [[EXIT]]
251 ; CHECK:       exit:
252 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
253 ; CHECK-NEXT:    ret i32 [[RESULT]]
256 entry:
257   %tmp5 = icmp sle i32 %n, 0
258   br i1 %tmp5, label %exit, label %loop.preheader
260 loop.preheader:                                   ; preds = %entry
261   br label %loop
263 loop:                                             ; preds = %guarded, %loop.preheader
264   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
265   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
266   %within.bounds = icmp ult i32 %i, %length
267   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
268   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
269   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
271 deopt:                                            ; preds = %loop
272   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
273   ret i32 %deoptcall
275 guarded:                                          ; preds = %loop
276   %i.i64 = zext i32 %i to i64
277   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
278   %array.i = load i32, ptr %array.i.ptr, align 4
279   %loop.acc.next = add i32 %loop.acc, %array.i
280   %i.next = add nuw i32 %i, 1
281   %continue = icmp slt i32 %i.next, %n
282   br i1 %continue, label %loop, label %exit, !prof !2
284 exit:                                             ; preds = %guarded, %entry
285   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
286   ret i32 %result
289 define i32 @signed_loop_0_to_n_ult_check_length_range_known(ptr %array, ptr %length.ptr, i32 %n) {
290 ; CHECK-LABEL: @signed_loop_0_to_n_ult_check_length_range_known(
291 ; CHECK-NEXT:  entry:
292 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
293 ; CHECK-NEXT:    [[LENGTH:%.*]] = load i32, ptr [[LENGTH_PTR:%.*]], align 4, !range [[RNG2:![0-9]+]]
294 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
295 ; CHECK:       loop.preheader:
296 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH]]
297 ; CHECK-NEXT:    [[TMP1:%.*]] = and i1 true, [[TMP0]]
298 ; CHECK-NEXT:    [[TMP2:%.*]] = freeze i1 [[TMP1]]
299 ; CHECK-NEXT:    br label [[LOOP:%.*]]
300 ; CHECK:       loop:
301 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
302 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
303 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
304 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
305 ; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
306 ; CHECK-NEXT:    br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
307 ; CHECK:       deopt:
308 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
309 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
310 ; CHECK:       guarded:
311 ; CHECK-NEXT:    call void @llvm.assume(i1 [[WITHIN_BOUNDS]])
312 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
313 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
314 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
315 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
316 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
317 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
318 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
319 ; CHECK:       exit.loopexit:
320 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
321 ; CHECK-NEXT:    br label [[EXIT]]
322 ; CHECK:       exit:
323 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
324 ; CHECK-NEXT:    ret i32 [[RESULT]]
326 entry:
327   %tmp5 = icmp sle i32 %n, 0
328   %length = load i32, ptr %length.ptr, !range !1
329   br i1 %tmp5, label %exit, label %loop.preheader
331 loop.preheader:                                   ; preds = %entry
332   br label %loop
334 loop:                                             ; preds = %guarded, %loop.preheader
335   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
336   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
337   %within.bounds = icmp ult i32 %i, %length
338   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
339   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
340   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
342 deopt:                                            ; preds = %loop
343   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
344   ret i32 %deoptcall
346 guarded:                                          ; preds = %loop
347   %i.i64 = zext i32 %i to i64
348   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
349   %array.i = load i32, ptr %array.i.ptr, align 4
350   %loop.acc.next = add i32 %loop.acc, %array.i
351   %i.next = add nuw i32 %i, 1
352   %continue = icmp slt i32 %i.next, %n
353   br i1 %continue, label %loop, label %exit, !prof !2
355 exit:                                             ; preds = %guarded, %entry
356   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
357   ret i32 %result
360 define i32 @signed_loop_0_to_n_inverse_latch_predicate(ptr %array, i32 %length, i32 %n) {
361 ; CHECK-LABEL: @signed_loop_0_to_n_inverse_latch_predicate(
362 ; CHECK-NEXT:  entry:
363 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
364 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
365 ; CHECK:       loop.preheader:
366 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]
367 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
368 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
369 ; CHECK-NEXT:    [[TMP3:%.*]] = freeze i1 [[TMP2]]
370 ; CHECK-NEXT:    br label [[LOOP:%.*]]
371 ; CHECK:       loop:
372 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
373 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
374 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
375 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
376 ; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
377 ; CHECK-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
378 ; CHECK:       deopt:
379 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
380 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
381 ; CHECK:       guarded:
382 ; CHECK-NEXT:    call void @llvm.assume(i1 [[WITHIN_BOUNDS]])
383 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
384 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
385 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
386 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
387 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
388 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp sgt i32 [[I_NEXT]], [[N]]
389 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP]], !prof [[PROF1]]
390 ; CHECK:       exit.loopexit:
391 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
392 ; CHECK-NEXT:    br label [[EXIT]]
393 ; CHECK:       exit:
394 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
395 ; CHECK-NEXT:    ret i32 [[RESULT]]
397 entry:
398   %tmp5 = icmp sle i32 %n, 0
399   br i1 %tmp5, label %exit, label %loop.preheader
401 loop.preheader:                                   ; preds = %entry
402   br label %loop
404 loop:                                             ; preds = %guarded, %loop.preheader
405   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
406   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
407   %within.bounds = icmp ult i32 %i, %length
408   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
409   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
410   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
412 deopt:                                            ; preds = %loop
413   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
414   ret i32 %deoptcall
416 guarded:                                          ; preds = %loop
417   %i.i64 = zext i32 %i to i64
418   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
419   %array.i = load i32, ptr %array.i.ptr, align 4
420   %loop.acc.next = add i32 %loop.acc, %array.i
421   %i.next = add nuw i32 %i, 1
422   %continue = icmp sgt i32 %i.next, %n
423   br i1 %continue, label %exit, label %loop, !prof !2
425 exit:                                             ; preds = %guarded, %entry
426   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
427   ret i32 %result
430 define i32 @signed_loop_0_to_n_sle_latch_ult_check(ptr %array, i32 %length, i32 %n) {
431 ; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_ult_check(
432 ; CHECK-NEXT:  entry:
433 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
434 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
435 ; CHECK:       loop.preheader:
436 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]
437 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
438 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
439 ; CHECK-NEXT:    [[TMP3:%.*]] = freeze i1 [[TMP2]]
440 ; CHECK-NEXT:    br label [[LOOP:%.*]]
441 ; CHECK:       loop:
442 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
443 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
444 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
445 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
446 ; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
447 ; CHECK-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
448 ; CHECK:       deopt:
449 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
450 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
451 ; CHECK:       guarded:
452 ; CHECK-NEXT:    call void @llvm.assume(i1 [[WITHIN_BOUNDS]])
453 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
454 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
455 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
456 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
457 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
458 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT]], [[N]]
459 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
460 ; CHECK:       exit.loopexit:
461 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
462 ; CHECK-NEXT:    br label [[EXIT]]
463 ; CHECK:       exit:
464 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
465 ; CHECK-NEXT:    ret i32 [[RESULT]]
467 entry:
468   %tmp5 = icmp sle i32 %n, 0
469   br i1 %tmp5, label %exit, label %loop.preheader
471 loop.preheader:                                   ; preds = %entry
472   br label %loop
474 loop:                                             ; preds = %guarded, %loop.preheader
475   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
476   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
477   %within.bounds = icmp ult i32 %i, %length
478   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
479   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
480   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
482 deopt:                                            ; preds = %loop
483   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
484   ret i32 %deoptcall
486 guarded:                                          ; preds = %loop
487   %i.i64 = zext i32 %i to i64
488   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
489   %array.i = load i32, ptr %array.i.ptr, align 4
490   %loop.acc.next = add i32 %loop.acc, %array.i
491   %i.next = add nuw i32 %i, 1
492   %continue = icmp sle i32 %i.next, %n
493   br i1 %continue, label %loop, label %exit, !prof !2
495 exit:                                             ; preds = %guarded, %entry
496   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
497   ret i32 %result
500 define i32 @signed_loop_0_to_n_preincrement_latch_check(ptr %array, i32 %length, i32 %n) {
501 ; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check(
502 ; CHECK-NEXT:  entry:
503 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
504 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
505 ; CHECK:       loop.preheader:
506 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1
507 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sle i32 [[N]], [[TMP0]]
508 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]]
509 ; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
510 ; CHECK-NEXT:    [[TMP4:%.*]] = freeze i1 [[TMP3]]
511 ; CHECK-NEXT:    br label [[LOOP:%.*]]
512 ; CHECK:       loop:
513 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
514 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
515 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
516 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
517 ; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[WIDENABLE_COND]]
518 ; CHECK-NEXT:    br i1 [[TMP5]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
519 ; CHECK:       deopt:
520 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
521 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
522 ; CHECK:       guarded:
523 ; CHECK-NEXT:    call void @llvm.assume(i1 [[WITHIN_BOUNDS]])
524 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
525 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
526 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
527 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
528 ; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
529 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I]], [[N]]
530 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
531 ; CHECK:       exit.loopexit:
532 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
533 ; CHECK-NEXT:    br label [[EXIT]]
534 ; CHECK:       exit:
535 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
536 ; CHECK-NEXT:    ret i32 [[RESULT]]
538 entry:
539   %tmp5 = icmp sle i32 %n, 0
540   br i1 %tmp5, label %exit, label %loop.preheader
542 loop.preheader:                                   ; preds = %entry
543   br label %loop
545 loop:                                             ; preds = %guarded, %loop.preheader
546   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
547   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
548   %within.bounds = icmp ult i32 %i, %length
549   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
550   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
551   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
553 deopt:                                            ; preds = %loop
554   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
555   ret i32 %deoptcall
557 guarded:                                          ; preds = %loop
558   %i.i64 = zext i32 %i to i64
559   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
560   %array.i = load i32, ptr %array.i.ptr, align 4
561   %loop.acc.next = add i32 %loop.acc, %array.i
562   %i.next = add i32 %i, 1
563   %continue = icmp slt i32 %i, %n
564   br i1 %continue, label %loop, label %exit, !prof !2
566 exit:                                             ; preds = %guarded, %entry
567   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
568   ret i32 %result
571 define i32 @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check(ptr %array, i32 %length, i32 %n) {
572 ; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check(
573 ; CHECK-NEXT:  entry:
574 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
575 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
576 ; CHECK:       loop.preheader:
577 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -2
578 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sle i32 [[N]], [[TMP0]]
579 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 1, [[LENGTH]]
580 ; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
581 ; CHECK-NEXT:    [[TMP4:%.*]] = freeze i1 [[TMP3]]
582 ; CHECK-NEXT:    br label [[LOOP:%.*]]
583 ; CHECK:       loop:
584 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
585 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
586 ; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
587 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_NEXT]], [[LENGTH]]
588 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
589 ; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[WIDENABLE_COND]]
590 ; CHECK-NEXT:    br i1 [[TMP5]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
591 ; CHECK:       deopt:
592 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
593 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
594 ; CHECK:       guarded:
595 ; CHECK-NEXT:    call void @llvm.assume(i1 [[WITHIN_BOUNDS]])
596 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
597 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
598 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
599 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
600 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I]], [[N]]
601 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
602 ; CHECK:       exit.loopexit:
603 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
604 ; CHECK-NEXT:    br label [[EXIT]]
605 ; CHECK:       exit:
606 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
607 ; CHECK-NEXT:    ret i32 [[RESULT]]
609 entry:
610   %tmp5 = icmp sle i32 %n, 0
611   br i1 %tmp5, label %exit, label %loop.preheader
613 loop.preheader:                                   ; preds = %entry
614   br label %loop
616 loop:                                             ; preds = %guarded, %loop.preheader
617   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
618   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
619   %i.next = add i32 %i, 1
620   %within.bounds = icmp ult i32 %i.next, %length
621   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
622   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
623   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
625 deopt:                                            ; preds = %loop
626   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
627   ret i32 %deoptcall
629 guarded:                                          ; preds = %loop
630   %i.i64 = zext i32 %i to i64
631   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
632   %array.i = load i32, ptr %array.i.ptr, align 4
633   %loop.acc.next = add i32 %loop.acc, %array.i
634   %continue = icmp slt i32 %i, %n
635   br i1 %continue, label %loop, label %exit, !prof !2
637 exit:                                             ; preds = %guarded, %entry
638   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
639   ret i32 %result
642 define i32 @signed_loop_0_to_n_sle_latch_offset_ult_check(ptr %array, i32 %length, i32 %n) {
643 ; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_offset_ult_check(
644 ; CHECK-NEXT:  entry:
645 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
646 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
647 ; CHECK:       loop.preheader:
648 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1
649 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[N]], [[TMP0]]
650 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 1, [[LENGTH]]
651 ; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
652 ; CHECK-NEXT:    [[TMP4:%.*]] = freeze i1 [[TMP3]]
653 ; CHECK-NEXT:    br label [[LOOP:%.*]]
654 ; CHECK:       loop:
655 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
656 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
657 ; CHECK-NEXT:    [[I_OFFSET:%.*]] = add i32 [[I]], 1
658 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_OFFSET]], [[LENGTH]]
659 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
660 ; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[WIDENABLE_COND]]
661 ; CHECK-NEXT:    br i1 [[TMP5]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
662 ; CHECK:       deopt:
663 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
664 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
665 ; CHECK:       guarded:
666 ; CHECK-NEXT:    call void @llvm.assume(i1 [[WITHIN_BOUNDS]])
667 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
668 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
669 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
670 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
671 ; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
672 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT]], [[N]]
673 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
674 ; CHECK:       exit.loopexit:
675 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
676 ; CHECK-NEXT:    br label [[EXIT]]
677 ; CHECK:       exit:
678 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
679 ; CHECK-NEXT:    ret i32 [[RESULT]]
681 entry:
682   %tmp5 = icmp sle i32 %n, 0
683   br i1 %tmp5, label %exit, label %loop.preheader
685 loop.preheader:                                   ; preds = %entry
686   br label %loop
688 loop:                                             ; preds = %guarded, %loop.preheader
689   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
690   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
691   %i.offset = add i32 %i, 1
692   %within.bounds = icmp ult i32 %i.offset, %length
693   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
694   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
695   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
697 deopt:                                            ; preds = %loop
698   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
699   ret i32 %deoptcall
701 guarded:                                          ; preds = %loop
702   %i.i64 = zext i32 %i to i64
703   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
704   %array.i = load i32, ptr %array.i.ptr, align 4
705   %loop.acc.next = add i32 %loop.acc, %array.i
706   %i.next = add i32 %i, 1
707   %continue = icmp sle i32 %i.next, %n
708   br i1 %continue, label %loop, label %exit, !prof !2
710 exit:                                             ; preds = %guarded, %entry
711   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
712   ret i32 %result
715 define i32 @signed_loop_0_to_n_offset_sle_latch_offset_ult_check(ptr %array, i32 %length, i32 %n) {
716 ; CHECK-LABEL: @signed_loop_0_to_n_offset_sle_latch_offset_ult_check(
717 ; CHECK-NEXT:  entry:
718 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
719 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
720 ; CHECK:       loop.preheader:
721 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]
722 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 1, [[LENGTH]]
723 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
724 ; CHECK-NEXT:    [[TMP3:%.*]] = freeze i1 [[TMP2]]
725 ; CHECK-NEXT:    br label [[LOOP:%.*]]
726 ; CHECK:       loop:
727 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
728 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
729 ; CHECK-NEXT:    [[I_OFFSET:%.*]] = add i32 [[I]], 1
730 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_OFFSET]], [[LENGTH]]
731 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
732 ; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
733 ; CHECK-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
734 ; CHECK:       deopt:
735 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
736 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
737 ; CHECK:       guarded:
738 ; CHECK-NEXT:    call void @llvm.assume(i1 [[WITHIN_BOUNDS]])
739 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
740 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
741 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
742 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
743 ; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
744 ; CHECK-NEXT:    [[I_NEXT_OFFSET:%.*]] = add i32 [[I_NEXT]], 1
745 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT_OFFSET]], [[N]]
746 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
747 ; CHECK:       exit.loopexit:
748 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
749 ; CHECK-NEXT:    br label [[EXIT]]
750 ; CHECK:       exit:
751 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
752 ; CHECK-NEXT:    ret i32 [[RESULT]]
754 entry:
755   %tmp5 = icmp sle i32 %n, 0
756   br i1 %tmp5, label %exit, label %loop.preheader
758 loop.preheader:                                   ; preds = %entry
759   br label %loop
761 loop:                                             ; preds = %guarded, %loop.preheader
762   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
763   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
764   %i.offset = add i32 %i, 1
765   %within.bounds = icmp ult i32 %i.offset, %length
766   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
767   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
768   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
770 deopt:                                            ; preds = %loop
771   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
772   ret i32 %deoptcall
774 guarded:                                          ; preds = %loop
775   %i.i64 = zext i32 %i to i64
776   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
777   %array.i = load i32, ptr %array.i.ptr, align 4
778   %loop.acc.next = add i32 %loop.acc, %array.i
779   %i.next = add i32 %i, 1
780   %i.next.offset = add i32 %i.next, 1
781   %continue = icmp sle i32 %i.next.offset, %n
782   br i1 %continue, label %loop, label %exit, !prof !2
784 exit:                                             ; preds = %guarded, %entry
785   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
786   ret i32 %result
789 define i32 @unsupported_latch_pred_loop_0_to_n(ptr %array, i32 %length, i32 %n) {
790 ; CHECK-LABEL: @unsupported_latch_pred_loop_0_to_n(
791 ; CHECK-NEXT:  entry:
792 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
793 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
794 ; CHECK:       loop.preheader:
795 ; CHECK-NEXT:    br label [[LOOP:%.*]]
796 ; CHECK:       loop:
797 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
798 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
799 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
800 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
801 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
802 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
803 ; CHECK:       deopt:
804 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
805 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
806 ; CHECK:       guarded:
807 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
808 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
809 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
810 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
811 ; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
812 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[N]]
813 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
814 ; CHECK:       exit.loopexit:
815 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
816 ; CHECK-NEXT:    br label [[EXIT]]
817 ; CHECK:       exit:
818 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
819 ; CHECK-NEXT:    ret i32 [[RESULT]]
821 entry:
822   %tmp5 = icmp sle i32 %n, 0
823   br i1 %tmp5, label %exit, label %loop.preheader
825 loop.preheader:                                   ; preds = %entry
826   br label %loop
828 loop:                                             ; preds = %guarded, %loop.preheader
829   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
830   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
831   %within.bounds = icmp ult i32 %i, %length
832   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
833   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
834   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
836 deopt:                                            ; preds = %loop
837   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
838   ret i32 %deoptcall
840 guarded:                                          ; preds = %loop
841   %i.i64 = zext i32 %i to i64
842   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
843   %array.i = load i32, ptr %array.i.ptr, align 4
844   %loop.acc.next = add i32 %loop.acc, %array.i
845   %i.next = add nsw i32 %i, 1
846   %continue = icmp ne i32 %i.next, %n
847   br i1 %continue, label %loop, label %exit, !prof !2
849 exit:                                             ; preds = %guarded, %entry
850   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
851   ret i32 %result
854 define i32 @signed_loop_0_to_n_unsupported_iv_step(ptr %array, i32 %length, i32 %n) {
855 ; CHECK-LABEL: @signed_loop_0_to_n_unsupported_iv_step(
856 ; CHECK-NEXT:  entry:
857 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
858 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
859 ; CHECK:       loop.preheader:
860 ; CHECK-NEXT:    br label [[LOOP:%.*]]
861 ; CHECK:       loop:
862 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
863 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
864 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
865 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
866 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
867 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
868 ; CHECK:       deopt:
869 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
870 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
871 ; CHECK:       guarded:
872 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
873 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
874 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
875 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
876 ; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 2
877 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
878 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
879 ; CHECK:       exit.loopexit:
880 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
881 ; CHECK-NEXT:    br label [[EXIT]]
882 ; CHECK:       exit:
883 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
884 ; CHECK-NEXT:    ret i32 [[RESULT]]
886 entry:
887   %tmp5 = icmp sle i32 %n, 0
888   br i1 %tmp5, label %exit, label %loop.preheader
890 loop.preheader:                                   ; preds = %entry
891   br label %loop
893 loop:                                             ; preds = %guarded, %loop.preheader
894   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
895   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
896   %within.bounds = icmp ult i32 %i, %length
897   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
898   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
899   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
901 deopt:                                            ; preds = %loop
902   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
903   ret i32 %deoptcall
905 guarded:                                          ; preds = %loop
906   %i.i64 = zext i32 %i to i64
907   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
908   %array.i = load i32, ptr %array.i.ptr, align 4
909   %loop.acc.next = add i32 %loop.acc, %array.i
910   %i.next = add nsw i32 %i, 2
911   %continue = icmp slt i32 %i.next, %n
912   br i1 %continue, label %loop, label %exit, !prof !2
914 exit:                                             ; preds = %guarded, %entry
915   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
916   ret i32 %result
919 define i32 @signed_loop_0_to_n_equal_iv_range_check(ptr %array, i32 %length, i32 %n) {
920 ; CHECK-LABEL: @signed_loop_0_to_n_equal_iv_range_check(
921 ; CHECK-NEXT:  entry:
922 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
923 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
924 ; CHECK:       loop.preheader:
925 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]]
926 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
927 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
928 ; CHECK-NEXT:    [[TMP3:%.*]] = freeze i1 [[TMP2]]
929 ; CHECK-NEXT:    br label [[LOOP:%.*]]
930 ; CHECK:       loop:
931 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
932 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
933 ; CHECK-NEXT:    [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
934 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH]]
935 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
936 ; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
937 ; CHECK-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
938 ; CHECK:       deopt:
939 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
940 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
941 ; CHECK:       guarded:
942 ; CHECK-NEXT:    call void @llvm.assume(i1 [[WITHIN_BOUNDS]])
943 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
944 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
945 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
946 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
947 ; CHECK-NEXT:    [[J_NEXT]] = add nsw i32 [[J]], 1
948 ; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
949 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
950 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
951 ; CHECK:       exit.loopexit:
952 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
953 ; CHECK-NEXT:    br label [[EXIT]]
954 ; CHECK:       exit:
955 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
956 ; CHECK-NEXT:    ret i32 [[RESULT]]
958 entry:
959   %tmp5 = icmp sle i32 %n, 0
960   br i1 %tmp5, label %exit, label %loop.preheader
962 loop.preheader:                                   ; preds = %entry
963   br label %loop
965 loop:                                             ; preds = %guarded, %loop.preheader
966   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
967   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
968   %j = phi i32 [ %j.next, %guarded ], [ 0, %loop.preheader ]
969   %within.bounds = icmp ult i32 %j, %length
970   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
971   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
972   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
974 deopt:                                            ; preds = %loop
975   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
976   ret i32 %deoptcall
978 guarded:                                          ; preds = %loop
979   %i.i64 = zext i32 %i to i64
980   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
981   %array.i = load i32, ptr %array.i.ptr, align 4
982   %loop.acc.next = add i32 %loop.acc, %array.i
983   %j.next = add nsw i32 %j, 1
984   %i.next = add nsw i32 %i, 1
985   %continue = icmp slt i32 %i.next, %n
986   br i1 %continue, label %loop, label %exit, !prof !2
988 exit:                                             ; preds = %guarded, %entry
989   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
990   ret i32 %result
993 define i32 @signed_loop_start_to_n_offset_iv_range_check(ptr %array, i32 %start.i, i32 %start.j, i32 %length, i32 %n) {
994 ; CHECK-LABEL: @signed_loop_start_to_n_offset_iv_range_check(
995 ; CHECK-NEXT:  entry:
996 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
997 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
998 ; CHECK:       loop.preheader:
999 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], [[START_I:%.*]]
1000 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[TMP0]], [[START_J:%.*]]
1001 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sle i32 [[N]], [[TMP1]]
1002 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i32 [[START_J]], [[LENGTH]]
1003 ; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[TMP2]]
1004 ; CHECK-NEXT:    [[TMP5:%.*]] = freeze i1 [[TMP4]]
1005 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1006 ; CHECK:       loop:
1007 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1008 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ [[START_I]], [[LOOP_PREHEADER]] ]
1009 ; CHECK-NEXT:    [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[GUARDED]] ], [ [[START_J]], [[LOOP_PREHEADER]] ]
1010 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH]]
1011 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1012 ; CHECK-NEXT:    [[TMP6:%.*]] = and i1 [[TMP5]], [[WIDENABLE_COND]]
1013 ; CHECK-NEXT:    br i1 [[TMP6]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
1014 ; CHECK:       deopt:
1015 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1016 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1017 ; CHECK:       guarded:
1018 ; CHECK-NEXT:    call void @llvm.assume(i1 [[WITHIN_BOUNDS]])
1019 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1020 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
1021 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
1022 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1023 ; CHECK-NEXT:    [[J_NEXT]] = add i32 [[J]], 1
1024 ; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
1025 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1026 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
1027 ; CHECK:       exit.loopexit:
1028 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1029 ; CHECK-NEXT:    br label [[EXIT]]
1030 ; CHECK:       exit:
1031 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1032 ; CHECK-NEXT:    ret i32 [[RESULT]]
1034 entry:
1035   %tmp5 = icmp sle i32 %n, 0
1036   br i1 %tmp5, label %exit, label %loop.preheader
1038 loop.preheader:                                   ; preds = %entry
1039   br label %loop
1041 loop:                                             ; preds = %guarded, %loop.preheader
1042   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1043   %i = phi i32 [ %i.next, %guarded ], [ %start.i, %loop.preheader ]
1044   %j = phi i32 [ %j.next, %guarded ], [ %start.j, %loop.preheader ]
1045   %within.bounds = icmp ult i32 %j, %length
1046   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1047   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
1048   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1050 deopt:                                            ; preds = %loop
1051   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1052   ret i32 %deoptcall
1054 guarded:                                          ; preds = %loop
1055   %i.i64 = zext i32 %i to i64
1056   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
1057   %array.i = load i32, ptr %array.i.ptr, align 4
1058   %loop.acc.next = add i32 %loop.acc, %array.i
1059   %j.next = add i32 %j, 1
1060   %i.next = add i32 %i, 1
1061   %continue = icmp slt i32 %i.next, %n
1062   br i1 %continue, label %loop, label %exit, !prof !2
1064 exit:                                             ; preds = %guarded, %entry
1065   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1066   ret i32 %result
1069 define i32 @signed_loop_0_to_n_different_iv_types(ptr %array, i16 %length, i32 %n) {
1070 ; CHECK-LABEL: @signed_loop_0_to_n_different_iv_types(
1071 ; CHECK-NEXT:  entry:
1072 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
1073 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1074 ; CHECK:       loop.preheader:
1075 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1076 ; CHECK:       loop:
1077 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1078 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1079 ; CHECK-NEXT:    [[J:%.*]] = phi i16 [ [[J_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1080 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i16 [[J]], [[LENGTH:%.*]]
1081 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1082 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
1083 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
1084 ; CHECK:       deopt:
1085 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1086 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1087 ; CHECK:       guarded:
1088 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1089 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
1090 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
1091 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1092 ; CHECK-NEXT:    [[J_NEXT]] = add i16 [[J]], 1
1093 ; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
1094 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1095 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
1096 ; CHECK:       exit.loopexit:
1097 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1098 ; CHECK-NEXT:    br label [[EXIT]]
1099 ; CHECK:       exit:
1100 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1101 ; CHECK-NEXT:    ret i32 [[RESULT]]
1103 entry:
1104   %tmp5 = icmp sle i32 %n, 0
1105   br i1 %tmp5, label %exit, label %loop.preheader
1107 loop.preheader:                                   ; preds = %entry
1108   br label %loop
1110 loop:                                             ; preds = %guarded, %loop.preheader
1111   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1112   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1113   %j = phi i16 [ %j.next, %guarded ], [ 0, %loop.preheader ]
1114   %within.bounds = icmp ult i16 %j, %length
1115   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1116   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
1117   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1119 deopt:                                            ; preds = %loop
1120   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1121   ret i32 %deoptcall
1123 guarded:                                          ; preds = %loop
1124   %i.i64 = zext i32 %i to i64
1125   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
1126   %array.i = load i32, ptr %array.i.ptr, align 4
1127   %loop.acc.next = add i32 %loop.acc, %array.i
1128   %j.next = add i16 %j, 1
1129   %i.next = add i32 %i, 1
1130   %continue = icmp slt i32 %i.next, %n
1131   br i1 %continue, label %loop, label %exit, !prof !2
1133 exit:                                             ; preds = %guarded, %entry
1134   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1135   ret i32 %result
1138 define i32 @signed_loop_0_to_n_different_iv_strides(ptr %array, i32 %length, i32 %n) {
1139 ; CHECK-LABEL: @signed_loop_0_to_n_different_iv_strides(
1140 ; CHECK-NEXT:  entry:
1141 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
1142 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1143 ; CHECK:       loop.preheader:
1144 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1145 ; CHECK:       loop:
1146 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1147 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1148 ; CHECK-NEXT:    [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1149 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH:%.*]]
1150 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1151 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
1152 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
1153 ; CHECK:       deopt:
1154 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1155 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1156 ; CHECK:       guarded:
1157 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1158 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
1159 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
1160 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1161 ; CHECK-NEXT:    [[J_NEXT]] = add nsw i32 [[J]], 2
1162 ; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
1163 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1164 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
1165 ; CHECK:       exit.loopexit:
1166 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1167 ; CHECK-NEXT:    br label [[EXIT]]
1168 ; CHECK:       exit:
1169 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1170 ; CHECK-NEXT:    ret i32 [[RESULT]]
1172 entry:
1173   %tmp5 = icmp sle i32 %n, 0
1174   br i1 %tmp5, label %exit, label %loop.preheader
1176 loop.preheader:                                   ; preds = %entry
1177   br label %loop
1179 loop:                                             ; preds = %guarded, %loop.preheader
1180   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1181   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1182   %j = phi i32 [ %j.next, %guarded ], [ 0, %loop.preheader ]
1183   %within.bounds = icmp ult i32 %j, %length
1184   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1185   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
1186   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1188 deopt:                                            ; preds = %loop
1189   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1190   ret i32 %deoptcall
1192 guarded:                                          ; preds = %loop
1193   %i.i64 = zext i32 %i to i64
1194   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
1195   %array.i = load i32, ptr %array.i.ptr, align 4
1196   %loop.acc.next = add i32 %loop.acc, %array.i
1197   %j.next = add nsw i32 %j, 2
1198   %i.next = add nsw i32 %i, 1
1199   %continue = icmp slt i32 %i.next, %n
1200   br i1 %continue, label %loop, label %exit, !prof !2
1202 exit:                                             ; preds = %guarded, %entry
1203   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1204   ret i32 %result
1207 define i32 @two_range_checks(ptr %array.1, i32 %length.1, ptr %array.2, i32 %length.2, i32 %n) {
1208 ; CHECK-LABEL: @two_range_checks(
1209 ; CHECK-NEXT:  entry:
1210 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1211 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1212 ; CHECK:       loop.preheader:
1213 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]
1214 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_2]]
1215 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
1216 ; CHECK-NEXT:    [[TMP3:%.*]] = freeze i1 [[TMP2]]
1217 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]
1218 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp ult i32 0, [[LENGTH_1]]
1219 ; CHECK-NEXT:    [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]]
1220 ; CHECK-NEXT:    [[TMP7:%.*]] = freeze i1 [[TMP6]]
1221 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1222 ; CHECK:       loop:
1223 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1224 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1225 ; CHECK-NEXT:    [[WITHIN_BOUNDS_1:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]]
1226 ; CHECK-NEXT:    [[WITHIN_BOUNDS_2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]]
1227 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1228 ; CHECK-NEXT:    [[TMP8:%.*]] = and i1 [[TMP3]], [[TMP7]]
1229 ; CHECK-NEXT:    [[TMP9:%.*]] = and i1 [[TMP8]], [[WIDENABLE_COND]]
1230 ; CHECK-NEXT:    br i1 [[TMP9]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
1231 ; CHECK:       deopt:
1232 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1233 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1234 ; CHECK:       guarded:
1235 ; CHECK-NEXT:    [[TMP10:%.*]] = and i1 [[WITHIN_BOUNDS_2]], [[WITHIN_BOUNDS_1]]
1236 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP10]])
1237 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1238 ; CHECK-NEXT:    [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_1:%.*]], i64 [[I_I64]]
1239 ; CHECK-NEXT:    [[ARRAY_1_I:%.*]] = load i32, ptr [[ARRAY_1_I_PTR]], align 4
1240 ; CHECK-NEXT:    [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
1241 ; CHECK-NEXT:    [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_2:%.*]], i64 [[I_I64]]
1242 ; CHECK-NEXT:    [[ARRAY_2_I:%.*]] = load i32, ptr [[ARRAY_2_I_PTR]], align 4
1243 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
1244 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1245 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1246 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
1247 ; CHECK:       exit.loopexit:
1248 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1249 ; CHECK-NEXT:    br label [[EXIT]]
1250 ; CHECK:       exit:
1251 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1252 ; CHECK-NEXT:    ret i32 [[RESULT]]
1254 entry:
1255   %tmp5 = icmp eq i32 %n, 0
1256   br i1 %tmp5, label %exit, label %loop.preheader
1258 loop.preheader:                                   ; preds = %entry
1259   br label %loop
1261 loop:                                             ; preds = %guarded, %loop.preheader
1262   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1263   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1264   %within.bounds.1 = icmp ult i32 %i, %length.1
1265   %within.bounds.2 = icmp ult i32 %i, %length.2
1266   %within.bounds = and i1 %within.bounds.1, %within.bounds.2
1267   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1268   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
1269   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1271 deopt:                                            ; preds = %loop
1272   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1273   ret i32 %deoptcall
1275 guarded:                                          ; preds = %loop
1276   %i.i64 = zext i32 %i to i64
1277   %array.1.i.ptr = getelementptr inbounds i32, ptr %array.1, i64 %i.i64
1278   %array.1.i = load i32, ptr %array.1.i.ptr, align 4
1279   %loop.acc.1 = add i32 %loop.acc, %array.1.i
1280   %array.2.i.ptr = getelementptr inbounds i32, ptr %array.2, i64 %i.i64
1281   %array.2.i = load i32, ptr %array.2.i.ptr, align 4
1282   %loop.acc.next = add i32 %loop.acc.1, %array.2.i
1283   %i.next = add nuw i32 %i, 1
1284   %continue = icmp ult i32 %i.next, %n
1285   br i1 %continue, label %loop, label %exit, !prof !2
1287 exit:                                             ; preds = %guarded, %entry
1288   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1289   ret i32 %result
1292 define i32 @three_range_checks(ptr %array.1, i32 %length.1, ptr %array.2, i32 %length.2, ptr %array.3, i32 %length.3, i32 %n) {
1293 ; CHECK-LABEL: @three_range_checks(
1294 ; CHECK-NEXT:  entry:
1295 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1296 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1297 ; CHECK:       loop.preheader:
1298 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_3:%.*]]
1299 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_3]]
1300 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
1301 ; CHECK-NEXT:    [[TMP3:%.*]] = freeze i1 [[TMP2]]
1302 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]
1303 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp ult i32 0, [[LENGTH_2]]
1304 ; CHECK-NEXT:    [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]]
1305 ; CHECK-NEXT:    [[TMP7:%.*]] = freeze i1 [[TMP6]]
1306 ; CHECK-NEXT:    [[TMP8:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]
1307 ; CHECK-NEXT:    [[TMP9:%.*]] = icmp ult i32 0, [[LENGTH_1]]
1308 ; CHECK-NEXT:    [[TMP10:%.*]] = and i1 [[TMP9]], [[TMP8]]
1309 ; CHECK-NEXT:    [[TMP11:%.*]] = freeze i1 [[TMP10]]
1310 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1311 ; CHECK:       loop:
1312 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1313 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1314 ; CHECK-NEXT:    [[WITHIN_BOUNDS_1:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]]
1315 ; CHECK-NEXT:    [[WITHIN_BOUNDS_2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]]
1316 ; CHECK-NEXT:    [[WITHIN_BOUNDS_3:%.*]] = icmp ult i32 [[I]], [[LENGTH_3]]
1317 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1318 ; CHECK-NEXT:    [[TMP12:%.*]] = and i1 [[TMP3]], [[TMP7]]
1319 ; CHECK-NEXT:    [[TMP13:%.*]] = and i1 [[TMP12]], [[TMP11]]
1320 ; CHECK-NEXT:    [[TMP14:%.*]] = and i1 [[TMP13]], [[WIDENABLE_COND]]
1321 ; CHECK-NEXT:    br i1 [[TMP14]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
1322 ; CHECK:       deopt:
1323 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1324 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1325 ; CHECK:       guarded:
1326 ; CHECK-NEXT:    [[TMP15:%.*]] = and i1 [[WITHIN_BOUNDS_3]], [[WITHIN_BOUNDS_2]]
1327 ; CHECK-NEXT:    [[TMP16:%.*]] = and i1 [[TMP15]], [[WITHIN_BOUNDS_1]]
1328 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP16]])
1329 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1330 ; CHECK-NEXT:    [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_1:%.*]], i64 [[I_I64]]
1331 ; CHECK-NEXT:    [[ARRAY_1_I:%.*]] = load i32, ptr [[ARRAY_1_I_PTR]], align 4
1332 ; CHECK-NEXT:    [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
1333 ; CHECK-NEXT:    [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_2:%.*]], i64 [[I_I64]]
1334 ; CHECK-NEXT:    [[ARRAY_2_I:%.*]] = load i32, ptr [[ARRAY_2_I_PTR]], align 4
1335 ; CHECK-NEXT:    [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
1336 ; CHECK-NEXT:    [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_3:%.*]], i64 [[I_I64]]
1337 ; CHECK-NEXT:    [[ARRAY_3_I:%.*]] = load i32, ptr [[ARRAY_3_I_PTR]], align 4
1338 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]]
1339 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1340 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1341 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
1342 ; CHECK:       exit.loopexit:
1343 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1344 ; CHECK-NEXT:    br label [[EXIT]]
1345 ; CHECK:       exit:
1346 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1347 ; CHECK-NEXT:    ret i32 [[RESULT]]
1349 entry:
1350   %tmp5 = icmp eq i32 %n, 0
1351   br i1 %tmp5, label %exit, label %loop.preheader
1353 loop.preheader:                                   ; preds = %entry
1354   br label %loop
1356 loop:                                             ; preds = %guarded, %loop.preheader
1357   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1358   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1359   %within.bounds.1 = icmp ult i32 %i, %length.1
1360   %within.bounds.2 = icmp ult i32 %i, %length.2
1361   %within.bounds.3 = icmp ult i32 %i, %length.3
1362   %within.bounds.1.and.2 = and i1 %within.bounds.1, %within.bounds.2
1363   %within.bounds = and i1 %within.bounds.1.and.2, %within.bounds.3
1364   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1365   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
1366   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1368 deopt:                                            ; preds = %loop
1369   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1370   ret i32 %deoptcall
1372 guarded:                                          ; preds = %loop
1373   %i.i64 = zext i32 %i to i64
1374   %array.1.i.ptr = getelementptr inbounds i32, ptr %array.1, i64 %i.i64
1375   %array.1.i = load i32, ptr %array.1.i.ptr, align 4
1376   %loop.acc.1 = add i32 %loop.acc, %array.1.i
1377   %array.2.i.ptr = getelementptr inbounds i32, ptr %array.2, i64 %i.i64
1378   %array.2.i = load i32, ptr %array.2.i.ptr, align 4
1379   %loop.acc.2 = add i32 %loop.acc.1, %array.2.i
1380   %array.3.i.ptr = getelementptr inbounds i32, ptr %array.3, i64 %i.i64
1381   %array.3.i = load i32, ptr %array.3.i.ptr, align 4
1382   %loop.acc.next = add i32 %loop.acc.2, %array.3.i
1383   %i.next = add nuw i32 %i, 1
1384   %continue = icmp ult i32 %i.next, %n
1385   br i1 %continue, label %loop, label %exit, !prof !2
1387 exit:                                             ; preds = %guarded, %entry
1388   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1389   ret i32 %result
1392 define i32 @three_guards(ptr %array.1, i32 %length.1, ptr %array.2, i32 %length.2, ptr %array.3, i32 %length.3, i32 %n) {
1393 ; CHECK-LABEL: @three_guards(
1394 ; CHECK-NEXT:  entry:
1395 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1396 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1397 ; CHECK:       loop.preheader:
1398 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]
1399 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_1]]
1400 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
1401 ; CHECK-NEXT:    [[TMP3:%.*]] = freeze i1 [[TMP2]]
1402 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]
1403 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp ult i32 0, [[LENGTH_2]]
1404 ; CHECK-NEXT:    [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]]
1405 ; CHECK-NEXT:    [[TMP7:%.*]] = freeze i1 [[TMP6]]
1406 ; CHECK-NEXT:    [[TMP8:%.*]] = icmp ule i32 [[N]], [[LENGTH_3:%.*]]
1407 ; CHECK-NEXT:    [[TMP9:%.*]] = icmp ult i32 0, [[LENGTH_3]]
1408 ; CHECK-NEXT:    [[TMP10:%.*]] = and i1 [[TMP9]], [[TMP8]]
1409 ; CHECK-NEXT:    [[TMP11:%.*]] = freeze i1 [[TMP10]]
1410 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1411 ; CHECK:       loop:
1412 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED6:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1413 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED6]] ], [ 0, [[LOOP_PREHEADER]] ]
1414 ; CHECK-NEXT:    [[WITHIN_BOUNDS_1:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]]
1415 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1416 ; CHECK-NEXT:    [[TMP12:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
1417 ; CHECK-NEXT:    br i1 [[TMP12]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
1418 ; CHECK:       deopt:
1419 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1420 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1421 ; CHECK:       guarded:
1422 ; CHECK-NEXT:    call void @llvm.assume(i1 [[WITHIN_BOUNDS_1]])
1423 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1424 ; CHECK-NEXT:    [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_1:%.*]], i64 [[I_I64]]
1425 ; CHECK-NEXT:    [[ARRAY_1_I:%.*]] = load i32, ptr [[ARRAY_1_I_PTR]], align 4
1426 ; CHECK-NEXT:    [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
1427 ; CHECK-NEXT:    [[WITHIN_BOUNDS_2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]]
1428 ; CHECK-NEXT:    [[WIDENABLE_COND4:%.*]] = call i1 @llvm.experimental.widenable.condition()
1429 ; CHECK-NEXT:    [[TMP13:%.*]] = and i1 [[TMP7]], [[WIDENABLE_COND4]]
1430 ; CHECK-NEXT:    br i1 [[TMP13]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
1431 ; CHECK:       deopt2:
1432 ; CHECK-NEXT:    [[DEOPTCALL3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1433 ; CHECK-NEXT:    ret i32 [[DEOPTCALL3]]
1434 ; CHECK:       guarded1:
1435 ; CHECK-NEXT:    call void @llvm.assume(i1 [[WITHIN_BOUNDS_2]])
1436 ; CHECK-NEXT:    [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_2:%.*]], i64 [[I_I64]]
1437 ; CHECK-NEXT:    [[ARRAY_2_I:%.*]] = load i32, ptr [[ARRAY_2_I_PTR]], align 4
1438 ; CHECK-NEXT:    [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
1439 ; CHECK-NEXT:    [[WITHIN_BOUNDS_3:%.*]] = icmp ult i32 [[I]], [[LENGTH_3]]
1440 ; CHECK-NEXT:    [[WIDENABLE_COND9:%.*]] = call i1 @llvm.experimental.widenable.condition()
1441 ; CHECK-NEXT:    [[TMP14:%.*]] = and i1 [[TMP11]], [[WIDENABLE_COND9]]
1442 ; CHECK-NEXT:    br i1 [[TMP14]], label [[GUARDED6]], label [[DEOPT7:%.*]], !prof [[PROF0]]
1443 ; CHECK:       deopt7:
1444 ; CHECK-NEXT:    [[DEOPTCALL8:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1445 ; CHECK-NEXT:    ret i32 [[DEOPTCALL8]]
1446 ; CHECK:       guarded6:
1447 ; CHECK-NEXT:    call void @llvm.assume(i1 [[WITHIN_BOUNDS_3]])
1448 ; CHECK-NEXT:    [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_3:%.*]], i64 [[I_I64]]
1449 ; CHECK-NEXT:    [[ARRAY_3_I:%.*]] = load i32, ptr [[ARRAY_3_I_PTR]], align 4
1450 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]]
1451 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1452 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1453 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
1454 ; CHECK:       exit.loopexit:
1455 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED6]] ]
1456 ; CHECK-NEXT:    br label [[EXIT]]
1457 ; CHECK:       exit:
1458 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1459 ; CHECK-NEXT:    ret i32 [[RESULT]]
1461 entry:
1462   %tmp5 = icmp eq i32 %n, 0
1463   br i1 %tmp5, label %exit, label %loop.preheader
1465 loop.preheader:                                   ; preds = %entry
1466   br label %loop
1468 loop:                                             ; preds = %guarded6, %loop.preheader
1469   %loop.acc = phi i32 [ %loop.acc.next, %guarded6 ], [ 0, %loop.preheader ]
1470   %i = phi i32 [ %i.next, %guarded6 ], [ 0, %loop.preheader ]
1471   %within.bounds.1 = icmp ult i32 %i, %length.1
1472   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1473   %exiplicit_guard_cond = and i1 %within.bounds.1, %widenable_cond
1474   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1476 deopt:                                            ; preds = %loop
1477   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1478   ret i32 %deoptcall
1480 guarded:                                          ; preds = %loop
1481   %i.i64 = zext i32 %i to i64
1482   %array.1.i.ptr = getelementptr inbounds i32, ptr %array.1, i64 %i.i64
1483   %array.1.i = load i32, ptr %array.1.i.ptr, align 4
1484   %loop.acc.1 = add i32 %loop.acc, %array.1.i
1485   %within.bounds.2 = icmp ult i32 %i, %length.2
1486   %widenable_cond4 = call i1 @llvm.experimental.widenable.condition()
1487   %exiplicit_guard_cond5 = and i1 %within.bounds.2, %widenable_cond4
1488   br i1 %exiplicit_guard_cond5, label %guarded1, label %deopt2, !prof !0
1490 deopt2:                                           ; preds = %guarded
1491   %deoptcall3 = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1492   ret i32 %deoptcall3
1494 guarded1:                                         ; preds = %guarded
1495   %array.2.i.ptr = getelementptr inbounds i32, ptr %array.2, i64 %i.i64
1496   %array.2.i = load i32, ptr %array.2.i.ptr, align 4
1497   %loop.acc.2 = add i32 %loop.acc.1, %array.2.i
1498   %within.bounds.3 = icmp ult i32 %i, %length.3
1499   %widenable_cond9 = call i1 @llvm.experimental.widenable.condition()
1500   %exiplicit_guard_cond10 = and i1 %within.bounds.3, %widenable_cond9
1501   br i1 %exiplicit_guard_cond10, label %guarded6, label %deopt7, !prof !0
1503 deopt7:                                           ; preds = %guarded1
1504   %deoptcall8 = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1505   ret i32 %deoptcall8
1507 guarded6:                                         ; preds = %guarded1
1508   %array.3.i.ptr = getelementptr inbounds i32, ptr %array.3, i64 %i.i64
1509   %array.3.i = load i32, ptr %array.3.i.ptr, align 4
1510   %loop.acc.next = add i32 %loop.acc.2, %array.3.i
1511   %i.next = add nuw i32 %i, 1
1512   %continue = icmp ult i32 %i.next, %n
1513   br i1 %continue, label %loop, label %exit, !prof !2
1515 exit:                                             ; preds = %guarded6, %entry
1516   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded6 ]
1517   ret i32 %result
1520 define i32 @unsigned_loop_0_to_n_unrelated_condition(ptr %array, i32 %length, i32 %n, i32 %x) {
1521 ; CHECK-LABEL: @unsigned_loop_0_to_n_unrelated_condition(
1522 ; CHECK-NEXT:  entry:
1523 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1524 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1525 ; CHECK:       loop.preheader:
1526 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
1527 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
1528 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
1529 ; CHECK-NEXT:    [[TMP3:%.*]] = freeze i1 [[TMP2]]
1530 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1531 ; CHECK:       loop:
1532 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1533 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1534 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
1535 ; CHECK-NEXT:    [[UNRELATED_COND:%.*]] = icmp ult i32 [[X:%.*]], [[LENGTH]]
1536 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1537 ; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[UNRELATED_COND]], [[TMP3]]
1538 ; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[WIDENABLE_COND]]
1539 ; CHECK-NEXT:    br i1 [[TMP5]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
1540 ; CHECK:       deopt:
1541 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1542 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1543 ; CHECK:       guarded:
1544 ; CHECK-NEXT:    call void @llvm.assume(i1 [[WITHIN_BOUNDS]])
1545 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1546 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
1547 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
1548 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1549 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1550 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1551 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
1552 ; CHECK:       exit.loopexit:
1553 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1554 ; CHECK-NEXT:    br label [[EXIT]]
1555 ; CHECK:       exit:
1556 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1557 ; CHECK-NEXT:    ret i32 [[RESULT]]
1559 entry:
1560   %tmp5 = icmp eq i32 %n, 0
1561   br i1 %tmp5, label %exit, label %loop.preheader
1563 loop.preheader:                                   ; preds = %entry
1564   br label %loop
1566 loop:                                             ; preds = %guarded, %loop.preheader
1567   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1568   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1569   %within.bounds = icmp ult i32 %i, %length
1570   %unrelated.cond = icmp ult i32 %x, %length
1571   %guard.cond = and i1 %within.bounds, %unrelated.cond
1572   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1573   %exiplicit_guard_cond = and i1 %guard.cond, %widenable_cond
1574   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1576 deopt:                                            ; preds = %loop
1577   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1578   ret i32 %deoptcall
1580 guarded:                                          ; preds = %loop
1581   %i.i64 = zext i32 %i to i64
1582   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
1583   %array.i = load i32, ptr %array.i.ptr, align 4
1584   %loop.acc.next = add i32 %loop.acc, %array.i
1585   %i.next = add nuw i32 %i, 1
1586   %continue = icmp ult i32 %i.next, %n
1587   br i1 %continue, label %loop, label %exit, !prof !2
1589 exit:                                             ; preds = %guarded, %entry
1590   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1591   ret i32 %result
1594 define i32 @test_no_widened_conditions(ptr %array, i32 %length, i32 %n, i32 %x1, i32 %x2, i32 %x3) {
1595 ; CHECK-LABEL: @test_no_widened_conditions(
1596 ; CHECK-NEXT:  entry:
1597 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1598 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1599 ; CHECK:       loop.preheader:
1600 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1601 ; CHECK:       loop:
1602 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1603 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1604 ; CHECK-NEXT:    [[UNRELATED_COND_1:%.*]] = icmp eq i32 [[X1:%.*]], [[I]]
1605 ; CHECK-NEXT:    [[UNRELATED_COND_2:%.*]] = icmp eq i32 [[X2:%.*]], [[I]]
1606 ; CHECK-NEXT:    [[UNRELATED_COND_3:%.*]] = icmp eq i32 [[X3:%.*]], [[I]]
1607 ; CHECK-NEXT:    [[UNRELATED_COND_AND_1:%.*]] = and i1 [[UNRELATED_COND_1]], [[UNRELATED_COND_2]]
1608 ; CHECK-NEXT:    [[GUARD_COND:%.*]] = and i1 [[UNRELATED_COND_AND_1]], [[UNRELATED_COND_3]]
1609 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1610 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[GUARD_COND]], [[WIDENABLE_COND]]
1611 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
1612 ; CHECK:       deopt:
1613 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1614 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1615 ; CHECK:       guarded:
1616 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1617 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
1618 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
1619 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1620 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1621 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1622 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
1623 ; CHECK:       exit.loopexit:
1624 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1625 ; CHECK-NEXT:    br label [[EXIT]]
1626 ; CHECK:       exit:
1627 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1628 ; CHECK-NEXT:    ret i32 [[RESULT]]
1630 entry:
1631   %tmp5 = icmp eq i32 %n, 0
1632   br i1 %tmp5, label %exit, label %loop.preheader
1634 loop.preheader:                                   ; preds = %entry
1635   br label %loop
1637 loop:                                             ; preds = %guarded, %loop.preheader
1638   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1639   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1640   %unrelated.cond.1 = icmp eq i32 %x1, %i
1641   %unrelated.cond.2 = icmp eq i32 %x2, %i
1642   %unrelated.cond.3 = icmp eq i32 %x3, %i
1643   %unrelated.cond.and.1 = and i1 %unrelated.cond.1, %unrelated.cond.2
1644   %guard.cond = and i1 %unrelated.cond.and.1, %unrelated.cond.3
1645   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1646   %exiplicit_guard_cond = and i1 %guard.cond, %widenable_cond
1647   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1649 deopt:                                            ; preds = %loop
1650   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1651   ret i32 %deoptcall
1653 guarded:                                          ; preds = %loop
1654   %i.i64 = zext i32 %i to i64
1655   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
1656   %array.i = load i32, ptr %array.i.ptr, align 4
1657   %loop.acc.next = add i32 %loop.acc, %array.i
1658   %i.next = add nuw i32 %i, 1
1659   %continue = icmp ult i32 %i.next, %n
1660   br i1 %continue, label %loop, label %exit, !prof !2
1662 exit:                                             ; preds = %guarded, %entry
1663   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1664   ret i32 %result
1667 define i32 @signed_loop_start_to_n_loop_variant_bound(ptr %array, i32 %x, i32 %start, i32 %n) {
1668 ; CHECK-LABEL: @signed_loop_start_to_n_loop_variant_bound(
1669 ; CHECK-NEXT:  entry:
1670 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
1671 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1672 ; CHECK:       loop.preheader:
1673 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1674 ; CHECK:       loop:
1675 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1676 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ]
1677 ; CHECK-NEXT:    [[BOUND:%.*]] = add i32 [[I]], [[X:%.*]]
1678 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[BOUND]]
1679 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1680 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
1681 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
1682 ; CHECK:       deopt:
1683 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1684 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1685 ; CHECK:       guarded:
1686 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1687 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
1688 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
1689 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1690 ; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
1691 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1692 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
1693 ; CHECK:       exit.loopexit:
1694 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1695 ; CHECK-NEXT:    br label [[EXIT]]
1696 ; CHECK:       exit:
1697 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1698 ; CHECK-NEXT:    ret i32 [[RESULT]]
1700 entry:
1701   %tmp5 = icmp sle i32 %n, 0
1702   br i1 %tmp5, label %exit, label %loop.preheader
1704 loop.preheader:                                   ; preds = %entry
1705   br label %loop
1707 loop:                                             ; preds = %guarded, %loop.preheader
1708   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1709   %i = phi i32 [ %i.next, %guarded ], [ %start, %loop.preheader ]
1710   %bound = add i32 %i, %x
1711   %within.bounds = icmp ult i32 %i, %bound
1712   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1713   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
1714   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1716 deopt:                                            ; preds = %loop
1717   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1718   ret i32 %deoptcall
1720 guarded:                                          ; preds = %loop
1721   %i.i64 = zext i32 %i to i64
1722   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
1723   %array.i = load i32, ptr %array.i.ptr, align 4
1724   %loop.acc.next = add i32 %loop.acc, %array.i
1725   %i.next = add nsw i32 %i, 1
1726   %continue = icmp slt i32 %i.next, %n
1727   br i1 %continue, label %loop, label %exit, !prof !2
1729 exit:                                             ; preds = %guarded, %entry
1730   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1731   ret i32 %result
1734 define i32 @signed_loop_start_to_n_non_monotonic_predicate(ptr %array, i32 %x, i32 %start, i32 %n) {
1735 ; CHECK-LABEL: @signed_loop_start_to_n_non_monotonic_predicate(
1736 ; CHECK-NEXT:  entry:
1737 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
1738 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1739 ; CHECK:       loop.preheader:
1740 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1741 ; CHECK:       loop:
1742 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1743 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ]
1744 ; CHECK-NEXT:    [[GUARD_COND:%.*]] = icmp eq i32 [[I]], [[X:%.*]]
1745 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1746 ; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[GUARD_COND]], [[WIDENABLE_COND]]
1747 ; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
1748 ; CHECK:       deopt:
1749 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1750 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1751 ; CHECK:       guarded:
1752 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1753 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
1754 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
1755 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1756 ; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
1757 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1758 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
1759 ; CHECK:       exit.loopexit:
1760 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1761 ; CHECK-NEXT:    br label [[EXIT]]
1762 ; CHECK:       exit:
1763 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1764 ; CHECK-NEXT:    ret i32 [[RESULT]]
1766 entry:
1767   %tmp5 = icmp sle i32 %n, 0
1768   br i1 %tmp5, label %exit, label %loop.preheader
1770 loop.preheader:                                   ; preds = %entry
1771   br label %loop
1773 loop:                                             ; preds = %guarded, %loop.preheader
1774   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1775   %i = phi i32 [ %i.next, %guarded ], [ %start, %loop.preheader ]
1776   %guard.cond = icmp eq i32 %i, %x
1777   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1778   %exiplicit_guard_cond = and i1 %guard.cond, %widenable_cond
1779   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1781 deopt:                                            ; preds = %loop
1782   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1783   ret i32 %deoptcall
1785 guarded:                                          ; preds = %loop
1786   %i.i64 = zext i32 %i to i64
1787   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
1788   %array.i = load i32, ptr %array.i.ptr, align 4
1789   %loop.acc.next = add i32 %loop.acc, %array.i
1790   %i.next = add nsw i32 %i, 1
1791   %continue = icmp slt i32 %i.next, %n
1792   br i1 %continue, label %loop, label %exit, !prof !2
1794 exit:                                             ; preds = %guarded, %entry
1795   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1796   ret i32 %result
1799 define i32 @unsigned_loop_0_to_n_hoist_length(ptr %array, i16 %length.i16, i32 %n) {
1800 ; CHECK-LABEL: @unsigned_loop_0_to_n_hoist_length(
1801 ; CHECK-NEXT:  entry:
1802 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1803 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1804 ; CHECK:       loop.preheader:
1805 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i16 [[LENGTH_I16:%.*]] to i32
1806 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]]
1807 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 0, [[TMP0]]
1808 ; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
1809 ; CHECK-NEXT:    [[TMP4:%.*]] = freeze i1 [[TMP3]]
1810 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1811 ; CHECK:       loop:
1812 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1813 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1814 ; CHECK-NEXT:    [[LENGTH:%.*]] = zext i16 [[LENGTH_I16]] to i32
1815 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
1816 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1817 ; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[WIDENABLE_COND]]
1818 ; CHECK-NEXT:    br i1 [[TMP5]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
1819 ; CHECK:       deopt:
1820 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1821 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1822 ; CHECK:       guarded:
1823 ; CHECK-NEXT:    call void @llvm.assume(i1 [[WITHIN_BOUNDS]])
1824 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1825 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
1826 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
1827 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1828 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1829 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1830 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
1831 ; CHECK:       exit.loopexit:
1832 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1833 ; CHECK-NEXT:    br label [[EXIT]]
1834 ; CHECK:       exit:
1835 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1836 ; CHECK-NEXT:    ret i32 [[RESULT]]
1838 entry:
1839   %tmp5 = icmp eq i32 %n, 0
1840   br i1 %tmp5, label %exit, label %loop.preheader
1842 loop.preheader:                                   ; preds = %entry
1843   br label %loop
1845 loop:                                             ; preds = %guarded, %loop.preheader
1846   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1847   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1848   %length = zext i16 %length.i16 to i32
1849   %within.bounds = icmp ult i32 %i, %length
1850   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1851   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
1852   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1854 deopt:                                            ; preds = %loop
1855   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1856   ret i32 %deoptcall
1858 guarded:                                          ; preds = %loop
1859   %i.i64 = zext i32 %i to i64
1860   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
1861   %array.i = load i32, ptr %array.i.ptr, align 4
1862   %loop.acc.next = add i32 %loop.acc, %array.i
1863   %i.next = add nuw i32 %i, 1
1864   %continue = icmp ult i32 %i.next, %n
1865   br i1 %continue, label %loop, label %exit, !prof !2
1867 exit:                                             ; preds = %guarded, %entry
1868   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1869   ret i32 %result
1872 define i32 @unsigned_loop_0_to_n_cant_hoist_length(ptr %array, i32 %length, i32 %divider, i32 %n) {
1873 ; CHECK-LABEL: @unsigned_loop_0_to_n_cant_hoist_length(
1874 ; CHECK-NEXT:  entry:
1875 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1876 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1877 ; CHECK:       loop.preheader:
1878 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1879 ; CHECK:       loop:
1880 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1881 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1882 ; CHECK-NEXT:    [[LENGTH_UDIV:%.*]] = udiv i32 [[LENGTH:%.*]], [[DIVIDER:%.*]]
1883 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH_UDIV]]
1884 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1885 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_UDIV]]
1886 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_UDIV]]
1887 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
1888 ; CHECK-NEXT:    [[TMP3:%.*]] = freeze i1 [[TMP2]]
1889 ; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
1890 ; CHECK-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
1891 ; CHECK:       deopt:
1892 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1893 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1894 ; CHECK:       guarded:
1895 ; CHECK-NEXT:    call void @llvm.assume(i1 [[WITHIN_BOUNDS]])
1896 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1897 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
1898 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
1899 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1900 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1901 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1902 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
1903 ; CHECK:       exit.loopexit:
1904 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1905 ; CHECK-NEXT:    br label [[EXIT]]
1906 ; CHECK:       exit:
1907 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1908 ; CHECK-NEXT:    ret i32 [[RESULT]]
1910 entry:
1911   %tmp5 = icmp eq i32 %n, 0
1912   br i1 %tmp5, label %exit, label %loop.preheader
1914 loop.preheader:                                   ; preds = %entry
1915   br label %loop
1917 loop:                                             ; preds = %guarded, %loop.preheader
1918   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1919   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1920   %length.udiv = udiv i32 %length, %divider
1921   %within.bounds = icmp ult i32 %i, %length.udiv
1922   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1923   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
1924   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1926 deopt:                                            ; preds = %loop
1927   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1928   ret i32 %deoptcall
1930 guarded:                                          ; preds = %loop
1931   %i.i64 = zext i32 %i to i64
1932   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
1933   %array.i = load i32, ptr %array.i.ptr, align 4
1934   %loop.acc.next = add i32 %loop.acc, %array.i
1935   %i.next = add nuw i32 %i, 1
1936   %continue = icmp ult i32 %i.next, %n
1937   br i1 %continue, label %loop, label %exit, !prof !2
1939 exit:                                             ; preds = %guarded, %entry
1940   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1941   ret i32 %result
1944 ; Make sure that if we're going to consider a branch widenable, that the
1945 ; call to widenable condition is actually present.
1946 define i32 @negative_WC_required(ptr %array, i32 %length, i32 %n, i1 %unrelated) {
1947 ; CHECK-LABEL: @negative_WC_required(
1948 ; CHECK-NEXT:  entry:
1949 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1950 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1951 ; CHECK:       loop.preheader:
1952 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1953 ; CHECK:       loop:
1954 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1955 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
1956 ; CHECK-NEXT:    [[NOT_WIDENABLE:%.*]] = and i1 [[WITHIN_BOUNDS]], [[UNRELATED:%.*]]
1957 ; CHECK-NEXT:    br i1 [[NOT_WIDENABLE]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
1958 ; CHECK:       deopt:
1959 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1960 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1961 ; CHECK:       guarded:
1962 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1963 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
1964 ; CHECK-NEXT:    store i32 0, ptr [[ARRAY_I_PTR]], align 4
1965 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1966 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1967 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
1968 ; CHECK:       exit.loopexit:
1969 ; CHECK-NEXT:    br label [[EXIT]]
1970 ; CHECK:       exit:
1971 ; CHECK-NEXT:    ret i32 0
1973 entry:
1974   %tmp5 = icmp eq i32 %n, 0
1975   br i1 %tmp5, label %exit, label %loop.preheader
1977 loop.preheader:                                   ; preds = %entry
1978   br label %loop
1980 loop:
1981   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1982   %within.bounds = icmp ult i32 %i, %length
1983   %not_widenable = and i1 %within.bounds, %unrelated
1984   br i1 %not_widenable, label %guarded, label %deopt, !prof !0
1986 deopt:
1987   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1988   ret i32 %deoptcall
1990 guarded:                                          ; preds = %loop
1991   %i.i64 = zext i32 %i to i64
1992   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
1993   store i32 0, ptr %array.i.ptr, align 4
1994   %i.next = add nuw i32 %i, 1
1995   %continue = icmp ult i32 %i.next, %n
1996   br i1 %continue, label %loop, label %exit, !prof !2
1998 exit:                                             ; preds = %guarded, %entry
1999   ret i32 0
2002 define i32 @swapped_wb(ptr %array, i32 %length, i32 %n) {
2003 ; CHECK-LABEL: @swapped_wb(
2004 ; CHECK-NEXT:  entry:
2005 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
2006 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
2007 ; CHECK:       loop.preheader:
2008 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
2009 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
2010 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
2011 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
2012 ; CHECK-NEXT:    [[TMP3:%.*]] = freeze i1 [[TMP2]]
2013 ; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
2014 ; CHECK-NEXT:    br label [[LOOP:%.*]]
2015 ; CHECK:       loop:
2016 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
2017 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
2018 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
2019 ; CHECK-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
2020 ; CHECK:       deopt:
2021 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
2022 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
2023 ; CHECK:       guarded:
2024 ; CHECK-NEXT:    call void @llvm.assume(i1 [[WITHIN_BOUNDS]])
2025 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
2026 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
2027 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
2028 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
2029 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
2030 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
2031 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
2032 ; CHECK:       exit.loopexit:
2033 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
2034 ; CHECK-NEXT:    br label [[EXIT]]
2035 ; CHECK:       exit:
2036 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
2037 ; CHECK-NEXT:    ret i32 [[RESULT]]
2039 entry:
2040   %tmp5 = icmp eq i32 %n, 0
2041   br i1 %tmp5, label %exit, label %loop.preheader
2043 loop.preheader:                                   ; preds = %entry
2044   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
2045   br label %loop
2047 loop:                                             ; preds = %guarded, %loop.preheader
2048   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
2049   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
2050   %within.bounds = icmp ult i32 %i, %length
2051   %exiplicit_guard_cond = and i1 %widenable_cond, %within.bounds
2052   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
2054 deopt:                                            ; preds = %loop
2055   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
2056   ret i32 %deoptcall
2058 guarded:                                          ; preds = %loop
2059   %i.i64 = zext i32 %i to i64
2060   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
2061   %array.i = load i32, ptr %array.i.ptr, align 4
2062   %loop.acc.next = add i32 %loop.acc, %array.i
2063   %i.next = add nuw i32 %i, 1
2064   %continue = icmp ult i32 %i.next, %n
2065   br i1 %continue, label %loop, label %exit, !prof !2
2067 exit:                                             ; preds = %guarded, %entry
2068   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
2069   ret i32 %result
2072 define i32 @unsigned_loop_0_to_n_ult_check_deep_deopt(ptr %array, i32 %length, i32 %n) {
2073 ; CHECK-LABEL: @unsigned_loop_0_to_n_ult_check_deep_deopt(
2074 ; CHECK-NEXT:  entry:
2075 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
2076 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
2077 ; CHECK:       loop.preheader:
2078 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
2079 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
2080 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
2081 ; CHECK-NEXT:    [[TMP3:%.*]] = freeze i1 [[TMP2]]
2082 ; CHECK-NEXT:    br label [[LOOP:%.*]]
2083 ; CHECK:       loop:
2084 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
2085 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
2086 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
2087 ; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
2088 ; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
2089 ; CHECK-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
2090 ; CHECK:       deopt:
2091 ; CHECK-NEXT:    br label [[REAL_DEOPT:%.*]]
2092 ; CHECK:       real_deopt:
2093 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
2094 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
2095 ; CHECK:       guarded:
2096 ; CHECK-NEXT:    call void @llvm.assume(i1 [[WITHIN_BOUNDS]])
2097 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
2098 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
2099 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
2100 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
2101 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
2102 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
2103 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
2104 ; CHECK:       exit.loopexit:
2105 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
2106 ; CHECK-NEXT:    br label [[EXIT]]
2107 ; CHECK:       exit:
2108 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
2109 ; CHECK-NEXT:    ret i32 [[RESULT]]
2111 entry:
2112   %tmp5 = icmp eq i32 %n, 0
2113   br i1 %tmp5, label %exit, label %loop.preheader
2115 loop.preheader:                                   ; preds = %entry
2116   br label %loop
2118 loop:                                             ; preds = %guarded, %loop.preheader
2119   %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
2120   %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
2121   %within.bounds = icmp ult i32 %i, %length
2122   %widenable_cond = call i1 @llvm.experimental.widenable.condition()
2123   %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
2124   br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
2126 deopt:                                            ; preds = %loop
2127   br label %real_deopt
2129 real_deopt:                                       ; preds = %deopt
2130   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
2131   ret i32 %deoptcall
2133 guarded:                                          ; preds = %loop
2134   %i.i64 = zext i32 %i to i64
2135   %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
2136   %array.i = load i32, ptr %array.i.ptr, align 4
2137   %loop.acc.next = add i32 %loop.acc, %array.i
2138   %i.next = add nuw i32 %i, 1
2139   %continue = icmp ult i32 %i.next, %n
2140   br i1 %continue, label %loop, label %exit, !prof !2
2142 exit:                                             ; preds = %guarded, %entry
2143   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
2144   ret i32 %result
2147 ; TODO: Support widenable branch in the form of br((wc and cond0) and cond1)
2148 ; At present LoopPredication assumes the form of br(wc && (...)) only.
2149 define i32 @wc_deep_in_expression_tree(i1 %cond0, i1 %cond1, i32 %limit) {
2150 ; CHECK-LABEL: @wc_deep_in_expression_tree(
2151 ; CHECK-NEXT:  entry:
2152 ; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
2153 ; CHECK-NEXT:    [[AND0:%.*]] = and i1 [[WC]], [[COND0:%.*]]
2154 ; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[AND0]], [[COND1:%.*]]
2155 ; CHECK-NEXT:    br i1 [[AND1]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]]
2156 ; CHECK:       loop.preheader:
2157 ; CHECK-NEXT:    br label [[LOOP:%.*]]
2158 ; CHECK:       loop:
2159 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
2160 ; CHECK-NEXT:    [[GUARD_COND:%.*]] = icmp sgt i32 [[IV]], 100
2161 ; CHECK-NEXT:    br i1 [[GUARD_COND]], label [[DEOPT_LOOPEXIT:%.*]], label [[GUARDED]]
2162 ; CHECK:       guarded:
2163 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
2164 ; CHECK-NEXT:    [[EXIT_COND:%.*]] = icmp ult i32 [[IV]], [[LIMIT:%.*]]
2165 ; CHECK-NEXT:    br i1 [[EXIT_COND]], label [[LOOP]], label [[EXIT:%.*]]
2166 ; CHECK:       deopt.loopexit:
2167 ; CHECK-NEXT:    br label [[DEOPT]]
2168 ; CHECK:       deopt:
2169 ; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
2170 ; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
2171 ; CHECK:       exit:
2172 ; CHECK-NEXT:    ret i32 0
2174 entry:
2175   %wc = call i1 @llvm.experimental.widenable.condition()
2176   %and0 = and i1 %wc, %cond0
2177   %and1 = and i1 %and0, %cond1
2178   br i1 %and1, label %loop, label %deopt
2180 loop:
2181   %iv = phi i32 [ %iv.next, %guarded ], [ 0, %entry ]
2182   %guard.cond = icmp sgt i32 %iv, 100
2183   br i1 %guard.cond, label %deopt, label %guarded
2185 guarded:
2186   %iv.next = add i32 %iv, 1
2187   %exit.cond = icmp ult i32 %iv, %limit
2188   br i1 %exit.cond, label %loop, label %exit
2190 deopt:
2191   %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
2192   ret i32 %deoptcall
2193 exit:
2194   ret i32 0
2197 declare i32 @llvm.experimental.deoptimize.i32(...)
2199 ; Function Attrs: inaccessiblememonly nounwind
2200 declare i1 @llvm.experimental.widenable.condition() #0
2202 attributes #0 = { inaccessiblememonly nounwind }
2204 !0 = !{!"branch_weights", i32 1048576, i32 1}
2205 !1 = !{i32 1, i32 -2147483648}
2206 !2 = !{!"branch_weights", i32 1024, i32 1}