1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=indvars -S -indvars-predicate-loops=0 < %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: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
40 ; CHECK-NEXT: [[TMP0:%.*]] = add nuw i32 [[SMAX]], 1
41 ; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP0]] to i64
42 ; CHECK-NEXT: br label [[LOOP:%.*]]
44 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
45 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
46 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[WIDE_TRIP_COUNT]]
47 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
49 ; CHECK-NEXT: ret void
54 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
55 %iv.next = add i64 %iv, 1
56 %narrow.iv = trunc i64 %iv to i32
57 %cmp = icmp slt i32 %narrow.iv, %n
58 br i1 %cmp, label %loop, label %exit
63 ; Max value at which we can eliminate trunc: SINT_MAX - 1.
64 define void @test_02(i32 %n) {
66 ; CHECK-LABEL: @test_02(
68 ; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 2147483646)
69 ; CHECK-NEXT: [[TMP0:%.*]] = add nuw i32 [[SMAX]], 1
70 ; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP0]] to i64
71 ; CHECK-NEXT: br label [[LOOP:%.*]]
73 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 2147483646, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
74 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
75 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[WIDE_TRIP_COUNT]]
76 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
78 ; CHECK-NEXT: ret void
83 %iv = phi i64 [ 2147483646, %entry ], [ %iv.next, %loop ]
84 %iv.next = add i64 %iv, 1
85 %narrow.iv = trunc i64 %iv to i32
86 %cmp = icmp slt i32 %narrow.iv, %n
87 br i1 %cmp, label %loop, label %exit
92 ; If we start from SINT_MAX then the predicate is always false.
93 define void @test_03(i32 %n) {
95 ; CHECK-LABEL: @test_03(
97 ; CHECK-NEXT: br label [[LOOP:%.*]]
99 ; CHECK-NEXT: br i1 false, label [[LOOP]], label [[EXIT:%.*]]
101 ; CHECK-NEXT: ret void
106 %iv = phi i64 [2147483647, %entry], [%iv.next, %loop]
107 %iv.next = add i64 %iv, 1
108 %narrow.iv = trunc i64 %iv to i32
109 %cmp = icmp slt i32 %narrow.iv, %n
110 br i1 %cmp, label %loop, label %exit
115 ; Minimum value at which we can apply the transform: SINT_MIN + 1.
116 define void @test_04(i32 %n) {
118 ; CHECK-LABEL: @test_04(
120 ; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 -2147483647)
121 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[SMAX]], 1
122 ; CHECK-NEXT: br label [[LOOP:%.*]]
124 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -2147483647, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
125 ; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], 1
126 ; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
127 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]]
128 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
130 ; CHECK-NEXT: ret void
135 %iv = phi i64 [ -2147483647, %entry ], [ %iv.next, %loop ]
136 %iv.next = add i64 %iv, 1
137 %narrow.iv = trunc i64 %iv to i32
138 %cmp = icmp slt i32 %narrow.iv, %n
139 br i1 %cmp, label %loop, label %exit
144 ; FIXME: Harmful LFTR should be thrown away.
145 define void @test_05(i32 %n) {
147 ; CHECK-LABEL: @test_05(
149 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 1
150 ; CHECK-NEXT: br label [[LOOP:%.*]]
152 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -2147483648, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
153 ; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], 1
154 ; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
155 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]]
156 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
158 ; CHECK-NEXT: ret void
163 %iv = phi i64 [ -2147483648, %entry ], [ %iv.next, %loop ]
164 %iv.next = add i64 %iv, 1
165 %narrow.iv = trunc i64 %iv to i32
166 %cmp = icmp slt i32 %narrow.iv, %n
167 br i1 %cmp, label %loop, label %exit
172 ; Trunc changes the actual value of the IV, so it is invalid to remove it: SINT_MIN - 1.
173 define void @test_06(i32 %n) {
175 ; CHECK-LABEL: @test_06(
177 ; CHECK-NEXT: br label [[LOOP:%.*]]
179 ; CHECK-NEXT: br i1 false, label [[LOOP]], label [[EXIT:%.*]]
181 ; CHECK-NEXT: ret void
186 %iv = phi i64 [ -2147483649, %entry ], [ %iv.next, %loop ]
187 %iv.next = add i64 %iv, 1
188 %narrow.iv = trunc i64 %iv to i32
189 %cmp = icmp slt i32 %narrow.iv, %n
190 br i1 %cmp, label %loop, label %exit
195 ; General case: without extra knowledge, trunc cannot be eliminated.
196 define void @test_00_unsigned(i64 %start, i32 %n) {
197 ; CHECK-LABEL: @test_00_unsigned(
199 ; CHECK-NEXT: br label [[LOOP:%.*]]
201 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
202 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
203 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
204 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[NARROW_IV]], [[N:%.*]]
205 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
207 ; CHECK-NEXT: ret void
212 %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ]
213 %iv.next = add i64 %iv, 1
214 %narrow.iv = trunc i64 %iv to i32
215 %cmp = icmp ult i32 %narrow.iv, %n
216 br i1 %cmp, label %loop, label %exit
221 ; FIXME: Harmful LFTR should be thrown away.
222 define void @test_01_unsigned(i32 %n) {
223 ; CHECK-LABEL: @test_01_unsigned(
225 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 1
226 ; CHECK-NEXT: br label [[LOOP:%.*]]
228 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
229 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
230 ; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
231 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]]
232 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
234 ; CHECK-NEXT: ret void
239 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
240 %iv.next = add i64 %iv, 1
241 %narrow.iv = trunc i64 %iv to i32
242 %cmp = icmp ult i32 %narrow.iv, %n
243 br i1 %cmp, label %loop, label %exit
248 ; Max value at which we can eliminate trunc: UINT_MAX - 1.
249 define void @test_02_unsigned(i32 %n) {
250 ; CHECK-LABEL: @test_02_unsigned(
252 ; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 -2)
253 ; CHECK-NEXT: [[TMP0:%.*]] = add nsw i32 [[UMAX]], 1
254 ; CHECK-NEXT: br label [[LOOP:%.*]]
256 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 4294967294, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
257 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
258 ; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
259 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]]
260 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
262 ; CHECK-NEXT: ret void
267 %iv = phi i64 [ 4294967294, %entry ], [ %iv.next, %loop ]
268 %iv.next = add i64 %iv, 1
269 %narrow.iv = trunc i64 %iv to i32
270 %cmp = icmp ult i32 %narrow.iv, %n
271 br i1 %cmp, label %loop, label %exit
276 ; If we start from UINT_MAX then the predicate is always false.
277 define void @test_03_unsigned(i32 %n) {
278 ; CHECK-LABEL: @test_03_unsigned(
280 ; CHECK-NEXT: br label [[LOOP:%.*]]
282 ; CHECK-NEXT: br i1 false, label [[LOOP]], label [[EXIT:%.*]]
284 ; CHECK-NEXT: ret void
289 %iv = phi i64 [ 4294967295, %entry ], [ %iv.next, %loop ]
290 %iv.next = add i64 %iv, 1
291 %narrow.iv = trunc i64 %iv to i32
292 %cmp = icmp ult i32 %narrow.iv, %n
293 br i1 %cmp, label %loop, label %exit
298 ; Minimum value at which we can apply the transform: UINT_MIN.
299 define void @test_04_unsigned(i32 %n) {
300 ; CHECK-LABEL: @test_04_unsigned(
302 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 1
303 ; CHECK-NEXT: br label [[LOOP:%.*]]
305 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
306 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
307 ; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
308 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]]
309 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
311 ; CHECK-NEXT: ret void
316 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
317 %iv.next = add i64 %iv, 1
318 %narrow.iv = trunc i64 %iv to i32
319 %cmp = icmp ult i32 %narrow.iv, %n
320 br i1 %cmp, label %loop, label %exit
326 define void @test_05_unsigned(i32 %n) {
327 ; CHECK-LABEL: @test_05_unsigned(
329 ; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
330 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], 1
331 ; CHECK-NEXT: br label [[LOOP:%.*]]
333 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
334 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
335 ; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
336 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]]
337 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
339 ; CHECK-NEXT: ret void
344 %iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ]
345 %iv.next = add i64 %iv, 1
346 %narrow.iv = trunc i64 %iv to i32
347 %cmp = icmp ult i32 %narrow.iv, %n
348 br i1 %cmp, label %loop, label %exit
353 ; Trunc changes the actual value of the IV, so it is invalid to remove it: UINT_MIN - 1.
354 define void @test_06_unsigned(i32 %n) {
355 ; CHECK-LABEL: @test_06_unsigned(
357 ; CHECK-NEXT: br label [[LOOP:%.*]]
359 ; CHECK-NEXT: br i1 false, label [[LOOP]], label [[EXIT:%.*]]
361 ; CHECK-NEXT: ret void
366 %iv = phi i64 [ -1, %entry ], [ %iv.next, %loop ]
367 %iv.next = add i64 %iv, 1
368 %narrow.iv = trunc i64 %iv to i32
369 %cmp = icmp ult i32 %narrow.iv, %n
370 br i1 %cmp, label %loop, label %exit
375 ; Do not eliminate trunc if it is used by something different from icmp.
376 define void @test_07(ptr %p, i32 %n) {
377 ; CHECK-LABEL: @test_07(
379 ; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
380 ; CHECK-NEXT: [[TMP0:%.*]] = add nuw i32 [[SMAX]], 1
381 ; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP0]] to i64
382 ; CHECK-NEXT: br label [[LOOP:%.*]]
384 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
385 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
386 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
387 ; CHECK-NEXT: store i32 [[NARROW_IV]], ptr [[P:%.*]], align 4
388 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[WIDE_TRIP_COUNT]]
389 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
391 ; CHECK-NEXT: ret void
396 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
397 %iv.next = add i64 %iv, 1
398 %narrow.iv = trunc i64 %iv to i32
399 store i32 %narrow.iv, ptr %p
400 %cmp = icmp slt i32 %narrow.iv, %n
401 br i1 %cmp, label %loop, label %exit
406 ; Check that we can eliminate both signed and unsigned compare.
407 define void @test_08(i32 %n) {
408 ; CHECK-LABEL: @test_08(
410 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64
411 ; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N]] to i64
412 ; CHECK-NEXT: br label [[LOOP:%.*]]
414 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
415 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
416 ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]]
417 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IV]], [[ZEXT]]
418 ; CHECK-NEXT: [[CMP:%.*]] = and i1 [[TMP0]], [[TMP1]]
419 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
421 ; CHECK-NEXT: ret void
426 %iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ]
427 %iv.next = add i64 %iv, 1
428 %narrow.iv = trunc i64 %iv to i32
429 %cmp1 = icmp slt i32 %narrow.iv, %n
430 %cmp2 = icmp ult i32 %narrow.iv, %n
431 %cmp = and i1 %cmp1, %cmp2
432 br i1 %cmp, label %loop, label %exit
437 ; Widen NE as unsigned.
438 define void @test_09(i32 %n) {
439 ; CHECK-LABEL: @test_09(
441 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64
442 ; CHECK-NEXT: br label [[LOOP:%.*]]
444 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
445 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
446 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ne i64 [[IV]], [[ZEXT]]
447 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
449 ; CHECK-NEXT: ret void
454 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
455 %iv.next = add i64 %iv, 1
456 %narrow.iv = trunc i64 %iv to i32
457 %cmp = icmp ne i32 %narrow.iv, %n
458 br i1 %cmp, label %loop, label %exit
463 ; Widen NE as signed.
464 define void @test_10(i32 %n) {
465 ; CHECK-LABEL: @test_10(
467 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 100
468 ; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
469 ; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP1]], i64 90)
470 ; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i64 [[UMIN]], -99
471 ; CHECK-NEXT: br label [[LOOP:%.*]]
473 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -100, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
474 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
475 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[TMP2]]
476 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
478 ; CHECK-NEXT: ret void
483 %iv = phi i64 [ -100, %entry ], [ %iv.next, %loop ]
484 %iv.next = add i64 %iv, 1
485 %narrow.iv = trunc i64 %iv to i32
486 %trunccmp = icmp ne i32 %narrow.iv, %n
487 %negcmp = icmp slt i64 %iv, -10
488 %cmp = and i1 %trunccmp, %negcmp
489 br i1 %cmp, label %loop, label %exit
494 define void @test_11(i1 %arg) {
495 ; CHECK-LABEL: @test_11(
496 ; CHECK-NEXT: br label [[BB1:%.*]]
498 ; CHECK-NEXT: br i1 [[ARG:%.*]], label [[BB2:%.*]], label [[BB6:%.*]]
500 ; CHECK-NEXT: br i1 [[ARG]], label [[BB3:%.*]], label [[BB4:%.*]]
502 ; CHECK-NEXT: br label [[BB4]]
504 ; CHECK-NEXT: br label [[BB6]]
506 ; CHECK-NEXT: br i1 poison, label [[BB5:%.*]], label [[BB5]]
508 ; CHECK-NEXT: br i1 false, label [[BB1]], label [[BB7:%.*]]
510 ; CHECK-NEXT: ret void
514 bb1: ; preds = %bb6, %0
515 %e.5.0 = phi i32 [ 0, %0 ], [ %_tmp32, %bb6 ]
516 br i1 %arg, label %bb2, label %bb6
519 %_tmp15 = trunc i32 %e.5.0 to i16
520 br i1 %arg, label %bb3, label %bb4
525 bb4: ; preds = %bb3, %bb2
528 bb5: ; preds = %bb5, %bb5
529 %_tmp24 = icmp slt i16 %_tmp15, 0
530 br i1 %_tmp24, label %bb5, label %bb5
532 bb6: ; preds = %bb4, %bb1
533 %_tmp32 = add nuw nsw i32 %e.5.0, 1
534 br i1 false, label %bb1, label %bb7
540 ; Show that we can turn signed comparison to unsigned and use zext while
541 ; comparing non-negative values.
542 define void @test_12(ptr %p) {
543 ; CHECK-LABEL: @test_12(
545 ; CHECK-NEXT: [[N:%.*]] = load i32, ptr [[P:%.*]], align 4, !range [[RNG0:![0-9]+]]
546 ; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N]], i32 1)
547 ; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
548 ; CHECK-NEXT: br label [[LOOP:%.*]]
550 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
551 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
552 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[WIDE_TRIP_COUNT]]
553 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
555 ; CHECK-NEXT: ret void
558 %n = load i32, ptr %p, !range !0
561 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
562 %iv.next = add i64 %iv, 1
563 %narrow.iv = trunc i64 %iv.next to i32
564 %cmp = icmp slt i32 %narrow.iv, %n
565 br i1 %cmp, label %loop, label %exit
570 define void @test_13a(i32 %n) {
572 ; CHECK-LABEL: @test_13a(
574 ; CHECK-NEXT: br label [[LOOP:%.*]]
576 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
577 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 2
578 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ne i64 [[IV]], 1024
579 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
581 ; CHECK-NEXT: ret void
586 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
587 %iv.next = add nsw nuw i64 %iv, 2
588 %narrow.iv = trunc i64 %iv to i32
589 %cmp = icmp ne i32 1024, %narrow.iv
590 br i1 %cmp, label %loop, label %exit
595 define void @test_13b(i32 %n) {
597 ; CHECK-LABEL: @test_13b(
599 ; CHECK-NEXT: br label [[LOOP:%.*]]
601 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
602 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 2
603 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV]], 1024
604 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
606 ; CHECK-NEXT: ret void
611 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
612 %iv.next = add nsw nuw i64 %iv, 2
613 %narrow.iv = trunc i64 %iv to i32
614 %cmp = icmp ugt i32 1024, %narrow.iv
615 br i1 %cmp, label %loop, label %exit
620 define void @test_13c(i32 %n) {
622 ; CHECK-LABEL: @test_13c(
624 ; CHECK-NEXT: br label [[LOOP:%.*]]
626 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
627 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 2
628 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV]], 1024
629 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
631 ; CHECK-NEXT: ret void
636 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
637 %iv.next = add nsw nuw i64 %iv, 2
638 %narrow.iv = trunc i64 %iv to i32
639 %cmp = icmp sgt i32 1024, %narrow.iv
640 br i1 %cmp, label %loop, label %exit
645 define void @test_13d(i32 %n) {
647 ; CHECK-LABEL: @test_13d(
649 ; CHECK-NEXT: br label [[LOOP:%.*]]
651 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -20, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
652 ; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], 2
653 ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], 1024
654 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
656 ; CHECK-NEXT: ret void
661 %iv = phi i64 [ -20, %entry ], [ %iv.next, %loop ]
662 %iv.next = add nsw i64 %iv, 2
663 %narrow.iv = trunc i64 %iv to i32
664 %cmp = icmp sgt i32 1024, %narrow.iv
665 br i1 %cmp, label %loop, label %exit
670 !0 = !{i32 0, i32 1000}