[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / Transforms / CorrelatedValuePropagation / range.ll
blob6315e3bd74da1a0894a6286eb1b0735e9590a84c
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -correlated-propagation -S < %s | FileCheck %s
4 declare i32 @foo()
6 define i32 @test1(i32 %a) nounwind {
7 ; CHECK-LABEL: @test1(
8 ; CHECK-NEXT:    [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
9 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A_OFF]], 8
10 ; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
11 ; CHECK:       then:
12 ; CHECK-NEXT:    br i1 false, label [[END:%.*]], label [[ELSE]]
13 ; CHECK:       else:
14 ; CHECK-NEXT:    ret i32 1
15 ; CHECK:       end:
16 ; CHECK-NEXT:    ret i32 2
18   %a.off = add i32 %a, -8
19   %cmp = icmp ult i32 %a.off, 8
20   br i1 %cmp, label %then, label %else
22 then:
23   %dead = icmp eq i32 %a, 7
24   br i1 %dead, label %end, label %else
26 else:
27   ret i32 1
29 end:
30   ret i32 2
33 define i32 @test2(i32 %a) nounwind {
34 ; CHECK-LABEL: @test2(
35 ; CHECK-NEXT:    [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
36 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A_OFF]], 8
37 ; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
38 ; CHECK:       then:
39 ; CHECK-NEXT:    br i1 false, label [[END:%.*]], label [[ELSE]]
40 ; CHECK:       else:
41 ; CHECK-NEXT:    ret i32 1
42 ; CHECK:       end:
43 ; CHECK-NEXT:    ret i32 2
45   %a.off = add i32 %a, -8
46   %cmp = icmp ult i32 %a.off, 8
47   br i1 %cmp, label %then, label %else
49 then:
50   %dead = icmp ugt i32 %a, 15
51   br i1 %dead, label %end, label %else
53 else:
54   ret i32 1
56 end:
57   ret i32 2
60 define i32 @test3(i32 %c) nounwind {
61 ; CHECK-LABEL: @test3(
62 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[C:%.*]], 2
63 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
64 ; CHECK:       if.then:
65 ; CHECK-NEXT:    ret i32 1
66 ; CHECK:       if.end:
67 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[C]], 3
68 ; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END8:%.*]]
69 ; CHECK:       if.then2:
70 ; CHECK-NEXT:    br i1 true, label [[IF_THEN4:%.*]], label [[IF_END6:%.*]]
71 ; CHECK:       if.end6:
72 ; CHECK-NEXT:    ret i32 2
73 ; CHECK:       if.then4:
74 ; CHECK-NEXT:    ret i32 3
75 ; CHECK:       if.end8:
76 ; CHECK-NEXT:    ret i32 4
78   %cmp = icmp slt i32 %c, 2
79   br i1 %cmp, label %if.then, label %if.end
81 if.then:
82   ret i32 1
84 if.end:
85   %cmp1 = icmp slt i32 %c, 3
86   br i1 %cmp1, label %if.then2, label %if.end8
88 if.then2:
89   %cmp2 = icmp eq i32 %c, 2
90   br i1 %cmp2, label %if.then4, label %if.end6
92 if.end6:
93   ret i32 2
95 if.then4:
96   ret i32 3
98 if.end8:
99   ret i32 4
102 define i32 @test4(i32 %c) nounwind {
103 ; CHECK-LABEL: @test4(
104 ; CHECK-NEXT:    switch i32 [[C:%.*]], label [[SW_DEFAULT:%.*]] [
105 ; CHECK-NEXT:    i32 1, label [[SW_BB:%.*]]
106 ; CHECK-NEXT:    i32 2, label [[SW_BB]]
107 ; CHECK-NEXT:    i32 4, label [[SW_BB]]
108 ; CHECK-NEXT:    ]
109 ; CHECK:       sw.bb:
110 ; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[IF_END:%.*]]
111 ; CHECK:       if.then:
112 ; CHECK-NEXT:    br label [[RETURN:%.*]]
113 ; CHECK:       if.end:
114 ; CHECK-NEXT:    br label [[RETURN]]
115 ; CHECK:       sw.default:
116 ; CHECK-NEXT:    br label [[RETURN]]
117 ; CHECK:       return:
118 ; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ 42, [[SW_DEFAULT]] ], [ 4, [[IF_THEN]] ], [ 9, [[IF_END]] ]
119 ; CHECK-NEXT:    ret i32 [[RETVAL_0]]
121   switch i32 %c, label %sw.default [
122   i32 1, label %sw.bb
123   i32 2, label %sw.bb
124   i32 4, label %sw.bb
125   ]
127 sw.bb:
128   %cmp = icmp sge i32 %c, 1
129   br i1 %cmp, label %if.then, label %if.end
131 if.then:
132   br label %return
134 if.end:
135   br label %return
137 sw.default:
138   br label %return
140 return:
141   %retval.0 = phi i32 [ 42, %sw.default ], [ 4, %if.then ], [ 9, %if.end ]
142   ret i32 %retval.0
145 define i1 @test5(i32 %c) nounwind {
146 ; CHECK-LABEL: @test5(
147 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[C:%.*]], 5
148 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
149 ; CHECK:       if.then:
150 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[C]], 4
151 ; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_END]], label [[IF_END8:%.*]]
152 ; CHECK:       if.end:
153 ; CHECK-NEXT:    ret i1 true
154 ; CHECK:       if.end8:
155 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[C]], 3
156 ; CHECK-NEXT:    [[OR:%.*]] = or i1 false, false
157 ; CHECK-NEXT:    ret i1 [[CMP2]]
159   %cmp = icmp slt i32 %c, 5
160   br i1 %cmp, label %if.then, label %if.end
162 if.then:
163   %cmp1 = icmp eq i32 %c, 4
164   br i1 %cmp1, label %if.end, label %if.end8
166 if.end:
167   ret i1 true
169 if.end8:
170   %cmp2 = icmp eq i32 %c, 3
171   %cmp3 = icmp eq i32 %c, 4
172   %cmp4 = icmp eq i32 %c, 6
173   %or = or i1 %cmp3, %cmp4
174   ret i1 %cmp2
177 define i1 @test6(i32 %c) nounwind {
178 ; CHECK-LABEL: @test6(
179 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[C:%.*]], 7
180 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
181 ; CHECK:       if.then:
182 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[C]], 6
183 ; CHECK-NEXT:    br i1 [[COND]], label [[SW_BB:%.*]], label [[IF_END]]
184 ; CHECK:       if.end:
185 ; CHECK-NEXT:    ret i1 true
186 ; CHECK:       sw.bb:
187 ; CHECK-NEXT:    ret i1 true
189   %cmp = icmp ule i32 %c, 7
190   br i1 %cmp, label %if.then, label %if.end
192 if.then:
193   switch i32 %c, label %if.end [
194   i32 6, label %sw.bb
195   i32 8, label %sw.bb
196   ]
198 if.end:
199   ret i1 true
201 sw.bb:
202   %cmp2 = icmp eq i32 %c, 6
203   ret i1 %cmp2
206 define i1 @test7(i32 %c) nounwind {
207 ; CHECK-LABEL: @test7(
208 ; CHECK-NEXT:  entry:
209 ; CHECK-NEXT:    switch i32 [[C:%.*]], label [[SW_DEFAULT:%.*]] [
210 ; CHECK-NEXT:    i32 6, label [[SW_BB:%.*]]
211 ; CHECK-NEXT:    i32 7, label [[SW_BB]]
212 ; CHECK-NEXT:    ]
213 ; CHECK:       sw.bb:
214 ; CHECK-NEXT:    ret i1 true
215 ; CHECK:       sw.default:
216 ; CHECK-NEXT:    [[CMP5:%.*]] = icmp eq i32 [[C]], 5
217 ; CHECK-NEXT:    [[CMP8:%.*]] = icmp eq i32 [[C]], 8
218 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP5]], false
219 ; CHECK-NEXT:    [[OR2:%.*]] = or i1 false, [[CMP8]]
220 ; CHECK-NEXT:    ret i1 false
222 entry:
223   switch i32 %c, label %sw.default [
224   i32 6, label %sw.bb
225   i32 7, label %sw.bb
226   ]
228 sw.bb:
229   ret i1 true
231 sw.default:
232   %cmp5 = icmp eq i32 %c, 5
233   %cmp6 = icmp eq i32 %c, 6
234   %cmp7 = icmp eq i32 %c, 7
235   %cmp8 = icmp eq i32 %c, 8
236   %or = or i1 %cmp5, %cmp6
237   %or2 = or i1 %cmp7, %cmp8
238   ret i1 false
241 define i1 @test8(i64* %p) {
242 ; CHECK-LABEL: @test8(
243 ; CHECK-NEXT:    [[A:%.*]] = load i64, i64* [[P:%.*]], !range !0
244 ; CHECK-NEXT:    [[RES:%.*]] = icmp eq i64 [[A]], 0
245 ; CHECK-NEXT:    ret i1 false
247   %a = load i64, i64* %p, !range !{i64 4, i64 255}
248   %res = icmp eq i64 %a, 0
249   ret i1 %res
252 define i1 @test9(i64* %p) {
253 ; CHECK-LABEL: @test9(
254 ; CHECK-NEXT:    [[A:%.*]] = load i64, i64* [[P:%.*]], !range !1
255 ; CHECK-NEXT:    [[RES:%.*]] = icmp eq i64 [[A]], 0
256 ; CHECK-NEXT:    ret i1 true
258   %a = load i64, i64* %p, !range !{i64 0, i64 1}
259   %res = icmp eq i64 %a, 0
260   ret i1 %res
263 define i1 @test10(i64* %p) {
264 ; CHECK-LABEL: @test10(
265 ; CHECK-NEXT:    [[A:%.*]] = load i64, i64* [[P:%.*]], !range !2
266 ; CHECK-NEXT:    [[RES:%.*]] = icmp eq i64 [[A]], 0
267 ; CHECK-NEXT:    ret i1 false
269   %a = load i64, i64* %p, !range !{i64 4, i64 8, i64 15, i64 20}
270   %res = icmp eq i64 %a, 0
271   ret i1 %res
274 @g = external global i32
276 define i1 @test11() {
277 ; CHECK-LABEL: @test11(
278 ; CHECK-NEXT:    [[POSITIVE:%.*]] = load i32, i32* @g, !range !3
279 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[POSITIVE]], 1
280 ; CHECK-NEXT:    [[TEST:%.*]] = icmp sgt i32 [[ADD]], 0
281 ; CHECK-NEXT:    br label [[NEXT:%.*]]
282 ; CHECK:       next:
283 ; CHECK-NEXT:    ret i1 true
285   %positive = load i32, i32* @g, !range !{i32 1, i32 2048}
286   %add = add i32 %positive, 1
287   %test = icmp sgt i32 %add, 0
288   br label %next
290 next:
291   ret i1 %test
294 define i32 @test12(i32 %a, i32 %b) {
295 ; CHECK-LABEL: @test12(
296 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
297 ; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
298 ; CHECK:       then:
299 ; CHECK-NEXT:    br i1 false, label [[END:%.*]], label [[ELSE]]
300 ; CHECK:       else:
301 ; CHECK-NEXT:    ret i32 1
302 ; CHECK:       end:
303 ; CHECK-NEXT:    ret i32 2
305   %cmp = icmp ult i32 %a, %b
306   br i1 %cmp, label %then, label %else
308 then:
309   %dead = icmp eq i32 %a, -1
310   br i1 %dead, label %end, label %else
312 else:
313   ret i32 1
315 end:
316   ret i32 2
319 define i32 @test12_swap(i32 %a, i32 %b) {
320 ; CHECK-LABEL: @test12_swap(
321 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[B:%.*]], [[A:%.*]]
322 ; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
323 ; CHECK:       then:
324 ; CHECK-NEXT:    br i1 false, label [[END:%.*]], label [[ELSE]]
325 ; CHECK:       else:
326 ; CHECK-NEXT:    ret i32 1
327 ; CHECK:       end:
328 ; CHECK-NEXT:    ret i32 2
330   %cmp = icmp ugt i32 %b, %a
331   br i1 %cmp, label %then, label %else
333 then:
334   %dead = icmp eq i32 %a, -1
335   br i1 %dead, label %end, label %else
337 else:
338   ret i32 1
340 end:
341   ret i32 2
344 ; The same as @test12 but the second check is on the false path
346 define i32 @test12_neg(i32 %a, i32 %b) {
347 ; CHECK-LABEL: @test12_neg(
348 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
349 ; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
350 ; CHECK:       else:
351 ; CHECK-NEXT:    [[ALIVE:%.*]] = icmp eq i32 [[A]], -1
352 ; CHECK-NEXT:    br i1 [[ALIVE]], label [[END:%.*]], label [[THEN]]
353 ; CHECK:       then:
354 ; CHECK-NEXT:    ret i32 1
355 ; CHECK:       end:
356 ; CHECK-NEXT:    ret i32 2
358   %cmp = icmp ult i32 %a, %b
359   br i1 %cmp, label %then, label %else
361 else:
362   %alive = icmp eq i32 %a, -1
363   br i1 %alive, label %end, label %then
365 then:
366   ret i32 1
368 end:
369   ret i32 2
372 ; The same as @test12 but with signed comparison
374 define i32 @test12_signed(i32 %a, i32 %b) {
375 ; CHECK-LABEL: @test12_signed(
376 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
377 ; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
378 ; CHECK:       then:
379 ; CHECK-NEXT:    br i1 false, label [[END:%.*]], label [[ELSE]]
380 ; CHECK:       else:
381 ; CHECK-NEXT:    ret i32 1
382 ; CHECK:       end:
383 ; CHECK-NEXT:    ret i32 2
385   %cmp = icmp slt i32 %a, %b
386   br i1 %cmp, label %then, label %else
388 then:
389   %dead = icmp eq i32 %a, 2147483647
390   br i1 %dead, label %end, label %else
392 else:
393   ret i32 1
395 end:
396   ret i32 2
399 define i32 @test13(i32 %a, i32 %b) {
400 ; CHECK-LABEL: @test13(
401 ; CHECK-NEXT:    [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
402 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A_OFF]], [[B:%.*]]
403 ; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
404 ; CHECK:       then:
405 ; CHECK-NEXT:    br i1 false, label [[END:%.*]], label [[ELSE]]
406 ; CHECK:       else:
407 ; CHECK-NEXT:    ret i32 1
408 ; CHECK:       end:
409 ; CHECK-NEXT:    ret i32 2
411   %a.off = add i32 %a, -8
412   %cmp = icmp ult i32 %a.off, %b
413   br i1 %cmp, label %then, label %else
415 then:
416   %dead = icmp eq i32 %a, 7
417   br i1 %dead, label %end, label %else
419 else:
420   ret i32 1
422 end:
423   ret i32 2
426 define i32 @test13_swap(i32 %a, i32 %b) {
427 ; CHECK-LABEL: @test13_swap(
428 ; CHECK-NEXT:    [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
429 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[B:%.*]], [[A_OFF]]
430 ; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
431 ; CHECK:       then:
432 ; CHECK-NEXT:    br i1 false, label [[END:%.*]], label [[ELSE]]
433 ; CHECK:       else:
434 ; CHECK-NEXT:    ret i32 1
435 ; CHECK:       end:
436 ; CHECK-NEXT:    ret i32 2
438   %a.off = add i32 %a, -8
439   %cmp = icmp ugt i32 %b, %a.off
440   br i1 %cmp, label %then, label %else
442 then:
443   %dead = icmp eq i32 %a, 7
444   br i1 %dead, label %end, label %else
446 else:
447   ret i32 1
449 end:
450   ret i32 2
453 define i1 @test14_slt(i32 %a) {
454 ; CHECK-LABEL: @test14_slt(
455 ; CHECK-NEXT:    [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
456 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A_OFF]], 8
457 ; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
458 ; CHECK:       then:
459 ; CHECK-NEXT:    [[RESULT:%.*]] = or i1 false, false
460 ; CHECK-NEXT:    ret i1 [[RESULT]]
461 ; CHECK:       else:
462 ; CHECK-NEXT:    ret i1 false
464   %a.off = add i32 %a, -8
465   %cmp = icmp slt i32 %a.off, 8
466   br i1 %cmp, label %then, label %else
468 then:
469   %dead.1 = icmp eq i32 %a, -2147483641
470   %dead.2 = icmp eq i32 %a, 16
471   %result = or i1 %dead.1, %dead.2
472   ret i1 %result
474 else:
475   ret i1 false
478 define i1 @test14_sle(i32 %a) {
479 ; CHECK-LABEL: @test14_sle(
480 ; CHECK-NEXT:    [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
481 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A_OFF]], 8
482 ; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
483 ; CHECK:       then:
484 ; CHECK-NEXT:    [[ALIVE:%.*]] = icmp eq i32 [[A]], 16
485 ; CHECK-NEXT:    [[RESULT:%.*]] = or i1 false, [[ALIVE]]
486 ; CHECK-NEXT:    ret i1 [[RESULT]]
487 ; CHECK:       else:
488 ; CHECK-NEXT:    ret i1 false
490   %a.off = add i32 %a, -8
491   %cmp = icmp sle i32 %a.off, 8
492   br i1 %cmp, label %then, label %else
494 then:
495   %dead = icmp eq i32 %a, -2147483641
496   %alive = icmp eq i32 %a, 16
497   %result = or i1 %dead, %alive
498   ret i1 %result
500 else:
501   ret i1 false
504 define i1 @test14_sgt(i32 %a) {
505 ; CHECK-LABEL: @test14_sgt(
506 ; CHECK-NEXT:    [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
507 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A_OFF]], 8
508 ; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
509 ; CHECK:       then:
510 ; CHECK-NEXT:    [[RESULT:%.*]] = or i1 false, false
511 ; CHECK-NEXT:    ret i1 [[RESULT]]
512 ; CHECK:       else:
513 ; CHECK-NEXT:    ret i1 false
515   %a.off = add i32 %a, -8
516   %cmp = icmp sgt i32 %a.off, 8
517   br i1 %cmp, label %then, label %else
519 then:
520   %dead.1 = icmp eq i32 %a, -2147483640
521   %dead.2 = icmp eq i32 %a, 16
522   %result = or i1 %dead.1, %dead.2
523   ret i1 %result
525 else:
526   ret i1 false
529 define i1 @test14_sge(i32 %a) {
530 ; CHECK-LABEL: @test14_sge(
531 ; CHECK-NEXT:    [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
532 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[A_OFF]], 8
533 ; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
534 ; CHECK:       then:
535 ; CHECK-NEXT:    [[ALIVE:%.*]] = icmp eq i32 [[A]], 16
536 ; CHECK-NEXT:    [[RESULT:%.*]] = or i1 false, [[ALIVE]]
537 ; CHECK-NEXT:    ret i1 [[RESULT]]
538 ; CHECK:       else:
539 ; CHECK-NEXT:    ret i1 false
541   %a.off = add i32 %a, -8
542   %cmp = icmp sge i32 %a.off, 8
543   br i1 %cmp, label %then, label %else
545 then:
546   %dead = icmp eq i32 %a, -2147483640
547   %alive = icmp eq i32 %a, 16
548   %result = or i1 %dead, %alive
549   ret i1 %result
551 else:
552   ret i1 false
555 define i1 @test14_ule(i32 %a) {
556 ; CHECK-LABEL: @test14_ule(
557 ; CHECK-NEXT:    [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
558 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[A_OFF]], 8
559 ; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
560 ; CHECK:       then:
561 ; CHECK-NEXT:    [[ALIVE:%.*]] = icmp eq i32 [[A]], 16
562 ; CHECK-NEXT:    [[RESULT:%.*]] = or i1 false, [[ALIVE]]
563 ; CHECK-NEXT:    ret i1 [[RESULT]]
564 ; CHECK:       else:
565 ; CHECK-NEXT:    ret i1 false
567   %a.off = add i32 %a, -8
568   %cmp = icmp ule i32 %a.off, 8
569   br i1 %cmp, label %then, label %else
571 then:
572   %dead = icmp eq i32 %a, 7
573   %alive = icmp eq i32 %a, 16
574   %result = or i1 %dead, %alive
575   ret i1 %result
577 else:
578   ret i1 false
581 define i1 @test14_ugt(i32 %a) {
582 ; CHECK-LABEL: @test14_ugt(
583 ; CHECK-NEXT:    [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
584 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[A_OFF]], 8
585 ; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
586 ; CHECK:       then:
587 ; CHECK-NEXT:    [[RESULT:%.*]] = or i1 false, false
588 ; CHECK-NEXT:    ret i1 [[RESULT]]
589 ; CHECK:       else:
590 ; CHECK-NEXT:    ret i1 false
592   %a.off = add i32 %a, -8
593   %cmp = icmp ugt i32 %a.off, 8
594   br i1 %cmp, label %then, label %else
596 then:
597   %dead.1 = icmp eq i32 %a, 8
598   %dead.2 = icmp eq i32 %a, 16
599   %result = or i1 %dead.1, %dead.2
600   ret i1 %result
602 else:
603   ret i1 false
606 define i1 @test14_uge(i32 %a) {
607 ; CHECK-LABEL: @test14_uge(
608 ; CHECK-NEXT:    [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
609 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[A_OFF]], 8
610 ; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
611 ; CHECK:       then:
612 ; CHECK-NEXT:    [[ALIVE:%.*]] = icmp eq i32 [[A]], 16
613 ; CHECK-NEXT:    [[RESULT:%.*]] = or i1 false, [[ALIVE]]
614 ; CHECK-NEXT:    ret i1 [[RESULT]]
615 ; CHECK:       else:
616 ; CHECK-NEXT:    ret i1 false
618   %a.off = add i32 %a, -8
619   %cmp = icmp uge i32 %a.off, 8
620   br i1 %cmp, label %then, label %else
622 then:
623   %dead = icmp eq i32 %a, 8
624   %alive = icmp eq i32 %a, 16
625   %result = or i1 %dead, %alive
626   ret i1 %result
628 else:
629   ret i1 false
632 @limit = external global i32
633 define i1 @test15(i32 %a) {
634 ; CHECK-LABEL: @test15(
635 ; CHECK-NEXT:    [[LIMIT:%.*]] = load i32, i32* @limit, !range !4
636 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A:%.*]], [[LIMIT]]
637 ; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
638 ; CHECK:       then:
639 ; CHECK-NEXT:    ret i1 false
640 ; CHECK:       else:
641 ; CHECK-NEXT:    ret i1 false
643   %limit = load i32, i32* @limit, !range !{i32 0, i32 256}
644   %cmp = icmp ult i32 %a, %limit
645   br i1 %cmp, label %then, label %else
647 then:
648   %result = icmp eq i32 %a, 255
649   ret i1 %result
651 else:
652   ret i1 false
655 define i32 @test16(i8 %a) {
656 ; CHECK-LABEL: @test16(
657 ; CHECK-NEXT:  entry:
658 ; CHECK-NEXT:    [[B:%.*]] = zext i8 [[A:%.*]] to i32
659 ; CHECK-NEXT:    br label [[DISPATCH:%.*]]
660 ; CHECK:       dispatch:
661 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A]], 93
662 ; CHECK-NEXT:    br i1 [[CMP]], label [[TARGET93:%.*]], label [[DISPATCH]]
663 ; CHECK:       target93:
664 ; CHECK-NEXT:    ret i32 93
666 entry:
667   %b = zext i8 %a to i32
668   br label %dispatch
670 dispatch:
671   %cmp = icmp eq i8 %a, 93
672   br i1 %cmp, label %target93, label %dispatch
674 target93:
675   ret i32 %b
678 define i32 @test16_i1(i1 %a) {
679 ; CHECK-LABEL: @test16_i1(
680 ; CHECK-NEXT:  entry:
681 ; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A:%.*]] to i32
682 ; CHECK-NEXT:    br label [[DISPATCH:%.*]]
683 ; CHECK:       dispatch:
684 ; CHECK-NEXT:    br i1 [[A]], label [[TRUE:%.*]], label [[DISPATCH]]
685 ; CHECK:       true:
686 ; CHECK-NEXT:    ret i32 1
688 entry:
689   %b = zext i1 %a to i32
690   br label %dispatch
692 dispatch:
693   br i1 %a, label %true, label %dispatch
695 true:
696   ret i32 %b
699 define i8 @test17(i8 %a) {
700 ; CHECK-LABEL: @test17(
701 ; CHECK-NEXT:  entry:
702 ; CHECK-NEXT:    [[C:%.*]] = add i8 [[A:%.*]], 3
703 ; CHECK-NEXT:    br label [[DISPATCH:%.*]]
704 ; CHECK:       dispatch:
705 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A]], 93
706 ; CHECK-NEXT:    br i1 [[CMP]], label [[TARGET93:%.*]], label [[DISPATCH]]
707 ; CHECK:       target93:
708 ; CHECK-NEXT:    ret i8 96
710 entry:
711   %c = add i8 %a, 3
712   br label %dispatch
714 dispatch:
715   %cmp = icmp eq i8 %a, 93
716   br i1 %cmp, label %target93, label %dispatch
718 target93:
719   ret i8 %c
722 define i8 @test17_2(i8 %a) {
723 ; CHECK-LABEL: @test17_2(
724 ; CHECK-NEXT:  entry:
725 ; CHECK-NEXT:    [[C:%.*]] = add i8 [[A:%.*]], [[A]]
726 ; CHECK-NEXT:    br label [[DISPATCH:%.*]]
727 ; CHECK:       dispatch:
728 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A]], 93
729 ; CHECK-NEXT:    br i1 [[CMP]], label [[TARGET93:%.*]], label [[DISPATCH]]
730 ; CHECK:       target93:
731 ; CHECK-NEXT:    ret i8 -70
733 entry:
734   %c = add i8 %a, %a
735   br label %dispatch
737 dispatch:
738   %cmp = icmp eq i8 %a, 93
739   br i1 %cmp, label %target93, label %dispatch
741 target93:
742   ret i8 %c
745 define i1 @test17_i1(i1 %a) {
746 ; CHECK-LABEL: @test17_i1(
747 ; CHECK-NEXT:  entry:
748 ; CHECK-NEXT:    br label [[DISPATCH:%.*]]
749 ; CHECK:       dispatch:
750 ; CHECK-NEXT:    br i1 [[A:%.*]], label [[TRUE:%.*]], label [[DISPATCH]]
751 ; CHECK:       true:
752 ; CHECK-NEXT:    ret i1 true
754 entry:
755   %c = and i1 %a, true
756   br label %dispatch
758 dispatch:
759   br i1 %a, label %true, label %dispatch
761 true:
762   ret i1 %c
765 define i32 @test18(i8 %a) {
766 ; CHECK-LABEL: @test18(
767 ; CHECK-NEXT:  entry:
768 ; CHECK-NEXT:    [[B:%.*]] = zext i8 [[A:%.*]] to i32
769 ; CHECK-NEXT:    br label [[DISPATCH:%.*]]
770 ; CHECK:       dispatch:
771 ; CHECK-NEXT:    switch i8 [[A]], label [[DISPATCH]] [
772 ; CHECK-NEXT:    i8 93, label [[TARGET93:%.*]]
773 ; CHECK-NEXT:    i8 -111, label [[DISPATCH]]
774 ; CHECK-NEXT:    ]
775 ; CHECK:       target93:
776 ; CHECK-NEXT:    ret i32 93
778 entry:
779   %b = zext i8 %a to i32
780   br label %dispatch
782 dispatch:
783   switch i8 %a, label %dispatch [
784   i8 93, label %target93
785   i8 -111, label %dispatch
786   ]
788 target93:
789   ret i32 %b
792 define i8 @test19(i8 %a) {
793 ; CHECK-LABEL: @test19(
794 ; CHECK-NEXT:  entry:
795 ; CHECK-NEXT:    [[C:%.*]] = add i8 [[A:%.*]], 3
796 ; CHECK-NEXT:    br label [[DISPATCH:%.*]]
797 ; CHECK:       dispatch:
798 ; CHECK-NEXT:    switch i8 [[A]], label [[DISPATCH]] [
799 ; CHECK-NEXT:    i8 93, label [[TARGET93:%.*]]
800 ; CHECK-NEXT:    i8 -111, label [[DISPATCH]]
801 ; CHECK-NEXT:    ]
802 ; CHECK:       target93:
803 ; CHECK-NEXT:    ret i8 96
805 entry:
806   %c = add i8 %a, 3
807   br label %dispatch
809 dispatch:
810   switch i8 %a, label %dispatch [
811   i8 93, label %target93
812   i8 -111, label %dispatch
813   ]
815 target93:
816   ret i8 %c
819 ; Negative test. Shouldn't be incorrectly optimized to "ret i1 false".
821 define i1 @test20(i64 %a) {
822 ; CHECK-LABEL: @test20(
823 ; CHECK-NEXT:  entry:
824 ; CHECK-NEXT:    [[B:%.*]] = and i64 [[A:%.*]], 7
825 ; CHECK-NEXT:    br label [[DISPATCH:%.*]]
826 ; CHECK:       dispatch:
827 ; CHECK-NEXT:    switch i64 [[A]], label [[DEFAULT:%.*]] [
828 ; CHECK-NEXT:    i64 0, label [[EXIT2:%.*]]
829 ; CHECK-NEXT:    i64 -2147483647, label [[EXIT2]]
830 ; CHECK-NEXT:    ]
831 ; CHECK:       default:
832 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i64 [[B]], 0
833 ; CHECK-NEXT:    br label [[EXIT:%.*]]
834 ; CHECK:       exit:
835 ; CHECK-NEXT:    ret i1 [[C]]
836 ; CHECK:       exit2:
837 ; CHECK-NEXT:    ret i1 false
839 entry:
840   %b = and i64 %a, 7
841   br label %dispatch
843 dispatch:
844   switch i64 %a, label %default [
845   i64 0, label %exit2
846   i64 -2147483647, label %exit2
847   ]
849 default:
850   %c = icmp eq i64 %b, 0
851   br label %exit
853 exit:
854   ret i1 %c
856 exit2:
857   ret i1 false
860 define i1 @slt(i8 %a, i8 %b) {
861 ; CHECK-LABEL: @slt(
862 ; CHECK-NEXT:  entry:
863 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[A:%.*]], [[B:%.*]]
864 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
865 ; CHECK-NEXT:    ret i1 true
867 entry:
868   %cmp = icmp slt i8 %a, %b
869   call void @llvm.assume(i1 %cmp)
870   %res = icmp slt i8 %a, 127
871   ret i1 %res
874 define i1 @sgt(i8 %a, i8 %b) {
875 ; CHECK-LABEL: @sgt(
876 ; CHECK-NEXT:  entry:
877 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], [[B:%.*]]
878 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
879 ; CHECK-NEXT:    ret i1 true
881 entry:
882   %cmp = icmp sgt i8 %a, %b
883   call void @llvm.assume(i1 %cmp)
884   %res = icmp sgt i8 %a, -128
885   ret i1 %res
888 define i1 @ult(i8 %a, i8 %b) {
889 ; CHECK-LABEL: @ult(
890 ; CHECK-NEXT:  entry:
891 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[A:%.*]], [[B:%.*]]
892 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
893 ; CHECK-NEXT:    ret i1 true
895 entry:
896   %cmp = icmp ult i8 %a, %b
897   call void @llvm.assume(i1 %cmp)
898   %res = icmp ult i8 %a, 255
899   ret i1 %res
902 define i1 @ugt(i8 %a, i8 %b) {
903 ; CHECK-LABEL: @ugt(
904 ; CHECK-NEXT:  entry:
905 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[A:%.*]], [[B:%.*]]
906 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
907 ; CHECK-NEXT:    ret i1 true
909 entry:
910   %cmp = icmp ugt i8 %a, %b
911   call void @llvm.assume(i1 %cmp)
912   %res = icmp ugt i8 %a, 0
913   ret i1 %res
916 declare void @llvm.assume(i1)