1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=indvars -S | FileCheck %s
5 declare i32 @llvm.smax.i32(i32, i32)
7 ; FIXME: In all tests in this file, signed_cond is equivalent to unsigned_cond, and therefore
8 ; one of the checks in the inner loop can be removed. The key to proving it is to prove that
9 ; %iv starts from something that is non-negative and only goes up. The positivity of its start
10 ; follows from the fact that %outer.iv also starts from somethign non-negative and only goes
11 ; up or remains same between iterations.
12 define i32 @test_01(i32 %a, i32 %b) {
13 ; CHECK-LABEL: @test_01(
15 ; CHECK-NEXT: [[B_IS_NON_NEGATIVE:%.*]] = icmp sge i32 [[B:%.*]], 0
16 ; CHECK-NEXT: br i1 [[B_IS_NON_NEGATIVE]], label [[OUTER_PREHEADER:%.*]], label [[FAILURE:%.*]]
17 ; CHECK: outer.preheader:
18 ; CHECK-NEXT: br label [[OUTER:%.*]]
20 ; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ], [ 0, [[OUTER_PREHEADER]] ]
21 ; CHECK-NEXT: br label [[INNER:%.*]]
23 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
24 ; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
25 ; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
27 ; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]]
28 ; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
29 ; CHECK: inner.backedge:
30 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
31 ; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond()
32 ; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
33 ; CHECK: outer.backedge:
34 ; CHECK-NEXT: [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
35 ; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
36 ; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
38 ; CHECK-NEXT: unreachable
40 ; CHECK-NEXT: ret i32 0
42 ; CHECK-NEXT: ret i32 1
45 %b_is_non_negative = icmp sge i32 %b, 0
46 br i1 %b_is_non_negative, label %outer, label %failure
49 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge]
54 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
55 %signed_cond = icmp slt i32 %iv, %b
56 br i1 %signed_cond, label %inner.1, label %side.exit
59 %unsigned_cond = icmp ult i32 %iv, %b
60 br i1 %unsigned_cond, label %inner.backedge, label %side.exit
63 %iv.next = add nuw nsw i32 %iv, 1
64 %inner.loop.cond = call i1 @cond()
65 br i1 %inner.loop.cond, label %inner, label %outer.backedge
68 %outer.loop.cond = call i1 @cond()
69 br i1 %outer.loop.cond, label %outer, label %exit
81 ; FIXME: iv <u b, b >=s 0 --> iv <s b. We should be able to remove the 2nd check.
82 define i32 @test_01a(i32 %a, i32 %b) {
83 ; CHECK-LABEL: @test_01a(
85 ; CHECK-NEXT: [[B_IS_NON_NEGATIVE:%.*]] = icmp sge i32 [[B:%.*]], 0
86 ; CHECK-NEXT: br i1 [[B_IS_NON_NEGATIVE]], label [[OUTER_PREHEADER:%.*]], label [[FAILURE:%.*]]
87 ; CHECK: outer.preheader:
88 ; CHECK-NEXT: br label [[OUTER:%.*]]
90 ; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ], [ 0, [[OUTER_PREHEADER]] ]
91 ; CHECK-NEXT: br label [[INNER:%.*]]
93 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
94 ; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]]
95 ; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
97 ; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
98 ; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
99 ; CHECK: inner.backedge:
100 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
101 ; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond()
102 ; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
103 ; CHECK: outer.backedge:
104 ; CHECK-NEXT: [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
105 ; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
106 ; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
108 ; CHECK-NEXT: unreachable
110 ; CHECK-NEXT: ret i32 0
112 ; CHECK-NEXT: ret i32 1
115 %b_is_non_negative = icmp sge i32 %b, 0
116 br i1 %b_is_non_negative, label %outer, label %failure
119 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge]
124 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
125 %signed_cond = icmp ult i32 %iv, %b
126 br i1 %signed_cond, label %inner.1, label %side.exit
129 %unsigned_cond = icmp slt i32 %iv, %b
130 br i1 %unsigned_cond, label %inner.backedge, label %side.exit
133 %iv.next = add nuw nsw i32 %iv, 1
134 %inner.loop.cond = call i1 @cond()
135 br i1 %inner.loop.cond, label %inner, label %outer.backedge
138 %outer.loop.cond = call i1 @cond()
139 br i1 %outer.loop.cond, label %outer, label %exit
151 define i32 @test_02(i32 %a, i32 %b) {
152 ; CHECK-LABEL: @test_02(
154 ; CHECK-NEXT: [[B_IS_NON_NEGATIVE:%.*]] = icmp sge i32 [[B:%.*]], 0
155 ; CHECK-NEXT: br i1 [[B_IS_NON_NEGATIVE]], label [[OUTER_PREHEADER:%.*]], label [[FAILURE:%.*]]
156 ; CHECK: outer.preheader:
157 ; CHECK-NEXT: br label [[OUTER:%.*]]
159 ; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ [[OUTER_MERGE:%.*]], [[OUTER_BACKEDGE:%.*]] ], [ 0, [[OUTER_PREHEADER]] ]
160 ; CHECK-NEXT: br label [[INNER:%.*]]
162 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
163 ; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
164 ; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
166 ; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]]
167 ; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
168 ; CHECK: inner.backedge:
169 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
170 ; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond()
171 ; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
172 ; CHECK: outer.backedge:
173 ; CHECK-NEXT: [[OUTER_MERGE]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
174 ; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
175 ; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
177 ; CHECK-NEXT: unreachable
179 ; CHECK-NEXT: ret i32 0
181 ; CHECK-NEXT: ret i32 1
184 %b_is_non_negative = icmp sge i32 %b, 0
185 br i1 %b_is_non_negative, label %outer, label %failure
188 %outer.iv = phi i32 [0, %entry], [%outer.merge, %outer.backedge]
193 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
194 %signed_cond = icmp slt i32 %iv, %b
195 br i1 %signed_cond, label %inner.1, label %side.exit
198 %unsigned_cond = icmp ult i32 %iv, %b
199 br i1 %unsigned_cond, label %inner.backedge, label %side.exit
202 %iv.next = add nuw nsw i32 %iv, 1
203 %inner.loop.cond = call i1 @cond()
204 br i1 %inner.loop.cond, label %inner, label %outer.backedge
207 %outer.merge = phi i32 [%iv.next, %inner.backedge]
208 %outer.loop.cond = call i1 @cond()
209 br i1 %outer.loop.cond, label %outer, label %exit
221 define i32 @test_03(i32 %a, i32 %b) {
222 ; CHECK-LABEL: @test_03(
224 ; CHECK-NEXT: [[B_IS_NON_NEGATIVE:%.*]] = icmp sge i32 [[B:%.*]], 0
225 ; CHECK-NEXT: br i1 [[B_IS_NON_NEGATIVE]], label [[OUTER_PREHEADER:%.*]], label [[FAILURE:%.*]]
226 ; CHECK: outer.preheader:
227 ; CHECK-NEXT: br label [[OUTER:%.*]]
229 ; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ [[OUTER_MERGE:%.*]], [[OUTER_BACKEDGE:%.*]] ], [ 0, [[OUTER_PREHEADER]] ]
230 ; CHECK-NEXT: [[OUTER_COND_1:%.*]] = call i1 @cond()
231 ; CHECK-NEXT: br i1 [[OUTER_COND_1]], label [[INNER_PREHEADER:%.*]], label [[NO_INNER:%.*]]
232 ; CHECK: inner.preheader:
233 ; CHECK-NEXT: br label [[INNER:%.*]]
235 ; CHECK-NEXT: [[OUTER_COND_2:%.*]] = call i1 @cond()
236 ; CHECK-NEXT: br label [[OUTER_BACKEDGE]]
238 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ], [ [[OUTER_IV]], [[INNER_PREHEADER]] ]
239 ; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
240 ; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
242 ; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]]
243 ; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
244 ; CHECK: inner.backedge:
245 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
246 ; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond()
247 ; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE_LOOPEXIT:%.*]]
248 ; CHECK: outer.backedge.loopexit:
249 ; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
250 ; CHECK-NEXT: br label [[OUTER_BACKEDGE]]
251 ; CHECK: outer.backedge:
252 ; CHECK-NEXT: [[OUTER_MERGE]] = phi i32 [ [[OUTER_IV]], [[NO_INNER]] ], [ [[IV_NEXT_LCSSA]], [[OUTER_BACKEDGE_LOOPEXIT]] ]
253 ; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
254 ; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
256 ; CHECK-NEXT: unreachable
258 ; CHECK-NEXT: ret i32 0
260 ; CHECK-NEXT: ret i32 1
263 %b_is_non_negative = icmp sge i32 %b, 0
264 br i1 %b_is_non_negative, label %outer, label %failure
267 %outer.iv = phi i32 [0, %entry], [%outer.merge, %outer.backedge]
268 %outer_cond_1 = call i1 @cond()
269 br i1 %outer_cond_1, label %inner, label %no_inner
272 %outer_cond_2 = call i1 @cond()
273 br label %outer.backedge
276 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
277 %signed_cond = icmp slt i32 %iv, %b
278 br i1 %signed_cond, label %inner.1, label %side.exit
281 %unsigned_cond = icmp ult i32 %iv, %b
282 br i1 %unsigned_cond, label %inner.backedge, label %side.exit
285 %iv.next = add nuw nsw i32 %iv, 1
286 %inner.loop.cond = call i1 @cond()
287 br i1 %inner.loop.cond, label %inner, label %outer.backedge
290 %outer.merge = phi i32 [%outer.iv, %no_inner], [%iv.next, %inner.backedge]
291 %outer.loop.cond = call i1 @cond()
292 br i1 %outer.loop.cond, label %outer, label %exit
304 define i32 @test_04(i32 %a, i32 %b) {
305 ; CHECK-LABEL: @test_04(
307 ; CHECK-NEXT: [[B_IS_NON_NEGATIVE:%.*]] = icmp sge i32 [[B:%.*]], 0
308 ; CHECK-NEXT: br i1 [[B_IS_NON_NEGATIVE]], label [[OUTER_PREHEADER:%.*]], label [[FAILURE:%.*]]
309 ; CHECK: outer.preheader:
310 ; CHECK-NEXT: br label [[OUTER:%.*]]
312 ; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ [[OUTER_MERGE:%.*]], [[OUTER_BACKEDGE:%.*]] ], [ 0, [[OUTER_PREHEADER]] ]
313 ; CHECK-NEXT: [[OUTER_COND_1:%.*]] = call i1 @cond()
314 ; CHECK-NEXT: br i1 [[OUTER_COND_1]], label [[INNER_PREHEADER:%.*]], label [[NO_INNER:%.*]]
315 ; CHECK: inner.preheader:
316 ; CHECK-NEXT: br label [[INNER:%.*]]
318 ; CHECK-NEXT: [[OUTER_COND_2:%.*]] = call i1 @cond()
319 ; CHECK-NEXT: br i1 [[OUTER_COND_2]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
321 ; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[A:%.*]], i32 [[OUTER_IV]])
322 ; CHECK-NEXT: br label [[OUTER_BACKEDGE]]
324 ; CHECK-NEXT: br label [[OUTER_BACKEDGE]]
326 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ], [ [[OUTER_IV]], [[INNER_PREHEADER]] ]
327 ; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
328 ; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
330 ; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]]
331 ; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
332 ; CHECK: inner.backedge:
333 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
334 ; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond()
335 ; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE_LOOPEXIT:%.*]]
336 ; CHECK: outer.backedge.loopexit:
337 ; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
338 ; CHECK-NEXT: br label [[OUTER_BACKEDGE]]
339 ; CHECK: outer.backedge:
340 ; CHECK-NEXT: [[OUTER_MERGE]] = phi i32 [ [[SMAX]], [[IF_TRUE]] ], [ [[OUTER_IV]], [[IF_FALSE]] ], [ [[IV_NEXT_LCSSA]], [[OUTER_BACKEDGE_LOOPEXIT]] ]
341 ; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
342 ; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
344 ; CHECK-NEXT: unreachable
346 ; CHECK-NEXT: ret i32 0
348 ; CHECK-NEXT: ret i32 1
351 %b_is_non_negative = icmp sge i32 %b, 0
352 br i1 %b_is_non_negative, label %outer, label %failure
355 %outer.iv = phi i32 [0, %entry], [%outer.merge, %outer.backedge]
356 %outer_cond_1 = call i1 @cond()
357 br i1 %outer_cond_1, label %inner, label %no_inner
360 %outer_cond_2 = call i1 @cond()
361 br i1 %outer_cond_2, label %if.true, label %if.false
364 %smax = call i32 @llvm.smax.i32(i32 %a, i32 %outer.iv)
365 br label %outer.backedge
368 br label %outer.backedge
371 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
372 %signed_cond = icmp slt i32 %iv, %b
373 br i1 %signed_cond, label %inner.1, label %side.exit
376 %unsigned_cond = icmp ult i32 %iv, %b
377 br i1 %unsigned_cond, label %inner.backedge, label %side.exit
380 %iv.next = add nuw nsw i32 %iv, 1
381 %inner.loop.cond = call i1 @cond()
382 br i1 %inner.loop.cond, label %inner, label %outer.backedge
385 %outer.merge = phi i32 [%smax, %if.true], [%outer.iv, %if.false], [%iv.next, %inner.backedge]
386 %outer.loop.cond = call i1 @cond()
387 br i1 %outer.loop.cond, label %outer, label %exit
399 ; Same as test_01, but non-negativity of %b is known without context.
400 ; FIXME: We can remove 2nd check in loop.
401 define i32 @test_05(i32 %a, ptr %bp) {
402 ; CHECK-LABEL: @test_05(
404 ; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0:![0-9]+]]
405 ; CHECK-NEXT: br label [[OUTER:%.*]]
407 ; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ]
408 ; CHECK-NEXT: br label [[INNER:%.*]]
410 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
411 ; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
412 ; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
414 ; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[B]]
415 ; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
416 ; CHECK: inner.backedge:
417 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
418 ; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond()
419 ; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
420 ; CHECK: outer.backedge:
421 ; CHECK-NEXT: [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
422 ; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
423 ; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
425 ; CHECK-NEXT: ret i32 0
427 ; CHECK-NEXT: ret i32 1
430 %b = load i32, ptr %bp, !range !0
434 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge]
439 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
440 %signed_cond = icmp slt i32 %iv, %b
441 br i1 %signed_cond, label %inner.1, label %side.exit
444 %unsigned_cond = icmp ult i32 %iv, %b
445 br i1 %unsigned_cond, label %inner.backedge, label %side.exit
448 %iv.next = add nuw nsw i32 %iv, 1
449 %inner.loop.cond = call i1 @cond()
450 br i1 %inner.loop.cond, label %inner, label %outer.backedge
453 %outer.loop.cond = call i1 @cond()
454 br i1 %outer.loop.cond, label %outer, label %exit
464 ; Same as test_01a, but non-negativity of %b is known without context.
465 define i32 @test_05a(i32 %a, ptr %bp) {
466 ; CHECK-LABEL: @test_05a(
468 ; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0]]
469 ; CHECK-NEXT: br label [[OUTER:%.*]]
471 ; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ]
472 ; CHECK-NEXT: br label [[INNER:%.*]]
474 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
475 ; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]]
476 ; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
478 ; CHECK-NEXT: br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
479 ; CHECK: inner.backedge:
480 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
481 ; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond()
482 ; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
483 ; CHECK: outer.backedge:
484 ; CHECK-NEXT: [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
485 ; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
486 ; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
488 ; CHECK-NEXT: ret i32 0
490 ; CHECK-NEXT: ret i32 1
493 %b = load i32, ptr %bp, !range !0
497 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge]
502 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
503 %unsigned_cond = icmp ult i32 %iv, %b
504 br i1 %unsigned_cond, label %inner.1, label %side.exit
507 %signed_cond = icmp slt i32 %iv, %b
508 br i1 %signed_cond, label %inner.backedge, label %side.exit
511 %iv.next = add nuw nsw i32 %iv, 1
512 %inner.loop.cond = call i1 @cond()
513 br i1 %inner.loop.cond, label %inner, label %outer.backedge
516 %outer.loop.cond = call i1 @cond()
517 br i1 %outer.loop.cond, label %outer, label %exit
526 ; Similar to test_05a, but inverted 2nd condition.
527 define i32 @test_05b(i32 %a, ptr %bp) {
528 ; CHECK-LABEL: @test_05b(
530 ; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0]]
531 ; CHECK-NEXT: br label [[OUTER:%.*]]
533 ; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ]
534 ; CHECK-NEXT: br label [[INNER:%.*]]
536 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
537 ; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]]
538 ; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
540 ; CHECK-NEXT: br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
541 ; CHECK: inner.backedge:
542 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
543 ; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond()
544 ; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
545 ; CHECK: outer.backedge:
546 ; CHECK-NEXT: [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
547 ; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
548 ; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
550 ; CHECK-NEXT: ret i32 0
552 ; CHECK-NEXT: ret i32 1
555 %b = load i32, ptr %bp, !range !0
559 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge]
564 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
565 %unsigned_cond = icmp ult i32 %iv, %b
566 br i1 %unsigned_cond, label %inner.1, label %side.exit
569 %signed_cond = icmp sgt i32 %b, %iv
570 br i1 %signed_cond, label %inner.backedge, label %side.exit
573 %iv.next = add nuw nsw i32 %iv, 1
574 %inner.loop.cond = call i1 @cond()
575 br i1 %inner.loop.cond, label %inner, label %outer.backedge
578 %outer.loop.cond = call i1 @cond()
579 br i1 %outer.loop.cond, label %outer, label %exit
588 ; We should prove implication: iv <s b, b <s 0 => iv <u b.
589 define i32 @test_05c(i32 %a, ptr %bp) {
590 ; CHECK-LABEL: @test_05c(
592 ; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG1:![0-9]+]]
593 ; CHECK-NEXT: br label [[OUTER:%.*]]
595 ; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ]
596 ; CHECK-NEXT: br label [[INNER:%.*]]
598 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
599 ; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
600 ; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
602 ; CHECK-NEXT: br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
603 ; CHECK: inner.backedge:
604 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
605 ; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond()
606 ; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
607 ; CHECK: outer.backedge:
608 ; CHECK-NEXT: [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
609 ; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
610 ; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
612 ; CHECK-NEXT: ret i32 0
614 ; CHECK-NEXT: ret i32 1
617 %b = load i32, ptr %bp, !range !1
621 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge]
626 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
627 %signed_cond = icmp slt i32 %iv, %b
628 br i1 %signed_cond, label %inner.1, label %side.exit
631 %unsigned_cond = icmp ult i32 %iv, %b
632 br i1 %unsigned_cond, label %inner.backedge, label %side.exit
635 %iv.next = add nuw nsw i32 %iv, 1
636 %inner.loop.cond = call i1 @cond()
637 br i1 %inner.loop.cond, label %inner, label %outer.backedge
640 %outer.loop.cond = call i1 @cond()
641 br i1 %outer.loop.cond, label %outer, label %exit
650 ; Same as test_05c, but 2nd condition reversed.
651 define i32 @test_05d(i32 %a, ptr %bp) {
652 ; CHECK-LABEL: @test_05d(
654 ; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG1]]
655 ; CHECK-NEXT: br label [[OUTER:%.*]]
657 ; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ]
658 ; CHECK-NEXT: br label [[INNER:%.*]]
660 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
661 ; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
662 ; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
664 ; CHECK-NEXT: br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
665 ; CHECK: inner.backedge:
666 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
667 ; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond()
668 ; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
669 ; CHECK: outer.backedge:
670 ; CHECK-NEXT: [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
671 ; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
672 ; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
674 ; CHECK-NEXT: ret i32 0
676 ; CHECK-NEXT: ret i32 1
679 %b = load i32, ptr %bp, !range !1
683 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge]
688 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
689 %signed_cond = icmp slt i32 %iv, %b
690 br i1 %signed_cond, label %inner.1, label %side.exit
693 %unsigned_cond = icmp ugt i32 %b, %iv
694 br i1 %unsigned_cond, label %inner.backedge, label %side.exit
697 %iv.next = add nuw nsw i32 %iv, 1
698 %inner.loop.cond = call i1 @cond()
699 br i1 %inner.loop.cond, label %inner, label %outer.backedge
702 %outer.loop.cond = call i1 @cond()
703 br i1 %outer.loop.cond, label %outer, label %exit
713 ; Same as test_05a, but 1st condition inverted.
714 define i32 @test_05e(i32 %a, ptr %bp) {
715 ; CHECK-LABEL: @test_05e(
717 ; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0]]
718 ; CHECK-NEXT: br label [[OUTER:%.*]]
720 ; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ]
721 ; CHECK-NEXT: br label [[INNER:%.*]]
723 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
724 ; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ugt i32 [[B]], [[IV]]
725 ; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
727 ; CHECK-NEXT: br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
728 ; CHECK: inner.backedge:
729 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
730 ; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond()
731 ; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
732 ; CHECK: outer.backedge:
733 ; CHECK-NEXT: [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
734 ; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
735 ; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
737 ; CHECK-NEXT: ret i32 0
739 ; CHECK-NEXT: ret i32 1
742 %b = load i32, ptr %bp, !range !0
746 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge]
751 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
752 %unsigned_cond = icmp ugt i32 %b, %iv
753 br i1 %unsigned_cond, label %inner.1, label %side.exit
756 %signed_cond = icmp slt i32 %iv, %b
757 br i1 %signed_cond, label %inner.backedge, label %side.exit
760 %iv.next = add nuw nsw i32 %iv, 1
761 %inner.loop.cond = call i1 @cond()
762 br i1 %inner.loop.cond, label %inner, label %outer.backedge
765 %outer.loop.cond = call i1 @cond()
766 br i1 %outer.loop.cond, label %outer, label %exit
775 ; Same as test_05b, but 1st condition inverted.
776 define i32 @test_05f(i32 %a, ptr %bp) {
777 ; CHECK-LABEL: @test_05f(
779 ; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0]]
780 ; CHECK-NEXT: br label [[OUTER:%.*]]
782 ; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ]
783 ; CHECK-NEXT: br label [[INNER:%.*]]
785 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
786 ; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ugt i32 [[B]], [[IV]]
787 ; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
789 ; CHECK-NEXT: br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
790 ; CHECK: inner.backedge:
791 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
792 ; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond()
793 ; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
794 ; CHECK: outer.backedge:
795 ; CHECK-NEXT: [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
796 ; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
797 ; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
799 ; CHECK-NEXT: ret i32 0
801 ; CHECK-NEXT: ret i32 1
804 %b = load i32, ptr %bp, !range !0
808 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge]
813 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
814 %unsigned_cond = icmp ugt i32 %b, %iv
815 br i1 %unsigned_cond, label %inner.1, label %side.exit
818 %signed_cond = icmp sgt i32 %b, %iv
819 br i1 %signed_cond, label %inner.backedge, label %side.exit
822 %iv.next = add nuw nsw i32 %iv, 1
823 %inner.loop.cond = call i1 @cond()
824 br i1 %inner.loop.cond, label %inner, label %outer.backedge
827 %outer.loop.cond = call i1 @cond()
828 br i1 %outer.loop.cond, label %outer, label %exit
837 ; Same as test_05c, but 1st condition inverted.
838 define i32 @test_05g(i32 %a, ptr %bp) {
839 ; CHECK-LABEL: @test_05g(
841 ; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG1]]
842 ; CHECK-NEXT: br label [[OUTER:%.*]]
844 ; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ]
845 ; CHECK-NEXT: br label [[INNER:%.*]]
847 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
848 ; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp sgt i32 [[B]], [[IV]]
849 ; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
851 ; CHECK-NEXT: br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
852 ; CHECK: inner.backedge:
853 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
854 ; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond()
855 ; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
856 ; CHECK: outer.backedge:
857 ; CHECK-NEXT: [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
858 ; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
859 ; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
861 ; CHECK-NEXT: ret i32 0
863 ; CHECK-NEXT: ret i32 1
866 %b = load i32, ptr %bp, !range !1
870 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge]
875 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
876 %signed_cond = icmp sgt i32 %b, %iv
877 br i1 %signed_cond, label %inner.1, label %side.exit
880 %unsigned_cond = icmp ult i32 %iv, %b
881 br i1 %unsigned_cond, label %inner.backedge, label %side.exit
884 %iv.next = add nuw nsw i32 %iv, 1
885 %inner.loop.cond = call i1 @cond()
886 br i1 %inner.loop.cond, label %inner, label %outer.backedge
889 %outer.loop.cond = call i1 @cond()
890 br i1 %outer.loop.cond, label %outer, label %exit
899 ; Same as test_05d, but 1st condition inverted.
900 define i32 @test_05h(i32 %a, ptr %bp) {
901 ; CHECK-LABEL: @test_05h(
903 ; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG1]]
904 ; CHECK-NEXT: br label [[OUTER:%.*]]
906 ; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA:%.*]], [[OUTER_BACKEDGE:%.*]] ]
907 ; CHECK-NEXT: br label [[INNER:%.*]]
909 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
910 ; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp sgt i32 [[B]], [[IV]]
911 ; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
913 ; CHECK-NEXT: br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
914 ; CHECK: inner.backedge:
915 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
916 ; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond()
917 ; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
918 ; CHECK: outer.backedge:
919 ; CHECK-NEXT: [[IV_NEXT_LCSSA]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
920 ; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
921 ; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
923 ; CHECK-NEXT: ret i32 0
925 ; CHECK-NEXT: ret i32 1
928 %b = load i32, ptr %bp, !range !1
932 %outer.iv = phi i32 [0, %entry], [%iv.next, %outer.backedge]
937 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
938 %signed_cond = icmp sgt i32 %b, %iv
939 br i1 %signed_cond, label %inner.1, label %side.exit
942 %unsigned_cond = icmp ugt i32 %b, %iv
943 br i1 %unsigned_cond, label %inner.backedge, label %side.exit
946 %iv.next = add nuw nsw i32 %iv, 1
947 %inner.loop.cond = call i1 @cond()
948 br i1 %inner.loop.cond, label %inner, label %outer.backedge
951 %outer.loop.cond = call i1 @cond()
952 br i1 %outer.loop.cond, label %outer, label %exit
961 ; Same as test_02, but non-negativity of %b is known without context.
962 ; FIXME: We can remove 2nd check in loop.
963 define i32 @test_06(i32 %a, ptr %bp) {
964 ; CHECK-LABEL: @test_06(
966 ; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0]]
967 ; CHECK-NEXT: br label [[OUTER:%.*]]
969 ; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[OUTER_MERGE:%.*]], [[OUTER_BACKEDGE:%.*]] ]
970 ; CHECK-NEXT: br label [[INNER:%.*]]
972 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[OUTER_IV]], [[OUTER]] ], [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ]
973 ; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
974 ; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
976 ; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[B]]
977 ; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
978 ; CHECK: inner.backedge:
979 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
980 ; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond()
981 ; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE]]
982 ; CHECK: outer.backedge:
983 ; CHECK-NEXT: [[OUTER_MERGE]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
984 ; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
985 ; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
987 ; CHECK-NEXT: ret i32 0
989 ; CHECK-NEXT: ret i32 1
992 %b = load i32, ptr %bp, !range !0
996 %outer.iv = phi i32 [0, %entry], [%outer.merge, %outer.backedge]
1001 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
1002 %signed_cond = icmp slt i32 %iv, %b
1003 br i1 %signed_cond, label %inner.1, label %side.exit
1006 %unsigned_cond = icmp ult i32 %iv, %b
1007 br i1 %unsigned_cond, label %inner.backedge, label %side.exit
1010 %iv.next = add nuw nsw i32 %iv, 1
1011 %inner.loop.cond = call i1 @cond()
1012 br i1 %inner.loop.cond, label %inner, label %outer.backedge
1015 %outer.merge = phi i32 [%iv.next, %inner.backedge]
1016 %outer.loop.cond = call i1 @cond()
1017 br i1 %outer.loop.cond, label %outer, label %exit
1026 ; Same as test_03, but non-negativity of %b is known without context.
1027 ; FIXME: We can remove 2nd check in loop.
1028 define i32 @test_07(i32 %a, ptr %bp) {
1029 ; CHECK-LABEL: @test_07(
1030 ; CHECK-NEXT: entry:
1031 ; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0]]
1032 ; CHECK-NEXT: br label [[OUTER:%.*]]
1034 ; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[OUTER_MERGE:%.*]], [[OUTER_BACKEDGE:%.*]] ]
1035 ; CHECK-NEXT: [[OUTER_COND_1:%.*]] = call i1 @cond()
1036 ; CHECK-NEXT: br i1 [[OUTER_COND_1]], label [[INNER_PREHEADER:%.*]], label [[NO_INNER:%.*]]
1037 ; CHECK: inner.preheader:
1038 ; CHECK-NEXT: br label [[INNER:%.*]]
1040 ; CHECK-NEXT: [[OUTER_COND_2:%.*]] = call i1 @cond()
1041 ; CHECK-NEXT: br label [[OUTER_BACKEDGE]]
1043 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ], [ [[OUTER_IV]], [[INNER_PREHEADER]] ]
1044 ; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
1045 ; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
1047 ; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[B]]
1048 ; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
1049 ; CHECK: inner.backedge:
1050 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
1051 ; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond()
1052 ; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE_LOOPEXIT:%.*]]
1053 ; CHECK: outer.backedge.loopexit:
1054 ; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
1055 ; CHECK-NEXT: br label [[OUTER_BACKEDGE]]
1056 ; CHECK: outer.backedge:
1057 ; CHECK-NEXT: [[OUTER_MERGE]] = phi i32 [ [[OUTER_IV]], [[NO_INNER]] ], [ [[IV_NEXT_LCSSA]], [[OUTER_BACKEDGE_LOOPEXIT]] ]
1058 ; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
1059 ; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
1061 ; CHECK-NEXT: ret i32 0
1063 ; CHECK-NEXT: ret i32 1
1066 %b = load i32, ptr %bp, !range !0
1070 %outer.iv = phi i32 [0, %entry], [%outer.merge, %outer.backedge]
1071 %outer_cond_1 = call i1 @cond()
1072 br i1 %outer_cond_1, label %inner, label %no_inner
1075 %outer_cond_2 = call i1 @cond()
1076 br label %outer.backedge
1079 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
1080 %signed_cond = icmp slt i32 %iv, %b
1081 br i1 %signed_cond, label %inner.1, label %side.exit
1084 %unsigned_cond = icmp ult i32 %iv, %b
1085 br i1 %unsigned_cond, label %inner.backedge, label %side.exit
1088 %iv.next = add nuw nsw i32 %iv, 1
1089 %inner.loop.cond = call i1 @cond()
1090 br i1 %inner.loop.cond, label %inner, label %outer.backedge
1093 %outer.merge = phi i32 [%outer.iv, %no_inner], [%iv.next, %inner.backedge]
1094 %outer.loop.cond = call i1 @cond()
1095 br i1 %outer.loop.cond, label %outer, label %exit
1104 ; Same as test_04, but non-negativity of %b is known without context.
1105 ; FIXME: We can remove 2nd check in loop.
1106 define i32 @test_08(i32 %a, ptr %bp) {
1107 ; CHECK-LABEL: @test_08(
1108 ; CHECK-NEXT: entry:
1109 ; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[BP:%.*]], align 4, !range [[RNG0]]
1110 ; CHECK-NEXT: br label [[OUTER:%.*]]
1112 ; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[OUTER_MERGE:%.*]], [[OUTER_BACKEDGE:%.*]] ]
1113 ; CHECK-NEXT: [[OUTER_COND_1:%.*]] = call i1 @cond()
1114 ; CHECK-NEXT: br i1 [[OUTER_COND_1]], label [[INNER_PREHEADER:%.*]], label [[NO_INNER:%.*]]
1115 ; CHECK: inner.preheader:
1116 ; CHECK-NEXT: br label [[INNER:%.*]]
1118 ; CHECK-NEXT: [[OUTER_COND_2:%.*]] = call i1 @cond()
1119 ; CHECK-NEXT: br i1 [[OUTER_COND_2]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1121 ; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[A:%.*]], i32 [[OUTER_IV]])
1122 ; CHECK-NEXT: br label [[OUTER_BACKEDGE]]
1124 ; CHECK-NEXT: br label [[OUTER_BACKEDGE]]
1126 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[INNER_BACKEDGE:%.*]] ], [ [[OUTER_IV]], [[INNER_PREHEADER]] ]
1127 ; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
1128 ; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
1130 ; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[B]]
1131 ; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
1132 ; CHECK: inner.backedge:
1133 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
1134 ; CHECK-NEXT: [[INNER_LOOP_COND:%.*]] = call i1 @cond()
1135 ; CHECK-NEXT: br i1 [[INNER_LOOP_COND]], label [[INNER]], label [[OUTER_BACKEDGE_LOOPEXIT:%.*]]
1136 ; CHECK: outer.backedge.loopexit:
1137 ; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[INNER_BACKEDGE]] ]
1138 ; CHECK-NEXT: br label [[OUTER_BACKEDGE]]
1139 ; CHECK: outer.backedge:
1140 ; CHECK-NEXT: [[OUTER_MERGE]] = phi i32 [ [[SMAX]], [[IF_TRUE]] ], [ [[OUTER_IV]], [[IF_FALSE]] ], [ [[IV_NEXT_LCSSA]], [[OUTER_BACKEDGE_LOOPEXIT]] ]
1141 ; CHECK-NEXT: [[OUTER_LOOP_COND:%.*]] = call i1 @cond()
1142 ; CHECK-NEXT: br i1 [[OUTER_LOOP_COND]], label [[OUTER]], label [[EXIT:%.*]]
1144 ; CHECK-NEXT: ret i32 0
1146 ; CHECK-NEXT: ret i32 1
1149 %b = load i32, ptr %bp, !range !0
1153 %outer.iv = phi i32 [0, %entry], [%outer.merge, %outer.backedge]
1154 %outer_cond_1 = call i1 @cond()
1155 br i1 %outer_cond_1, label %inner, label %no_inner
1158 %outer_cond_2 = call i1 @cond()
1159 br i1 %outer_cond_2, label %if.true, label %if.false
1162 %smax = call i32 @llvm.smax.i32(i32 %a, i32 %outer.iv)
1163 br label %outer.backedge
1166 br label %outer.backedge
1169 %iv = phi i32 [%outer.iv, %outer], [%iv.next, %inner.backedge]
1170 %signed_cond = icmp slt i32 %iv, %b
1171 br i1 %signed_cond, label %inner.1, label %side.exit
1174 %unsigned_cond = icmp ult i32 %iv, %b
1175 br i1 %unsigned_cond, label %inner.backedge, label %side.exit
1178 %iv.next = add nuw nsw i32 %iv, 1
1179 %inner.loop.cond = call i1 @cond()
1180 br i1 %inner.loop.cond, label %inner, label %outer.backedge
1183 %outer.merge = phi i32 [%smax, %if.true], [%outer.iv, %if.false], [%iv.next, %inner.backedge]
1184 %outer.loop.cond = call i1 @cond()
1185 br i1 %outer.loop.cond, label %outer, label %exit
1194 !0 = !{i32 0, i32 2147483647}
1195 !1 = !{i32 -2147483648, i32 0}