[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / llvm / test / Transforms / CorrelatedValuePropagation / basic.ll
bloba0175f3ebdd73193fe32f42ca8a4698ba5a9fed3
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2 ; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s
3 ; PR2581
5 define i32 @test1(i1 %C) {
6 ; CHECK-LABEL: define range(i32 10, 12) i32 @test1
7 ; CHECK-SAME: (i1 [[C:%.*]]) {
8 ; CHECK-NEXT:    br i1 [[C]], label [[EXIT:%.*]], label [[BODY:%.*]]
9 ; CHECK:       body:
10 ; CHECK-NEXT:    ret i32 11
11 ; CHECK:       exit:
12 ; CHECK-NEXT:    ret i32 10
14   br i1 %C, label %exit, label %body
16 body:           ; preds = %0
17   %A = select i1 %C, i32 10, i32 11
18   ret i32 %A
20 exit:           ; preds = %0
21   ret i32 10
24 ; PR4420
25 declare i1 @ext()
26 define i1 @test2() {
27 ; CHECK-LABEL: define i1 @test2() {
28 ; CHECK-NEXT:  entry:
29 ; CHECK-NEXT:    [[COND:%.*]] = tail call i1 @ext()
30 ; CHECK-NEXT:    br i1 [[COND]], label [[BB1:%.*]], label [[BB2:%.*]]
31 ; CHECK:       bb1:
32 ; CHECK-NEXT:    [[COND2:%.*]] = tail call i1 @ext()
33 ; CHECK-NEXT:    br i1 [[COND2]], label [[BB3:%.*]], label [[BB2]]
34 ; CHECK:       bb2:
35 ; CHECK-NEXT:    ret i1 false
36 ; CHECK:       bb3:
37 ; CHECK-NEXT:    [[RES:%.*]] = tail call i1 @ext()
38 ; CHECK-NEXT:    ret i1 [[RES]]
40 entry:
41   %cond = tail call i1 @ext()
42   br i1 %cond, label %bb1, label %bb2
44 bb1:
45   %cond2 = tail call i1 @ext()
46   br i1 %cond2, label %bb3, label %bb2
48 bb2:
49   %cond_merge = phi i1 [ %cond, %entry ], [ false, %bb1 ]
50   ret i1 %cond_merge
52 bb3:
53   %res = tail call i1 @ext()
54   ret i1 %res
57 ; PR4855
58 @gv = internal constant i8 7
59 define i8 @test3(ptr %a) nounwind {
60 ; CHECK-LABEL: define i8 @test3
61 ; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
62 ; CHECK-NEXT:  entry:
63 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq ptr [[A]], @gv
64 ; CHECK-NEXT:    br i1 [[COND]], label [[BB2:%.*]], label [[BB:%.*]]
65 ; CHECK:       bb:
66 ; CHECK-NEXT:    ret i8 0
67 ; CHECK:       bb2:
68 ; CHECK-NEXT:    [[SHOULD_BE_CONST:%.*]] = load i8, ptr [[A]], align 1
69 ; CHECK-NEXT:    ret i8 [[SHOULD_BE_CONST]]
71 entry:
72   %cond = icmp eq ptr %a, @gv
73   br i1 %cond, label %bb2, label %bb
75 bb:
76   ret i8 0
78 bb2:
79   %should_be_const = load i8, ptr %a
80   ret i8 %should_be_const
83 ; PR1757
84 define i32 @test4(i32) {
85 ; CHECK-LABEL: define range(i32 0, 3) i32 @test4
86 ; CHECK-SAME: (i32 [[TMP0:%.*]]) {
87 ; CHECK-NEXT:  EntryBlock:
88 ; CHECK-NEXT:    [[DOTDEMORGAN:%.*]] = icmp sgt i32 [[TMP0]], 2
89 ; CHECK-NEXT:    br i1 [[DOTDEMORGAN]], label [[GREATERTHANTWO:%.*]], label [[LESSTHANOREQUALTOTWO:%.*]]
90 ; CHECK:       GreaterThanTwo:
91 ; CHECK-NEXT:    br i1 false, label [[IMPOSSIBLE:%.*]], label [[NOTTWOANDGREATERTHANTWO:%.*]]
92 ; CHECK:       NotTwoAndGreaterThanTwo:
93 ; CHECK-NEXT:    ret i32 2
94 ; CHECK:       Impossible:
95 ; CHECK-NEXT:    ret i32 1
96 ; CHECK:       LessThanOrEqualToTwo:
97 ; CHECK-NEXT:    ret i32 0
99 EntryBlock:
100   %.demorgan = icmp sgt i32 %0, 2
101   br i1 %.demorgan, label %GreaterThanTwo, label %LessThanOrEqualToTwo
103 GreaterThanTwo:
104   icmp eq i32 %0, 2
105   br i1 %1, label %Impossible, label %NotTwoAndGreaterThanTwo
107 NotTwoAndGreaterThanTwo:
108   ret i32 2
110 Impossible:
111   ret i32 1
113 LessThanOrEqualToTwo:
114   ret i32 0
117 declare ptr @f(ptr)
118 define void @test5(ptr %x, ptr %y) {
119 ; CHECK-LABEL: define void @test5
120 ; CHECK-SAME: (ptr [[X:%.*]], ptr [[Y:%.*]]) {
121 ; CHECK-NEXT:  entry:
122 ; CHECK-NEXT:    [[PRE:%.*]] = icmp eq ptr [[X]], null
123 ; CHECK-NEXT:    br i1 [[PRE]], label [[RETURN:%.*]], label [[LOOP:%.*]]
124 ; CHECK:       loop:
125 ; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[F:%.*]], [[LOOP]] ], [ [[X]], [[ENTRY:%.*]] ]
126 ; CHECK-NEXT:    [[F]] = tail call ptr @f(ptr [[PHI]])
127 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne ptr [[F]], [[Y]]
128 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP1]], ptr [[F]], ptr null
129 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq ptr [[SEL]], null
130 ; CHECK-NEXT:    br i1 [[CMP2]], label [[RETURN]], label [[LOOP]]
131 ; CHECK:       return:
132 ; CHECK-NEXT:    ret void
134 entry:
135   %pre = icmp eq ptr %x, null
136   br i1 %pre, label %return, label %loop
138 loop:
139   %phi = phi ptr [ %sel, %loop ], [ %x, %entry ]
140   %f = tail call ptr @f(ptr %phi)
141   %cmp1 = icmp ne ptr %f, %y
142   %sel = select i1 %cmp1, ptr %f, ptr null
143   %cmp2 = icmp eq ptr %sel, null
144   br i1 %cmp2, label %return, label %loop
146 return:
147   ret void
150 ; "false" case for CorrelatedValuePropagation
151 define void @loop1(ptr %x, ptr %y) {
152 ; CHECK-LABEL: define void @loop1
153 ; CHECK-SAME: (ptr [[X:%.*]], ptr [[Y:%.*]]) {
154 ; CHECK-NEXT:  entry:
155 ; CHECK-NEXT:    br label [[LOOP:%.*]]
156 ; CHECK:       loop:
157 ; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[F:%.*]], [[LOOP]] ], [ [[X]], [[ENTRY:%.*]] ]
158 ; CHECK-NEXT:    [[F]] = tail call ptr @f(ptr [[PHI]])
159 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne ptr [[F]], [[Y]]
160 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP1]], ptr [[F]], ptr null
161 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq ptr [[SEL]], null
162 ; CHECK-NEXT:    br i1 [[CMP2]], label [[RETURN:%.*]], label [[LOOP]]
163 ; CHECK:       return:
164 ; CHECK-NEXT:    ret void
166 entry:
167   br label %loop
169 loop:
170   %phi = phi ptr [ %sel, %loop ], [ %x, %entry ]
171   %f = tail call ptr @f(ptr %phi)
172   %cmp1 = icmp ne ptr %f, %y
173   %sel = select i1 %cmp1, ptr %f, ptr null
174   %cmp2 = icmp eq ptr %sel, null
175   br i1 %cmp2, label %return, label %loop
177 return:
178   ret void
181 ; "true" case for CorrelatedValuePropagation
182 define void @loop2(ptr %x, ptr %y) {
183 ; CHECK-LABEL: define void @loop2
184 ; CHECK-SAME: (ptr [[X:%.*]], ptr [[Y:%.*]]) {
185 ; CHECK-NEXT:  entry:
186 ; CHECK-NEXT:    br label [[LOOP:%.*]]
187 ; CHECK:       loop:
188 ; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[F:%.*]], [[LOOP]] ], [ [[X]], [[ENTRY:%.*]] ]
189 ; CHECK-NEXT:    [[F]] = tail call ptr @f(ptr [[PHI]])
190 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq ptr [[F]], [[Y]]
191 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP1]], ptr null, ptr [[F]]
192 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq ptr [[SEL]], null
193 ; CHECK-NEXT:    br i1 [[CMP2]], label [[RETURN:%.*]], label [[LOOP]]
194 ; CHECK:       return:
195 ; CHECK-NEXT:    ret void
197 entry:
198   br label %loop
200 loop:
201   %phi = phi ptr [ %sel, %loop ], [ %x, %entry ]
202   %f = tail call ptr @f(ptr %phi)
203   %cmp1 = icmp eq ptr %f, %y
204   %sel = select i1 %cmp1, ptr null, ptr %f
205   %cmp2 = icmp eq ptr %sel, null
206   br i1 %cmp2, label %return, label %loop
208 return:
209   ret void
212 define i32 @switch1(i32 %s) {
213 ; CHECK-LABEL: define range(i32 -1, 2) i32 @switch1
214 ; CHECK-SAME: (i32 [[S:%.*]]) {
215 ; CHECK-NEXT:  entry:
216 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[S]], 0
217 ; CHECK-NEXT:    br i1 [[CMP]], label [[NEGATIVE:%.*]], label [[OUT:%.*]]
218 ; CHECK:       negative:
219 ; CHECK-NEXT:    switch i32 [[S]], label [[OUT]] [
220 ; CHECK-NEXT:      i32 -2, label [[NEXT:%.*]]
221 ; CHECK-NEXT:      i32 -1, label [[NEXT]]
222 ; CHECK-NEXT:    ]
223 ; CHECK:       out:
224 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ -1, [[NEGATIVE]] ]
225 ; CHECK-NEXT:    ret i32 [[P]]
226 ; CHECK:       next:
227 ; CHECK-NEXT:    ret i32 0
229 entry:
230   %cmp = icmp slt i32 %s, 0
231   br i1 %cmp, label %negative, label %out
233 negative:
234   switch i32 %s, label %out [
235   i32 0, label %out
236   i32 1, label %out
237   i32 -1, label %next
238   i32 -2, label %next
239   i32 2, label %out
240   i32 3, label %out
241   ]
243 out:
244   %p = phi i32 [ 1, %entry ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ]
245   ret i32 %p
247 next:
248   %q = phi i32 [ 0, %negative ], [ 0, %negative ]
249   ret i32 %q
252 define i32 @switch2(i32 %s) {
253 ; CHECK-LABEL: define range(i32 -1, 2) i32 @switch2
254 ; CHECK-SAME: (i32 [[S:%.*]]) {
255 ; CHECK-NEXT:  entry:
256 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[S]], 0
257 ; CHECK-NEXT:    br i1 [[CMP]], label [[POSITIVE:%.*]], label [[OUT:%.*]]
258 ; CHECK:       positive:
259 ; CHECK-NEXT:    br label [[OUT]]
260 ; CHECK:       out:
261 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ 1, [[POSITIVE]] ]
262 ; CHECK-NEXT:    ret i32 [[P]]
263 ; CHECK:       next:
264 ; CHECK-NEXT:    ret i32 0
266 entry:
267   %cmp = icmp sgt i32 %s, 0
268   br i1 %cmp, label %positive, label %out
270 positive:
271   switch i32 %s, label %out [
272   i32 0, label %out
273   i32 -1, label %next
274   i32 -2, label %next
275   ]
277 out:
278   %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]
279   ret i32 %p
281 next:
282   %q = phi i32 [ 0, %positive ], [ 0, %positive ]
283   ret i32 %q
286 define i32 @switch3(i32 %s) {
287 ; CHECK-LABEL: define range(i32 -1, 2) i32 @switch3
288 ; CHECK-SAME: (i32 [[S:%.*]]) {
289 ; CHECK-NEXT:  entry:
290 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[S]], 0
291 ; CHECK-NEXT:    br i1 [[CMP]], label [[POSITIVE:%.*]], label [[OUT:%.*]]
292 ; CHECK:       positive:
293 ; CHECK-NEXT:    br label [[OUT]]
294 ; CHECK:       out:
295 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ 1, [[POSITIVE]] ]
296 ; CHECK-NEXT:    ret i32 [[P]]
297 ; CHECK:       next:
298 ; CHECK-NEXT:    ret i32 0
300 entry:
301   %cmp = icmp sgt i32 %s, 0
302   br i1 %cmp, label %positive, label %out
304 positive:
305   switch i32 %s, label %out [
306   i32 -1, label %out
307   i32 -2, label %next
308   i32 -3, label %next
309   ]
311 out:
312   %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]
313   ret i32 %p
315 next:
316   %q = phi i32 [ 0, %positive ], [ 0, %positive ]
317   ret i32 %q
320 define void @switch4(i32 %s) {
321 ; CHECK-LABEL: define void @switch4
322 ; CHECK-SAME: (i32 [[S:%.*]]) {
323 ; CHECK-NEXT:  entry:
324 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[S]], 0
325 ; CHECK-NEXT:    br i1 [[CMP]], label [[ZERO:%.*]], label [[OUT:%.*]]
326 ; CHECK:       zero:
327 ; CHECK-NEXT:    br label [[NEXT:%.*]]
328 ; CHECK:       out:
329 ; CHECK-NEXT:    ret void
330 ; CHECK:       next:
331 ; CHECK-NEXT:    ret void
333 entry:
334   %cmp = icmp eq i32 %s, 0
335   br i1 %cmp, label %zero, label %out
337 zero:
338   switch i32 %s, label %out [
339   i32 0, label %next
340   i32 1, label %out
341   i32 -1, label %out
342   ]
344 out:
345   ret void
347 next:
348   ret void
351 define void @switch_nonzero_zext(i8 %s) {
352 ; CHECK-LABEL: define void @switch_nonzero_zext
353 ; CHECK-SAME: (i8 [[S:%.*]]) {
354 ; CHECK-NEXT:  entry:
355 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[S]], 0
356 ; CHECK-NEXT:    br i1 [[CMP]], label [[SWITCH:%.*]], label [[EXIT:%.*]]
357 ; CHECK:       switch:
358 ; CHECK-NEXT:    [[S_EXT:%.*]] = zext i8 [[S]] to i32
359 ; CHECK-NEXT:    br label [[EXIT]]
360 ; CHECK:       exit:
361 ; CHECK-NEXT:    ret void
362 ; CHECK:       unreachable:
363 ; CHECK-NEXT:    ret void
365 entry:
366   %cmp = icmp ne i8 %s, 0
367   br i1 %cmp, label %switch, label %exit
369 switch:
370   %s.ext = zext i8 %s to i32
371   switch i32 %s.ext, label %exit [
372   i32 0, label %unreachable
373   i32 1, label %exit
374   i32 -1, label %exit
375   ]
377 exit:
378   ret void
380 unreachable:
381   ret void
384 define void @switch_assume_nonzero(i32 %s) {
385 ; CHECK-LABEL: define void @switch_assume_nonzero
386 ; CHECK-SAME: (i32 [[S:%.*]]) {
387 ; CHECK-NEXT:  entry:
388 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[S]], 0
389 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
390 ; CHECK-NEXT:    br label [[EXIT:%.*]]
391 ; CHECK:       exit:
392 ; CHECK-NEXT:    ret void
393 ; CHECK:       unreachable:
394 ; CHECK-NEXT:    ret void
396 entry:
397   %cmp = icmp ne i32 %s, 0
398   call void @llvm.assume(i1 %cmp)
399   switch i32 %s, label %exit [
400   i32 0, label %unreachable
401   i32 1, label %exit
402   i32 -1, label %exit
403   ]
405 exit:
406   ret void
408 unreachable:
409   ret void
412 define void @switch_nonzero_phi(i1 %cond) {
413 ; CHECK-LABEL: define void @switch_nonzero_phi
414 ; CHECK-SAME: (i1 [[COND:%.*]]) {
415 ; CHECK-NEXT:  entry:
416 ; CHECK-NEXT:    br i1 [[COND]], label [[IF:%.*]], label [[ELSE:%.*]]
417 ; CHECK:       if:
418 ; CHECK-NEXT:    br label [[SWITCH:%.*]]
419 ; CHECK:       else:
420 ; CHECK-NEXT:    br label [[SWITCH]]
421 ; CHECK:       switch:
422 ; CHECK-NEXT:    [[S:%.*]] = phi i32 [ 1, [[IF]] ], [ -1, [[ELSE]] ]
423 ; CHECK-NEXT:    br label [[EXIT:%.*]]
424 ; CHECK:       exit:
425 ; CHECK-NEXT:    ret void
426 ; CHECK:       unreachable:
427 ; CHECK-NEXT:    ret void
429 entry:
430   br i1 %cond, label %if, label %else
433   br label %switch
435 else:
436   br label %switch
438 switch:
439   %s = phi i32 [ 1, %if ], [ -1, %else ]
440   switch i32 %s, label %exit [
441   i32 0, label %unreachable
442   i32 1, label %exit
443   i32 -1, label %exit
444   ]
446 exit:
447   ret void
449 unreachable:
450   ret void
453 define i32 @switch_range(i32 %cond) {
454 ; CHECK-LABEL: define range(i32 1, 3) i32 @switch_range
455 ; CHECK-SAME: (i32 [[COND:%.*]]) {
456 ; CHECK-NEXT:  entry:
457 ; CHECK-NEXT:    [[S:%.*]] = urem i32 [[COND]], 3
458 ; CHECK-NEXT:    [[S1:%.*]] = add nuw nsw i32 [[S]], 1
459 ; CHECK-NEXT:    switch i32 [[S1]], label [[DEFAULT_UNREACHABLE:%.*]] [
460 ; CHECK-NEXT:      i32 1, label [[EXIT1:%.*]]
461 ; CHECK-NEXT:      i32 2, label [[EXIT2:%.*]]
462 ; CHECK-NEXT:      i32 3, label [[EXIT1]]
463 ; CHECK-NEXT:    ]
464 ; CHECK:       exit1:
465 ; CHECK-NEXT:    ret i32 1
466 ; CHECK:       exit2:
467 ; CHECK-NEXT:    ret i32 2
468 ; CHECK:       default.unreachable:
469 ; CHECK-NEXT:    unreachable
470 ; CHECK:       unreachable:
471 ; CHECK-NEXT:    ret i32 0
473 entry:
474   %s = urem i32 %cond, 3
475   %s1 = add i32 %s, 1
476   switch i32 %s1, label %unreachable [
477   i32 1, label %exit1
478   i32 2, label %exit2
479   i32 3, label %exit1
480   ]
482 exit1:
483   ret i32 1
484 exit2:
485   ret i32 2
486 unreachable:
487   ret i32 0
490 ; If the cases do not cover the entire range of the
491 ; switch condition, we should not change the default.
493 define i32 @switch_range_not_full(i32 %cond) {
494 ; CHECK-LABEL: define range(i32 0, 3) i32 @switch_range_not_full
495 ; CHECK-SAME: (i32 [[COND:%.*]]) {
496 ; CHECK-NEXT:  entry:
497 ; CHECK-NEXT:    [[S:%.*]] = urem i32 [[COND]], 3
498 ; CHECK-NEXT:    [[S1:%.*]] = add nuw nsw i32 [[S]], 1
499 ; CHECK-NEXT:    switch i32 [[S1]], label [[UNREACHABLE:%.*]] [
500 ; CHECK-NEXT:      i32 1, label [[EXIT1:%.*]]
501 ; CHECK-NEXT:      i32 3, label [[EXIT2:%.*]]
502 ; CHECK-NEXT:    ]
503 ; CHECK:       exit1:
504 ; CHECK-NEXT:    ret i32 1
505 ; CHECK:       exit2:
506 ; CHECK-NEXT:    ret i32 2
507 ; CHECK:       unreachable:
508 ; CHECK-NEXT:    ret i32 0
510 entry:
511   %s = urem i32 %cond, 3
512   %s1 = add i32 %s, 1
513   switch i32 %s1, label %unreachable [
514   i32 1, label %exit1
515   i32 3, label %exit2
516   ]
518 exit1:
519   ret i32 1
520 exit2:
521   ret i32 2
522 unreachable:
523   ret i32 0
526 ; PR51531
528 define i8 @switch_defaultdest_multipleuse(i8 %t0) {
529 ; CHECK-LABEL: define i8 @switch_defaultdest_multipleuse
530 ; CHECK-SAME: (i8 [[T0:%.*]]) {
531 ; CHECK-NEXT:  entry:
532 ; CHECK-NEXT:    [[O:%.*]] = or i8 [[T0]], 1
533 ; CHECK-NEXT:    [[R:%.*]] = srem i8 1, [[O]]
534 ; CHECK-NEXT:    br label [[EXIT:%.*]]
535 ; CHECK:       default.unreachable:
536 ; CHECK-NEXT:    unreachable
537 ; CHECK:       exit:
538 ; CHECK-NEXT:    ret i8 0
540 entry:
541   %o = or i8 %t0, 1
542   %r = srem i8 1, %o
543   switch i8 %r, label %exit [
544   i8 0, label %exit
545   i8 1, label %exit
546   ]
548 exit:
549   ret i8 0
552 define i1 @arg_attribute(ptr nonnull %a) {
553 ; CHECK-LABEL: define i1 @arg_attribute
554 ; CHECK-SAME: (ptr nonnull [[A:%.*]]) {
555 ; CHECK-NEXT:    ret i1 false
557   %cmp = icmp eq ptr %a, null
558   ret i1 %cmp
561 declare nonnull ptr @return_nonnull()
562 define i1 @call_attribute() {
563 ; CHECK-LABEL: define i1 @call_attribute() {
564 ; CHECK-NEXT:    [[A:%.*]] = call ptr @return_nonnull()
565 ; CHECK-NEXT:    ret i1 false
567   %a = call ptr @return_nonnull()
568   %cmp = icmp eq ptr %a, null
569   ret i1 %cmp
572 define i1 @umin(i32 %a, i32 %b) {
573 ; CHECK-LABEL: define i1 @umin
574 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
575 ; CHECK-NEXT:  entry:
576 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A]], 5
577 ; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
578 ; CHECK:       a_guard:
579 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[B]], 20
580 ; CHECK-NEXT:    br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
581 ; CHECK:       b_guard:
582 ; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp samesign ult i32 [[A]], [[B]]
583 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
584 ; CHECK-NEXT:    ret i1 false
585 ; CHECK:       out:
586 ; CHECK-NEXT:    ret i1 false
588 entry:
589   %cmp = icmp ult i32 %a, 5
590   br i1 %cmp, label %a_guard, label %out
592 a_guard:
593   %cmp2 = icmp ult i32 %b, 20
594   br i1 %cmp2, label %b_guard, label %out
596 b_guard:
597   %sel_cmp = icmp ult i32 %a, %b
598   %min = select i1 %sel_cmp, i32 %a, i32 %b
599   %res = icmp eq i32 %min, 7
600   ret i1 %res
601 out:
602   ret i1 false
605 define i1 @smin(i32 %a, i32 %b) {
606 ; CHECK-LABEL: define i1 @smin
607 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
608 ; CHECK-NEXT:  entry:
609 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A]], 5
610 ; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
611 ; CHECK:       a_guard:
612 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[B]], 20
613 ; CHECK-NEXT:    br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
614 ; CHECK:       b_guard:
615 ; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp samesign ule i32 [[A]], [[B]]
616 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
617 ; CHECK-NEXT:    ret i1 false
618 ; CHECK:       out:
619 ; CHECK-NEXT:    ret i1 false
621 entry:
622   %cmp = icmp ult i32 %a, 5
623   br i1 %cmp, label %a_guard, label %out
625 a_guard:
626   %cmp2 = icmp ult i32 %b, 20
627   br i1 %cmp2, label %b_guard, label %out
629 b_guard:
630   %sel_cmp = icmp sle i32 %a, %b
631   %min = select i1 %sel_cmp, i32 %a, i32 %b
632   %res = icmp eq i32 %min, 7
633   ret i1 %res
634 out:
635   ret i1 false
638 define i1 @smax(i32 %a, i32 %b) {
639 ; CHECK-LABEL: define i1 @smax
640 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
641 ; CHECK-NEXT:  entry:
642 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A]], 5
643 ; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
644 ; CHECK:       a_guard:
645 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[B]], 20
646 ; CHECK-NEXT:    br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
647 ; CHECK:       b_guard:
648 ; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp samesign uge i32 [[A]], [[B]]
649 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
650 ; CHECK-NEXT:    ret i1 false
651 ; CHECK:       out:
652 ; CHECK-NEXT:    ret i1 false
654 entry:
655   %cmp = icmp sgt i32 %a, 5
656   br i1 %cmp, label %a_guard, label %out
658 a_guard:
659   %cmp2 = icmp sgt i32 %b, 20
660   br i1 %cmp2, label %b_guard, label %out
662 b_guard:
663   %sel_cmp = icmp sge i32 %a, %b
664   %max = select i1 %sel_cmp, i32 %a, i32 %b
665   %res = icmp eq i32 %max, 7
666   ret i1 %res
667 out:
668   ret i1 false
671 define i1 @umax(i32 %a, i32 %b) {
672 ; CHECK-LABEL: define i1 @umax
673 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
674 ; CHECK-NEXT:  entry:
675 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A]], 5
676 ; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
677 ; CHECK:       a_guard:
678 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[B]], 20
679 ; CHECK-NEXT:    br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
680 ; CHECK:       b_guard:
681 ; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp samesign uge i32 [[A]], [[B]]
682 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
683 ; CHECK-NEXT:    ret i1 false
684 ; CHECK:       out:
685 ; CHECK-NEXT:    ret i1 false
687 entry:
688   %cmp = icmp sgt i32 %a, 5
689   br i1 %cmp, label %a_guard, label %out
691 a_guard:
692   %cmp2 = icmp sgt i32 %b, 20
693   br i1 %cmp2, label %b_guard, label %out
695 b_guard:
696   %sel_cmp = icmp uge i32 %a, %b
697   %max = select i1 %sel_cmp, i32 %a, i32 %b
698   %res = icmp eq i32 %max, 7
699   ret i1 %res
700 out:
701   ret i1 false
704 define i1 @umin_lhs_overdefined_rhs_const(i32 %a) {
705 ; CHECK-LABEL: define i1 @umin_lhs_overdefined_rhs_const
706 ; CHECK-SAME: (i32 [[A:%.*]]) {
707 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A]], 42
708 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 [[A]], i32 42
709 ; CHECK-NEXT:    ret i1 true
711   %cmp = icmp ult i32 %a, 42
712   %sel = select i1 %cmp, i32 %a, i32 42
713   %cmp2 = icmp ule i32 %sel, 42
714   ret i1 %cmp2
717 define i1 @umin_rhs_overdefined_lhs_const(i32 %a) {
718 ; CHECK-LABEL: define i1 @umin_rhs_overdefined_lhs_const
719 ; CHECK-SAME: (i32 [[A:%.*]]) {
720 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[A]], 42
721 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 42, i32 [[A]]
722 ; CHECK-NEXT:    ret i1 true
724   %cmp = icmp uge i32 %a, 42
725   %sel = select i1 %cmp, i32 42, i32 %a
726   %cmp2 = icmp ule i32 %sel, 42
727   ret i1 %cmp2
730 define i1 @umin_lhs_overdefined_rhs_range(i32 %a, i32 %b) {
731 ; CHECK-LABEL: define i1 @umin_lhs_overdefined_rhs_range
732 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
733 ; CHECK-NEXT:    [[ASSUME:%.*]] = icmp ult i32 [[B]], 42
734 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME]])
735 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A]], [[B]]
736 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[B]]
737 ; CHECK-NEXT:    ret i1 true
739   %assume = icmp ult i32 %b, 42
740   call void @llvm.assume(i1 %assume)
741   %cmp = icmp ult i32 %a, %b
742   %sel = select i1 %cmp, i32 %a, i32 %b
743   %cmp2 = icmp ult i32 %sel, 42
744   ret i1 %cmp2
747 define i1 @umin_rhs_overdefined_lhs_range(i32 %a, i32 %b) {
748 ; CHECK-LABEL: define i1 @umin_rhs_overdefined_lhs_range
749 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
750 ; CHECK-NEXT:    [[ASSUME:%.*]] = icmp ult i32 [[B]], 42
751 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME]])
752 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[A]], [[B]]
753 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 [[B]], i32 [[A]]
754 ; CHECK-NEXT:    ret i1 true
756   %assume = icmp ult i32 %b, 42
757   call void @llvm.assume(i1 %assume)
758   %cmp = icmp uge i32 %a, %b
759   %sel = select i1 %cmp, i32 %b, i32 %a
760   %cmp2 = icmp ult i32 %sel, 42
761   ret i1 %cmp2
764 define i1 @clamp_low1(i32 noundef %a) {
765 ; CHECK-LABEL: define i1 @clamp_low1
766 ; CHECK-SAME: (i32 noundef [[A:%.*]]) {
767 ; CHECK-NEXT:  entry:
768 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[A]], 5
769 ; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
770 ; CHECK:       a_guard:
771 ; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5
772 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], -1
773 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
774 ; CHECK-NEXT:    ret i1 false
775 ; CHECK:       out:
776 ; CHECK-NEXT:    ret i1 false
778 entry:
779   %cmp = icmp sge i32 %a, 5
780   br i1 %cmp, label %a_guard, label %out
782 a_guard:
783   %sel_cmp = icmp eq i32 %a, 5
784   %add = add i32 %a, -1
785   %sel = select i1 %sel_cmp, i32 5, i32 %add
786   %res = icmp eq i32 %sel, 4
787   ret i1 %res
788 out:
789   ret i1 false
792 define i1 @clamp_low2(i32 noundef %a) {
793 ; CHECK-LABEL: define i1 @clamp_low2
794 ; CHECK-SAME: (i32 noundef [[A:%.*]]) {
795 ; CHECK-NEXT:  entry:
796 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[A]], 5
797 ; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
798 ; CHECK:       a_guard:
799 ; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5
800 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], -1
801 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
802 ; CHECK-NEXT:    ret i1 false
803 ; CHECK:       out:
804 ; CHECK-NEXT:    ret i1 false
806 entry:
807   %cmp = icmp sge i32 %a, 5
808   br i1 %cmp, label %a_guard, label %out
810 a_guard:
811   %sel_cmp = icmp ne i32 %a, 5
812   %add = add i32 %a, -1
813   %sel = select i1 %sel_cmp, i32 %add, i32 5
814   %res = icmp eq i32 %sel, 4
815   ret i1 %res
816 out:
817   ret i1 false
820 define i1 @clamp_low3(i32 noundef %a) {
821 ; CHECK-LABEL: define i1 @clamp_low3
822 ; CHECK-SAME: (i32 noundef [[A:%.*]]) {
823 ; CHECK-NEXT:  entry:
824 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[A]], 5
825 ; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
826 ; CHECK:       a_guard:
827 ; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp samesign ugt i32 [[A]], 5
828 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], -1
829 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
830 ; CHECK-NEXT:    ret i1 false
831 ; CHECK:       out:
832 ; CHECK-NEXT:    ret i1 false
834 entry:
835   %cmp = icmp sge i32 %a, 5
836   br i1 %cmp, label %a_guard, label %out
838 a_guard:
839   %sel_cmp = icmp sgt i32 %a, 5
840   %add = add i32 %a, -1
841   %sel = select i1 %sel_cmp, i32 %add, i32 5
842   %res = icmp eq i32 %sel, 4
843   ret i1 %res
844 out:
845   ret i1 false
848 define i1 @clamp_low4(i32 noundef %a) {
849 ; CHECK-LABEL: define i1 @clamp_low4
850 ; CHECK-SAME: (i32 noundef [[A:%.*]]) {
851 ; CHECK-NEXT:  entry:
852 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[A]], 5
853 ; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
854 ; CHECK:       a_guard:
855 ; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp samesign ule i32 [[A]], 5
856 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], -1
857 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
858 ; CHECK-NEXT:    ret i1 false
859 ; CHECK:       out:
860 ; CHECK-NEXT:    ret i1 false
862 entry:
863   %cmp = icmp sge i32 %a, 5
864   br i1 %cmp, label %a_guard, label %out
866 a_guard:
867   %sel_cmp = icmp sle i32 %a, 5
868   %add = add i32 %a, -1
869   %sel = select i1 %sel_cmp, i32 5, i32 %add
870   %res = icmp eq i32 %sel, 4
871   ret i1 %res
872 out:
873   ret i1 false
876 define i1 @clamp_high1(i32 noundef %a) {
877 ; CHECK-LABEL: define i1 @clamp_high1
878 ; CHECK-SAME: (i32 noundef [[A:%.*]]) {
879 ; CHECK-NEXT:  entry:
880 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A]], 5
881 ; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
882 ; CHECK:       a_guard:
883 ; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5
884 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 1
885 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
886 ; CHECK-NEXT:    ret i1 false
887 ; CHECK:       out:
888 ; CHECK-NEXT:    ret i1 false
890 entry:
891   %cmp = icmp sle i32 %a, 5
892   br i1 %cmp, label %a_guard, label %out
894 a_guard:
895   %sel_cmp = icmp eq i32 %a, 5
896   %add = add i32 %a, 1
897   %sel = select i1 %sel_cmp, i32 5, i32 %add
898   %res = icmp eq i32 %sel, 6
899   ret i1 %res
900 out:
901   ret i1 false
904 define i1 @clamp_high1_or(i32 noundef %a) {
905 ; CHECK-LABEL: define i1 @clamp_high1_or
906 ; CHECK-SAME: (i32 noundef [[A:%.*]]) {
907 ; CHECK-NEXT:  entry:
908 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A]], 5
909 ; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
910 ; CHECK:       a_guard:
911 ; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5
912 ; CHECK-NEXT:    [[ADD:%.*]] = or disjoint i32 [[A]], 1
913 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
914 ; CHECK-NEXT:    ret i1 false
915 ; CHECK:       out:
916 ; CHECK-NEXT:    ret i1 false
918 entry:
919   %cmp = icmp sle i32 %a, 5
920   br i1 %cmp, label %a_guard, label %out
922 a_guard:
923   %sel_cmp = icmp eq i32 %a, 5
924   %add = or disjoint i32 %a, 1
925   %sel = select i1 %sel_cmp, i32 5, i32 %add
926   %res = icmp eq i32 %sel, 6
927   ret i1 %res
928 out:
929   ret i1 false
932 define i1 @clamp_high2(i32 noundef %a) {
933 ; CHECK-LABEL: define i1 @clamp_high2
934 ; CHECK-SAME: (i32 noundef [[A:%.*]]) {
935 ; CHECK-NEXT:  entry:
936 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A]], 5
937 ; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
938 ; CHECK:       a_guard:
939 ; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5
940 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 1
941 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
942 ; CHECK-NEXT:    ret i1 false
943 ; CHECK:       out:
944 ; CHECK-NEXT:    ret i1 false
946 entry:
947   %cmp = icmp sle i32 %a, 5
948   br i1 %cmp, label %a_guard, label %out
950 a_guard:
951   %sel_cmp = icmp ne i32 %a, 5
952   %add = add i32 %a, 1
953   %sel = select i1 %sel_cmp, i32 %add, i32 5
954   %res = icmp eq i32 %sel, 6
955   ret i1 %res
956 out:
957   ret i1 false
961 define i1 @clamp_high2_or_disjoint(i32 noundef %a) {
962 ; CHECK-LABEL: define i1 @clamp_high2_or_disjoint
963 ; CHECK-SAME: (i32 noundef [[A:%.*]]) {
964 ; CHECK-NEXT:  entry:
965 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A]], 5
966 ; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
967 ; CHECK:       a_guard:
968 ; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5
969 ; CHECK-NEXT:    [[ADD:%.*]] = or disjoint i32 [[A]], 1
970 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
971 ; CHECK-NEXT:    ret i1 false
972 ; CHECK:       out:
973 ; CHECK-NEXT:    ret i1 false
975 entry:
976   %cmp = icmp sle i32 %a, 5
977   br i1 %cmp, label %a_guard, label %out
979 a_guard:
980   %sel_cmp = icmp ne i32 %a, 5
981   %add = or disjoint i32 %a, 1
982   %sel = select i1 %sel_cmp, i32 %add, i32 5
983   %res = icmp eq i32 %sel, 6
984   ret i1 %res
985 out:
986   ret i1 false
990 define i1 @clamp_high3(i32 noundef %a) {
991 ; CHECK-LABEL: define i1 @clamp_high3
992 ; CHECK-SAME: (i32 noundef [[A:%.*]]) {
993 ; CHECK-NEXT:  entry:
994 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A]], 5
995 ; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
996 ; CHECK:       a_guard:
997 ; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp slt i32 [[A]], 5
998 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 1
999 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
1000 ; CHECK-NEXT:    ret i1 false
1001 ; CHECK:       out:
1002 ; CHECK-NEXT:    ret i1 false
1004 entry:
1005   %cmp = icmp sle i32 %a, 5
1006   br i1 %cmp, label %a_guard, label %out
1008 a_guard:
1009   %sel_cmp = icmp slt i32 %a, 5
1010   %add = add i32 %a, 1
1011   %sel = select i1 %sel_cmp, i32 %add, i32 5
1012   %res = icmp eq i32 %sel, 6
1013   ret i1 %res
1014 out:
1015   ret i1 false
1018 define i1 @clamp_high4(i32 noundef %a) {
1019 ; CHECK-LABEL: define i1 @clamp_high4
1020 ; CHECK-SAME: (i32 noundef [[A:%.*]]) {
1021 ; CHECK-NEXT:  entry:
1022 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A]], 5
1023 ; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
1024 ; CHECK:       a_guard:
1025 ; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp sge i32 [[A]], 5
1026 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 1
1027 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
1028 ; CHECK-NEXT:    ret i1 false
1029 ; CHECK:       out:
1030 ; CHECK-NEXT:    ret i1 false
1032 entry:
1033   %cmp = icmp sle i32 %a, 5
1034   br i1 %cmp, label %a_guard, label %out
1036 a_guard:
1037   %sel_cmp = icmp sge i32 %a, 5
1038   %add = add i32 %a, 1
1039   %sel = select i1 %sel_cmp, i32 5, i32 %add
1040   %res = icmp eq i32 %sel, 6
1041   ret i1 %res
1042 out:
1043   ret i1 false
1046 ; Just showing arbitrary constants work, not really a clamp
1047 define i1 @not_clamp_high(i32 noundef %a) {
1048 ; CHECK-LABEL: define i1 @not_clamp_high
1049 ; CHECK-SAME: (i32 noundef [[A:%.*]]) {
1050 ; CHECK-NEXT:  entry:
1051 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A]], 5
1052 ; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
1053 ; CHECK:       a_guard:
1054 ; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5
1055 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 100
1056 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
1057 ; CHECK-NEXT:    ret i1 false
1058 ; CHECK:       out:
1059 ; CHECK-NEXT:    ret i1 false
1061 entry:
1062   %cmp = icmp sle i32 %a, 5
1063   br i1 %cmp, label %a_guard, label %out
1065 a_guard:
1066   %sel_cmp = icmp ne i32 %a, 5
1067   %add = add i32 %a, 100
1068   %sel = select i1 %sel_cmp, i32 %add, i32 5
1069   %res = icmp eq i32 %sel, 105
1070   ret i1 %res
1071 out:
1072   ret i1 false
1075 define void @abs1(i32 %a, ptr %p) {
1076 ; CHECK-LABEL: define void @abs1
1077 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1078 ; CHECK-NEXT:  entry:
1079 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A]], 10
1080 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
1081 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1082 ; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1083 ; CHECK:       guard:
1084 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 0, [[A]]
1085 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], 0
1086 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]]
1087 ; CHECK-NEXT:    store i1 true, ptr [[P]], align 1
1088 ; CHECK-NEXT:    [[C2:%.*]] = icmp samesign ult i32 [[ABS]], 19
1089 ; CHECK-NEXT:    store i1 [[C2]], ptr [[P]], align 1
1090 ; CHECK-NEXT:    store i1 true, ptr [[P]], align 1
1091 ; CHECK-NEXT:    [[C4:%.*]] = icmp samesign uge i32 [[ABS]], 1
1092 ; CHECK-NEXT:    store i1 [[C4]], ptr [[P]], align 1
1093 ; CHECK-NEXT:    br label [[EXIT]]
1094 ; CHECK:       exit:
1095 ; CHECK-NEXT:    ret void
1097 entry:
1098   %cmp1 = icmp slt i32 %a, 10
1099   %cmp2 = icmp sgt i32 %a, -20
1100   %and = and i1 %cmp1, %cmp2
1101   br i1 %and, label %guard, label %exit
1103 guard:
1104   %sub = sub i32 0, %a
1105   %cmp = icmp slt i32 %a, 0
1106   %abs = select i1 %cmp, i32 %sub, i32 %a
1107   %c1 = icmp slt i32 %abs, 20
1108   store i1 %c1, ptr %p
1109   %c2 = icmp slt i32 %abs, 19
1110   store i1 %c2, ptr %p
1111   %c3 = icmp sge i32 %abs, 0
1112   store i1 %c3, ptr %p
1113   %c4 = icmp sge i32 %abs, 1
1114   store i1 %c4, ptr %p
1115   br label %exit
1117 exit:
1118   ret void
1121 define void @abs2(i32 %a, ptr %p) {
1122 ; CHECK-LABEL: define void @abs2
1123 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1124 ; CHECK-NEXT:  entry:
1125 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A]], 10
1126 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
1127 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1128 ; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1129 ; CHECK:       guard:
1130 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 0, [[A]]
1131 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[A]], 0
1132 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[SUB]]
1133 ; CHECK-NEXT:    store i1 true, ptr [[P]], align 1
1134 ; CHECK-NEXT:    [[C2:%.*]] = icmp samesign ult i32 [[ABS]], 19
1135 ; CHECK-NEXT:    store i1 [[C2]], ptr [[P]], align 1
1136 ; CHECK-NEXT:    store i1 true, ptr [[P]], align 1
1137 ; CHECK-NEXT:    [[C4:%.*]] = icmp samesign uge i32 [[ABS]], 1
1138 ; CHECK-NEXT:    store i1 [[C4]], ptr [[P]], align 1
1139 ; CHECK-NEXT:    br label [[EXIT]]
1140 ; CHECK:       exit:
1141 ; CHECK-NEXT:    ret void
1143 entry:
1144   %cmp1 = icmp slt i32 %a, 10
1145   %cmp2 = icmp sgt i32 %a, -20
1146   %and = and i1 %cmp1, %cmp2
1147   br i1 %and, label %guard, label %exit
1149 guard:
1150   %sub = sub i32 0, %a
1151   %cmp = icmp sge i32 %a, 0
1152   %abs = select i1 %cmp, i32 %a, i32 %sub
1153   %c1 = icmp slt i32 %abs, 20
1154   store i1 %c1, ptr %p
1155   %c2 = icmp slt i32 %abs, 19
1156   store i1 %c2, ptr %p
1157   %c3 = icmp sge i32 %abs, 0
1158   store i1 %c3, ptr %p
1159   %c4 = icmp sge i32 %abs, 1
1160   store i1 %c4, ptr %p
1161   br label %exit
1163 exit:
1164   ret void
1167 define void @nabs1(i32 %a, ptr %p) {
1168 ; CHECK-LABEL: define void @nabs1
1169 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1170 ; CHECK-NEXT:  entry:
1171 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A]], 10
1172 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
1173 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1174 ; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1175 ; CHECK:       guard:
1176 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 0, [[A]]
1177 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A]], 0
1178 ; CHECK-NEXT:    [[NABS:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]]
1179 ; CHECK-NEXT:    store i1 true, ptr [[P]], align 1
1180 ; CHECK-NEXT:    [[C2:%.*]] = icmp sgt i32 [[NABS]], -19
1181 ; CHECK-NEXT:    store i1 [[C2]], ptr [[P]], align 1
1182 ; CHECK-NEXT:    store i1 true, ptr [[P]], align 1
1183 ; CHECK-NEXT:    [[C4:%.*]] = icmp sle i32 [[NABS]], -1
1184 ; CHECK-NEXT:    store i1 [[C4]], ptr [[P]], align 1
1185 ; CHECK-NEXT:    br label [[EXIT]]
1186 ; CHECK:       exit:
1187 ; CHECK-NEXT:    ret void
1189 entry:
1190   %cmp1 = icmp slt i32 %a, 10
1191   %cmp2 = icmp sgt i32 %a, -20
1192   %and = and i1 %cmp1, %cmp2
1193   br i1 %and, label %guard, label %exit
1195 guard:
1196   %sub = sub i32 0, %a
1197   %cmp = icmp sgt i32 %a, 0
1198   %nabs = select i1 %cmp, i32 %sub, i32 %a
1199   %c1 = icmp sgt i32 %nabs, -20
1200   store i1 %c1, ptr %p
1201   %c2 = icmp sgt i32 %nabs, -19
1202   store i1 %c2, ptr %p
1203   %c3 = icmp sle i32 %nabs, 0
1204   store i1 %c3, ptr %p
1205   %c4 = icmp sle i32 %nabs, -1
1206   store i1 %c4, ptr %p
1207   br label %exit
1209 exit:
1210   ret void
1213 define void @nabs2(i32 %a, ptr %p) {
1214 ; CHECK-LABEL: define void @nabs2
1215 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1216 ; CHECK-NEXT:  entry:
1217 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A]], 10
1218 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
1219 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1220 ; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1221 ; CHECK:       guard:
1222 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 0, [[A]]
1223 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], 0
1224 ; CHECK-NEXT:    [[NABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[SUB]]
1225 ; CHECK-NEXT:    store i1 true, ptr [[P]], align 1
1226 ; CHECK-NEXT:    [[C2:%.*]] = icmp sgt i32 [[NABS]], -19
1227 ; CHECK-NEXT:    store i1 [[C2]], ptr [[P]], align 1
1228 ; CHECK-NEXT:    store i1 true, ptr [[P]], align 1
1229 ; CHECK-NEXT:    [[C4:%.*]] = icmp sle i32 [[NABS]], -1
1230 ; CHECK-NEXT:    store i1 [[C4]], ptr [[P]], align 1
1231 ; CHECK-NEXT:    br label [[EXIT]]
1232 ; CHECK:       exit:
1233 ; CHECK-NEXT:    ret void
1235 entry:
1236   %cmp1 = icmp slt i32 %a, 10
1237   %cmp2 = icmp sgt i32 %a, -20
1238   %and = and i1 %cmp1, %cmp2
1239   br i1 %and, label %guard, label %exit
1241 guard:
1242   %sub = sub i32 0, %a
1243   %cmp = icmp slt i32 %a, 0
1244   %nabs = select i1 %cmp, i32 %a, i32 %sub
1245   %c1 = icmp sgt i32 %nabs, -20
1246   store i1 %c1, ptr %p
1247   %c2 = icmp sgt i32 %nabs, -19
1248   store i1 %c2, ptr %p
1249   %c3 = icmp sle i32 %nabs, 0
1250   store i1 %c3, ptr %p
1251   %c4 = icmp sle i32 %nabs, -1
1252   store i1 %c4, ptr %p
1253   br label %exit
1255 exit:
1256   ret void
1259 define i1 @zext_unknown(i8 %a) {
1260 ; CHECK-LABEL: define i1 @zext_unknown
1261 ; CHECK-SAME: (i8 [[A:%.*]]) {
1262 ; CHECK-NEXT:  entry:
1263 ; CHECK-NEXT:    [[A32:%.*]] = zext i8 [[A]] to i32
1264 ; CHECK-NEXT:    ret i1 true
1266 entry:
1267   %a32 = zext i8 %a to i32
1268   %cmp = icmp sle i32 %a32, 256
1269   ret i1 %cmp
1272 define i1 @trunc_unknown(i32 %a) {
1273 ; CHECK-LABEL: define i1 @trunc_unknown
1274 ; CHECK-SAME: (i32 [[A:%.*]]) {
1275 ; CHECK-NEXT:  entry:
1276 ; CHECK-NEXT:    [[A8:%.*]] = trunc i32 [[A]] to i8
1277 ; CHECK-NEXT:    [[A32:%.*]] = sext i8 [[A8]] to i32
1278 ; CHECK-NEXT:    ret i1 true
1280 entry:
1281   %a8 = trunc i32 %a to i8
1282   %a32 = sext i8 %a8 to i32
1283   %cmp = icmp sle i32 %a32, 128
1284   ret i1 %cmp
1287 define void @trunc_icmp_ule(i32 %x, ptr %p) {
1288 ; CHECK-LABEL: define void @trunc_icmp_ule
1289 ; CHECK-SAME: (i32 [[X:%.*]], ptr [[P:%.*]]) {
1290 ; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[X]] to i8
1291 ; CHECK-NEXT:    [[C:%.*]] = icmp uge i8 [[T]], 5
1292 ; CHECK-NEXT:    br i1 [[C]], label [[TRUE:%.*]], label [[FALSE:%.*]]
1293 ; CHECK:       true:
1294 ; CHECK-NEXT:    store i1 true, ptr [[P]], align 1
1295 ; CHECK-NEXT:    [[C2:%.*]] = icmp ugt i32 [[X]], 5
1296 ; CHECK-NEXT:    store i1 [[C2]], ptr [[P]], align 1
1297 ; CHECK-NEXT:    [[C3:%.*]] = icmp ule i32 [[X]], 5
1298 ; CHECK-NEXT:    store i1 [[C3]], ptr [[P]], align 1
1299 ; CHECK-NEXT:    store i1 false, ptr [[P]], align 1
1300 ; CHECK-NEXT:    ret void
1301 ; CHECK:       false:
1302 ; CHECK-NEXT:    [[C1_2:%.*]] = icmp uge i32 [[X]], 5
1303 ; CHECK-NEXT:    store i1 [[C1_2]], ptr [[P]], align 1
1304 ; CHECK-NEXT:    [[C2_2:%.*]] = icmp ugt i32 [[X]], 5
1305 ; CHECK-NEXT:    store i1 [[C2_2]], ptr [[P]], align 1
1306 ; CHECK-NEXT:    [[C3_2:%.*]] = icmp ule i32 [[X]], 5
1307 ; CHECK-NEXT:    store i1 [[C3_2]], ptr [[P]], align 1
1308 ; CHECK-NEXT:    [[C4_2:%.*]] = icmp ult i32 [[X]], 5
1309 ; CHECK-NEXT:    store i1 [[C4_2]], ptr [[P]], align 1
1310 ; CHECK-NEXT:    ret void
1312   %t = trunc i32 %x to i8
1313   %c = icmp uge i8 %t, 5
1314   br i1 %c, label %true, label %false
1316 true:
1317   %c1 = icmp uge i32 %x, 5
1318   store i1 %c1, ptr %p
1319   %c2 = icmp ugt i32 %x, 5
1320   store i1 %c2, ptr %p
1321   %c3 = icmp ule i32 %x, 5
1322   store i1 %c3, ptr %p
1323   %c4 = icmp ult i32 %x, 5
1324   store i1 %c4, ptr %p
1325   ret void
1327 false:
1328   %c1.2 = icmp uge i32 %x, 5
1329   store i1 %c1.2, ptr %p
1330   %c2.2 = icmp ugt i32 %x, 5
1331   store i1 %c2.2, ptr %p
1332   %c3.2 = icmp ule i32 %x, 5
1333   store i1 %c3.2, ptr %p
1334   %c4.2 = icmp ult i32 %x, 5
1335   store i1 %c4.2, ptr %p
1336   ret void
1339 define void @trunc_icmp_eq(i32 %x, ptr %p) {
1340 ; CHECK-LABEL: define void @trunc_icmp_eq
1341 ; CHECK-SAME: (i32 [[X:%.*]], ptr [[P:%.*]]) {
1342 ; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[X]] to i8
1343 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[T]], 5
1344 ; CHECK-NEXT:    br i1 [[C]], label [[TRUE:%.*]], label [[FALSE:%.*]]
1345 ; CHECK:       true:
1346 ; CHECK-NEXT:    store i1 true, ptr [[P]], align 1
1347 ; CHECK-NEXT:    [[C2:%.*]] = icmp ugt i32 [[X]], 5
1348 ; CHECK-NEXT:    store i1 [[C2]], ptr [[P]], align 1
1349 ; CHECK-NEXT:    [[C3:%.*]] = icmp ule i32 [[X]], 5
1350 ; CHECK-NEXT:    store i1 [[C3]], ptr [[P]], align 1
1351 ; CHECK-NEXT:    store i1 false, ptr [[P]], align 1
1352 ; CHECK-NEXT:    ret void
1353 ; CHECK:       false:
1354 ; CHECK-NEXT:    [[C1_2:%.*]] = icmp uge i32 [[X]], 5
1355 ; CHECK-NEXT:    store i1 [[C1_2]], ptr [[P]], align 1
1356 ; CHECK-NEXT:    [[C2_2:%.*]] = icmp ugt i32 [[X]], 5
1357 ; CHECK-NEXT:    store i1 [[C2_2]], ptr [[P]], align 1
1358 ; CHECK-NEXT:    [[C3_2:%.*]] = icmp ule i32 [[X]], 5
1359 ; CHECK-NEXT:    store i1 [[C3_2]], ptr [[P]], align 1
1360 ; CHECK-NEXT:    [[C4_2:%.*]] = icmp ult i32 [[X]], 5
1361 ; CHECK-NEXT:    store i1 [[C4_2]], ptr [[P]], align 1
1362 ; CHECK-NEXT:    ret void
1364   %t = trunc i32 %x to i8
1365   %c = icmp eq i8 %t, 5
1366   br i1 %c, label %true, label %false
1368 true:
1369   %c1 = icmp uge i32 %x, 5
1370   store i1 %c1, ptr %p
1371   %c2 = icmp ugt i32 %x, 5
1372   store i1 %c2, ptr %p
1373   %c3 = icmp ule i32 %x, 5
1374   store i1 %c3, ptr %p
1375   %c4 = icmp ult i32 %x, 5
1376   store i1 %c4, ptr %p
1377   ret void
1379 false:
1380   %c1.2 = icmp uge i32 %x, 5
1381   store i1 %c1.2, ptr %p
1382   %c2.2 = icmp ugt i32 %x, 5
1383   store i1 %c2.2, ptr %p
1384   %c3.2 = icmp ule i32 %x, 5
1385   store i1 %c3.2, ptr %p
1386   %c4.2 = icmp ult i32 %x, 5
1387   store i1 %c4.2, ptr %p
1388   ret void
1391 ; TODO: missed optimization
1392 ; Make sure we exercise non-integer inputs to unary operators (i.e. crash check).
1393 define i1 @bitcast_unknown(float %a) {
1394 ; CHECK-LABEL: define i1 @bitcast_unknown
1395 ; CHECK-SAME: (float [[A:%.*]]) {
1396 ; CHECK-NEXT:  entry:
1397 ; CHECK-NEXT:    [[A32:%.*]] = bitcast float [[A]] to i32
1398 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A32]], 128
1399 ; CHECK-NEXT:    ret i1 [[CMP]]
1401 entry:
1402   %a32 = bitcast float %a to i32
1403   %cmp = icmp sle i32 %a32, 128
1404   ret i1 %cmp
1407 define i1 @bitcast_unknown2(ptr %p) {
1408 ; CHECK-LABEL: define i1 @bitcast_unknown2
1409 ; CHECK-SAME: (ptr [[P:%.*]]) {
1410 ; CHECK-NEXT:  entry:
1411 ; CHECK-NEXT:    [[P64:%.*]] = ptrtoint ptr [[P]] to i64
1412 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i64 [[P64]], 128
1413 ; CHECK-NEXT:    ret i1 [[CMP]]
1415 entry:
1416   %p64 = ptrtoint ptr %p to i64
1417   %cmp = icmp sle i64 %p64, 128
1418   ret i1 %cmp
1422 define i1 @and_unknown(i32 %a) {
1423 ; CHECK-LABEL: define i1 @and_unknown
1424 ; CHECK-SAME: (i32 [[A:%.*]]) {
1425 ; CHECK-NEXT:  entry:
1426 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A]], 128
1427 ; CHECK-NEXT:    ret i1 true
1429 entry:
1430   %and = and i32 %a, 128
1431   %cmp = icmp sle i32 %and, 128
1432   ret i1 %cmp
1435 define i1 @lshr_unknown(i32 %a) {
1436 ; CHECK-LABEL: define i1 @lshr_unknown
1437 ; CHECK-SAME: (i32 [[A:%.*]]) {
1438 ; CHECK-NEXT:  entry:
1439 ; CHECK-NEXT:    [[AND:%.*]] = lshr i32 [[A]], 30
1440 ; CHECK-NEXT:    ret i1 true
1442 entry:
1443   %and = lshr i32 %a, 30
1444   %cmp = icmp sle i32 %and, 128
1445   ret i1 %cmp
1448 define i1 @urem_unknown(i32 %a) {
1449 ; CHECK-LABEL: define i1 @urem_unknown
1450 ; CHECK-SAME: (i32 [[A:%.*]]) {
1451 ; CHECK-NEXT:  entry:
1452 ; CHECK-NEXT:    [[UREM:%.*]] = urem i32 [[A]], 30
1453 ; CHECK-NEXT:    ret i1 true
1455 entry:
1456   %urem = urem i32 %a, 30
1457   %cmp = icmp ult i32 %urem, 30
1458   ret i1 %cmp
1461 define i1 @srem_unknown(i32 %a, i1 %arg) {
1462 ; CHECK-LABEL: define i1 @srem_unknown
1463 ; CHECK-SAME: (i32 [[A:%.*]], i1 [[ARG:%.*]]) {
1464 ; CHECK-NEXT:  entry:
1465 ; CHECK-NEXT:    [[SREM:%.*]] = srem i32 [[A]], 30
1466 ; CHECK-NEXT:    br i1 [[ARG]], label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1467 ; CHECK:       exit1:
1468 ; CHECK-NEXT:    ret i1 true
1469 ; CHECK:       exit2:
1470 ; CHECK-NEXT:    ret i1 true
1472 entry:
1473   %srem = srem i32 %a, 30
1474   %cmp1 = icmp slt i32 %srem, 30
1475   %cmp2 = icmp sgt i32 %srem, -30
1476   br i1 %arg, label %exit1, label %exit2
1477 exit1:
1478   ret i1 %cmp1
1479 exit2:
1480   ret i1 %cmp2
1483 define i1 @sdiv_unknown(i32 %a, i1 %arg) {
1484 ; CHECK-LABEL: define i1 @sdiv_unknown
1485 ; CHECK-SAME: (i32 [[A:%.*]], i1 [[ARG:%.*]]) {
1486 ; CHECK-NEXT:  entry:
1487 ; CHECK-NEXT:    [[SREM:%.*]] = sdiv i32 [[A]], 123
1488 ; CHECK-NEXT:    br i1 [[ARG]], label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1489 ; CHECK:       exit1:
1490 ; CHECK-NEXT:    ret i1 true
1491 ; CHECK:       exit2:
1492 ; CHECK-NEXT:    ret i1 true
1494 entry:
1495   %srem = sdiv i32 %a, 123
1496   %cmp1 = icmp slt i32 %srem, 17459217
1497   %cmp2 = icmp sgt i32 %srem, -17459217
1498   br i1 %arg, label %exit1, label %exit2
1499 exit1:
1500   ret i1 %cmp1
1501 exit2:
1502   ret i1 %cmp2
1505 define i1 @uadd_sat_unknown(i32 %a, i1 %arg) {
1506 ; CHECK-LABEL: define i1 @uadd_sat_unknown
1507 ; CHECK-SAME: (i32 [[A:%.*]], i1 [[ARG:%.*]]) {
1508 ; CHECK-NEXT:  entry:
1509 ; CHECK-NEXT:    [[VAL:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[A]], i32 100)
1510 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 [[VAL]], 100
1511 ; CHECK-NEXT:    br i1 [[ARG]], label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1512 ; CHECK:       exit1:
1513 ; CHECK-NEXT:    ret i1 true
1514 ; CHECK:       exit2:
1515 ; CHECK-NEXT:    ret i1 [[CMP2]]
1517 entry:
1518   %val = call i32 @llvm.uadd.sat.i32(i32 %a, i32 100)
1519   %cmp1 = icmp uge i32 %val, 100
1520   %cmp2 = icmp ugt i32 %val, 100
1521   br i1 %arg, label %exit1, label %exit2
1522 exit1:
1523   ret i1 %cmp1
1524 exit2:
1525   ret i1 %cmp2
1528 define i1 @usub_sat_unknown(i32 %a, i1 %arg) {
1529 ; CHECK-LABEL: define i1 @usub_sat_unknown
1530 ; CHECK-SAME: (i32 [[A:%.*]], i1 [[ARG:%.*]]) {
1531 ; CHECK-NEXT:  entry:
1532 ; CHECK-NEXT:    [[VAL:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A]], i32 100)
1533 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[VAL]], -101
1534 ; CHECK-NEXT:    br i1 [[ARG]], label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1535 ; CHECK:       exit1:
1536 ; CHECK-NEXT:    ret i1 true
1537 ; CHECK:       exit2:
1538 ; CHECK-NEXT:    ret i1 [[CMP2]]
1540 entry:
1541   %val = call i32 @llvm.usub.sat.i32(i32 %a, i32 100)
1542   %cmp1 = icmp ule i32 %val, 4294967195
1543   %cmp2 = icmp ult i32 %val, 4294967195
1544   br i1 %arg, label %exit1, label %exit2
1545 exit1:
1546   ret i1 %cmp1
1547 exit2:
1548   ret i1 %cmp2
1551 define i1 @sadd_sat_unknown(i32 %a, i1 %arg) {
1552 ; CHECK-LABEL: define i1 @sadd_sat_unknown
1553 ; CHECK-SAME: (i32 [[A:%.*]], i1 [[ARG:%.*]]) {
1554 ; CHECK-NEXT:  entry:
1555 ; CHECK-NEXT:    [[VAL:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[A]], i32 100)
1556 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[VAL]], -2147483548
1557 ; CHECK-NEXT:    br i1 [[ARG]], label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1558 ; CHECK:       exit1:
1559 ; CHECK-NEXT:    ret i1 true
1560 ; CHECK:       exit2:
1561 ; CHECK-NEXT:    ret i1 [[CMP2]]
1563 entry:
1564   %val = call i32 @llvm.sadd.sat.i32(i32 %a, i32 100)
1565   %cmp1 = icmp sge i32 %val, -2147483548
1566   %cmp2 = icmp sgt i32 %val, -2147483548
1567   br i1 %arg, label %exit1, label %exit2
1568 exit1:
1569   ret i1 %cmp1
1570 exit2:
1571   ret i1 %cmp2
1574 define i1 @ssub_sat_unknown(i32 %a, i1 %arg) {
1575 ; CHECK-LABEL: define i1 @ssub_sat_unknown
1576 ; CHECK-SAME: (i32 [[A:%.*]], i1 [[ARG:%.*]]) {
1577 ; CHECK-NEXT:  entry:
1578 ; CHECK-NEXT:    [[VAL:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[A]], i32 100)
1579 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[VAL]], 2147483547
1580 ; CHECK-NEXT:    br i1 [[ARG]], label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1581 ; CHECK:       exit1:
1582 ; CHECK-NEXT:    ret i1 true
1583 ; CHECK:       exit2:
1584 ; CHECK-NEXT:    ret i1 [[CMP2]]
1586 entry:
1587   %val = call i32 @llvm.ssub.sat.i32(i32 %a, i32 100)
1588   %cmp1 = icmp sle i32 %val, 2147483547
1589   %cmp2 = icmp slt i32 %val, 2147483547
1590   br i1 %arg, label %exit1, label %exit2
1591 exit1:
1592   ret i1 %cmp1
1593 exit2:
1594   ret i1 %cmp2
1597 define void @select_and(i32 %a, ptr %p) {
1598 ; CHECK-LABEL: define void @select_and
1599 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1600 ; CHECK-NEXT:  entry:
1601 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[A]], -10
1602 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[A]], 10
1603 ; CHECK-NEXT:    [[AND:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1604 ; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1605 ; CHECK:       guard:
1606 ; CHECK-NEXT:    store i1 false, ptr [[P]], align 1
1607 ; CHECK-NEXT:    store i1 false, ptr [[P]], align 1
1608 ; CHECK-NEXT:    br label [[EXIT]]
1609 ; CHECK:       exit:
1610 ; CHECK-NEXT:    ret void
1612 entry:
1613   %cmp1 = icmp sgt i32 %a, -10
1614   %cmp2 = icmp slt i32 %a, 10
1615   %and = select i1 %cmp1, i1 %cmp2, i1 false
1616   br i1 %and, label %guard, label %exit
1618 guard:
1619   %c1 = icmp sgt i32 %a, 20
1620   store i1 %c1, ptr %p
1621   %c2 = icmp slt i32 %a, -20
1622   store i1 %c2, ptr %p
1623   br label %exit
1625 exit:
1626   ret void
1629 define void @select_and_wrong_const(i32 %a, ptr %p) {
1630 ; CHECK-LABEL: define void @select_and_wrong_const
1631 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1632 ; CHECK-NEXT:  entry:
1633 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[A]], -10
1634 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[A]], 10
1635 ; CHECK-NEXT:    [[AND:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 true
1636 ; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1637 ; CHECK:       guard:
1638 ; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i32 [[A]], 20
1639 ; CHECK-NEXT:    store i1 [[C1]], ptr [[P]], align 1
1640 ; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[A]], -20
1641 ; CHECK-NEXT:    store i1 [[C2]], ptr [[P]], align 1
1642 ; CHECK-NEXT:    br label [[EXIT]]
1643 ; CHECK:       exit:
1644 ; CHECK-NEXT:    ret void
1646 entry:
1647   %cmp1 = icmp sgt i32 %a, -10
1648   %cmp2 = icmp slt i32 %a, 10
1649   %and = select i1 %cmp1, i1 %cmp2, i1 true
1650   br i1 %and, label %guard, label %exit
1652 guard:
1653   %c1 = icmp sgt i32 %a, 20
1654   store i1 %c1, ptr %p
1655   %c2 = icmp slt i32 %a, -20
1656   store i1 %c2, ptr %p
1657   br label %exit
1659 exit:
1660   ret void
1663 define void @select_and_wrong_operand(i32 %a, ptr %p) {
1664 ; CHECK-LABEL: define void @select_and_wrong_operand
1665 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1666 ; CHECK-NEXT:  entry:
1667 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[A]], -10
1668 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[A]], 10
1669 ; CHECK-NEXT:    [[AND:%.*]] = select i1 [[CMP1]], i1 false, i1 [[CMP2]]
1670 ; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1671 ; CHECK:       guard:
1672 ; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i32 [[A]], 20
1673 ; CHECK-NEXT:    store i1 [[C1]], ptr [[P]], align 1
1674 ; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[A]], -20
1675 ; CHECK-NEXT:    store i1 [[C2]], ptr [[P]], align 1
1676 ; CHECK-NEXT:    br label [[EXIT]]
1677 ; CHECK:       exit:
1678 ; CHECK-NEXT:    ret void
1680 entry:
1681   %cmp1 = icmp sgt i32 %a, -10
1682   %cmp2 = icmp slt i32 %a, 10
1683   %and = select i1 %cmp1, i1 false, i1 %cmp2
1684   br i1 %and, label %guard, label %exit
1686 guard:
1687   %c1 = icmp sgt i32 %a, 20
1688   store i1 %c1, ptr %p
1689   %c2 = icmp slt i32 %a, -20
1690   store i1 %c2, ptr %p
1691   br label %exit
1693 exit:
1694   ret void
1697 define void @select_or(i32 %a, ptr %p) {
1698 ; CHECK-LABEL: define void @select_or
1699 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1700 ; CHECK-NEXT:  entry:
1701 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A]], -10
1702 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], 10
1703 ; CHECK-NEXT:    [[OR:%.*]] = select i1 [[CMP1]], i1 true, i1 [[CMP2]]
1704 ; CHECK-NEXT:    br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1705 ; CHECK:       guard:
1706 ; CHECK-NEXT:    store i1 false, ptr [[P]], align 1
1707 ; CHECK-NEXT:    store i1 false, ptr [[P]], align 1
1708 ; CHECK-NEXT:    br label [[EXIT]]
1709 ; CHECK:       exit:
1710 ; CHECK-NEXT:    ret void
1712 entry:
1713   %cmp1 = icmp slt i32 %a, -10
1714   %cmp2 = icmp sgt i32 %a, 10
1715   %or = select i1 %cmp1, i1 true, i1 %cmp2
1716   br i1 %or, label %exit, label %guard
1718 guard:
1719   %c1 = icmp sgt i32 %a, 20
1720   store i1 %c1, ptr %p
1721   %c2 = icmp slt i32 %a, -20
1722   store i1 %c2, ptr %p
1723   br label %exit
1725 exit:
1726   ret void
1729 define void @select_or_wrong_const(i32 %a, ptr %p) {
1730 ; CHECK-LABEL: define void @select_or_wrong_const
1731 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1732 ; CHECK-NEXT:  entry:
1733 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A]], -10
1734 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], 10
1735 ; CHECK-NEXT:    [[OR:%.*]] = select i1 [[CMP1]], i1 false, i1 [[CMP2]]
1736 ; CHECK-NEXT:    br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1737 ; CHECK:       guard:
1738 ; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i32 [[A]], 20
1739 ; CHECK-NEXT:    store i1 [[C1]], ptr [[P]], align 1
1740 ; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[A]], -20
1741 ; CHECK-NEXT:    store i1 [[C2]], ptr [[P]], align 1
1742 ; CHECK-NEXT:    br label [[EXIT]]
1743 ; CHECK:       exit:
1744 ; CHECK-NEXT:    ret void
1746 entry:
1747   %cmp1 = icmp slt i32 %a, -10
1748   %cmp2 = icmp sgt i32 %a, 10
1749   %or = select i1 %cmp1, i1 false, i1 %cmp2
1750   br i1 %or, label %exit, label %guard
1752 guard:
1753   %c1 = icmp sgt i32 %a, 20
1754   store i1 %c1, ptr %p
1755   %c2 = icmp slt i32 %a, -20
1756   store i1 %c2, ptr %p
1757   br label %exit
1759 exit:
1760   ret void
1763 define void @select_or_wrong_operand(i32 %a, ptr %p) {
1764 ; CHECK-LABEL: define void @select_or_wrong_operand
1765 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1766 ; CHECK-NEXT:  entry:
1767 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A]], -10
1768 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], 10
1769 ; CHECK-NEXT:    [[OR:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 true
1770 ; CHECK-NEXT:    br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1771 ; CHECK:       guard:
1772 ; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i32 [[A]], 20
1773 ; CHECK-NEXT:    store i1 [[C1]], ptr [[P]], align 1
1774 ; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[A]], -20
1775 ; CHECK-NEXT:    store i1 [[C2]], ptr [[P]], align 1
1776 ; CHECK-NEXT:    br label [[EXIT]]
1777 ; CHECK:       exit:
1778 ; CHECK-NEXT:    ret void
1780 entry:
1781   %cmp1 = icmp slt i32 %a, -10
1782   %cmp2 = icmp sgt i32 %a, 10
1783   %or = select i1 %cmp1, i1 %cmp2, i1 true
1784   br i1 %or, label %exit, label %guard
1786 guard:
1787   %c1 = icmp sgt i32 %a, 20
1788   store i1 %c1, ptr %p
1789   %c2 = icmp slt i32 %a, -20
1790   store i1 %c2, ptr %p
1791   br label %exit
1793 exit:
1794   ret void
1797 define void @or_union(i32 %a, ptr %p) {
1798 ; CHECK-LABEL: define void @or_union
1799 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1800 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[A]], 10
1801 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[A]], 12
1802 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
1803 ; CHECK-NEXT:    br i1 [[OR]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1804 ; CHECK:       guard:
1805 ; CHECK-NEXT:    store i1 false, ptr [[P]], align 1
1806 ; CHECK-NEXT:    [[C2:%.*]] = icmp eq i32 [[A]], 10
1807 ; CHECK-NEXT:    store i1 [[C2]], ptr [[P]], align 1
1808 ; CHECK-NEXT:    [[C3:%.*]] = icmp eq i32 [[A]], 11
1809 ; CHECK-NEXT:    store i1 [[C3]], ptr [[P]], align 1
1810 ; CHECK-NEXT:    [[C4:%.*]] = icmp eq i32 [[A]], 12
1811 ; CHECK-NEXT:    store i1 [[C4]], ptr [[P]], align 1
1812 ; CHECK-NEXT:    store i1 false, ptr [[P]], align 1
1813 ; CHECK-NEXT:    br label [[EXIT]]
1814 ; CHECK:       exit:
1815 ; CHECK-NEXT:    ret void
1817   %cmp1 = icmp eq i32 %a, 10
1818   %cmp2 = icmp eq i32 %a, 12
1819   %or = or i1 %cmp1, %cmp2
1820   br i1 %or, label %guard, label %exit
1822 guard:
1823   %c1 = icmp eq i32 %a, 9
1824   store i1 %c1, ptr %p
1825   %c2 = icmp eq i32 %a, 10
1826   store i1 %c2, ptr %p
1827   %c3 = icmp eq i32 %a, 11
1828   store i1 %c3, ptr %p
1829   %c4 = icmp eq i32 %a, 12
1830   store i1 %c4, ptr %p
1831   %c5 = icmp eq i32 %a, 13
1832   store i1 %c5, ptr %p
1833   br label %exit
1835 exit:
1836   ret void
1839 define i1 @or_union_unknown_cond(i32 %a, i1 %c) {
1840 ; CHECK-LABEL: define i1 @or_union_unknown_cond
1841 ; CHECK-SAME: (i32 [[A:%.*]], i1 [[C:%.*]]) {
1842 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[A]], 10
1843 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP1]], [[C]]
1844 ; CHECK-NEXT:    br i1 [[OR]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1845 ; CHECK:       guard:
1846 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[A]], 10
1847 ; CHECK-NEXT:    ret i1 [[CMP2]]
1848 ; CHECK:       exit:
1849 ; CHECK-NEXT:    ret i1 false
1851   %cmp1 = icmp eq i32 %a, 10
1852   %or = or i1 %cmp1, %c
1853   br i1 %or, label %guard, label %exit
1855 guard:
1856   %cmp2 = icmp eq i32 %a, 10
1857   ret i1 %cmp2
1859 exit:
1860   ret i1 false
1863 define void @and_union(i32 %a, ptr %p) {
1864 ; CHECK-LABEL: define void @and_union
1865 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1866 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[A]], 10
1867 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i32 [[A]], 12
1868 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1869 ; CHECK-NEXT:    br i1 [[AND]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1870 ; CHECK:       guard:
1871 ; CHECK-NEXT:    store i1 false, ptr [[P]], align 1
1872 ; CHECK-NEXT:    [[C2:%.*]] = icmp eq i32 [[A]], 10
1873 ; CHECK-NEXT:    store i1 [[C2]], ptr [[P]], align 1
1874 ; CHECK-NEXT:    [[C3:%.*]] = icmp eq i32 [[A]], 11
1875 ; CHECK-NEXT:    store i1 [[C3]], ptr [[P]], align 1
1876 ; CHECK-NEXT:    [[C4:%.*]] = icmp eq i32 [[A]], 12
1877 ; CHECK-NEXT:    store i1 [[C4]], ptr [[P]], align 1
1878 ; CHECK-NEXT:    store i1 false, ptr [[P]], align 1
1879 ; CHECK-NEXT:    br label [[EXIT]]
1880 ; CHECK:       exit:
1881 ; CHECK-NEXT:    ret void
1883   %cmp1 = icmp ne i32 %a, 10
1884   %cmp2 = icmp ne i32 %a, 12
1885   %and = and i1 %cmp1, %cmp2
1886   br i1 %and, label %exit, label %guard
1888 guard:
1889   %c1 = icmp eq i32 %a, 9
1890   store i1 %c1, ptr %p
1891   %c2 = icmp eq i32 %a, 10
1892   store i1 %c2, ptr %p
1893   %c3 = icmp eq i32 %a, 11
1894   store i1 %c3, ptr %p
1895   %c4 = icmp eq i32 %a, 12
1896   store i1 %c4, ptr %p
1897   %c5 = icmp eq i32 %a, 13
1898   store i1 %c5, ptr %p
1899   br label %exit
1901 exit:
1902   ret void
1905 define i1 @and_union_unknown_cond(i32 %a, i1 %c) {
1906 ; CHECK-LABEL: define i1 @and_union_unknown_cond
1907 ; CHECK-SAME: (i32 [[A:%.*]], i1 [[C:%.*]]) {
1908 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[A]], 10
1909 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[C]]
1910 ; CHECK-NEXT:    br i1 [[AND]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1911 ; CHECK:       guard:
1912 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[A]], 10
1913 ; CHECK-NEXT:    ret i1 [[CMP2]]
1914 ; CHECK:       exit:
1915 ; CHECK-NEXT:    ret i1 false
1917   %cmp1 = icmp ne i32 %a, 10
1918   %and = and i1 %cmp1, %c
1919   br i1 %and, label %exit, label %guard
1921 guard:
1922   %cmp2 = icmp eq i32 %a, 10
1923   ret i1 %cmp2
1925 exit:
1926   ret i1 false
1929 define void @select_assume(i32 %a, i32 %b, i1 %c, ptr %p) {
1930 ; CHECK-LABEL: define void @select_assume
1931 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i1 [[C:%.*]], ptr [[P:%.*]]) {
1932 ; CHECK-NEXT:    [[C1:%.*]] = icmp ult i32 [[A]], 10
1933 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C1]])
1934 ; CHECK-NEXT:    [[C2:%.*]] = icmp ult i32 [[B]], 20
1935 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C2]])
1936 ; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i32 [[A]], i32 [[B]]
1937 ; CHECK-NEXT:    [[C3:%.*]] = icmp samesign ult i32 [[S]], 19
1938 ; CHECK-NEXT:    store i1 [[C3]], ptr [[P]], align 1
1939 ; CHECK-NEXT:    store i1 true, ptr [[P]], align 1
1940 ; CHECK-NEXT:    ret void
1942   %c1 = icmp ult i32 %a, 10
1943   call void @llvm.assume(i1 %c1)
1944   %c2 = icmp ult i32 %b, 20
1945   call void @llvm.assume(i1 %c2)
1946   %s = select i1 %c, i32 %a, i32 %b
1947   %c3 = icmp ult i32 %s, 19
1948   store i1 %c3, ptr %p
1949   %c4 = icmp ult i32 %s, 20
1950   store i1 %c4, ptr %p
1951   ret void
1954 define void @xor(i8 %a, ptr %p) {
1955 ; CHECK-LABEL: define void @xor
1956 ; CHECK-SAME: (i8 [[A:%.*]], ptr [[P:%.*]]) {
1957 ; CHECK-NEXT:    [[A_MASK:%.*]] = and i8 [[A]], 15
1958 ; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[A_MASK]], -86
1959 ; CHECK-NEXT:    store i1 true, ptr [[P]], align 1
1960 ; CHECK-NEXT:    [[C2:%.*]] = icmp samesign ugt i8 [[XOR]], -96
1961 ; CHECK-NEXT:    store i1 [[C2]], ptr [[P]], align 1
1962 ; CHECK-NEXT:    store i1 true, ptr [[P]], align 1
1963 ; CHECK-NEXT:    [[C4:%.*]] = icmp samesign ult i8 [[XOR]], -81
1964 ; CHECK-NEXT:    store i1 [[C4]], ptr [[P]], align 1
1965 ; CHECK-NEXT:    ret void
1967   %a.mask = and i8 %a, 15 ; 0b0000????
1968   %xor = xor i8 %a.mask, 170 ; ^ 0b10101010 == 0b1010????
1969   %c1 = icmp uge i8 %xor, 160
1970   store i1 %c1, ptr %p
1971   %c2 = icmp ugt i8 %xor, 160
1972   store i1 %c2, ptr %p
1973   %c3 = icmp ule i8 %xor, 175
1974   store i1 %c3, ptr %p
1975   %c4 = icmp ult i8 %xor, 175
1976   store i1 %c4, ptr %p
1977   ret void
1980 define i1 @xor_neg_cond(i32 %a) {
1981 ; CHECK-LABEL: define i1 @xor_neg_cond
1982 ; CHECK-SAME: (i32 [[A:%.*]]) {
1983 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[A]], 10
1984 ; CHECK-NEXT:    [[XOR:%.*]] = xor i1 [[CMP1]], true
1985 ; CHECK-NEXT:    br i1 [[XOR]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1986 ; CHECK:       guard:
1987 ; CHECK-NEXT:    ret i1 true
1988 ; CHECK:       exit:
1989 ; CHECK-NEXT:    ret i1 false
1991   %cmp1 = icmp eq i32 %a, 10
1992   %xor = xor i1 %cmp1, true
1993   br i1 %xor, label %exit, label %guard
1995 guard:
1996   %cmp2 = icmp eq i32 %a, 10
1997   ret i1 %cmp2
1999 exit:
2000   ret i1 false
2003 define i1 @xor_approx(i32 %a) {
2004 ; CHECK-LABEL: define i1 @xor_approx
2005 ; CHECK-SAME: (i32 [[A:%.*]]) {
2006 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt i32 [[A]], 2
2007 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[A]], 5
2008 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp ugt i32 [[A]], 7
2009 ; CHECK-NEXT:    [[CMP4:%.*]] = icmp ult i32 [[A]], 9
2010 ; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[CMP1]], [[CMP2]]
2011 ; CHECK-NEXT:    [[AND2:%.*]] = and i1 [[CMP3]], [[CMP4]]
2012 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[AND1]], [[AND2]]
2013 ; CHECK-NEXT:    [[XOR:%.*]] = xor i1 [[OR]], true
2014 ; CHECK-NEXT:    br i1 [[XOR]], label [[EXIT:%.*]], label [[GUARD:%.*]]
2015 ; CHECK:       guard:
2016 ; CHECK-NEXT:    [[CMP5:%.*]] = icmp eq i32 [[A]], 6
2017 ; CHECK-NEXT:    ret i1 [[CMP5]]
2018 ; CHECK:       exit:
2019 ; CHECK-NEXT:    ret i1 false
2021   %cmp1 = icmp ugt i32 %a, 2
2022   %cmp2 = icmp ult i32 %a, 5
2023   %cmp3 = icmp ugt i32 %a, 7
2024   %cmp4 = icmp ult i32 %a, 9
2025   %and1 = and i1 %cmp1, %cmp2
2026   %and2 = and i1 %cmp3, %cmp4
2027   %or = or i1 %and1, %and2
2028   %xor = xor i1 %or, true
2029   br i1 %xor, label %exit, label %guard
2031 guard:
2032   %cmp5 = icmp eq i32 %a, 6
2033   ret i1 %cmp5
2035 exit:
2036   ret i1 false
2039 define i1 @binop_eval_order(i32 %x) {
2040 ; CHECK-LABEL: define i1 @binop_eval_order
2041 ; CHECK-SAME: (i32 [[X:%.*]]) {
2042 ; CHECK-NEXT:    [[A:%.*]] = add nuw nsw i32 [[X]], 1
2043 ; CHECK-NEXT:    [[B:%.*]] = add nuw nsw i32 [[A]], 1
2044 ; CHECK-NEXT:    [[C:%.*]] = add nuw nsw i32 [[A]], [[B]]
2045 ; CHECK-NEXT:    ret i1 true
2047   %a = add nuw nsw i32 %x, 1
2048   %b = add nuw nsw i32 %a, 1
2049   %c = add nuw nsw i32 %a, %b
2050   %d = icmp ugt i32 %c, 2
2051   ret i1 %d
2054 define range(i32 0, 1024) i32 @range_larger(i8 %x) {
2055 ; CHECK-LABEL: define range(i32 0, 256) i32 @range_larger
2056 ; CHECK-SAME: (i8 [[X:%.*]]) {
2057 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[X]] to i32
2058 ; CHECK-NEXT:    ret i32 [[ZEXT]]
2060   %zext = zext i8 %x to i32
2061   ret i32 %zext
2064 define range(i32 0, 128) i32 @range_smaller(i8 %x) {
2065 ; CHECK-LABEL: define range(i32 0, 128) i32 @range_smaller
2066 ; CHECK-SAME: (i8 [[X:%.*]]) {
2067 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[X]] to i32
2068 ; CHECK-NEXT:    ret i32 [[ZEXT]]
2070   %zext = zext i8 %x to i32
2071   ret i32 %zext
2074 define range(i32 128, 512) i32 @range_intersect(i8 %x) {
2075 ; CHECK-LABEL: define range(i32 128, 256) i32 @range_intersect
2076 ; CHECK-SAME: (i8 [[X:%.*]]) {
2077 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[X]] to i32
2078 ; CHECK-NEXT:    ret i32 [[ZEXT]]
2080   %zext = zext i8 %x to i32
2081   ret i32 %zext
2084 define range(i32 512, 1024) i32 @range_non_overlapping(i8 %x) {
2085 ; CHECK-LABEL: define range(i32 512, 1024) i32 @range_non_overlapping
2086 ; CHECK-SAME: (i8 [[X:%.*]]) {
2087 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[X]] to i32
2088 ; CHECK-NEXT:    ret i32 [[ZEXT]]
2090   %zext = zext i8 %x to i32
2091   ret i32 %zext
2094 declare i32 @llvm.uadd.sat.i32(i32, i32)
2095 declare i32 @llvm.usub.sat.i32(i32, i32)
2096 declare i32 @llvm.sadd.sat.i32(i32, i32)
2097 declare i32 @llvm.ssub.sat.i32(i32, i32)
2098 declare void @llvm.assume(i1)