1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -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(i32* %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]], i32* [[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, i32* %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() {
495 ; CHECK-LABEL: @test_11(
496 ; CHECK-NEXT: br label [[BB1:%.*]]
498 ; CHECK-NEXT: br i1 undef, label [[BB2:%.*]], label [[BB6:%.*]]
500 ; CHECK-NEXT: br i1 undef, label [[BB3:%.*]], label [[BB4:%.*]]
502 ; CHECK-NEXT: br label [[BB4]]
504 ; CHECK-NEXT: br label [[BB6]]
506 ; CHECK-NEXT: [[_TMP24:%.*]] = icmp slt i16 undef, 0
507 ; CHECK-NEXT: br i1 [[_TMP24]], label [[BB5:%.*]], label [[BB5]]
509 ; CHECK-NEXT: br i1 false, label [[BB1]], label [[BB7:%.*]]
511 ; CHECK-NEXT: ret void
515 bb1: ; preds = %bb6, %0
516 %e.5.0 = phi i32 [ 0, %0 ], [ %_tmp32, %bb6 ]
517 br i1 undef, label %bb2, label %bb6
520 %_tmp15 = trunc i32 %e.5.0 to i16
521 br i1 undef, label %bb3, label %bb4
526 bb4: ; preds = %bb3, %bb2
529 bb5: ; preds = %bb5, %bb5
530 %_tmp24 = icmp slt i16 %_tmp15, 0
531 br i1 %_tmp24, label %bb5, label %bb5
533 bb6: ; preds = %bb4, %bb1
534 %_tmp32 = add nuw nsw i32 %e.5.0, 1
535 br i1 false, label %bb1, label %bb7
541 ; Show that we can turn signed comparison to unsigned and use zext while
542 ; comparing non-negative values.
543 define void @test_12(i32* %p) {
544 ; CHECK-LABEL: @test_12(
546 ; CHECK-NEXT: [[N:%.*]] = load i32, i32* [[P:%.*]], align 4, [[RNG0:!range !.*]]
547 ; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N]], i32 1)
548 ; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
549 ; CHECK-NEXT: br label [[LOOP:%.*]]
551 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
552 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
553 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[WIDE_TRIP_COUNT]]
554 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
556 ; CHECK-NEXT: ret void
559 %n = load i32, i32* %p, !range !0
562 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
563 %iv.next = add i64 %iv, 1
564 %narrow.iv = trunc i64 %iv.next to i32
565 %cmp = icmp slt i32 %narrow.iv, %n
566 br i1 %cmp, label %loop, label %exit
571 define void @test_13a(i32 %n) {
573 ; CHECK-LABEL: @test_13a(
575 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 1024 to i64
576 ; CHECK-NEXT: br label [[LOOP:%.*]]
578 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
579 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 2
580 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ne i64 [[IV]], [[ZEXT]]
581 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
583 ; CHECK-NEXT: ret void
588 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
589 %iv.next = add nsw nuw i64 %iv, 2
590 %narrow.iv = trunc i64 %iv to i32
591 %cmp = icmp ne i32 1024, %narrow.iv
592 br i1 %cmp, label %loop, label %exit
597 define void @test_13b(i32 %n) {
599 ; CHECK-LABEL: @test_13b(
601 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 1024 to i64
602 ; CHECK-NEXT: br label [[LOOP:%.*]]
604 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
605 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 2
606 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV]], [[ZEXT]]
607 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
609 ; CHECK-NEXT: ret void
614 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
615 %iv.next = add nsw nuw i64 %iv, 2
616 %narrow.iv = trunc i64 %iv to i32
617 %cmp = icmp ugt i32 1024, %narrow.iv
618 br i1 %cmp, label %loop, label %exit
623 define void @test_13c(i32 %n) {
625 ; CHECK-LABEL: @test_13c(
627 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 1024 to i64
628 ; CHECK-NEXT: br label [[LOOP:%.*]]
630 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
631 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 2
632 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV]], [[ZEXT]]
633 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
635 ; CHECK-NEXT: ret void
640 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
641 %iv.next = add nsw nuw i64 %iv, 2
642 %narrow.iv = trunc i64 %iv to i32
643 %cmp = icmp sgt i32 1024, %narrow.iv
644 br i1 %cmp, label %loop, label %exit
649 define void @test_13d(i32 %n) {
651 ; CHECK-LABEL: @test_13d(
653 ; CHECK-NEXT: [[SEXT:%.*]] = sext i32 1024 to i64
654 ; CHECK-NEXT: br label [[LOOP:%.*]]
656 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -20, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
657 ; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], 2
658 ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]]
659 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
661 ; CHECK-NEXT: ret void
666 %iv = phi i64 [ -20, %entry ], [ %iv.next, %loop ]
667 %iv.next = add nsw i64 %iv, 2
668 %narrow.iv = trunc i64 %iv to i32
669 %cmp = icmp sgt i32 1024, %narrow.iv
670 br i1 %cmp, label %loop, label %exit
675 !0 = !{i32 0, i32 1000}