1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -indvars -S < %s | FileCheck %s
4 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5 target triple = "x86_64-unknown-linux-gnu"
7 ; General case: without extra knowledge, trunc cannot be eliminated.
8 define void @test_00(i64 %start, i32 %n) {
10 ; CHECK-LABEL: @test_00(
12 ; CHECK-NEXT: br label [[LOOP:%.*]]
14 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
15 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
16 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
17 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[NARROW_IV]], [[N:%.*]]
18 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
20 ; CHECK-NEXT: ret void
25 %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ]
26 %iv.next = add i64 %iv, 1
27 %narrow.iv = trunc i64 %iv to i32
28 %cmp = icmp slt i32 %narrow.iv, %n
29 br i1 %cmp, label %loop, label %exit
35 define void @test_01(i32 %n) {
37 ; CHECK-LABEL: @test_01(
39 ; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64
40 ; CHECK-NEXT: br label [[LOOP:%.*]]
42 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
43 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
44 ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]]
45 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
47 ; CHECK-NEXT: ret void
52 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
53 %iv.next = add i64 %iv, 1
54 %narrow.iv = trunc i64 %iv to i32
55 %cmp = icmp slt i32 %narrow.iv, %n
56 br i1 %cmp, label %loop, label %exit
61 ; Max value at which we can eliminate trunc: SINT_MAX - 1.
62 define void @test_02(i32 %n) {
64 ; CHECK-LABEL: @test_02(
66 ; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64
67 ; CHECK-NEXT: br label [[LOOP:%.*]]
69 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 2147483646, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
70 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
71 ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]]
72 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
74 ; CHECK-NEXT: ret void
79 %iv = phi i64 [ 2147483646, %entry ], [ %iv.next, %loop ]
80 %iv.next = add i64 %iv, 1
81 %narrow.iv = trunc i64 %iv to i32
82 %cmp = icmp slt i32 %narrow.iv, %n
83 br i1 %cmp, label %loop, label %exit
88 ; If we start from SINT_MAX then the predicate is always false.
89 define void @test_03(i32 %n) {
91 ; CHECK-LABEL: @test_03(
93 ; CHECK-NEXT: br label [[LOOP:%.*]]
95 ; CHECK-NEXT: br i1 false, label [[LOOP]], label [[EXIT:%.*]]
97 ; CHECK-NEXT: ret void
102 %iv = phi i64 [2147483647, %entry], [%iv.next, %loop]
103 %iv.next = add i64 %iv, 1
104 %narrow.iv = trunc i64 %iv to i32
105 %cmp = icmp slt i32 %narrow.iv, %n
106 br i1 %cmp, label %loop, label %exit
111 ; Minimum value at which we can apply the transform: SINT_MIN + 1.
112 define void @test_04(i32 %n) {
114 ; CHECK-LABEL: @test_04(
116 ; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64
117 ; CHECK-NEXT: br label [[LOOP:%.*]]
119 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -2147483647, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
120 ; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], 1
121 ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]]
122 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
124 ; CHECK-NEXT: ret void
129 %iv = phi i64 [ -2147483647, %entry ], [ %iv.next, %loop ]
130 %iv.next = add i64 %iv, 1
131 %narrow.iv = trunc i64 %iv to i32
132 %cmp = icmp slt i32 %narrow.iv, %n
133 br i1 %cmp, label %loop, label %exit
138 ; FIXME: Harmful LFTR should be thrown away.
139 define void @test_05(i32 %n) {
141 ; CHECK-LABEL: @test_05(
143 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 1
144 ; CHECK-NEXT: br label [[LOOP:%.*]]
146 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -2147483648, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
147 ; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], 1
148 ; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
149 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]]
150 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
152 ; CHECK-NEXT: ret void
157 %iv = phi i64 [ -2147483648, %entry ], [ %iv.next, %loop ]
158 %iv.next = add i64 %iv, 1
159 %narrow.iv = trunc i64 %iv to i32
160 %cmp = icmp slt i32 %narrow.iv, %n
161 br i1 %cmp, label %loop, label %exit
166 ; Trunc changes the actual value of the IV, so it is invalid to remove it: SINT_MIN - 1.
167 define void @test_06(i32 %n) {
169 ; CHECK-LABEL: @test_06(
171 ; CHECK-NEXT: br label [[LOOP:%.*]]
173 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -2147483649, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
174 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
175 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
176 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[NARROW_IV]], [[N:%.*]]
177 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
179 ; CHECK-NEXT: ret void
184 %iv = phi i64 [ -2147483649, %entry ], [ %iv.next, %loop ]
185 %iv.next = add i64 %iv, 1
186 %narrow.iv = trunc i64 %iv to i32
187 %cmp = icmp slt i32 %narrow.iv, %n
188 br i1 %cmp, label %loop, label %exit
193 ; General case: without extra knowledge, trunc cannot be eliminated.
194 define void @test_00_unsigned(i64 %start, i32 %n) {
195 ; CHECK-LABEL: @test_00_unsigned(
197 ; CHECK-NEXT: br label [[LOOP:%.*]]
199 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
200 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
201 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
202 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[NARROW_IV]], [[N:%.*]]
203 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
205 ; CHECK-NEXT: ret void
210 %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ]
211 %iv.next = add i64 %iv, 1
212 %narrow.iv = trunc i64 %iv to i32
213 %cmp = icmp ult i32 %narrow.iv, %n
214 br i1 %cmp, label %loop, label %exit
219 ; FIXME: Harmful LFTR should be thrown away.
220 define void @test_01_unsigned(i32 %n) {
221 ; CHECK-LABEL: @test_01_unsigned(
223 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 1
224 ; CHECK-NEXT: br label [[LOOP:%.*]]
226 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
227 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
228 ; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
229 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]]
230 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
232 ; CHECK-NEXT: ret void
237 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
238 %iv.next = add i64 %iv, 1
239 %narrow.iv = trunc i64 %iv to i32
240 %cmp = icmp ult i32 %narrow.iv, %n
241 br i1 %cmp, label %loop, label %exit
246 ; Max value at which we can eliminate trunc: UINT_MAX - 1.
247 define void @test_02_unsigned(i32 %n) {
248 ; CHECK-LABEL: @test_02_unsigned(
250 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64
251 ; CHECK-NEXT: br label [[LOOP:%.*]]
253 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 4294967294, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
254 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
255 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV]], [[ZEXT]]
256 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
258 ; CHECK-NEXT: ret void
263 %iv = phi i64 [ 4294967294, %entry ], [ %iv.next, %loop ]
264 %iv.next = add i64 %iv, 1
265 %narrow.iv = trunc i64 %iv to i32
266 %cmp = icmp ult i32 %narrow.iv, %n
267 br i1 %cmp, label %loop, label %exit
272 ; If we start from UINT_MAX then the predicate is always false.
273 define void @test_03_unsigned(i32 %n) {
274 ; CHECK-LABEL: @test_03_unsigned(
276 ; CHECK-NEXT: br label [[LOOP:%.*]]
278 ; CHECK-NEXT: br i1 false, label [[LOOP]], label [[EXIT:%.*]]
280 ; CHECK-NEXT: ret void
285 %iv = phi i64 [ 4294967295, %entry ], [ %iv.next, %loop ]
286 %iv.next = add i64 %iv, 1
287 %narrow.iv = trunc i64 %iv to i32
288 %cmp = icmp ult i32 %narrow.iv, %n
289 br i1 %cmp, label %loop, label %exit
294 ; Minimum value at which we can apply the transform: UINT_MIN.
295 define void @test_04_unsigned(i32 %n) {
296 ; CHECK-LABEL: @test_04_unsigned(
298 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 1
299 ; CHECK-NEXT: br label [[LOOP:%.*]]
301 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
302 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
303 ; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
304 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]]
305 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
307 ; CHECK-NEXT: ret void
312 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
313 %iv.next = add i64 %iv, 1
314 %narrow.iv = trunc i64 %iv to i32
315 %cmp = icmp ult i32 %narrow.iv, %n
316 br i1 %cmp, label %loop, label %exit
322 define void @test_05_unsigned(i32 %n) {
323 ; CHECK-LABEL: @test_05_unsigned(
325 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64
326 ; CHECK-NEXT: br label [[LOOP:%.*]]
328 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
329 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
330 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV]], [[ZEXT]]
331 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
333 ; CHECK-NEXT: ret void
338 %iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ]
339 %iv.next = add i64 %iv, 1
340 %narrow.iv = trunc i64 %iv to i32
341 %cmp = icmp ult i32 %narrow.iv, %n
342 br i1 %cmp, label %loop, label %exit
347 ; Trunc changes the actual value of the IV, so it is invalid to remove it: UINT_MIN - 1.
348 define void @test_06_unsigned(i32 %n) {
349 ; CHECK-LABEL: @test_06_unsigned(
351 ; CHECK-NEXT: br label [[LOOP:%.*]]
353 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
354 ; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], 1
355 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
356 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[NARROW_IV]], [[N:%.*]]
357 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
359 ; CHECK-NEXT: ret void
364 %iv = phi i64 [ -1, %entry ], [ %iv.next, %loop ]
365 %iv.next = add i64 %iv, 1
366 %narrow.iv = trunc i64 %iv to i32
367 %cmp = icmp ult i32 %narrow.iv, %n
368 br i1 %cmp, label %loop, label %exit
373 ; Do not eliminate trunc if it is used by something different from icmp.
374 define void @test_07(i32* %p, i32 %n) {
375 ; CHECK-LABEL: @test_07(
377 ; CHECK-NEXT: br label [[LOOP:%.*]]
379 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
380 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
381 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
382 ; CHECK-NEXT: store i32 [[NARROW_IV]], i32* [[P:%.*]]
383 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[NARROW_IV]], [[N:%.*]]
384 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
386 ; CHECK-NEXT: ret void
391 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
392 %iv.next = add i64 %iv, 1
393 %narrow.iv = trunc i64 %iv to i32
394 store i32 %narrow.iv, i32* %p
395 %cmp = icmp slt i32 %narrow.iv, %n
396 br i1 %cmp, label %loop, label %exit
401 ; Check that we can eliminate both signed and unsigned compare.
402 define void @test_08(i32 %n) {
403 ; CHECK-LABEL: @test_08(
405 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64
406 ; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N]] to i64
407 ; CHECK-NEXT: br label [[LOOP:%.*]]
409 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
410 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
411 ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]]
412 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IV]], [[ZEXT]]
413 ; CHECK-NEXT: [[CMP:%.*]] = and i1 [[TMP0]], [[TMP1]]
414 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
416 ; CHECK-NEXT: ret void
421 %iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ]
422 %iv.next = add i64 %iv, 1
423 %narrow.iv = trunc i64 %iv to i32
424 %cmp1 = icmp slt i32 %narrow.iv, %n
425 %cmp2 = icmp ult i32 %narrow.iv, %n
426 %cmp = and i1 %cmp1, %cmp2
427 br i1 %cmp, label %loop, label %exit
432 ; Widen NE as unsigned.
433 define void @test_09(i32 %n) {
434 ; CHECK-LABEL: @test_09(
436 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64
437 ; CHECK-NEXT: br label [[LOOP:%.*]]
439 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
440 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
441 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ne i64 [[IV]], [[ZEXT]]
442 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
444 ; CHECK-NEXT: ret void
449 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
450 %iv.next = add i64 %iv, 1
451 %narrow.iv = trunc i64 %iv to i32
452 %cmp = icmp ne i32 %narrow.iv, %n
453 br i1 %cmp, label %loop, label %exit
458 ; Widen NE as signed.
459 define void @test_10(i32 %n) {
460 ; CHECK-LABEL: @test_10(
462 ; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64
463 ; CHECK-NEXT: br label [[LOOP:%.*]]
465 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -100, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
466 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
467 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ne i64 [[IV]], [[SEXT]]
468 ; CHECK-NEXT: [[NEGCMP:%.*]] = icmp slt i64 [[IV]], -10
469 ; CHECK-NEXT: [[CMP:%.*]] = and i1 [[TMP0]], [[NEGCMP]]
470 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
472 ; CHECK-NEXT: ret void
477 %iv = phi i64 [ -100, %entry ], [ %iv.next, %loop ]
478 %iv.next = add i64 %iv, 1
479 %narrow.iv = trunc i64 %iv to i32
480 %trunccmp = icmp ne i32 %narrow.iv, %n
481 %negcmp = icmp slt i64 %iv, -10
482 %cmp = and i1 %trunccmp, %negcmp
483 br i1 %cmp, label %loop, label %exit
488 define void @test_11() {
489 ; CHECK-LABEL: @test_11(
490 ; CHECK-NEXT: br label [[BB1:%.*]]
492 ; CHECK-NEXT: br i1 undef, label [[BB2:%.*]], label [[BB6:%.*]]
494 ; CHECK-NEXT: br i1 undef, label [[BB3:%.*]], label [[BB4:%.*]]
496 ; CHECK-NEXT: br label [[BB4]]
498 ; CHECK-NEXT: br label [[BB6]]
500 ; CHECK-NEXT: [[_TMP24:%.*]] = icmp slt i16 undef, 0
501 ; CHECK-NEXT: br i1 [[_TMP24]], label [[BB5:%.*]], label [[BB5]]
503 ; CHECK-NEXT: br i1 false, label [[BB1]], label [[BB7:%.*]]
505 ; CHECK-NEXT: ret void
509 bb1: ; preds = %bb6, %0
510 %e.5.0 = phi i32 [ 0, %0 ], [ %_tmp32, %bb6 ]
511 br i1 undef, label %bb2, label %bb6
514 %_tmp15 = trunc i32 %e.5.0 to i16
515 br i1 undef, label %bb3, label %bb4
520 bb4: ; preds = %bb3, %bb2
523 bb5: ; preds = %bb5, %bb5
524 %_tmp24 = icmp slt i16 %_tmp15, 0
525 br i1 %_tmp24, label %bb5, label %bb5
527 bb6: ; preds = %bb4, %bb1
528 %_tmp32 = add nuw nsw i32 %e.5.0, 1
529 br i1 false, label %bb1, label %bb7
535 ; Show that we can turn signed comparison to unsigned and use zext while
536 ; comparing non-negative values.
537 define void @test_12(i32* %p) {
538 ; CHECK-LABEL: @test_12(
540 ; CHECK-NEXT: [[N:%.*]] = load i32, i32* [[P:%.*]], !range !0
541 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N]] to i64
542 ; CHECK-NEXT: br label [[LOOP:%.*]]
544 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
545 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
546 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV_NEXT]], [[ZEXT]]
547 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
549 ; CHECK-NEXT: ret void
552 %n = load i32, i32* %p, !range !0
555 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
556 %iv.next = add i64 %iv, 1
557 %narrow.iv = trunc i64 %iv.next to i32
558 %cmp = icmp slt i32 %narrow.iv, %n
559 br i1 %cmp, label %loop, label %exit
564 !0 = !{i32 0, i32 1000}