1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s
3; PR2581
4
5define i32 @test1(i1 %C) {
6; CHECK-LABEL: @test1(
7; CHECK-NEXT:    br i1 [[C:%.*]], label [[EXIT:%.*]], label [[BODY:%.*]]
8; CHECK:       body:
9; CHECK-NEXT:    ret i32 11
10; CHECK:       exit:
11; CHECK-NEXT:    ret i32 10
12;
13  br i1 %C, label %exit, label %body
14
15body:           ; preds = %0
16  %A = select i1 %C, i32 10, i32 11
17  ret i32 %A
18
19exit:           ; preds = %0
20  ret i32 10
21}
22
23; PR4420
24declare i1 @ext()
25define i1 @test2() {
26; CHECK-LABEL: @test2(
27; CHECK-NEXT:  entry:
28; CHECK-NEXT:    [[COND:%.*]] = tail call i1 @ext()
29; CHECK-NEXT:    br i1 [[COND]], label [[BB1:%.*]], label [[BB2:%.*]]
30; CHECK:       bb1:
31; CHECK-NEXT:    [[COND2:%.*]] = tail call i1 @ext()
32; CHECK-NEXT:    br i1 [[COND2]], label [[BB3:%.*]], label [[BB2]]
33; CHECK:       bb2:
34; CHECK-NEXT:    ret i1 false
35; CHECK:       bb3:
36; CHECK-NEXT:    [[RES:%.*]] = tail call i1 @ext()
37; CHECK-NEXT:    ret i1 [[RES]]
38;
39entry:
40  %cond = tail call i1 @ext()
41  br i1 %cond, label %bb1, label %bb2
42
43bb1:
44  %cond2 = tail call i1 @ext()
45  br i1 %cond2, label %bb3, label %bb2
46
47bb2:
48  %cond_merge = phi i1 [ %cond, %entry ], [ false, %bb1 ]
49  ret i1 %cond_merge
50
51bb3:
52  %res = tail call i1 @ext()
53  ret i1 %res
54}
55
56; PR4855
57@gv = internal constant i8 7
58define i8 @test3(i8* %a) nounwind {
59; CHECK-LABEL: @test3(
60; CHECK-NEXT:  entry:
61; CHECK-NEXT:    [[COND:%.*]] = icmp eq i8* [[A:%.*]], @gv
62; CHECK-NEXT:    br i1 [[COND]], label [[BB2:%.*]], label [[BB:%.*]]
63; CHECK:       bb:
64; CHECK-NEXT:    ret i8 0
65; CHECK:       bb2:
66; CHECK-NEXT:    [[SHOULD_BE_CONST:%.*]] = load i8, i8* @gv, align 1
67; CHECK-NEXT:    ret i8 [[SHOULD_BE_CONST]]
68;
69entry:
70  %cond = icmp eq i8* %a, @gv
71  br i1 %cond, label %bb2, label %bb
72
73bb:
74  ret i8 0
75
76bb2:
77  %should_be_const = load i8, i8* %a
78  ret i8 %should_be_const
79}
80
81; PR1757
82define i32 @test4(i32) {
83; CHECK-LABEL: @test4(
84; CHECK-NEXT:  EntryBlock:
85; CHECK-NEXT:    [[DOTDEMORGAN:%.*]] = icmp sgt i32 [[TMP0:%.*]], 2
86; CHECK-NEXT:    br i1 [[DOTDEMORGAN]], label [[GREATERTHANTWO:%.*]], label [[LESSTHANOREQUALTOTWO:%.*]]
87; CHECK:       GreaterThanTwo:
88; CHECK-NEXT:    br i1 false, label [[IMPOSSIBLE:%.*]], label [[NOTTWOANDGREATERTHANTWO:%.*]]
89; CHECK:       NotTwoAndGreaterThanTwo:
90; CHECK-NEXT:    ret i32 2
91; CHECK:       Impossible:
92; CHECK-NEXT:    ret i32 1
93; CHECK:       LessThanOrEqualToTwo:
94; CHECK-NEXT:    ret i32 0
95;
96EntryBlock:
97  %.demorgan = icmp sgt i32 %0, 2
98  br i1 %.demorgan, label %GreaterThanTwo, label %LessThanOrEqualToTwo
99
100GreaterThanTwo:
101  icmp eq i32 %0, 2
102  br i1 %1, label %Impossible, label %NotTwoAndGreaterThanTwo
103
104NotTwoAndGreaterThanTwo:
105  ret i32 2
106
107Impossible:
108  ret i32 1
109
110LessThanOrEqualToTwo:
111  ret i32 0
112}
113
114declare i32* @f(i32*)
115define void @test5(i32* %x, i32* %y) {
116; CHECK-LABEL: @test5(
117; CHECK-NEXT:  entry:
118; CHECK-NEXT:    [[PRE:%.*]] = icmp eq i32* [[X:%.*]], null
119; CHECK-NEXT:    br i1 [[PRE]], label [[RETURN:%.*]], label [[LOOP:%.*]]
120; CHECK:       loop:
121; CHECK-NEXT:    [[PHI:%.*]] = phi i32* [ [[F:%.*]], [[LOOP]] ], [ [[X]], [[ENTRY:%.*]] ]
122; CHECK-NEXT:    [[F]] = tail call i32* @f(i32* [[PHI]])
123; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32* [[F]], [[Y:%.*]]
124; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP1]], i32* [[F]], i32* null
125; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32* [[SEL]], null
126; CHECK-NEXT:    br i1 [[CMP2]], label [[RETURN]], label [[LOOP]]
127; CHECK:       return:
128; CHECK-NEXT:    ret void
129;
130entry:
131  %pre = icmp eq i32* %x, null
132  br i1 %pre, label %return, label %loop
133
134loop:
135  %phi = phi i32* [ %sel, %loop ], [ %x, %entry ]
136  %f = tail call i32* @f(i32* %phi)
137  %cmp1 = icmp ne i32* %f, %y
138  %sel = select i1 %cmp1, i32* %f, i32* null
139  %cmp2 = icmp eq i32* %sel, null
140  br i1 %cmp2, label %return, label %loop
141
142return:
143  ret void
144}
145
146; "false" case for CorrelatedValuePropagation
147define void @loop1(i32* %x, i32* %y) {
148; CHECK-LABEL: @loop1(
149; CHECK-NEXT:  entry:
150; CHECK-NEXT:    br label [[LOOP:%.*]]
151; CHECK:       loop:
152; CHECK-NEXT:    [[PHI:%.*]] = phi i32* [ [[F:%.*]], [[LOOP]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
153; CHECK-NEXT:    [[F]] = tail call i32* @f(i32* [[PHI]])
154; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32* [[F]], [[Y:%.*]]
155; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP1]], i32* [[F]], i32* null
156; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32* [[SEL]], null
157; CHECK-NEXT:    br i1 [[CMP2]], label [[RETURN:%.*]], label [[LOOP]]
158; CHECK:       return:
159; CHECK-NEXT:    ret void
160;
161entry:
162  br label %loop
163
164loop:
165  %phi = phi i32* [ %sel, %loop ], [ %x, %entry ]
166  %f = tail call i32* @f(i32* %phi)
167  %cmp1 = icmp ne i32* %f, %y
168  %sel = select i1 %cmp1, i32* %f, i32* null
169  %cmp2 = icmp eq i32* %sel, null
170  br i1 %cmp2, label %return, label %loop
171
172return:
173  ret void
174}
175
176; "true" case for CorrelatedValuePropagation
177define void @loop2(i32* %x, i32* %y) {
178; CHECK-LABEL: @loop2(
179; CHECK-NEXT:  entry:
180; CHECK-NEXT:    br label [[LOOP:%.*]]
181; CHECK:       loop:
182; CHECK-NEXT:    [[PHI:%.*]] = phi i32* [ [[F:%.*]], [[LOOP]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
183; CHECK-NEXT:    [[F]] = tail call i32* @f(i32* [[PHI]])
184; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32* [[F]], [[Y:%.*]]
185; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP1]], i32* null, i32* [[F]]
186; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32* [[SEL]], null
187; CHECK-NEXT:    br i1 [[CMP2]], label [[RETURN:%.*]], label [[LOOP]]
188; CHECK:       return:
189; CHECK-NEXT:    ret void
190;
191entry:
192  br label %loop
193
194loop:
195  %phi = phi i32* [ %sel, %loop ], [ %x, %entry ]
196  %f = tail call i32* @f(i32* %phi)
197  %cmp1 = icmp eq i32* %f, %y
198  %sel = select i1 %cmp1, i32* null, i32* %f
199  %cmp2 = icmp eq i32* %sel, null
200  br i1 %cmp2, label %return, label %loop
201
202return:
203  ret void
204}
205
206define i32 @switch1(i32 %s) {
207; CHECK-LABEL: @switch1(
208; CHECK-NEXT:  entry:
209; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[S:%.*]], 0
210; CHECK-NEXT:    br i1 [[CMP]], label [[NEGATIVE:%.*]], label [[OUT:%.*]]
211; CHECK:       negative:
212; CHECK-NEXT:    switch i32 [[S]], label [[OUT]] [
213; CHECK-NEXT:    i32 -2, label [[NEXT:%.*]]
214; CHECK-NEXT:    i32 -1, label [[NEXT]]
215; CHECK-NEXT:    ]
216; CHECK:       out:
217; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ -1, [[NEGATIVE]] ]
218; CHECK-NEXT:    ret i32 [[P]]
219; CHECK:       next:
220; CHECK-NEXT:    ret i32 0
221;
222entry:
223  %cmp = icmp slt i32 %s, 0
224  br i1 %cmp, label %negative, label %out
225
226negative:
227  switch i32 %s, label %out [
228  i32 0, label %out
229  i32 1, label %out
230  i32 -1, label %next
231  i32 -2, label %next
232  i32 2, label %out
233  i32 3, label %out
234  ]
235
236out:
237  %p = phi i32 [ 1, %entry ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ]
238  ret i32 %p
239
240next:
241  %q = phi i32 [ 0, %negative ], [ 0, %negative ]
242  ret i32 %q
243}
244
245define i32 @switch2(i32 %s) {
246; CHECK-LABEL: @switch2(
247; CHECK-NEXT:  entry:
248; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[S:%.*]], 0
249; CHECK-NEXT:    br i1 [[CMP]], label [[POSITIVE:%.*]], label [[OUT:%.*]]
250; CHECK:       positive:
251; CHECK-NEXT:    br label [[OUT]]
252; CHECK:       out:
253; CHECK-NEXT:    [[P:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ 1, [[POSITIVE]] ]
254; CHECK-NEXT:    ret i32 [[P]]
255; CHECK:       next:
256; CHECK-NEXT:    ret i32 0
257;
258entry:
259  %cmp = icmp sgt i32 %s, 0
260  br i1 %cmp, label %positive, label %out
261
262positive:
263  switch i32 %s, label %out [
264  i32 0, label %out
265  i32 -1, label %next
266  i32 -2, label %next
267  ]
268
269out:
270  %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]
271  ret i32 %p
272
273next:
274  %q = phi i32 [ 0, %positive ], [ 0, %positive ]
275  ret i32 %q
276}
277
278define i32 @switch3(i32 %s) {
279; CHECK-LABEL: @switch3(
280; CHECK-NEXT:  entry:
281; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[S:%.*]], 0
282; CHECK-NEXT:    br i1 [[CMP]], label [[POSITIVE:%.*]], label [[OUT:%.*]]
283; CHECK:       positive:
284; CHECK-NEXT:    br label [[OUT]]
285; CHECK:       out:
286; CHECK-NEXT:    [[P:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ 1, [[POSITIVE]] ]
287; CHECK-NEXT:    ret i32 [[P]]
288; CHECK:       next:
289; CHECK-NEXT:    ret i32 0
290;
291entry:
292  %cmp = icmp sgt i32 %s, 0
293  br i1 %cmp, label %positive, label %out
294
295positive:
296  switch i32 %s, label %out [
297  i32 -1, label %out
298  i32 -2, label %next
299  i32 -3, label %next
300  ]
301
302out:
303  %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]
304  ret i32 %p
305
306next:
307  %q = phi i32 [ 0, %positive ], [ 0, %positive ]
308  ret i32 %q
309}
310
311define void @switch4(i32 %s) {
312; CHECK-LABEL: @switch4(
313; CHECK-NEXT:  entry:
314; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[S:%.*]], 0
315; CHECK-NEXT:    br i1 [[CMP]], label [[ZERO:%.*]], label [[OUT:%.*]]
316; CHECK:       zero:
317; CHECK-NEXT:    br label [[NEXT:%.*]]
318; CHECK:       out:
319; CHECK-NEXT:    ret void
320; CHECK:       next:
321; CHECK-NEXT:    ret void
322;
323entry:
324  %cmp = icmp eq i32 %s, 0
325  br i1 %cmp, label %zero, label %out
326
327zero:
328  switch i32 %s, label %out [
329  i32 0, label %next
330  i32 1, label %out
331  i32 -1, label %out
332  ]
333
334out:
335  ret void
336
337next:
338  ret void
339}
340
341define void @switch_nonzero_zext(i8 %s) {
342; CHECK-LABEL: @switch_nonzero_zext(
343; CHECK-NEXT:  entry:
344; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[S:%.*]], 0
345; CHECK-NEXT:    br i1 [[CMP]], label [[SWITCH:%.*]], label [[EXIT:%.*]]
346; CHECK:       switch:
347; CHECK-NEXT:    [[S_EXT:%.*]] = zext i8 [[S]] to i32
348; CHECK-NEXT:    br label [[EXIT]]
349; CHECK:       exit:
350; CHECK-NEXT:    ret void
351; CHECK:       unreachable:
352; CHECK-NEXT:    ret void
353;
354entry:
355  %cmp = icmp ne i8 %s, 0
356  br i1 %cmp, label %switch, label %exit
357
358switch:
359  %s.ext = zext i8 %s to i32
360  switch i32 %s.ext, label %exit [
361  i32 0, label %unreachable
362  i32 1, label %exit
363  i32 -1, label %exit
364  ]
365
366exit:
367  ret void
368
369unreachable:
370  ret void
371}
372
373define void @switch_assume_nonzero(i32 %s) {
374; CHECK-LABEL: @switch_assume_nonzero(
375; CHECK-NEXT:  entry:
376; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[S:%.*]], 0
377; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
378; CHECK-NEXT:    br label [[EXIT:%.*]]
379; CHECK:       exit:
380; CHECK-NEXT:    ret void
381; CHECK:       unreachable:
382; CHECK-NEXT:    ret void
383;
384entry:
385  %cmp = icmp ne i32 %s, 0
386  call void @llvm.assume(i1 %cmp)
387  switch i32 %s, label %exit [
388  i32 0, label %unreachable
389  i32 1, label %exit
390  i32 -1, label %exit
391  ]
392
393exit:
394  ret void
395
396unreachable:
397  ret void
398}
399
400define void @switch_nonzero_phi(i1 %cond) {
401; CHECK-LABEL: @switch_nonzero_phi(
402; CHECK-NEXT:  entry:
403; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
404; CHECK:       if:
405; CHECK-NEXT:    br label [[SWITCH:%.*]]
406; CHECK:       else:
407; CHECK-NEXT:    br label [[SWITCH]]
408; CHECK:       switch:
409; CHECK-NEXT:    [[S:%.*]] = phi i32 [ 1, [[IF]] ], [ -1, [[ELSE]] ]
410; CHECK-NEXT:    br label [[EXIT:%.*]]
411; CHECK:       exit:
412; CHECK-NEXT:    ret void
413; CHECK:       unreachable:
414; CHECK-NEXT:    ret void
415;
416entry:
417  br i1 %cond, label %if, label %else
418
419if:
420  br label %switch
421
422else:
423  br label %switch
424
425switch:
426  %s = phi i32 [ 1, %if ], [ -1, %else ]
427  switch i32 %s, label %exit [
428  i32 0, label %unreachable
429  i32 1, label %exit
430  i32 -1, label %exit
431  ]
432
433exit:
434  ret void
435
436unreachable:
437  ret void
438}
439
440define i32 @switch_range(i32 %cond) {
441; CHECK-LABEL: @switch_range(
442; CHECK-NEXT:  entry:
443; CHECK-NEXT:    [[S:%.*]] = urem i32 [[COND:%.*]], 3
444; CHECK-NEXT:    [[S1:%.*]] = add nuw nsw i32 [[S]], 1
445; CHECK-NEXT:    switch i32 [[S1]], label [[UNREACHABLE:%.*]] [
446; CHECK-NEXT:    i32 1, label [[EXIT1:%.*]]
447; CHECK-NEXT:    i32 2, label [[EXIT2:%.*]]
448; CHECK-NEXT:    i32 3, label [[EXIT1]]
449; CHECK-NEXT:    ]
450; CHECK:       exit1:
451; CHECK-NEXT:    ret i32 1
452; CHECK:       exit2:
453; CHECK-NEXT:    ret i32 2
454; CHECK:       unreachable:
455; CHECK-NEXT:    ret i32 0
456;
457entry:
458  %s = urem i32 %cond, 3
459  %s1 = add i32 %s, 1
460  switch i32 %s1, label %unreachable [
461  i32 1, label %exit1
462  i32 2, label %exit2
463  i32 3, label %exit1
464  ]
465
466exit1:
467  ret i32 1
468exit2:
469  ret i32 2
470unreachable:
471  ret i32 0
472}
473
474; If the cases do not cover the entire range of the
475; switch condition, we should not change the default.
476
477define i32 @switch_range_not_full(i32 %cond) {
478; CHECK-LABEL: @switch_range_not_full(
479; CHECK-NEXT:  entry:
480; CHECK-NEXT:    [[S:%.*]] = urem i32 [[COND:%.*]], 3
481; CHECK-NEXT:    [[S1:%.*]] = add nuw nsw i32 [[S]], 1
482; CHECK-NEXT:    switch i32 [[S1]], label [[UNREACHABLE:%.*]] [
483; CHECK-NEXT:    i32 1, label [[EXIT1:%.*]]
484; CHECK-NEXT:    i32 3, label [[EXIT2:%.*]]
485; CHECK-NEXT:    ]
486; CHECK:       exit1:
487; CHECK-NEXT:    ret i32 1
488; CHECK:       exit2:
489; CHECK-NEXT:    ret i32 2
490; CHECK:       unreachable:
491; CHECK-NEXT:    ret i32 0
492;
493entry:
494  %s = urem i32 %cond, 3
495  %s1 = add i32 %s, 1
496  switch i32 %s1, label %unreachable [
497  i32 1, label %exit1
498  i32 3, label %exit2
499  ]
500
501exit1:
502  ret i32 1
503exit2:
504  ret i32 2
505unreachable:
506  ret i32 0
507}
508
509; PR51531
510
511define i8 @switch_defaultdest_multipleuse(i8 %t0) {
512; CHECK-LABEL: @switch_defaultdest_multipleuse(
513; CHECK-NEXT:  entry:
514; CHECK-NEXT:    [[O:%.*]] = or i8 [[T0:%.*]], 1
515; CHECK-NEXT:    [[R:%.*]] = srem i8 1, [[O]]
516; CHECK-NEXT:    switch i8 [[R]], label [[EXIT:%.*]] [
517; CHECK-NEXT:    i8 0, label [[EXIT]]
518; CHECK-NEXT:    i8 1, label [[EXIT]]
519; CHECK-NEXT:    ]
520; CHECK:       exit:
521; CHECK-NEXT:    ret i8 0
522;
523entry:
524  %o = or i8 %t0, 1
525  %r = srem i8 1, %o
526  switch i8 %r, label %exit [
527  i8 0, label %exit
528  i8 1, label %exit
529  ]
530
531exit:
532  ret i8 0
533}
534
535define i1 @arg_attribute(i8* nonnull %a) {
536; CHECK-LABEL: @arg_attribute(
537; CHECK-NEXT:    ret i1 false
538;
539  %cmp = icmp eq i8* %a, null
540  ret i1 %cmp
541}
542
543declare nonnull i8* @return_nonnull()
544define i1 @call_attribute() {
545; CHECK-LABEL: @call_attribute(
546; CHECK-NEXT:    [[A:%.*]] = call i8* @return_nonnull()
547; CHECK-NEXT:    ret i1 false
548;
549  %a = call i8* @return_nonnull()
550  %cmp = icmp eq i8* %a, null
551  ret i1 %cmp
552}
553
554define i1 @umin(i32 %a, i32 %b) {
555; CHECK-LABEL: @umin(
556; CHECK-NEXT:  entry:
557; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 5
558; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
559; CHECK:       a_guard:
560; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[B:%.*]], 20
561; CHECK-NEXT:    br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
562; CHECK:       b_guard:
563; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp ult i32 [[A]], [[B]]
564; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
565; CHECK-NEXT:    ret i1 false
566; CHECK:       out:
567; CHECK-NEXT:    ret i1 false
568;
569entry:
570  %cmp = icmp ult i32 %a, 5
571  br i1 %cmp, label %a_guard, label %out
572
573a_guard:
574  %cmp2 = icmp ult i32 %b, 20
575  br i1 %cmp2, label %b_guard, label %out
576
577b_guard:
578  %sel_cmp = icmp ult i32 %a, %b
579  %min = select i1 %sel_cmp, i32 %a, i32 %b
580  %res = icmp eq i32 %min, 7
581  ret i1 %res
582out:
583  ret i1 false
584}
585
586define i1 @smin(i32 %a, i32 %b) {
587; CHECK-LABEL: @smin(
588; CHECK-NEXT:  entry:
589; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 5
590; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
591; CHECK:       a_guard:
592; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[B:%.*]], 20
593; CHECK-NEXT:    br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
594; CHECK:       b_guard:
595; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp ule i32 [[A]], [[B]]
596; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
597; CHECK-NEXT:    ret i1 false
598; CHECK:       out:
599; CHECK-NEXT:    ret i1 false
600;
601entry:
602  %cmp = icmp ult i32 %a, 5
603  br i1 %cmp, label %a_guard, label %out
604
605a_guard:
606  %cmp2 = icmp ult i32 %b, 20
607  br i1 %cmp2, label %b_guard, label %out
608
609b_guard:
610  %sel_cmp = icmp sle i32 %a, %b
611  %min = select i1 %sel_cmp, i32 %a, i32 %b
612  %res = icmp eq i32 %min, 7
613  ret i1 %res
614out:
615  ret i1 false
616}
617
618define i1 @smax(i32 %a, i32 %b) {
619; CHECK-LABEL: @smax(
620; CHECK-NEXT:  entry:
621; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 5
622; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
623; CHECK:       a_guard:
624; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[B:%.*]], 20
625; CHECK-NEXT:    br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
626; CHECK:       b_guard:
627; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp uge i32 [[A]], [[B]]
628; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
629; CHECK-NEXT:    ret i1 false
630; CHECK:       out:
631; CHECK-NEXT:    ret i1 false
632;
633entry:
634  %cmp = icmp sgt i32 %a, 5
635  br i1 %cmp, label %a_guard, label %out
636
637a_guard:
638  %cmp2 = icmp sgt i32 %b, 20
639  br i1 %cmp2, label %b_guard, label %out
640
641b_guard:
642  %sel_cmp = icmp sge i32 %a, %b
643  %max = select i1 %sel_cmp, i32 %a, i32 %b
644  %res = icmp eq i32 %max, 7
645  ret i1 %res
646out:
647  ret i1 false
648}
649
650define i1 @umax(i32 %a, i32 %b) {
651; CHECK-LABEL: @umax(
652; CHECK-NEXT:  entry:
653; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 5
654; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
655; CHECK:       a_guard:
656; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[B:%.*]], 20
657; CHECK-NEXT:    br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
658; CHECK:       b_guard:
659; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp uge i32 [[A]], [[B]]
660; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
661; CHECK-NEXT:    ret i1 false
662; CHECK:       out:
663; CHECK-NEXT:    ret i1 false
664;
665entry:
666  %cmp = icmp sgt i32 %a, 5
667  br i1 %cmp, label %a_guard, label %out
668
669a_guard:
670  %cmp2 = icmp sgt i32 %b, 20
671  br i1 %cmp2, label %b_guard, label %out
672
673b_guard:
674  %sel_cmp = icmp uge i32 %a, %b
675  %max = select i1 %sel_cmp, i32 %a, i32 %b
676  %res = icmp eq i32 %max, 7
677  ret i1 %res
678out:
679  ret i1 false
680}
681
682define i1 @umin_lhs_overdefined_rhs_const(i32 %a) {
683; CHECK-LABEL: @umin_lhs_overdefined_rhs_const(
684; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 42
685; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 [[A]], i32 42
686; CHECK-NEXT:    ret i1 true
687;
688  %cmp = icmp ult i32 %a, 42
689  %sel = select i1 %cmp, i32 %a, i32 42
690  %cmp2 = icmp ule i32 %sel, 42
691  ret i1 %cmp2
692}
693
694define i1 @umin_rhs_overdefined_lhs_const(i32 %a) {
695; CHECK-LABEL: @umin_rhs_overdefined_lhs_const(
696; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[A:%.*]], 42
697; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 42, i32 [[A]]
698; CHECK-NEXT:    ret i1 true
699;
700  %cmp = icmp uge i32 %a, 42
701  %sel = select i1 %cmp, i32 42, i32 %a
702  %cmp2 = icmp ule i32 %sel, 42
703  ret i1 %cmp2
704}
705
706define i1 @umin_lhs_overdefined_rhs_range(i32 %a, i32 %b) {
707; CHECK-LABEL: @umin_lhs_overdefined_rhs_range(
708; CHECK-NEXT:    [[ASSUME:%.*]] = icmp ult i32 [[B:%.*]], 42
709; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME]])
710; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A:%.*]], [[B]]
711; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[B]]
712; CHECK-NEXT:    ret i1 true
713;
714  %assume = icmp ult i32 %b, 42
715  call void @llvm.assume(i1 %assume)
716  %cmp = icmp ult i32 %a, %b
717  %sel = select i1 %cmp, i32 %a, i32 %b
718  %cmp2 = icmp ult i32 %sel, 42
719  ret i1 %cmp2
720}
721
722define i1 @umin_rhs_overdefined_lhs_range(i32 %a, i32 %b) {
723; CHECK-LABEL: @umin_rhs_overdefined_lhs_range(
724; CHECK-NEXT:    [[ASSUME:%.*]] = icmp ult i32 [[B:%.*]], 42
725; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME]])
726; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[A:%.*]], [[B]]
727; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 [[B]], i32 [[A]]
728; CHECK-NEXT:    ret i1 true
729;
730  %assume = icmp ult i32 %b, 42
731  call void @llvm.assume(i1 %assume)
732  %cmp = icmp uge i32 %a, %b
733  %sel = select i1 %cmp, i32 %b, i32 %a
734  %cmp2 = icmp ult i32 %sel, 42
735  ret i1 %cmp2
736}
737
738define i1 @clamp_low1(i32 %a) {
739; CHECK-LABEL: @clamp_low1(
740; CHECK-NEXT:  entry:
741; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5
742; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
743; CHECK:       a_guard:
744; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5
745; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], -1
746; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
747; CHECK-NEXT:    ret i1 false
748; CHECK:       out:
749; CHECK-NEXT:    ret i1 false
750;
751entry:
752  %cmp = icmp sge i32 %a, 5
753  br i1 %cmp, label %a_guard, label %out
754
755a_guard:
756  %sel_cmp = icmp eq i32 %a, 5
757  %add = add i32 %a, -1
758  %sel = select i1 %sel_cmp, i32 5, i32 %add
759  %res = icmp eq i32 %sel, 4
760  ret i1 %res
761out:
762  ret i1 false
763}
764
765define i1 @clamp_low2(i32 %a) {
766; CHECK-LABEL: @clamp_low2(
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 ne i32 [[A]], 5
772; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], -1
773; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
774; CHECK-NEXT:    ret i1 false
775; CHECK:       out:
776; CHECK-NEXT:    ret i1 false
777;
778entry:
779  %cmp = icmp sge i32 %a, 5
780  br i1 %cmp, label %a_guard, label %out
781
782a_guard:
783  %sel_cmp = icmp ne i32 %a, 5
784  %add = add i32 %a, -1
785  %sel = select i1 %sel_cmp, i32 %add, i32 5
786  %res = icmp eq i32 %sel, 4
787  ret i1 %res
788out:
789  ret i1 false
790}
791
792define i1 @clamp_low3(i32 %a) {
793; CHECK-LABEL: @clamp_low3(
794; CHECK-NEXT:  entry:
795; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5
796; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
797; CHECK:       a_guard:
798; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp ugt i32 [[A]], 5
799; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], -1
800; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
801; CHECK-NEXT:    ret i1 false
802; CHECK:       out:
803; CHECK-NEXT:    ret i1 false
804;
805entry:
806  %cmp = icmp sge i32 %a, 5
807  br i1 %cmp, label %a_guard, label %out
808
809a_guard:
810  %sel_cmp = icmp sgt i32 %a, 5
811  %add = add i32 %a, -1
812  %sel = select i1 %sel_cmp, i32 %add, i32 5
813  %res = icmp eq i32 %sel, 4
814  ret i1 %res
815out:
816  ret i1 false
817}
818
819define i1 @clamp_low4(i32 %a) {
820; CHECK-LABEL: @clamp_low4(
821; CHECK-NEXT:  entry:
822; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5
823; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
824; CHECK:       a_guard:
825; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp ule i32 [[A]], 5
826; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], -1
827; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
828; CHECK-NEXT:    ret i1 false
829; CHECK:       out:
830; CHECK-NEXT:    ret i1 false
831;
832entry:
833  %cmp = icmp sge i32 %a, 5
834  br i1 %cmp, label %a_guard, label %out
835
836a_guard:
837  %sel_cmp = icmp sle i32 %a, 5
838  %add = add i32 %a, -1
839  %sel = select i1 %sel_cmp, i32 5, i32 %add
840  %res = icmp eq i32 %sel, 4
841  ret i1 %res
842out:
843  ret i1 false
844}
845
846define i1 @clamp_high1(i32 %a) {
847; CHECK-LABEL: @clamp_high1(
848; CHECK-NEXT:  entry:
849; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5
850; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
851; CHECK:       a_guard:
852; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5
853; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 1
854; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
855; CHECK-NEXT:    ret i1 false
856; CHECK:       out:
857; CHECK-NEXT:    ret i1 false
858;
859entry:
860  %cmp = icmp sle i32 %a, 5
861  br i1 %cmp, label %a_guard, label %out
862
863a_guard:
864  %sel_cmp = icmp eq i32 %a, 5
865  %add = add i32 %a, 1
866  %sel = select i1 %sel_cmp, i32 5, i32 %add
867  %res = icmp eq i32 %sel, 6
868  ret i1 %res
869out:
870  ret i1 false
871}
872
873define i1 @clamp_high2(i32 %a) {
874; CHECK-LABEL: @clamp_high2(
875; CHECK-NEXT:  entry:
876; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5
877; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
878; CHECK:       a_guard:
879; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5
880; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 1
881; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
882; CHECK-NEXT:    ret i1 false
883; CHECK:       out:
884; CHECK-NEXT:    ret i1 false
885;
886entry:
887  %cmp = icmp sle i32 %a, 5
888  br i1 %cmp, label %a_guard, label %out
889
890a_guard:
891  %sel_cmp = icmp ne i32 %a, 5
892  %add = add i32 %a, 1
893  %sel = select i1 %sel_cmp, i32 %add, i32 5
894  %res = icmp eq i32 %sel, 6
895  ret i1 %res
896out:
897  ret i1 false
898}
899
900define i1 @clamp_high3(i32 %a) {
901; CHECK-LABEL: @clamp_high3(
902; CHECK-NEXT:  entry:
903; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5
904; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
905; CHECK:       a_guard:
906; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp slt i32 [[A]], 5
907; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 1
908; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
909; CHECK-NEXT:    ret i1 false
910; CHECK:       out:
911; CHECK-NEXT:    ret i1 false
912;
913entry:
914  %cmp = icmp sle i32 %a, 5
915  br i1 %cmp, label %a_guard, label %out
916
917a_guard:
918  %sel_cmp = icmp slt i32 %a, 5
919  %add = add i32 %a, 1
920  %sel = select i1 %sel_cmp, i32 %add, i32 5
921  %res = icmp eq i32 %sel, 6
922  ret i1 %res
923out:
924  ret i1 false
925}
926
927define i1 @clamp_high4(i32 %a) {
928; CHECK-LABEL: @clamp_high4(
929; CHECK-NEXT:  entry:
930; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5
931; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
932; CHECK:       a_guard:
933; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp sge i32 [[A]], 5
934; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 1
935; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
936; CHECK-NEXT:    ret i1 false
937; CHECK:       out:
938; CHECK-NEXT:    ret i1 false
939;
940entry:
941  %cmp = icmp sle i32 %a, 5
942  br i1 %cmp, label %a_guard, label %out
943
944a_guard:
945  %sel_cmp = icmp sge i32 %a, 5
946  %add = add i32 %a, 1
947  %sel = select i1 %sel_cmp, i32 5, i32 %add
948  %res = icmp eq i32 %sel, 6
949  ret i1 %res
950out:
951  ret i1 false
952}
953
954; Just showing arbitrary constants work, not really a clamp
955define i1 @not_clamp_high(i32 %a) {
956; CHECK-LABEL: @not_clamp_high(
957; CHECK-NEXT:  entry:
958; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5
959; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
960; CHECK:       a_guard:
961; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5
962; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 100
963; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
964; CHECK-NEXT:    ret i1 false
965; CHECK:       out:
966; CHECK-NEXT:    ret i1 false
967;
968entry:
969  %cmp = icmp sle i32 %a, 5
970  br i1 %cmp, label %a_guard, label %out
971
972a_guard:
973  %sel_cmp = icmp ne i32 %a, 5
974  %add = add i32 %a, 100
975  %sel = select i1 %sel_cmp, i32 %add, i32 5
976  %res = icmp eq i32 %sel, 105
977  ret i1 %res
978out:
979  ret i1 false
980}
981
982define void @abs1(i32 %a, i1* %p) {
983; CHECK-LABEL: @abs1(
984; CHECK-NEXT:  entry:
985; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10
986; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
987; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
988; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
989; CHECK:       guard:
990; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 0, [[A]]
991; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], 0
992; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]]
993; CHECK-NEXT:    store i1 true, i1* [[P:%.*]], align 1
994; CHECK-NEXT:    [[C2:%.*]] = icmp ult i32 [[ABS]], 19
995; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
996; CHECK-NEXT:    store i1 true, i1* [[P]], align 1
997; CHECK-NEXT:    [[C4:%.*]] = icmp uge i32 [[ABS]], 1
998; CHECK-NEXT:    store i1 [[C4]], i1* [[P]], align 1
999; CHECK-NEXT:    br label [[EXIT]]
1000; CHECK:       exit:
1001; CHECK-NEXT:    ret void
1002;
1003entry:
1004  %cmp1 = icmp slt i32 %a, 10
1005  %cmp2 = icmp sgt i32 %a, -20
1006  %and = and i1 %cmp1, %cmp2
1007  br i1 %and, label %guard, label %exit
1008
1009guard:
1010  %sub = sub i32 0, %a
1011  %cmp = icmp slt i32 %a, 0
1012  %abs = select i1 %cmp, i32 %sub, i32 %a
1013  %c1 = icmp slt i32 %abs, 20
1014  store i1 %c1, i1* %p
1015  %c2 = icmp slt i32 %abs, 19
1016  store i1 %c2, i1* %p
1017  %c3 = icmp sge i32 %abs, 0
1018  store i1 %c3, i1* %p
1019  %c4 = icmp sge i32 %abs, 1
1020  store i1 %c4, i1* %p
1021  br label %exit
1022
1023exit:
1024  ret void
1025}
1026
1027define void @abs2(i32 %a, i1* %p) {
1028; CHECK-LABEL: @abs2(
1029; CHECK-NEXT:  entry:
1030; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10
1031; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
1032; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1033; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1034; CHECK:       guard:
1035; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 0, [[A]]
1036; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[A]], 0
1037; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[SUB]]
1038; CHECK-NEXT:    store i1 true, i1* [[P:%.*]], align 1
1039; CHECK-NEXT:    [[C2:%.*]] = icmp ult i32 [[ABS]], 19
1040; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
1041; CHECK-NEXT:    store i1 true, i1* [[P]], align 1
1042; CHECK-NEXT:    [[C4:%.*]] = icmp uge i32 [[ABS]], 1
1043; CHECK-NEXT:    store i1 [[C4]], i1* [[P]], align 1
1044; CHECK-NEXT:    br label [[EXIT]]
1045; CHECK:       exit:
1046; CHECK-NEXT:    ret void
1047;
1048entry:
1049  %cmp1 = icmp slt i32 %a, 10
1050  %cmp2 = icmp sgt i32 %a, -20
1051  %and = and i1 %cmp1, %cmp2
1052  br i1 %and, label %guard, label %exit
1053
1054guard:
1055  %sub = sub i32 0, %a
1056  %cmp = icmp sge i32 %a, 0
1057  %abs = select i1 %cmp, i32 %a, i32 %sub
1058  %c1 = icmp slt i32 %abs, 20
1059  store i1 %c1, i1* %p
1060  %c2 = icmp slt i32 %abs, 19
1061  store i1 %c2, i1* %p
1062  %c3 = icmp sge i32 %abs, 0
1063  store i1 %c3, i1* %p
1064  %c4 = icmp sge i32 %abs, 1
1065  store i1 %c4, i1* %p
1066  br label %exit
1067
1068exit:
1069  ret void
1070}
1071
1072define void @nabs1(i32 %a, i1* %p) {
1073; CHECK-LABEL: @nabs1(
1074; CHECK-NEXT:  entry:
1075; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10
1076; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
1077; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1078; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1079; CHECK:       guard:
1080; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 0, [[A]]
1081; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A]], 0
1082; CHECK-NEXT:    [[NABS:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]]
1083; CHECK-NEXT:    store i1 true, i1* [[P:%.*]], align 1
1084; CHECK-NEXT:    [[C2:%.*]] = icmp sgt i32 [[NABS]], -19
1085; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
1086; CHECK-NEXT:    store i1 true, i1* [[P]], align 1
1087; CHECK-NEXT:    [[C4:%.*]] = icmp sle i32 [[NABS]], -1
1088; CHECK-NEXT:    store i1 [[C4]], i1* [[P]], align 1
1089; CHECK-NEXT:    br label [[EXIT]]
1090; CHECK:       exit:
1091; CHECK-NEXT:    ret void
1092;
1093entry:
1094  %cmp1 = icmp slt i32 %a, 10
1095  %cmp2 = icmp sgt i32 %a, -20
1096  %and = and i1 %cmp1, %cmp2
1097  br i1 %and, label %guard, label %exit
1098
1099guard:
1100  %sub = sub i32 0, %a
1101  %cmp = icmp sgt i32 %a, 0
1102  %nabs = select i1 %cmp, i32 %sub, i32 %a
1103  %c1 = icmp sgt i32 %nabs, -20
1104  store i1 %c1, i1* %p
1105  %c2 = icmp sgt i32 %nabs, -19
1106  store i1 %c2, i1* %p
1107  %c3 = icmp sle i32 %nabs, 0
1108  store i1 %c3, i1* %p
1109  %c4 = icmp sle i32 %nabs, -1
1110  store i1 %c4, i1* %p
1111  br label %exit
1112
1113exit:
1114  ret void
1115}
1116
1117define void @nabs2(i32 %a, i1* %p) {
1118; CHECK-LABEL: @nabs2(
1119; CHECK-NEXT:  entry:
1120; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10
1121; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
1122; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1123; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1124; CHECK:       guard:
1125; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 0, [[A]]
1126; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], 0
1127; CHECK-NEXT:    [[NABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[SUB]]
1128; CHECK-NEXT:    store i1 true, i1* [[P:%.*]], align 1
1129; CHECK-NEXT:    [[C2:%.*]] = icmp sgt i32 [[NABS]], -19
1130; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
1131; CHECK-NEXT:    store i1 true, i1* [[P]], align 1
1132; CHECK-NEXT:    [[C4:%.*]] = icmp sle i32 [[NABS]], -1
1133; CHECK-NEXT:    store i1 [[C4]], i1* [[P]], align 1
1134; CHECK-NEXT:    br label [[EXIT]]
1135; CHECK:       exit:
1136; CHECK-NEXT:    ret void
1137;
1138entry:
1139  %cmp1 = icmp slt i32 %a, 10
1140  %cmp2 = icmp sgt i32 %a, -20
1141  %and = and i1 %cmp1, %cmp2
1142  br i1 %and, label %guard, label %exit
1143
1144guard:
1145  %sub = sub i32 0, %a
1146  %cmp = icmp slt i32 %a, 0
1147  %nabs = select i1 %cmp, i32 %a, i32 %sub
1148  %c1 = icmp sgt i32 %nabs, -20
1149  store i1 %c1, i1* %p
1150  %c2 = icmp sgt i32 %nabs, -19
1151  store i1 %c2, i1* %p
1152  %c3 = icmp sle i32 %nabs, 0
1153  store i1 %c3, i1* %p
1154  %c4 = icmp sle i32 %nabs, -1
1155  store i1 %c4, i1* %p
1156  br label %exit
1157
1158exit:
1159  ret void
1160}
1161
1162define i1 @zext_unknown(i8 %a) {
1163; CHECK-LABEL: @zext_unknown(
1164; CHECK-NEXT:  entry:
1165; CHECK-NEXT:    [[A32:%.*]] = zext i8 [[A:%.*]] to i32
1166; CHECK-NEXT:    ret i1 true
1167;
1168entry:
1169  %a32 = zext i8 %a to i32
1170  %cmp = icmp sle i32 %a32, 256
1171  ret i1 %cmp
1172}
1173
1174define i1 @trunc_unknown(i32 %a) {
1175; CHECK-LABEL: @trunc_unknown(
1176; CHECK-NEXT:  entry:
1177; CHECK-NEXT:    [[A8:%.*]] = trunc i32 [[A:%.*]] to i8
1178; CHECK-NEXT:    [[A32:%.*]] = sext i8 [[A8]] to i32
1179; CHECK-NEXT:    ret i1 true
1180;
1181entry:
1182  %a8 = trunc i32 %a to i8
1183  %a32 = sext i8 %a8 to i32
1184  %cmp = icmp sle i32 %a32, 128
1185  ret i1 %cmp
1186}
1187
1188define void @trunc_icmp_ule(i32 %x, i1* %p) {
1189; CHECK-LABEL: @trunc_icmp_ule(
1190; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[X:%.*]] to i8
1191; CHECK-NEXT:    [[C:%.*]] = icmp uge i8 [[T]], 5
1192; CHECK-NEXT:    br i1 [[C]], label [[TRUE:%.*]], label [[FALSE:%.*]]
1193; CHECK:       true:
1194; CHECK-NEXT:    store i1 true, i1* [[P:%.*]], align 1
1195; CHECK-NEXT:    [[C2:%.*]] = icmp ugt i32 [[X]], 5
1196; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
1197; CHECK-NEXT:    [[C3:%.*]] = icmp ule i32 [[X]], 5
1198; CHECK-NEXT:    store i1 [[C3]], i1* [[P]], align 1
1199; CHECK-NEXT:    store i1 false, i1* [[P]], align 1
1200; CHECK-NEXT:    ret void
1201; CHECK:       false:
1202; CHECK-NEXT:    [[C1_2:%.*]] = icmp uge i32 [[X]], 5
1203; CHECK-NEXT:    store i1 [[C1_2]], i1* [[P]], align 1
1204; CHECK-NEXT:    [[C2_2:%.*]] = icmp ugt i32 [[X]], 5
1205; CHECK-NEXT:    store i1 [[C2_2]], i1* [[P]], align 1
1206; CHECK-NEXT:    [[C3_2:%.*]] = icmp ule i32 [[X]], 5
1207; CHECK-NEXT:    store i1 [[C3_2]], i1* [[P]], align 1
1208; CHECK-NEXT:    [[C4_2:%.*]] = icmp ult i32 [[X]], 5
1209; CHECK-NEXT:    store i1 [[C4_2]], i1* [[P]], align 1
1210; CHECK-NEXT:    ret void
1211;
1212  %t = trunc i32 %x to i8
1213  %c = icmp uge i8 %t, 5
1214  br i1 %c, label %true, label %false
1215
1216true:
1217  %c1 = icmp uge i32 %x, 5
1218  store i1 %c1, i1* %p
1219  %c2 = icmp ugt i32 %x, 5
1220  store i1 %c2, i1* %p
1221  %c3 = icmp ule i32 %x, 5
1222  store i1 %c3, i1* %p
1223  %c4 = icmp ult i32 %x, 5
1224  store i1 %c4, i1* %p
1225  ret void
1226
1227false:
1228  %c1.2 = icmp uge i32 %x, 5
1229  store i1 %c1.2, i1* %p
1230  %c2.2 = icmp ugt i32 %x, 5
1231  store i1 %c2.2, i1* %p
1232  %c3.2 = icmp ule i32 %x, 5
1233  store i1 %c3.2, i1* %p
1234  %c4.2 = icmp ult i32 %x, 5
1235  store i1 %c4.2, i1* %p
1236  ret void
1237}
1238
1239define void @trunc_icmp_eq(i32 %x, i1* %p) {
1240; CHECK-LABEL: @trunc_icmp_eq(
1241; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[X:%.*]] to i8
1242; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[T]], 5
1243; CHECK-NEXT:    br i1 [[C]], label [[TRUE:%.*]], label [[FALSE:%.*]]
1244; CHECK:       true:
1245; CHECK-NEXT:    store i1 true, i1* [[P:%.*]], align 1
1246; CHECK-NEXT:    [[C2:%.*]] = icmp ugt i32 [[X]], 5
1247; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
1248; CHECK-NEXT:    [[C3:%.*]] = icmp ule i32 [[X]], 5
1249; CHECK-NEXT:    store i1 [[C3]], i1* [[P]], align 1
1250; CHECK-NEXT:    store i1 false, i1* [[P]], align 1
1251; CHECK-NEXT:    ret void
1252; CHECK:       false:
1253; CHECK-NEXT:    [[C1_2:%.*]] = icmp uge i32 [[X]], 5
1254; CHECK-NEXT:    store i1 [[C1_2]], i1* [[P]], align 1
1255; CHECK-NEXT:    [[C2_2:%.*]] = icmp ugt i32 [[X]], 5
1256; CHECK-NEXT:    store i1 [[C2_2]], i1* [[P]], align 1
1257; CHECK-NEXT:    [[C3_2:%.*]] = icmp ule i32 [[X]], 5
1258; CHECK-NEXT:    store i1 [[C3_2]], i1* [[P]], align 1
1259; CHECK-NEXT:    [[C4_2:%.*]] = icmp ult i32 [[X]], 5
1260; CHECK-NEXT:    store i1 [[C4_2]], i1* [[P]], align 1
1261; CHECK-NEXT:    ret void
1262;
1263  %t = trunc i32 %x to i8
1264  %c = icmp eq i8 %t, 5
1265  br i1 %c, label %true, label %false
1266
1267true:
1268  %c1 = icmp uge i32 %x, 5
1269  store i1 %c1, i1* %p
1270  %c2 = icmp ugt i32 %x, 5
1271  store i1 %c2, i1* %p
1272  %c3 = icmp ule i32 %x, 5
1273  store i1 %c3, i1* %p
1274  %c4 = icmp ult i32 %x, 5
1275  store i1 %c4, i1* %p
1276  ret void
1277
1278false:
1279  %c1.2 = icmp uge i32 %x, 5
1280  store i1 %c1.2, i1* %p
1281  %c2.2 = icmp ugt i32 %x, 5
1282  store i1 %c2.2, i1* %p
1283  %c3.2 = icmp ule i32 %x, 5
1284  store i1 %c3.2, i1* %p
1285  %c4.2 = icmp ult i32 %x, 5
1286  store i1 %c4.2, i1* %p
1287  ret void
1288}
1289
1290; TODO: missed optimization
1291; Make sure we exercise non-integer inputs to unary operators (i.e. crash check).
1292define i1 @bitcast_unknown(float %a) {
1293; CHECK-LABEL: @bitcast_unknown(
1294; CHECK-NEXT:  entry:
1295; CHECK-NEXT:    [[A32:%.*]] = bitcast float [[A:%.*]] to i32
1296; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A32]], 128
1297; CHECK-NEXT:    ret i1 [[CMP]]
1298;
1299entry:
1300  %a32 = bitcast float %a to i32
1301  %cmp = icmp sle i32 %a32, 128
1302  ret i1 %cmp
1303}
1304
1305define i1 @bitcast_unknown2(i8* %p) {
1306; CHECK-LABEL: @bitcast_unknown2(
1307; CHECK-NEXT:  entry:
1308; CHECK-NEXT:    [[P64:%.*]] = ptrtoint i8* [[P:%.*]] to i64
1309; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i64 [[P64]], 128
1310; CHECK-NEXT:    ret i1 [[CMP]]
1311;
1312entry:
1313  %p64 = ptrtoint i8* %p to i64
1314  %cmp = icmp sle i64 %p64, 128
1315  ret i1 %cmp
1316}
1317
1318
1319define i1 @and_unknown(i32 %a) {
1320; CHECK-LABEL: @and_unknown(
1321; CHECK-NEXT:  entry:
1322; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 128
1323; CHECK-NEXT:    ret i1 true
1324;
1325entry:
1326  %and = and i32 %a, 128
1327  %cmp = icmp sle i32 %and, 128
1328  ret i1 %cmp
1329}
1330
1331define i1 @lshr_unknown(i32 %a) {
1332; CHECK-LABEL: @lshr_unknown(
1333; CHECK-NEXT:  entry:
1334; CHECK-NEXT:    [[AND:%.*]] = lshr i32 [[A:%.*]], 30
1335; CHECK-NEXT:    ret i1 true
1336;
1337entry:
1338  %and = lshr i32 %a, 30
1339  %cmp = icmp sle i32 %and, 128
1340  ret i1 %cmp
1341}
1342
1343define i1 @urem_unknown(i32 %a) {
1344; CHECK-LABEL: @urem_unknown(
1345; CHECK-NEXT:  entry:
1346; CHECK-NEXT:    [[UREM:%.*]] = urem i32 [[A:%.*]], 30
1347; CHECK-NEXT:    ret i1 true
1348;
1349entry:
1350  %urem = urem i32 %a, 30
1351  %cmp = icmp ult i32 %urem, 30
1352  ret i1 %cmp
1353}
1354
1355define i1 @srem_unknown(i32 %a) {
1356; CHECK-LABEL: @srem_unknown(
1357; CHECK-NEXT:  entry:
1358; CHECK-NEXT:    [[SREM:%.*]] = srem i32 [[A:%.*]], 30
1359; CHECK-NEXT:    br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1360; CHECK:       exit1:
1361; CHECK-NEXT:    ret i1 true
1362; CHECK:       exit2:
1363; CHECK-NEXT:    ret i1 true
1364;
1365entry:
1366  %srem = srem i32 %a, 30
1367  %cmp1 = icmp slt i32 %srem, 30
1368  %cmp2 = icmp sgt i32 %srem, -30
1369  br i1 undef, label %exit1, label %exit2
1370exit1:
1371  ret i1 %cmp1
1372exit2:
1373  ret i1 %cmp2
1374}
1375
1376define i1 @sdiv_unknown(i32 %a) {
1377; CHECK-LABEL: @sdiv_unknown(
1378; CHECK-NEXT:  entry:
1379; CHECK-NEXT:    [[SREM:%.*]] = sdiv i32 [[A:%.*]], 123
1380; CHECK-NEXT:    br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1381; CHECK:       exit1:
1382; CHECK-NEXT:    ret i1 true
1383; CHECK:       exit2:
1384; CHECK-NEXT:    ret i1 true
1385;
1386entry:
1387  %srem = sdiv i32 %a, 123
1388  %cmp1 = icmp slt i32 %srem, 17459217
1389  %cmp2 = icmp sgt i32 %srem, -17459217
1390  br i1 undef, label %exit1, label %exit2
1391exit1:
1392  ret i1 %cmp1
1393exit2:
1394  ret i1 %cmp2
1395}
1396
1397define i1 @uadd_sat_unknown(i32 %a) {
1398; CHECK-LABEL: @uadd_sat_unknown(
1399; CHECK-NEXT:  entry:
1400; CHECK-NEXT:    [[VAL:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[A:%.*]], i32 100)
1401; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 [[VAL]], 100
1402; CHECK-NEXT:    br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1403; CHECK:       exit1:
1404; CHECK-NEXT:    ret i1 true
1405; CHECK:       exit2:
1406; CHECK-NEXT:    ret i1 [[CMP2]]
1407;
1408entry:
1409  %val = call i32 @llvm.uadd.sat.i32(i32 %a, i32 100)
1410  %cmp1 = icmp uge i32 %val, 100
1411  %cmp2 = icmp ugt i32 %val, 100
1412  br i1 undef, label %exit1, label %exit2
1413exit1:
1414  ret i1 %cmp1
1415exit2:
1416  ret i1 %cmp2
1417}
1418
1419define i1 @usub_sat_unknown(i32 %a) {
1420; CHECK-LABEL: @usub_sat_unknown(
1421; CHECK-NEXT:  entry:
1422; CHECK-NEXT:    [[VAL:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A:%.*]], i32 100)
1423; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[VAL]], -101
1424; CHECK-NEXT:    br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1425; CHECK:       exit1:
1426; CHECK-NEXT:    ret i1 true
1427; CHECK:       exit2:
1428; CHECK-NEXT:    ret i1 [[CMP2]]
1429;
1430entry:
1431  %val = call i32 @llvm.usub.sat.i32(i32 %a, i32 100)
1432  %cmp1 = icmp ule i32 %val, 4294967195
1433  %cmp2 = icmp ult i32 %val, 4294967195
1434  br i1 undef, label %exit1, label %exit2
1435exit1:
1436  ret i1 %cmp1
1437exit2:
1438  ret i1 %cmp2
1439}
1440
1441define i1 @sadd_sat_unknown(i32 %a) {
1442; CHECK-LABEL: @sadd_sat_unknown(
1443; CHECK-NEXT:  entry:
1444; CHECK-NEXT:    [[VAL:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[A:%.*]], i32 100)
1445; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[VAL]], -2147483548
1446; CHECK-NEXT:    br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1447; CHECK:       exit1:
1448; CHECK-NEXT:    ret i1 true
1449; CHECK:       exit2:
1450; CHECK-NEXT:    ret i1 [[CMP2]]
1451;
1452entry:
1453  %val = call i32 @llvm.sadd.sat.i32(i32 %a, i32 100)
1454  %cmp1 = icmp sge i32 %val, -2147483548
1455  %cmp2 = icmp sgt i32 %val, -2147483548
1456  br i1 undef, label %exit1, label %exit2
1457exit1:
1458  ret i1 %cmp1
1459exit2:
1460  ret i1 %cmp2
1461}
1462
1463define i1 @ssub_sat_unknown(i32 %a) {
1464; CHECK-LABEL: @ssub_sat_unknown(
1465; CHECK-NEXT:  entry:
1466; CHECK-NEXT:    [[VAL:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[A:%.*]], i32 100)
1467; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[VAL]], 2147483547
1468; CHECK-NEXT:    br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1469; CHECK:       exit1:
1470; CHECK-NEXT:    ret i1 true
1471; CHECK:       exit2:
1472; CHECK-NEXT:    ret i1 [[CMP2]]
1473;
1474entry:
1475  %val = call i32 @llvm.ssub.sat.i32(i32 %a, i32 100)
1476  %cmp1 = icmp sle i32 %val, 2147483547
1477  %cmp2 = icmp slt i32 %val, 2147483547
1478  br i1 undef, label %exit1, label %exit2
1479exit1:
1480  ret i1 %cmp1
1481exit2:
1482  ret i1 %cmp2
1483}
1484
1485define void @select_and(i32 %a, i1* %p) {
1486; CHECK-LABEL: @select_and(
1487; CHECK-NEXT:  entry:
1488; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[A:%.*]], -10
1489; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[A]], 10
1490; CHECK-NEXT:    [[AND:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1491; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1492; CHECK:       guard:
1493; CHECK-NEXT:    store i1 false, i1* [[P:%.*]], align 1
1494; CHECK-NEXT:    store i1 false, i1* [[P]], align 1
1495; CHECK-NEXT:    br label [[EXIT]]
1496; CHECK:       exit:
1497; CHECK-NEXT:    ret void
1498;
1499entry:
1500  %cmp1 = icmp sgt i32 %a, -10
1501  %cmp2 = icmp slt i32 %a, 10
1502  %and = select i1 %cmp1, i1 %cmp2, i1 false
1503  br i1 %and, label %guard, label %exit
1504
1505guard:
1506  %c1 = icmp sgt i32 %a, 20
1507  store i1 %c1, i1* %p
1508  %c2 = icmp slt i32 %a, -20
1509  store i1 %c2, i1* %p
1510  br label %exit
1511
1512exit:
1513  ret void
1514}
1515
1516define void @select_and_wrong_const(i32 %a, i1* %p) {
1517; CHECK-LABEL: @select_and_wrong_const(
1518; CHECK-NEXT:  entry:
1519; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[A:%.*]], -10
1520; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[A]], 10
1521; CHECK-NEXT:    [[AND:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 true
1522; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1523; CHECK:       guard:
1524; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i32 [[A]], 20
1525; CHECK-NEXT:    store i1 [[C1]], i1* [[P:%.*]], align 1
1526; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[A]], -20
1527; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
1528; CHECK-NEXT:    br label [[EXIT]]
1529; CHECK:       exit:
1530; CHECK-NEXT:    ret void
1531;
1532entry:
1533  %cmp1 = icmp sgt i32 %a, -10
1534  %cmp2 = icmp slt i32 %a, 10
1535  %and = select i1 %cmp1, i1 %cmp2, i1 true
1536  br i1 %and, label %guard, label %exit
1537
1538guard:
1539  %c1 = icmp sgt i32 %a, 20
1540  store i1 %c1, i1* %p
1541  %c2 = icmp slt i32 %a, -20
1542  store i1 %c2, i1* %p
1543  br label %exit
1544
1545exit:
1546  ret void
1547}
1548
1549define void @select_and_wrong_operand(i32 %a, i1* %p) {
1550; CHECK-LABEL: @select_and_wrong_operand(
1551; CHECK-NEXT:  entry:
1552; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[A:%.*]], -10
1553; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[A]], 10
1554; CHECK-NEXT:    [[AND:%.*]] = select i1 [[CMP1]], i1 false, i1 [[CMP2]]
1555; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1556; CHECK:       guard:
1557; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i32 [[A]], 20
1558; CHECK-NEXT:    store i1 [[C1]], i1* [[P:%.*]], align 1
1559; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[A]], -20
1560; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
1561; CHECK-NEXT:    br label [[EXIT]]
1562; CHECK:       exit:
1563; CHECK-NEXT:    ret void
1564;
1565entry:
1566  %cmp1 = icmp sgt i32 %a, -10
1567  %cmp2 = icmp slt i32 %a, 10
1568  %and = select i1 %cmp1, i1 false, i1 %cmp2
1569  br i1 %and, label %guard, label %exit
1570
1571guard:
1572  %c1 = icmp sgt i32 %a, 20
1573  store i1 %c1, i1* %p
1574  %c2 = icmp slt i32 %a, -20
1575  store i1 %c2, i1* %p
1576  br label %exit
1577
1578exit:
1579  ret void
1580}
1581
1582define void @select_or(i32 %a, i1* %p) {
1583; CHECK-LABEL: @select_or(
1584; CHECK-NEXT:  entry:
1585; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], -10
1586; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], 10
1587; CHECK-NEXT:    [[OR:%.*]] = select i1 [[CMP1]], i1 true, i1 [[CMP2]]
1588; CHECK-NEXT:    br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1589; CHECK:       guard:
1590; CHECK-NEXT:    store i1 false, i1* [[P:%.*]], align 1
1591; CHECK-NEXT:    store i1 false, i1* [[P]], align 1
1592; CHECK-NEXT:    br label [[EXIT]]
1593; CHECK:       exit:
1594; CHECK-NEXT:    ret void
1595;
1596entry:
1597  %cmp1 = icmp slt i32 %a, -10
1598  %cmp2 = icmp sgt i32 %a, 10
1599  %or = select i1 %cmp1, i1 true, i1 %cmp2
1600  br i1 %or, label %exit, label %guard
1601
1602guard:
1603  %c1 = icmp sgt i32 %a, 20
1604  store i1 %c1, i1* %p
1605  %c2 = icmp slt i32 %a, -20
1606  store i1 %c2, i1* %p
1607  br label %exit
1608
1609exit:
1610  ret void
1611}
1612
1613define void @select_or_wrong_const(i32 %a, i1* %p) {
1614; CHECK-LABEL: @select_or_wrong_const(
1615; CHECK-NEXT:  entry:
1616; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], -10
1617; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], 10
1618; CHECK-NEXT:    [[OR:%.*]] = select i1 [[CMP1]], i1 false, i1 [[CMP2]]
1619; CHECK-NEXT:    br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1620; CHECK:       guard:
1621; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i32 [[A]], 20
1622; CHECK-NEXT:    store i1 [[C1]], i1* [[P:%.*]], align 1
1623; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[A]], -20
1624; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
1625; CHECK-NEXT:    br label [[EXIT]]
1626; CHECK:       exit:
1627; CHECK-NEXT:    ret void
1628;
1629entry:
1630  %cmp1 = icmp slt i32 %a, -10
1631  %cmp2 = icmp sgt i32 %a, 10
1632  %or = select i1 %cmp1, i1 false, i1 %cmp2
1633  br i1 %or, label %exit, label %guard
1634
1635guard:
1636  %c1 = icmp sgt i32 %a, 20
1637  store i1 %c1, i1* %p
1638  %c2 = icmp slt i32 %a, -20
1639  store i1 %c2, i1* %p
1640  br label %exit
1641
1642exit:
1643  ret void
1644}
1645
1646define void @select_or_wrong_operand(i32 %a, i1* %p) {
1647; CHECK-LABEL: @select_or_wrong_operand(
1648; CHECK-NEXT:  entry:
1649; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], -10
1650; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], 10
1651; CHECK-NEXT:    [[OR:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 true
1652; CHECK-NEXT:    br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1653; CHECK:       guard:
1654; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i32 [[A]], 20
1655; CHECK-NEXT:    store i1 [[C1]], i1* [[P:%.*]], align 1
1656; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[A]], -20
1657; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
1658; CHECK-NEXT:    br label [[EXIT]]
1659; CHECK:       exit:
1660; CHECK-NEXT:    ret void
1661;
1662entry:
1663  %cmp1 = icmp slt i32 %a, -10
1664  %cmp2 = icmp sgt i32 %a, 10
1665  %or = select i1 %cmp1, i1 %cmp2, i1 true
1666  br i1 %or, label %exit, label %guard
1667
1668guard:
1669  %c1 = icmp sgt i32 %a, 20
1670  store i1 %c1, i1* %p
1671  %c2 = icmp slt i32 %a, -20
1672  store i1 %c2, i1* %p
1673  br label %exit
1674
1675exit:
1676  ret void
1677}
1678
1679define void @or_union(i32 %a, i1* %p) {
1680; CHECK-LABEL: @or_union(
1681; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 10
1682; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[A]], 12
1683; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
1684; CHECK-NEXT:    br i1 [[OR]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1685; CHECK:       guard:
1686; CHECK-NEXT:    store i1 false, i1* [[P:%.*]], align 1
1687; CHECK-NEXT:    [[C2:%.*]] = icmp eq i32 [[A]], 10
1688; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
1689; CHECK-NEXT:    [[C3:%.*]] = icmp eq i32 [[A]], 11
1690; CHECK-NEXT:    store i1 [[C3]], i1* [[P]], align 1
1691; CHECK-NEXT:    [[C4:%.*]] = icmp eq i32 [[A]], 12
1692; CHECK-NEXT:    store i1 [[C4]], i1* [[P]], align 1
1693; CHECK-NEXT:    store i1 false, i1* [[P]], align 1
1694; CHECK-NEXT:    br label [[EXIT]]
1695; CHECK:       exit:
1696; CHECK-NEXT:    ret void
1697;
1698  %cmp1 = icmp eq i32 %a, 10
1699  %cmp2 = icmp eq i32 %a, 12
1700  %or = or i1 %cmp1, %cmp2
1701  br i1 %or, label %guard, label %exit
1702
1703guard:
1704  %c1 = icmp eq i32 %a, 9
1705  store i1 %c1, i1* %p
1706  %c2 = icmp eq i32 %a, 10
1707  store i1 %c2, i1* %p
1708  %c3 = icmp eq i32 %a, 11
1709  store i1 %c3, i1* %p
1710  %c4 = icmp eq i32 %a, 12
1711  store i1 %c4, i1* %p
1712  %c5 = icmp eq i32 %a, 13
1713  store i1 %c5, i1* %p
1714  br label %exit
1715
1716exit:
1717  ret void
1718}
1719
1720define i1 @or_union_unknown_cond(i32 %a, i1 %c) {
1721; CHECK-LABEL: @or_union_unknown_cond(
1722; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 10
1723; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP1]], [[C:%.*]]
1724; CHECK-NEXT:    br i1 [[OR]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1725; CHECK:       guard:
1726; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[A]], 10
1727; CHECK-NEXT:    ret i1 [[CMP2]]
1728; CHECK:       exit:
1729; CHECK-NEXT:    ret i1 false
1730;
1731  %cmp1 = icmp eq i32 %a, 10
1732  %or = or i1 %cmp1, %c
1733  br i1 %or, label %guard, label %exit
1734
1735guard:
1736  %cmp2 = icmp eq i32 %a, 10
1737  ret i1 %cmp2
1738
1739exit:
1740  ret i1 false
1741}
1742
1743define void @and_union(i32 %a, i1* %p) {
1744; CHECK-LABEL: @and_union(
1745; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], 10
1746; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i32 [[A]], 12
1747; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1748; CHECK-NEXT:    br i1 [[AND]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1749; CHECK:       guard:
1750; CHECK-NEXT:    store i1 false, i1* [[P:%.*]], align 1
1751; CHECK-NEXT:    [[C2:%.*]] = icmp eq i32 [[A]], 10
1752; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
1753; CHECK-NEXT:    [[C3:%.*]] = icmp eq i32 [[A]], 11
1754; CHECK-NEXT:    store i1 [[C3]], i1* [[P]], align 1
1755; CHECK-NEXT:    [[C4:%.*]] = icmp eq i32 [[A]], 12
1756; CHECK-NEXT:    store i1 [[C4]], i1* [[P]], align 1
1757; CHECK-NEXT:    store i1 false, i1* [[P]], align 1
1758; CHECK-NEXT:    br label [[EXIT]]
1759; CHECK:       exit:
1760; CHECK-NEXT:    ret void
1761;
1762  %cmp1 = icmp ne i32 %a, 10
1763  %cmp2 = icmp ne i32 %a, 12
1764  %and = and i1 %cmp1, %cmp2
1765  br i1 %and, label %exit, label %guard
1766
1767guard:
1768  %c1 = icmp eq i32 %a, 9
1769  store i1 %c1, i1* %p
1770  %c2 = icmp eq i32 %a, 10
1771  store i1 %c2, i1* %p
1772  %c3 = icmp eq i32 %a, 11
1773  store i1 %c3, i1* %p
1774  %c4 = icmp eq i32 %a, 12
1775  store i1 %c4, i1* %p
1776  %c5 = icmp eq i32 %a, 13
1777  store i1 %c5, i1* %p
1778  br label %exit
1779
1780exit:
1781  ret void
1782}
1783
1784define i1 @and_union_unknown_cond(i32 %a, i1 %c) {
1785; CHECK-LABEL: @and_union_unknown_cond(
1786; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], 10
1787; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[C:%.*]]
1788; CHECK-NEXT:    br i1 [[AND]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1789; CHECK:       guard:
1790; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[A]], 10
1791; CHECK-NEXT:    ret i1 [[CMP2]]
1792; CHECK:       exit:
1793; CHECK-NEXT:    ret i1 false
1794;
1795  %cmp1 = icmp ne i32 %a, 10
1796  %and = and i1 %cmp1, %c
1797  br i1 %and, label %exit, label %guard
1798
1799guard:
1800  %cmp2 = icmp eq i32 %a, 10
1801  ret i1 %cmp2
1802
1803exit:
1804  ret i1 false
1805}
1806
1807define void @select_assume(i32 %a, i32 %b, i1 %c, i1* %p) {
1808; CHECK-LABEL: @select_assume(
1809; CHECK-NEXT:    [[C1:%.*]] = icmp ult i32 [[A:%.*]], 10
1810; CHECK-NEXT:    call void @llvm.assume(i1 [[C1]])
1811; CHECK-NEXT:    [[C2:%.*]] = icmp ult i32 [[B:%.*]], 20
1812; CHECK-NEXT:    call void @llvm.assume(i1 [[C2]])
1813; CHECK-NEXT:    [[S:%.*]] = select i1 [[C:%.*]], i32 [[A]], i32 [[B]]
1814; CHECK-NEXT:    [[C3:%.*]] = icmp ult i32 [[S]], 19
1815; CHECK-NEXT:    store i1 [[C3]], i1* [[P:%.*]], align 1
1816; CHECK-NEXT:    store i1 true, i1* [[P]], align 1
1817; CHECK-NEXT:    ret void
1818;
1819  %c1 = icmp ult i32 %a, 10
1820  call void @llvm.assume(i1 %c1)
1821  %c2 = icmp ult i32 %b, 20
1822  call void @llvm.assume(i1 %c2)
1823  %s = select i1 %c, i32 %a, i32 %b
1824  %c3 = icmp ult i32 %s, 19
1825  store i1 %c3, i1* %p
1826  %c4 = icmp ult i32 %s, 20
1827  store i1 %c4, i1* %p
1828  ret void
1829}
1830
1831define void @xor(i8 %a, i1* %p) {
1832; CHECK-LABEL: @xor(
1833; CHECK-NEXT:    [[A_MASK:%.*]] = and i8 [[A:%.*]], 15
1834; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[A_MASK]], -86
1835; CHECK-NEXT:    store i1 true, i1* [[P:%.*]], align 1
1836; CHECK-NEXT:    [[C2:%.*]] = icmp ugt i8 [[XOR]], -96
1837; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
1838; CHECK-NEXT:    store i1 true, i1* [[P]], align 1
1839; CHECK-NEXT:    [[C4:%.*]] = icmp ult i8 [[XOR]], -81
1840; CHECK-NEXT:    store i1 [[C4]], i1* [[P]], align 1
1841; CHECK-NEXT:    ret void
1842;
1843  %a.mask = and i8 %a, 15 ; 0b0000????
1844  %xor = xor i8 %a.mask, 170 ; ^ 0b10101010 == 0b1010????
1845  %c1 = icmp uge i8 %xor, 160
1846  store i1 %c1, i1* %p
1847  %c2 = icmp ugt i8 %xor, 160
1848  store i1 %c2, i1* %p
1849  %c3 = icmp ule i8 %xor, 175
1850  store i1 %c3, i1* %p
1851  %c4 = icmp ult i8 %xor, 175
1852  store i1 %c4, i1* %p
1853  ret void
1854}
1855
1856declare i32 @llvm.uadd.sat.i32(i32, i32)
1857declare i32 @llvm.usub.sat.i32(i32, i32)
1858declare i32 @llvm.sadd.sat.i32(i32, i32)
1859declare i32 @llvm.ssub.sat.i32(i32, i32)
1860declare void @llvm.assume(i1)
1861