1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=indvars -indvars-predicate-loops=0 %s | FileCheck %s
3 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4 target triple = "x86_64-unknown-linux-gnu"
6 define void @test1(i64 %start) {
9 ; CHECK-NEXT: br label [[LOOP:%.*]]
11 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[START:%.*]], -1
12 ; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END:%.*]], label [[LOOP]]
14 ; CHECK-NEXT: ret void
20 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
21 %indvars.iv.next = add nsw i64 %indvars.iv, 1
22 %cmp1 = icmp slt i64 %indvars.iv, -1
23 br i1 %cmp1, label %for.end, label %loop
25 for.end: ; preds = %if.end, %entry
29 define void @test1.next(i64 %start) {
30 ; CHECK-LABEL: @test1.next(
32 ; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[START:%.*]], 1
33 ; CHECK-NEXT: br label [[LOOP:%.*]]
35 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[TMP0]], 0
36 ; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END:%.*]], label [[LOOP]]
38 ; CHECK-NEXT: ret void
44 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
45 %indvars.iv.next = add nsw i64 %indvars.iv, 1
46 %cmp1 = icmp slt i64 %indvars.iv.next, 0
47 br i1 %cmp1, label %for.end, label %loop
49 for.end: ; preds = %if.end, %entry
53 define void @test2(i64 %start) {
54 ; CHECK-LABEL: @test2(
56 ; CHECK-NEXT: br label [[LOOP:%.*]]
58 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sle i64 [[START:%.*]], -1
59 ; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END:%.*]], label [[LOOP]]
61 ; CHECK-NEXT: ret void
67 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
68 %indvars.iv.next = add nsw i64 %indvars.iv, 1
69 %cmp1 = icmp sle i64 %indvars.iv, -1
70 br i1 %cmp1, label %for.end, label %loop
72 for.end: ; preds = %if.end, %entry
76 define void @test2.next(i64 %start) {
77 ; CHECK-LABEL: @test2.next(
79 ; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[START:%.*]], 1
80 ; CHECK-NEXT: br label [[LOOP:%.*]]
82 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sle i64 [[TMP0]], 0
83 ; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END:%.*]], label [[LOOP]]
85 ; CHECK-NEXT: ret void
91 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
92 %indvars.iv.next = add nsw i64 %indvars.iv, 1
93 %cmp1 = icmp sle i64 %indvars.iv.next, 0
94 br i1 %cmp1, label %for.end, label %loop
96 for.end: ; preds = %if.end, %entry
100 ; As long as the test dominates the backedge, we're good
101 define void @test3(i64 %start) {
102 ; CHECK-LABEL: @test3(
104 ; CHECK-NEXT: br label [[LOOP:%.*]]
106 ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
107 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
108 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25
109 ; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]]
111 ; CHECK-NEXT: call void @foo()
112 ; CHECK-NEXT: br i1 false, label [[FOR_END]], label [[LOOP]]
114 ; CHECK-NEXT: ret void
120 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
121 %indvars.iv.next = add nsw i64 %indvars.iv, 1
122 %cmp = icmp eq i64 %indvars.iv.next, 25
123 br i1 %cmp, label %backedge, label %for.end
126 ; prevent flattening, needed to make sure we're testing what we intend
128 %cmp1 = icmp slt i64 %indvars.iv, -1
129 br i1 %cmp1, label %for.end, label %loop
131 for.end: ; preds = %if.end, %entry
135 define void @test3.next(i64 %start) {
136 ; CHECK-LABEL: @test3.next(
138 ; CHECK-NEXT: br label [[LOOP:%.*]]
140 ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
141 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
142 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25
143 ; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]]
145 ; CHECK-NEXT: call void @foo()
146 ; CHECK-NEXT: br i1 false, label [[FOR_END]], label [[LOOP]]
148 ; CHECK-NEXT: ret void
154 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
155 %indvars.iv.next = add nsw i64 %indvars.iv, 1
156 %cmp = icmp eq i64 %indvars.iv.next, 25
157 br i1 %cmp, label %backedge, label %for.end
160 ; prevent flattening, needed to make sure we're testing what we intend
162 %cmp1 = icmp slt i64 %indvars.iv.next, 0
163 br i1 %cmp1, label %for.end, label %loop
165 for.end: ; preds = %if.end, %entry
170 define void @test4(i64 %start) {
171 ; CHECK-LABEL: @test4(
173 ; CHECK-NEXT: br label [[LOOP:%.*]]
175 ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
176 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
177 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25
178 ; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]]
180 ; CHECK-NEXT: call void @foo()
181 ; CHECK-NEXT: br i1 true, label [[LOOP]], label [[FOR_END]]
183 ; CHECK-NEXT: ret void
189 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
190 %indvars.iv.next = add nsw i64 %indvars.iv, 1
191 %cmp = icmp eq i64 %indvars.iv.next, 25
192 br i1 %cmp, label %backedge, label %for.end
195 ; prevent flattening, needed to make sure we're testing what we intend
197 %cmp1 = icmp sgt i64 %indvars.iv, -1
198 br i1 %cmp1, label %loop, label %for.end
200 for.end: ; preds = %if.end, %entry
204 define void @test4.next(i64 %start) {
205 ; CHECK-LABEL: @test4.next(
207 ; CHECK-NEXT: br label [[LOOP:%.*]]
209 ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
210 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
211 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25
212 ; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]]
214 ; CHECK-NEXT: call void @foo()
215 ; CHECK-NEXT: br i1 true, label [[LOOP]], label [[FOR_END]]
217 ; CHECK-NEXT: ret void
223 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
224 %indvars.iv.next = add nsw i64 %indvars.iv, 1
225 %cmp = icmp eq i64 %indvars.iv.next, 25
226 br i1 %cmp, label %backedge, label %for.end
229 ; prevent flattening, needed to make sure we're testing what we intend
231 %cmp1 = icmp sgt i64 %indvars.iv.next, 0
232 br i1 %cmp1, label %loop, label %for.end
234 for.end: ; preds = %if.end, %entry
238 define void @test5(i64 %start) {
239 ; CHECK-LABEL: @test5(
241 ; CHECK-NEXT: br label [[LOOP:%.*]]
243 ; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nuw i64 [[START:%.*]], 1
244 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25
245 ; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE:%.*]], label [[FOR_END:%.*]]
247 ; CHECK-NEXT: call void @foo()
248 ; CHECK-NEXT: br i1 false, label [[LOOP]], label [[FOR_END]]
250 ; CHECK-NEXT: ret void
256 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
257 %indvars.iv.next = add nuw i64 %indvars.iv, 1
258 %cmp = icmp eq i64 %indvars.iv.next, 25
259 br i1 %cmp, label %backedge, label %for.end
262 ; prevent flattening, needed to make sure we're testing what we intend
264 %cmp1 = icmp ugt i64 %indvars.iv, 100
265 br i1 %cmp1, label %loop, label %for.end
267 for.end: ; preds = %if.end, %entry
271 define void @test5.next(i64 %start) {
272 ; CHECK-LABEL: @test5.next(
274 ; CHECK-NEXT: br label [[LOOP:%.*]]
276 ; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nuw i64 [[START:%.*]], 1
277 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25
278 ; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE:%.*]], label [[FOR_END:%.*]]
280 ; CHECK-NEXT: call void @foo()
281 ; CHECK-NEXT: br i1 false, label [[LOOP]], label [[FOR_END]]
283 ; CHECK-NEXT: ret void
289 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
290 %indvars.iv.next = add nuw i64 %indvars.iv, 1
291 %cmp = icmp eq i64 %indvars.iv.next, 25
292 br i1 %cmp, label %backedge, label %for.end
295 ; prevent flattening, needed to make sure we're testing what we intend
297 %cmp1 = icmp ugt i64 %indvars.iv.next, 101
298 br i1 %cmp1, label %loop, label %for.end
300 for.end: ; preds = %if.end, %entry
305 define void @test6(i64 %start) {
306 ; CHECK-LABEL: @test6(
308 ; CHECK-NEXT: br label [[LOOP:%.*]]
310 ; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nuw i64 [[START:%.*]], 1
311 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25
312 ; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE:%.*]], label [[FOR_END:%.*]]
314 ; CHECK-NEXT: call void @foo()
315 ; CHECK-NEXT: br i1 true, label [[FOR_END]], label [[LOOP]]
317 ; CHECK-NEXT: ret void
323 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
324 %indvars.iv.next = add nuw i64 %indvars.iv, 1
325 %cmp = icmp eq i64 %indvars.iv.next, 25
326 br i1 %cmp, label %backedge, label %for.end
329 ; prevent flattening, needed to make sure we're testing what we intend
331 %cmp1 = icmp ult i64 %indvars.iv, 100
332 br i1 %cmp1, label %for.end, label %loop
334 for.end: ; preds = %if.end, %entry
338 define void @test6.next(i64 %start) {
339 ; CHECK-LABEL: @test6.next(
341 ; CHECK-NEXT: br label [[LOOP:%.*]]
343 ; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nuw i64 [[START:%.*]], 1
344 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25
345 ; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE:%.*]], label [[FOR_END:%.*]]
347 ; CHECK-NEXT: call void @foo()
348 ; CHECK-NEXT: br i1 true, label [[FOR_END]], label [[LOOP]]
350 ; CHECK-NEXT: ret void
356 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
357 %indvars.iv.next = add nuw i64 %indvars.iv, 1
358 %cmp = icmp eq i64 %indvars.iv.next, 25
359 br i1 %cmp, label %backedge, label %for.end
362 ; prevent flattening, needed to make sure we're testing what we intend
364 %cmp1 = icmp ult i64 %indvars.iv.next, 101
365 br i1 %cmp1, label %for.end, label %loop
367 for.end: ; preds = %if.end, %entry
371 define void @test7(i64 %start, ptr %inc_ptr) {
372 ; CHECK-LABEL: @test7(
374 ; CHECK-NEXT: [[INC:%.*]] = load i64, ptr [[INC_PTR:%.*]], align 8, !range [[RNG0:![0-9]+]]
375 ; CHECK-NEXT: [[OK:%.*]] = icmp sge i64 [[INC]], 0
376 ; CHECK-NEXT: br i1 [[OK]], label [[LOOP_PREHEADER:%.*]], label [[FOR_END:%.*]]
377 ; CHECK: loop.preheader:
378 ; CHECK-NEXT: br label [[LOOP:%.*]]
380 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[START:%.*]], -1
381 ; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END_LOOPEXIT:%.*]], label [[LOOP]]
382 ; CHECK: for.end.loopexit:
383 ; CHECK-NEXT: br label [[FOR_END]]
385 ; CHECK-NEXT: ret void
388 %inc = load i64, ptr %inc_ptr, !range !0
389 %ok = icmp sge i64 %inc, 0
390 br i1 %ok, label %loop, label %for.end
393 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
394 %indvars.iv.next = add nsw i64 %indvars.iv, %inc
395 %cmp1 = icmp slt i64 %indvars.iv, -1
396 br i1 %cmp1, label %for.end, label %loop
398 for.end: ; preds = %if.end, %entry
402 define void @test7.next(i64 %start, ptr %inc_ptr) {
403 ; CHECK-LABEL: @test7.next(
405 ; CHECK-NEXT: [[INC:%.*]] = load i64, ptr [[INC_PTR:%.*]], align 8, !range [[RNG0]]
406 ; CHECK-NEXT: [[OK:%.*]] = icmp sge i64 [[INC]], 0
407 ; CHECK-NEXT: br i1 [[OK]], label [[LOOP_PREHEADER:%.*]], label [[FOR_END:%.*]]
408 ; CHECK: loop.preheader:
409 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INC]], [[START:%.*]]
410 ; CHECK-NEXT: br label [[LOOP:%.*]]
412 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[TMP0]], 0
413 ; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END_LOOPEXIT:%.*]], label [[LOOP]]
414 ; CHECK: for.end.loopexit:
415 ; CHECK-NEXT: br label [[FOR_END]]
417 ; CHECK-NEXT: ret void
420 %inc = load i64, ptr %inc_ptr, !range !0
421 %ok = icmp sge i64 %inc, 0
422 br i1 %ok, label %loop, label %for.end
425 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
426 %indvars.iv.next = add nsw i64 %indvars.iv, %inc
427 %cmp1 = icmp slt i64 %indvars.iv.next, 0
428 br i1 %cmp1, label %for.end, label %loop
430 for.end: ; preds = %if.end, %entry
434 ; Negative test - we can't show that the internal branch executes, so we can't
435 ; fold the test to a loop invariant one.
436 define void @test1_neg(i64 %start) {
437 ; CHECK-LABEL: @test1_neg(
439 ; CHECK-NEXT: br label [[LOOP:%.*]]
441 ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
442 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
443 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25
444 ; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[SKIP:%.*]]
446 ; CHECK-NEXT: call void @foo()
447 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[INDVARS_IV]], -1
448 ; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END:%.*]], label [[BACKEDGE]]
450 ; CHECK-NEXT: call void @foo()
451 ; CHECK-NEXT: br label [[LOOP]]
453 ; CHECK-NEXT: ret void
459 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
460 %indvars.iv.next = add nsw i64 %indvars.iv, 1
461 %cmp = icmp eq i64 %indvars.iv.next, 25
462 br i1 %cmp, label %backedge, label %skip
464 ; prevent flattening, needed to make sure we're testing what we intend
466 %cmp1 = icmp slt i64 %indvars.iv, -1
467 br i1 %cmp1, label %for.end, label %backedge
469 ; prevent flattening, needed to make sure we're testing what we intend
473 for.end: ; preds = %if.end, %entry
477 ; Slightly subtle version of @test4 where the icmp dominates the backedge,
478 ; but the exit branch doesn't.
479 define void @test2_neg(i64 %start) {
480 ; CHECK-LABEL: @test2_neg(
482 ; CHECK-NEXT: br label [[LOOP:%.*]]
484 ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
485 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
486 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25
487 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[INDVARS_IV]], -1
488 ; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[SKIP:%.*]]
490 ; CHECK-NEXT: call void @foo()
491 ; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END:%.*]], label [[BACKEDGE]]
493 ; CHECK-NEXT: call void @foo()
494 ; CHECK-NEXT: br label [[LOOP]]
496 ; CHECK-NEXT: ret void
502 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
503 %indvars.iv.next = add nsw i64 %indvars.iv, 1
504 %cmp = icmp eq i64 %indvars.iv.next, 25
505 %cmp1 = icmp slt i64 %indvars.iv, -1
506 br i1 %cmp, label %backedge, label %skip
508 ; prevent flattening, needed to make sure we're testing what we intend
510 br i1 %cmp1, label %for.end, label %backedge
512 ; prevent flattening, needed to make sure we're testing what we intend
516 for.end: ; preds = %if.end, %entry
520 ; The branch has to exit the loop if the condition is true
521 define void @test3_neg(i64 %start) {
522 ; CHECK-LABEL: @test3_neg(
524 ; CHECK-NEXT: br label [[LOOP:%.*]]
526 ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
527 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
528 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[INDVARS_IV]], -1
529 ; CHECK-NEXT: br i1 [[CMP1]], label [[LOOP]], label [[FOR_END:%.*]]
531 ; CHECK-NEXT: ret void
537 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
538 %indvars.iv.next = add nsw i64 %indvars.iv, 1
539 %cmp1 = icmp slt i64 %indvars.iv, -1
540 br i1 %cmp1, label %loop, label %for.end
542 for.end: ; preds = %if.end, %entry
546 define void @test4_neg(i64 %start) {
547 ; CHECK-LABEL: @test4_neg(
549 ; CHECK-NEXT: br label [[LOOP:%.*]]
551 ; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nsw i64 [[START:%.*]], 1
552 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25
553 ; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE:%.*]], label [[FOR_END:%.*]]
555 ; CHECK-NEXT: call void @foo()
556 ; CHECK-NEXT: br i1 true, label [[FOR_END]], label [[LOOP]]
558 ; CHECK-NEXT: ret void
564 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
565 %indvars.iv.next = add nsw i64 %indvars.iv, 1
566 %cmp = icmp eq i64 %indvars.iv.next, 25
567 br i1 %cmp, label %backedge, label %for.end
570 ; prevent flattening, needed to make sure we're testing what we intend
572 %cmp1 = icmp sgt i64 %indvars.iv, -1
574 ; %cmp1 can be made loop invariant only if the branch below goes to
575 ; %the header when %cmp1 is true.
576 br i1 %cmp1, label %for.end, label %loop
578 for.end: ; preds = %if.end, %entry
582 define void @test5_neg(i64 %start, i64 %inc) {
583 ; CHECK-LABEL: @test5_neg(
585 ; CHECK-NEXT: br label [[LOOP:%.*]]
587 ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
588 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], [[INC:%.*]]
589 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[INDVARS_IV]], -1
590 ; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END:%.*]], label [[LOOP]]
592 ; CHECK-NEXT: ret void
598 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
599 %indvars.iv.next = add nsw i64 %indvars.iv, %inc
600 %cmp1 = icmp slt i64 %indvars.iv, -1
601 br i1 %cmp1, label %for.end, label %loop
603 for.end: ; preds = %if.end, %entry
607 define void @test8(i64 %start, ptr %inc_ptr) {
608 ; CHECK-LABEL: @test8(
610 ; CHECK-NEXT: [[INC:%.*]] = load i64, ptr [[INC_PTR:%.*]], align 8, !range [[RNG1:![0-9]+]]
611 ; CHECK-NEXT: [[OK:%.*]] = icmp sge i64 [[INC]], 0
612 ; CHECK-NEXT: br i1 [[OK]], label [[LOOP_PREHEADER:%.*]], label [[FOR_END:%.*]]
613 ; CHECK: loop.preheader:
614 ; CHECK-NEXT: br label [[LOOP:%.*]]
616 ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ]
617 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], [[INC]]
618 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[INDVARS_IV]], -1
619 ; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END_LOOPEXIT:%.*]], label [[LOOP]]
620 ; CHECK: for.end.loopexit:
621 ; CHECK-NEXT: br label [[FOR_END]]
623 ; CHECK-NEXT: ret void
626 %inc = load i64, ptr %inc_ptr, !range !1
627 %ok = icmp sge i64 %inc, 0
628 br i1 %ok, label %loop, label %for.end
631 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
632 %indvars.iv.next = add nsw i64 %indvars.iv, %inc
633 %cmp1 = icmp slt i64 %indvars.iv, -1
634 br i1 %cmp1, label %for.end, label %loop
636 for.end: ; preds = %if.end, %entry
640 ; check to handle loops without preheaders, but invariant operands
641 ; (we handle this today by inserting a preheader)
642 define void @test9(i1 %cnd, i64 %start) {
643 ; CHECK-LABEL: @test9(
645 ; CHECK-NEXT: br i1 [[CND:%.*]], label [[ENTRY1:%.*]], label [[ENTRY2:%.*]]
647 ; CHECK-NEXT: br label [[LOOP_PREHEADER:%.*]]
649 ; CHECK-NEXT: br label [[LOOP_PREHEADER]]
650 ; CHECK: loop.preheader:
651 ; CHECK-NEXT: br label [[LOOP:%.*]]
653 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[START:%.*]], -1
654 ; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END:%.*]], label [[LOOP]]
656 ; CHECK-NEXT: ret void
659 br i1 %cnd, label %entry1, label %entry2
665 %indvars.iv = phi i64 [ %start, %entry1 ],[ %start, %entry2 ], [ %indvars.iv.next, %loop ]
666 %indvars.iv.next = add nsw i64 %indvars.iv, 1
667 %cmp1 = icmp slt i64 %indvars.iv, -1
668 br i1 %cmp1, label %for.end, label %loop
670 for.end: ; preds = %if.end, %entry
674 declare void @use(i1 %x)
676 ; check that we handle conditions with loop invariant operands which
677 ; *aren't* in the header - this is a very rare and fragile case where
678 ; we have a "loop" which is known to run exactly one iteration but
679 ; haven't yet simplified the uses of the IV
680 define void @test10() {
681 ; CHECK-LABEL: @test10(
683 ; CHECK-NEXT: br label [[LOOP:%.*]]
685 ; CHECK-NEXT: br i1 false, label [[LEFT:%.*]], label [[RIGHT:%.*]]
687 ; CHECK-NEXT: br label [[LATCH:%.*]]
689 ; CHECK-NEXT: br label [[LATCH]]
691 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 -1, undef
692 ; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[LOOP]]
694 ; CHECK-NEXT: [[CMP_LCSSA:%.*]] = phi i1 [ [[CMP]], [[LATCH]] ]
695 ; CHECK-NEXT: call void @use(i1 [[CMP_LCSSA]])
696 ; CHECK-NEXT: ret void
702 %phi1 = phi i32 [ %phi2, %latch ], [ 0, %entry ]
703 %dec = add i32 %phi1, -1
704 br i1 false, label %left, label %right
713 %phi2 = phi i32 [ %phi1, %left ], [ %dec, %right ]
714 %cmp = icmp slt i32 %phi2, undef
715 br i1 true, label %exit, label %loop
718 call void @use(i1 %cmp)
722 ; check that we can figure out that iv.next > 1 from the facts that iv >= 0 and
724 define void @test11(ptr %inc_ptr) {
725 ; CHECK-LABEL: @test11(
727 ; CHECK-NEXT: [[INC:%.*]] = load i64, ptr [[INC_PTR:%.*]], align 8, !range [[RNG0]]
728 ; CHECK-NEXT: [[NE_COND:%.*]] = icmp ne i64 [[INC]], 0
729 ; CHECK-NEXT: br i1 [[NE_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
730 ; CHECK: loop.preheader:
731 ; CHECK-NEXT: br label [[LOOP:%.*]]
733 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[INC]], [[LOOP_PREHEADER]] ]
734 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
735 ; CHECK-NEXT: br i1 true, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
737 ; CHECK-NEXT: br label [[BACKEDGE]]
739 ; CHECK-NEXT: br label [[BACKEDGE]]
741 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], 201
742 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
743 ; CHECK: exit.loopexit:
744 ; CHECK-NEXT: br label [[EXIT]]
746 ; CHECK-NEXT: ret void
749 %inc = load i64, ptr %inc_ptr, !range !0
750 %ne.cond = icmp ne i64 %inc, 0
751 br i1 %ne.cond, label %loop, label %exit
754 %iv = phi i64 [ %inc, %entry ], [ %iv.next, %backedge ]
755 %iv.next = add i64 %iv, 1
756 %brcond = icmp sgt i64 %iv.next, 1
757 br i1 %brcond, label %if.true, label %if.false
766 %loopcond = icmp slt i64 %iv, 200
767 br i1 %loopcond, label %loop, label %exit
773 ; check that we can prove that a recurrency is greater than another recurrency
774 ; in the same loop, with the same step, and with smaller starting value.
775 define void @test12(ptr %inc_ptr) {
776 ; CHECK-LABEL: @test12(
778 ; CHECK-NEXT: [[INC:%.*]] = load i64, ptr [[INC_PTR:%.*]], align 8, !range [[RNG0]]
779 ; CHECK-NEXT: br label [[LOOP:%.*]]
781 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
782 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
783 ; CHECK-NEXT: br i1 true, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
785 ; CHECK-NEXT: br label [[BACKEDGE]]
787 ; CHECK-NEXT: br label [[BACKEDGE]]
789 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], 201
790 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
792 ; CHECK-NEXT: ret void
795 %inc = load i64, ptr %inc_ptr, !range !0
796 %inc.minus.1 = sub i64 %inc, 1
800 %iv = phi i64 [ %inc, %entry ], [ %iv.next, %backedge ]
801 %iv.minus.1 = phi i64 [ %inc.minus.1, %entry ], [ %iv.minus.1.next, %backedge ]
802 %iv.next = add i64 %iv, 1
803 %iv.minus.1.next = add i64 %iv.minus.1, 1
804 %brcond = icmp sgt i64 %iv.next, %iv.minus.1.next
805 br i1 %brcond, label %if.true, label %if.false
814 %loopcond = icmp slt i64 %iv, 200
815 br i1 %loopcond, label %loop, label %exit
821 !0 = !{i64 0, i64 100}
822 !1 = !{i64 -1, i64 100}