Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / test / Transforms / IndVarSimplify / eliminate-trunc.ll
blob7e0971f9f31defcca3d7cf34a51df9e441c51dd4
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(
11 ; CHECK-NEXT:  entry:
12 ; CHECK-NEXT:    br label [[LOOP:%.*]]
13 ; CHECK:       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:%.*]]
19 ; CHECK:       exit:
20 ; CHECK-NEXT:    ret void
22 entry:
23   br label %loop
24 loop:
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
30 exit:
31   ret void
35 define void @test_01(i32 %n) {
37 ; CHECK-LABEL: @test_01(
38 ; CHECK-NEXT:  entry:
39 ; CHECK-NEXT:    [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64
40 ; CHECK-NEXT:    br label [[LOOP:%.*]]
41 ; CHECK:       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:%.*]]
46 ; CHECK:       exit:
47 ; CHECK-NEXT:    ret void
49 entry:
50   br label %loop
51 loop:
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
57 exit:
58   ret void
61 ; Max value at which we can eliminate trunc: SINT_MAX - 1.
62 define void @test_02(i32 %n) {
64 ; CHECK-LABEL: @test_02(
65 ; CHECK-NEXT:  entry:
66 ; CHECK-NEXT:    [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64
67 ; CHECK-NEXT:    br label [[LOOP:%.*]]
68 ; CHECK:       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:%.*]]
73 ; CHECK:       exit:
74 ; CHECK-NEXT:    ret void
76 entry:
77   br label %loop
78 loop:
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
84 exit:
85   ret void
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(
92 ; CHECK-NEXT:  entry:
93 ; CHECK-NEXT:    br label [[LOOP:%.*]]
94 ; CHECK:       loop:
95 ; CHECK-NEXT:    br i1 false, label [[LOOP]], label [[EXIT:%.*]]
96 ; CHECK:       exit:
97 ; CHECK-NEXT:    ret void
99 entry:
100   br label %loop
101 loop:
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
107 exit:
108   ret void
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(
115 ; CHECK-NEXT:  entry:
116 ; CHECK-NEXT:    [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64
117 ; CHECK-NEXT:    br label [[LOOP:%.*]]
118 ; CHECK:       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:%.*]]
123 ; CHECK:       exit:
124 ; CHECK-NEXT:    ret void
126 entry:
127   br label %loop
128 loop:
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
134 exit:
135   ret void
138 ; FIXME: Harmful LFTR should be thrown away.
139 define void @test_05(i32 %n) {
141 ; CHECK-LABEL: @test_05(
142 ; CHECK-NEXT:  entry:
143 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[N:%.*]], 1
144 ; CHECK-NEXT:    br label [[LOOP:%.*]]
145 ; CHECK:       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:%.*]]
151 ; CHECK:       exit:
152 ; CHECK-NEXT:    ret void
154 entry:
155   br label %loop
156 loop:
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
162 exit:
163   ret void
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(
170 ; CHECK-NEXT:  entry:
171 ; CHECK-NEXT:    br label [[LOOP:%.*]]
172 ; CHECK:       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:%.*]]
178 ; CHECK:       exit:
179 ; CHECK-NEXT:    ret void
181 entry:
182   br label %loop
183 loop:
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
189 exit:
190   ret void
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(
196 ; CHECK-NEXT:  entry:
197 ; CHECK-NEXT:    br label [[LOOP:%.*]]
198 ; CHECK:       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:%.*]]
204 ; CHECK:       exit:
205 ; CHECK-NEXT:    ret void
207 entry:
208   br label %loop
209 loop:
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
215 exit:
216   ret void
219 ; FIXME: Harmful LFTR should be thrown away.
220 define void @test_01_unsigned(i32 %n) {
221 ; CHECK-LABEL: @test_01_unsigned(
222 ; CHECK-NEXT:  entry:
223 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[N:%.*]], 1
224 ; CHECK-NEXT:    br label [[LOOP:%.*]]
225 ; CHECK:       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:%.*]]
231 ; CHECK:       exit:
232 ; CHECK-NEXT:    ret void
234 entry:
235   br label %loop
236 loop:
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
242 exit:
243   ret void
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(
249 ; CHECK-NEXT:  entry:
250 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64
251 ; CHECK-NEXT:    br label [[LOOP:%.*]]
252 ; CHECK:       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:%.*]]
257 ; CHECK:       exit:
258 ; CHECK-NEXT:    ret void
260 entry:
261   br label %loop
262 loop:
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
268 exit:
269   ret void
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(
275 ; CHECK-NEXT:  entry:
276 ; CHECK-NEXT:    br label [[LOOP:%.*]]
277 ; CHECK:       loop:
278 ; CHECK-NEXT:    br i1 false, label [[LOOP]], label [[EXIT:%.*]]
279 ; CHECK:       exit:
280 ; CHECK-NEXT:    ret void
282 entry:
283   br label %loop
284 loop:
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
290 exit:
291   ret void
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(
297 ; CHECK-NEXT:  entry:
298 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[N:%.*]], 1
299 ; CHECK-NEXT:    br label [[LOOP:%.*]]
300 ; CHECK:       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:%.*]]
306 ; CHECK:       exit:
307 ; CHECK-NEXT:    ret void
309 entry:
310   br label %loop
311 loop:
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
317 exit:
318   ret void
321 ; Start from 1.
322 define void @test_05_unsigned(i32 %n) {
323 ; CHECK-LABEL: @test_05_unsigned(
324 ; CHECK-NEXT:  entry:
325 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64
326 ; CHECK-NEXT:    br label [[LOOP:%.*]]
327 ; CHECK:       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:%.*]]
332 ; CHECK:       exit:
333 ; CHECK-NEXT:    ret void
335 entry:
336   br label %loop
337 loop:
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
343 exit:
344   ret void
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(
350 ; CHECK-NEXT:  entry:
351 ; CHECK-NEXT:    br label [[LOOP:%.*]]
352 ; CHECK:       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:%.*]]
358 ; CHECK:       exit:
359 ; CHECK-NEXT:    ret void
361 entry:
362   br label %loop
363 loop:
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
369 exit:
370   ret void
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(
376 ; CHECK-NEXT:  entry:
377 ; CHECK-NEXT:    br label [[LOOP:%.*]]
378 ; CHECK:       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:%.*]]
385 ; CHECK:       exit:
386 ; CHECK-NEXT:    ret void
388 entry:
389   br label %loop
390 loop:
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
397 exit:
398   ret void
401 ; Check that we can eliminate both signed and unsigned compare.
402 define void @test_08(i32 %n) {
403 ; CHECK-LABEL: @test_08(
404 ; CHECK-NEXT:  entry:
405 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64
406 ; CHECK-NEXT:    [[SEXT:%.*]] = sext i32 [[N]] to i64
407 ; CHECK-NEXT:    br label [[LOOP:%.*]]
408 ; CHECK:       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:%.*]]
415 ; CHECK:       exit:
416 ; CHECK-NEXT:    ret void
418 entry:
419   br label %loop
420 loop:
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
428 exit:
429   ret void
432 ; Widen NE as unsigned.
433 define void @test_09(i32 %n) {
434 ; CHECK-LABEL: @test_09(
435 ; CHECK-NEXT:  entry:
436 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64
437 ; CHECK-NEXT:    br label [[LOOP:%.*]]
438 ; CHECK:       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:%.*]]
443 ; CHECK:       exit:
444 ; CHECK-NEXT:    ret void
446 entry:
447   br label %loop
448 loop:
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
454 exit:
455   ret void
458 ; Widen NE as signed.
459 define void @test_10(i32 %n) {
460 ; CHECK-LABEL: @test_10(
461 ; CHECK-NEXT:  entry:
462 ; CHECK-NEXT:    [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64
463 ; CHECK-NEXT:    br label [[LOOP:%.*]]
464 ; CHECK:       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:%.*]]
471 ; CHECK:       exit:
472 ; CHECK-NEXT:    ret void
474 entry:
475   br label %loop
476 loop:
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
484 exit:
485   ret void
488 define void @test_11() {
489 ; CHECK-LABEL: @test_11(
490 ; CHECK-NEXT:    br label [[BB1:%.*]]
491 ; CHECK:       bb1:
492 ; CHECK-NEXT:    br i1 undef, label [[BB2:%.*]], label [[BB6:%.*]]
493 ; CHECK:       bb2:
494 ; CHECK-NEXT:    br i1 undef, label [[BB3:%.*]], label [[BB4:%.*]]
495 ; CHECK:       bb3:
496 ; CHECK-NEXT:    br label [[BB4]]
497 ; CHECK:       bb4:
498 ; CHECK-NEXT:    br label [[BB6]]
499 ; CHECK:       bb5:
500 ; CHECK-NEXT:    [[_TMP24:%.*]] = icmp slt i16 undef, 0
501 ; CHECK-NEXT:    br i1 [[_TMP24]], label [[BB5:%.*]], label [[BB5]]
502 ; CHECK:       bb6:
503 ; CHECK-NEXT:    br i1 false, label [[BB1]], label [[BB7:%.*]]
504 ; CHECK:       bb7:
505 ; CHECK-NEXT:    ret void
507   br label %bb1
509 bb1:                                              ; preds = %bb6, %0
510   %e.5.0 = phi i32 [ 0, %0 ], [ %_tmp32, %bb6 ]
511   br i1 undef, label %bb2, label %bb6
513 bb2:                                              ; preds = %bb1
514   %_tmp15 = trunc i32 %e.5.0 to i16
515   br i1 undef, label %bb3, label %bb4
517 bb3:                                              ; preds = %bb2
518   br label %bb4
520 bb4:                                              ; preds = %bb3, %bb2
521   br label %bb6
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
531 bb7:                                             ; preds = %bb6
532   ret void
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(
539 ; CHECK-NEXT:  entry:
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:%.*]]
543 ; CHECK:       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:%.*]]
548 ; CHECK:       exit:
549 ; CHECK-NEXT:    ret void
551 entry:
552   %n = load i32, i32* %p, !range !0
553   br label %loop
554 loop:
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
560 exit:
561   ret void
564 !0 = !{i32 0, i32 1000}