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