1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -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 [[ENTRY_UNREACHABLEDEFAULT:%.*]] [
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:       entry.unreachabledefault:
395; CHECK-NEXT:    unreachable
396; CHECK:       unreachable:
397; CHECK-NEXT:    ret i32 0
398;
399entry:
400  %s = urem i32 %cond, 3
401  %s1 = add i32 %s, 1
402  switch i32 %s1, label %unreachable [
403  i32 1, label %exit1
404  i32 2, label %exit2
405  i32 3, label %exit1
406  ]
407
408exit1:
409  ret i32 1
410exit2:
411  ret i32 2
412unreachable:
413  ret i32 0
414}
415
416; If the cases do not cover the entire range of the
417; switch condition, we should not change the default.
418
419define i32 @switch_range_not_full(i32 %cond) {
420; CHECK-LABEL: @switch_range_not_full(
421; CHECK-NEXT:  entry:
422; CHECK-NEXT:    [[S:%.*]] = urem i32 [[COND:%.*]], 3
423; CHECK-NEXT:    [[S1:%.*]] = add nuw nsw i32 [[S]], 1
424; CHECK-NEXT:    switch i32 [[S1]], label [[UNREACHABLE:%.*]] [
425; CHECK-NEXT:    i32 1, label [[EXIT1:%.*]]
426; CHECK-NEXT:    i32 3, label [[EXIT2:%.*]]
427; CHECK-NEXT:    ]
428; CHECK:       exit1:
429; CHECK-NEXT:    ret i32 1
430; CHECK:       exit2:
431; CHECK-NEXT:    ret i32 2
432; CHECK:       unreachable:
433; CHECK-NEXT:    ret i32 0
434;
435entry:
436  %s = urem i32 %cond, 3
437  %s1 = add i32 %s, 1
438  switch i32 %s1, label %unreachable [
439  i32 1, label %exit1
440  i32 3, label %exit2
441  ]
442
443exit1:
444  ret i32 1
445exit2:
446  ret i32 2
447unreachable:
448  ret i32 0
449}
450
451; PR51531
452
453define i8 @switch_defaultdest_multipleuse(i8 %t0) {
454; CHECK-LABEL: @switch_defaultdest_multipleuse(
455; CHECK-NEXT:  entry:
456; CHECK-NEXT:    [[O:%.*]] = or i8 [[T0:%.*]], 1
457; CHECK-NEXT:    [[R:%.*]] = srem i8 1, [[O]]
458; CHECK-NEXT:    br label [[EXIT:%.*]]
459; CHECK:       entry.unreachabledefault:
460; CHECK-NEXT:    unreachable
461; CHECK:       exit:
462; CHECK-NEXT:    ret i8 0
463;
464entry:
465  %o = or i8 %t0, 1
466  %r = srem i8 1, %o
467  switch i8 %r, label %exit [
468  i8 0, label %exit
469  i8 1, label %exit
470  ]
471
472exit:
473  ret i8 0
474}
475
476define i1 @arg_attribute(i8* nonnull %a) {
477; CHECK-LABEL: @arg_attribute(
478; CHECK-NEXT:    ret i1 false
479;
480  %cmp = icmp eq i8* %a, null
481  ret i1 %cmp
482}
483
484declare nonnull i8* @return_nonnull()
485define i1 @call_attribute() {
486; CHECK-LABEL: @call_attribute(
487; CHECK-NEXT:    [[A:%.*]] = call i8* @return_nonnull()
488; CHECK-NEXT:    ret i1 false
489;
490  %a = call i8* @return_nonnull()
491  %cmp = icmp eq i8* %a, null
492  ret i1 %cmp
493}
494
495define i1 @umin(i32 %a, i32 %b) {
496; CHECK-LABEL: @umin(
497; CHECK-NEXT:  entry:
498; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 5
499; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
500; CHECK:       a_guard:
501; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[B:%.*]], 20
502; CHECK-NEXT:    br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
503; CHECK:       b_guard:
504; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp ult i32 [[A]], [[B]]
505; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
506; CHECK-NEXT:    ret i1 false
507; CHECK:       out:
508; CHECK-NEXT:    ret i1 false
509;
510entry:
511  %cmp = icmp ult i32 %a, 5
512  br i1 %cmp, label %a_guard, label %out
513
514a_guard:
515  %cmp2 = icmp ult i32 %b, 20
516  br i1 %cmp2, label %b_guard, label %out
517
518b_guard:
519  %sel_cmp = icmp ult i32 %a, %b
520  %min = select i1 %sel_cmp, i32 %a, i32 %b
521  %res = icmp eq i32 %min, 7
522  ret i1 %res
523out:
524  ret i1 false
525}
526
527define i1 @smin(i32 %a, i32 %b) {
528; CHECK-LABEL: @smin(
529; CHECK-NEXT:  entry:
530; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 5
531; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
532; CHECK:       a_guard:
533; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[B:%.*]], 20
534; CHECK-NEXT:    br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
535; CHECK:       b_guard:
536; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp sle i32 [[A]], [[B]]
537; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
538; CHECK-NEXT:    ret i1 false
539; CHECK:       out:
540; CHECK-NEXT:    ret i1 false
541;
542entry:
543  %cmp = icmp ult i32 %a, 5
544  br i1 %cmp, label %a_guard, label %out
545
546a_guard:
547  %cmp2 = icmp ult i32 %b, 20
548  br i1 %cmp2, label %b_guard, label %out
549
550b_guard:
551  %sel_cmp = icmp sle i32 %a, %b
552  %min = select i1 %sel_cmp, i32 %a, i32 %b
553  %res = icmp eq i32 %min, 7
554  ret i1 %res
555out:
556  ret i1 false
557}
558
559define i1 @smax(i32 %a, i32 %b) {
560; CHECK-LABEL: @smax(
561; CHECK-NEXT:  entry:
562; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 5
563; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
564; CHECK:       a_guard:
565; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[B:%.*]], 20
566; CHECK-NEXT:    br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
567; CHECK:       b_guard:
568; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp sge i32 [[A]], [[B]]
569; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
570; CHECK-NEXT:    ret i1 false
571; CHECK:       out:
572; CHECK-NEXT:    ret i1 false
573;
574entry:
575  %cmp = icmp sgt i32 %a, 5
576  br i1 %cmp, label %a_guard, label %out
577
578a_guard:
579  %cmp2 = icmp sgt i32 %b, 20
580  br i1 %cmp2, label %b_guard, label %out
581
582b_guard:
583  %sel_cmp = icmp sge i32 %a, %b
584  %max = select i1 %sel_cmp, i32 %a, i32 %b
585  %res = icmp eq i32 %max, 7
586  ret i1 %res
587out:
588  ret i1 false
589}
590
591define i1 @umax(i32 %a, i32 %b) {
592; CHECK-LABEL: @umax(
593; CHECK-NEXT:  entry:
594; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 5
595; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
596; CHECK:       a_guard:
597; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[B:%.*]], 20
598; CHECK-NEXT:    br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
599; CHECK:       b_guard:
600; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp uge i32 [[A]], [[B]]
601; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
602; CHECK-NEXT:    ret i1 false
603; CHECK:       out:
604; CHECK-NEXT:    ret i1 false
605;
606entry:
607  %cmp = icmp sgt i32 %a, 5
608  br i1 %cmp, label %a_guard, label %out
609
610a_guard:
611  %cmp2 = icmp sgt i32 %b, 20
612  br i1 %cmp2, label %b_guard, label %out
613
614b_guard:
615  %sel_cmp = icmp uge i32 %a, %b
616  %max = select i1 %sel_cmp, i32 %a, i32 %b
617  %res = icmp eq i32 %max, 7
618  ret i1 %res
619out:
620  ret i1 false
621}
622
623define i1 @umin_lhs_overdefined_rhs_const(i32 %a) {
624; CHECK-LABEL: @umin_lhs_overdefined_rhs_const(
625; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 42
626; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 [[A]], i32 42
627; CHECK-NEXT:    ret i1 true
628;
629  %cmp = icmp ult i32 %a, 42
630  %sel = select i1 %cmp, i32 %a, i32 42
631  %cmp2 = icmp ule i32 %sel, 42
632  ret i1 %cmp2
633}
634
635define i1 @umin_rhs_overdefined_lhs_const(i32 %a) {
636; CHECK-LABEL: @umin_rhs_overdefined_lhs_const(
637; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[A:%.*]], 42
638; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 42, i32 [[A]]
639; CHECK-NEXT:    ret i1 true
640;
641  %cmp = icmp uge i32 %a, 42
642  %sel = select i1 %cmp, i32 42, i32 %a
643  %cmp2 = icmp ule i32 %sel, 42
644  ret i1 %cmp2
645}
646
647define i1 @umin_lhs_overdefined_rhs_range(i32 %a, i32 %b) {
648; CHECK-LABEL: @umin_lhs_overdefined_rhs_range(
649; CHECK-NEXT:    [[ASSUME:%.*]] = icmp ult i32 [[B:%.*]], 42
650; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME]])
651; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A:%.*]], [[B]]
652; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[B]]
653; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[SEL]], 42
654; CHECK-NEXT:    ret i1 [[CMP2]]
655;
656  %assume = icmp ult i32 %b, 42
657  call void @llvm.assume(i1 %assume)
658  %cmp = icmp ult i32 %a, %b
659  %sel = select i1 %cmp, i32 %a, i32 %b
660  %cmp2 = icmp ult i32 %sel, 42
661  ret i1 %cmp2
662}
663
664define i1 @umin_rhs_overdefined_lhs_range(i32 %a, i32 %b) {
665; CHECK-LABEL: @umin_rhs_overdefined_lhs_range(
666; CHECK-NEXT:    [[ASSUME:%.*]] = icmp ult i32 [[B:%.*]], 42
667; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME]])
668; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[A:%.*]], [[B]]
669; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 [[B]], i32 [[A]]
670; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[SEL]], 42
671; CHECK-NEXT:    ret i1 [[CMP2]]
672;
673  %assume = icmp ult i32 %b, 42
674  call void @llvm.assume(i1 %assume)
675  %cmp = icmp uge i32 %a, %b
676  %sel = select i1 %cmp, i32 %b, i32 %a
677  %cmp2 = icmp ult i32 %sel, 42
678  ret i1 %cmp2
679}
680
681define i1 @clamp_low1(i32 %a) {
682; CHECK-LABEL: @clamp_low1(
683; CHECK-NEXT:  entry:
684; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5
685; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
686; CHECK:       a_guard:
687; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5
688; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], -1
689; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
690; CHECK-NEXT:    ret i1 false
691; CHECK:       out:
692; CHECK-NEXT:    ret i1 false
693;
694entry:
695  %cmp = icmp sge i32 %a, 5
696  br i1 %cmp, label %a_guard, label %out
697
698a_guard:
699  %sel_cmp = icmp eq i32 %a, 5
700  %add = add i32 %a, -1
701  %sel = select i1 %sel_cmp, i32 5, i32 %add
702  %res = icmp eq i32 %sel, 4
703  ret i1 %res
704out:
705  ret i1 false
706}
707
708define i1 @clamp_low2(i32 %a) {
709; CHECK-LABEL: @clamp_low2(
710; CHECK-NEXT:  entry:
711; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5
712; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
713; CHECK:       a_guard:
714; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5
715; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], -1
716; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
717; CHECK-NEXT:    ret i1 false
718; CHECK:       out:
719; CHECK-NEXT:    ret i1 false
720;
721entry:
722  %cmp = icmp sge i32 %a, 5
723  br i1 %cmp, label %a_guard, label %out
724
725a_guard:
726  %sel_cmp = icmp ne i32 %a, 5
727  %add = add i32 %a, -1
728  %sel = select i1 %sel_cmp, i32 %add, i32 5
729  %res = icmp eq i32 %sel, 4
730  ret i1 %res
731out:
732  ret i1 false
733}
734
735define i1 @clamp_low3(i32 %a) {
736; CHECK-LABEL: @clamp_low3(
737; CHECK-NEXT:  entry:
738; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5
739; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
740; CHECK:       a_guard:
741; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp sgt i32 [[A]], 5
742; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], -1
743; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
744; CHECK-NEXT:    ret i1 false
745; CHECK:       out:
746; CHECK-NEXT:    ret i1 false
747;
748entry:
749  %cmp = icmp sge i32 %a, 5
750  br i1 %cmp, label %a_guard, label %out
751
752a_guard:
753  %sel_cmp = icmp sgt i32 %a, 5
754  %add = add i32 %a, -1
755  %sel = select i1 %sel_cmp, i32 %add, i32 5
756  %res = icmp eq i32 %sel, 4
757  ret i1 %res
758out:
759  ret i1 false
760}
761
762define i1 @clamp_low4(i32 %a) {
763; CHECK-LABEL: @clamp_low4(
764; CHECK-NEXT:  entry:
765; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5
766; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
767; CHECK:       a_guard:
768; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp sle i32 [[A]], 5
769; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], -1
770; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
771; CHECK-NEXT:    ret i1 false
772; CHECK:       out:
773; CHECK-NEXT:    ret i1 false
774;
775entry:
776  %cmp = icmp sge i32 %a, 5
777  br i1 %cmp, label %a_guard, label %out
778
779a_guard:
780  %sel_cmp = icmp sle i32 %a, 5
781  %add = add i32 %a, -1
782  %sel = select i1 %sel_cmp, i32 5, i32 %add
783  %res = icmp eq i32 %sel, 4
784  ret i1 %res
785out:
786  ret i1 false
787}
788
789define i1 @clamp_high1(i32 %a) {
790; CHECK-LABEL: @clamp_high1(
791; CHECK-NEXT:  entry:
792; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5
793; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
794; CHECK:       a_guard:
795; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5
796; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 1
797; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
798; CHECK-NEXT:    ret i1 false
799; CHECK:       out:
800; CHECK-NEXT:    ret i1 false
801;
802entry:
803  %cmp = icmp sle i32 %a, 5
804  br i1 %cmp, label %a_guard, label %out
805
806a_guard:
807  %sel_cmp = icmp eq i32 %a, 5
808  %add = add i32 %a, 1
809  %sel = select i1 %sel_cmp, i32 5, i32 %add
810  %res = icmp eq i32 %sel, 6
811  ret i1 %res
812out:
813  ret i1 false
814}
815
816define i1 @clamp_high2(i32 %a) {
817; CHECK-LABEL: @clamp_high2(
818; CHECK-NEXT:  entry:
819; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5
820; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
821; CHECK:       a_guard:
822; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5
823; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 1
824; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
825; CHECK-NEXT:    ret i1 false
826; CHECK:       out:
827; CHECK-NEXT:    ret i1 false
828;
829entry:
830  %cmp = icmp sle i32 %a, 5
831  br i1 %cmp, label %a_guard, label %out
832
833a_guard:
834  %sel_cmp = icmp ne i32 %a, 5
835  %add = add i32 %a, 1
836  %sel = select i1 %sel_cmp, i32 %add, i32 5
837  %res = icmp eq i32 %sel, 6
838  ret i1 %res
839out:
840  ret i1 false
841}
842
843define i1 @clamp_high3(i32 %a) {
844; CHECK-LABEL: @clamp_high3(
845; CHECK-NEXT:  entry:
846; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5
847; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
848; CHECK:       a_guard:
849; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp slt i32 [[A]], 5
850; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 1
851; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
852; CHECK-NEXT:    ret i1 false
853; CHECK:       out:
854; CHECK-NEXT:    ret i1 false
855;
856entry:
857  %cmp = icmp sle i32 %a, 5
858  br i1 %cmp, label %a_guard, label %out
859
860a_guard:
861  %sel_cmp = icmp slt i32 %a, 5
862  %add = add i32 %a, 1
863  %sel = select i1 %sel_cmp, i32 %add, i32 5
864  %res = icmp eq i32 %sel, 6
865  ret i1 %res
866out:
867  ret i1 false
868}
869
870define i1 @clamp_high4(i32 %a) {
871; CHECK-LABEL: @clamp_high4(
872; CHECK-NEXT:  entry:
873; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5
874; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
875; CHECK:       a_guard:
876; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp sge i32 [[A]], 5
877; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 1
878; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
879; CHECK-NEXT:    ret i1 false
880; CHECK:       out:
881; CHECK-NEXT:    ret i1 false
882;
883entry:
884  %cmp = icmp sle i32 %a, 5
885  br i1 %cmp, label %a_guard, label %out
886
887a_guard:
888  %sel_cmp = icmp sge i32 %a, 5
889  %add = add i32 %a, 1
890  %sel = select i1 %sel_cmp, i32 5, i32 %add
891  %res = icmp eq i32 %sel, 6
892  ret i1 %res
893out:
894  ret i1 false
895}
896
897; Just showing arbitrary constants work, not really a clamp
898define i1 @not_clamp_high(i32 %a) {
899; CHECK-LABEL: @not_clamp_high(
900; CHECK-NEXT:  entry:
901; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5
902; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
903; CHECK:       a_guard:
904; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5
905; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 100
906; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
907; CHECK-NEXT:    ret i1 false
908; CHECK:       out:
909; CHECK-NEXT:    ret i1 false
910;
911entry:
912  %cmp = icmp sle i32 %a, 5
913  br i1 %cmp, label %a_guard, label %out
914
915a_guard:
916  %sel_cmp = icmp ne i32 %a, 5
917  %add = add i32 %a, 100
918  %sel = select i1 %sel_cmp, i32 %add, i32 5
919  %res = icmp eq i32 %sel, 105
920  ret i1 %res
921out:
922  ret i1 false
923}
924
925define void @abs1(i32 %a, i1* %p) {
926; CHECK-LABEL: @abs1(
927; CHECK-NEXT:  entry:
928; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10
929; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
930; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
931; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
932; CHECK:       guard:
933; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 0, [[A]]
934; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], 0
935; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]]
936; CHECK-NEXT:    store i1 true, i1* [[P:%.*]], align 1
937; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[ABS]], 19
938; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
939; CHECK-NEXT:    store i1 true, i1* [[P]], align 1
940; CHECK-NEXT:    [[C4:%.*]] = icmp sge i32 [[ABS]], 1
941; CHECK-NEXT:    store i1 [[C4]], i1* [[P]], align 1
942; CHECK-NEXT:    br label [[EXIT]]
943; CHECK:       exit:
944; CHECK-NEXT:    ret void
945;
946entry:
947  %cmp1 = icmp slt i32 %a, 10
948  %cmp2 = icmp sgt i32 %a, -20
949  %and = and i1 %cmp1, %cmp2
950  br i1 %and, label %guard, label %exit
951
952guard:
953  %sub = sub i32 0, %a
954  %cmp = icmp slt i32 %a, 0
955  %abs = select i1 %cmp, i32 %sub, i32 %a
956  %c1 = icmp slt i32 %abs, 20
957  store i1 %c1, i1* %p
958  %c2 = icmp slt i32 %abs, 19
959  store i1 %c2, i1* %p
960  %c3 = icmp sge i32 %abs, 0
961  store i1 %c3, i1* %p
962  %c4 = icmp sge i32 %abs, 1
963  store i1 %c4, i1* %p
964  br label %exit
965
966exit:
967  ret void
968}
969
970define void @abs2(i32 %a, i1* %p) {
971; CHECK-LABEL: @abs2(
972; CHECK-NEXT:  entry:
973; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10
974; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
975; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
976; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
977; CHECK:       guard:
978; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 0, [[A]]
979; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[A]], 0
980; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[SUB]]
981; CHECK-NEXT:    store i1 true, i1* [[P:%.*]], align 1
982; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[ABS]], 19
983; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
984; CHECK-NEXT:    store i1 true, i1* [[P]], align 1
985; CHECK-NEXT:    [[C4:%.*]] = icmp sge i32 [[ABS]], 1
986; CHECK-NEXT:    store i1 [[C4]], i1* [[P]], align 1
987; CHECK-NEXT:    br label [[EXIT]]
988; CHECK:       exit:
989; CHECK-NEXT:    ret void
990;
991entry:
992  %cmp1 = icmp slt i32 %a, 10
993  %cmp2 = icmp sgt i32 %a, -20
994  %and = and i1 %cmp1, %cmp2
995  br i1 %and, label %guard, label %exit
996
997guard:
998  %sub = sub i32 0, %a
999  %cmp = icmp sge i32 %a, 0
1000  %abs = select i1 %cmp, i32 %a, i32 %sub
1001  %c1 = icmp slt i32 %abs, 20
1002  store i1 %c1, i1* %p
1003  %c2 = icmp slt i32 %abs, 19
1004  store i1 %c2, i1* %p
1005  %c3 = icmp sge i32 %abs, 0
1006  store i1 %c3, i1* %p
1007  %c4 = icmp sge i32 %abs, 1
1008  store i1 %c4, i1* %p
1009  br label %exit
1010
1011exit:
1012  ret void
1013}
1014
1015define void @nabs1(i32 %a, i1* %p) {
1016; CHECK-LABEL: @nabs1(
1017; CHECK-NEXT:  entry:
1018; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10
1019; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
1020; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1021; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1022; CHECK:       guard:
1023; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 0, [[A]]
1024; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A]], 0
1025; CHECK-NEXT:    [[NABS:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]]
1026; CHECK-NEXT:    store i1 true, i1* [[P:%.*]], align 1
1027; CHECK-NEXT:    [[C2:%.*]] = icmp sgt i32 [[NABS]], -19
1028; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
1029; CHECK-NEXT:    store i1 true, i1* [[P]], align 1
1030; CHECK-NEXT:    [[C4:%.*]] = icmp sle i32 [[NABS]], -1
1031; CHECK-NEXT:    store i1 [[C4]], i1* [[P]], align 1
1032; CHECK-NEXT:    br label [[EXIT]]
1033; CHECK:       exit:
1034; CHECK-NEXT:    ret void
1035;
1036entry:
1037  %cmp1 = icmp slt i32 %a, 10
1038  %cmp2 = icmp sgt i32 %a, -20
1039  %and = and i1 %cmp1, %cmp2
1040  br i1 %and, label %guard, label %exit
1041
1042guard:
1043  %sub = sub i32 0, %a
1044  %cmp = icmp sgt i32 %a, 0
1045  %nabs = select i1 %cmp, i32 %sub, i32 %a
1046  %c1 = icmp sgt i32 %nabs, -20
1047  store i1 %c1, i1* %p
1048  %c2 = icmp sgt i32 %nabs, -19
1049  store i1 %c2, i1* %p
1050  %c3 = icmp sle i32 %nabs, 0
1051  store i1 %c3, i1* %p
1052  %c4 = icmp sle i32 %nabs, -1
1053  store i1 %c4, i1* %p
1054  br label %exit
1055
1056exit:
1057  ret void
1058}
1059
1060define void @nabs2(i32 %a, i1* %p) {
1061; CHECK-LABEL: @nabs2(
1062; CHECK-NEXT:  entry:
1063; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10
1064; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
1065; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1066; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1067; CHECK:       guard:
1068; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 0, [[A]]
1069; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], 0
1070; CHECK-NEXT:    [[NABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[SUB]]
1071; CHECK-NEXT:    store i1 true, i1* [[P:%.*]], align 1
1072; CHECK-NEXT:    [[C2:%.*]] = icmp sgt i32 [[NABS]], -19
1073; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
1074; CHECK-NEXT:    store i1 true, i1* [[P]], align 1
1075; CHECK-NEXT:    [[C4:%.*]] = icmp sle i32 [[NABS]], -1
1076; CHECK-NEXT:    store i1 [[C4]], i1* [[P]], align 1
1077; CHECK-NEXT:    br label [[EXIT]]
1078; CHECK:       exit:
1079; CHECK-NEXT:    ret void
1080;
1081entry:
1082  %cmp1 = icmp slt i32 %a, 10
1083  %cmp2 = icmp sgt i32 %a, -20
1084  %and = and i1 %cmp1, %cmp2
1085  br i1 %and, label %guard, label %exit
1086
1087guard:
1088  %sub = sub i32 0, %a
1089  %cmp = icmp slt i32 %a, 0
1090  %nabs = select i1 %cmp, i32 %a, i32 %sub
1091  %c1 = icmp sgt i32 %nabs, -20
1092  store i1 %c1, i1* %p
1093  %c2 = icmp sgt i32 %nabs, -19
1094  store i1 %c2, i1* %p
1095  %c3 = icmp sle i32 %nabs, 0
1096  store i1 %c3, i1* %p
1097  %c4 = icmp sle i32 %nabs, -1
1098  store i1 %c4, i1* %p
1099  br label %exit
1100
1101exit:
1102  ret void
1103}
1104
1105define i1 @zext_unknown(i8 %a) {
1106; CHECK-LABEL: @zext_unknown(
1107; CHECK-NEXT:  entry:
1108; CHECK-NEXT:    [[A32:%.*]] = zext i8 [[A:%.*]] to i32
1109; CHECK-NEXT:    ret i1 true
1110;
1111entry:
1112  %a32 = zext i8 %a to i32
1113  %cmp = icmp sle i32 %a32, 256
1114  ret i1 %cmp
1115}
1116
1117define i1 @trunc_unknown(i32 %a) {
1118; CHECK-LABEL: @trunc_unknown(
1119; CHECK-NEXT:  entry:
1120; CHECK-NEXT:    [[A8:%.*]] = trunc i32 [[A:%.*]] to i8
1121; CHECK-NEXT:    [[A32:%.*]] = sext i8 [[A8]] to i32
1122; CHECK-NEXT:    ret i1 true
1123;
1124entry:
1125  %a8 = trunc i32 %a to i8
1126  %a32 = sext i8 %a8 to i32
1127  %cmp = icmp sle i32 %a32, 128
1128  ret i1 %cmp
1129}
1130
1131; TODO: missed optimization
1132; Make sure we exercise non-integer inputs to unary operators (i.e. crash check).
1133define i1 @bitcast_unknown(float %a) {
1134; CHECK-LABEL: @bitcast_unknown(
1135; CHECK-NEXT:  entry:
1136; CHECK-NEXT:    [[A32:%.*]] = bitcast float [[A:%.*]] to i32
1137; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A32]], 128
1138; CHECK-NEXT:    ret i1 [[CMP]]
1139;
1140entry:
1141  %a32 = bitcast float %a to i32
1142  %cmp = icmp sle i32 %a32, 128
1143  ret i1 %cmp
1144}
1145
1146define i1 @bitcast_unknown2(i8* %p) {
1147; CHECK-LABEL: @bitcast_unknown2(
1148; CHECK-NEXT:  entry:
1149; CHECK-NEXT:    [[P64:%.*]] = ptrtoint i8* [[P:%.*]] to i64
1150; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i64 [[P64]], 128
1151; CHECK-NEXT:    ret i1 [[CMP]]
1152;
1153entry:
1154  %p64 = ptrtoint i8* %p to i64
1155  %cmp = icmp sle i64 %p64, 128
1156  ret i1 %cmp
1157}
1158
1159
1160define i1 @and_unknown(i32 %a) {
1161; CHECK-LABEL: @and_unknown(
1162; CHECK-NEXT:  entry:
1163; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 128
1164; CHECK-NEXT:    ret i1 true
1165;
1166entry:
1167  %and = and i32 %a, 128
1168  %cmp = icmp sle i32 %and, 128
1169  ret i1 %cmp
1170}
1171
1172define i1 @lshr_unknown(i32 %a) {
1173; CHECK-LABEL: @lshr_unknown(
1174; CHECK-NEXT:  entry:
1175; CHECK-NEXT:    [[AND:%.*]] = lshr i32 [[A:%.*]], 30
1176; CHECK-NEXT:    ret i1 true
1177;
1178entry:
1179  %and = lshr i32 %a, 30
1180  %cmp = icmp sle i32 %and, 128
1181  ret i1 %cmp
1182}
1183
1184define i1 @urem_unknown(i32 %a) {
1185; CHECK-LABEL: @urem_unknown(
1186; CHECK-NEXT:  entry:
1187; CHECK-NEXT:    [[UREM:%.*]] = urem i32 [[A:%.*]], 30
1188; CHECK-NEXT:    ret i1 true
1189;
1190entry:
1191  %urem = urem i32 %a, 30
1192  %cmp = icmp ult i32 %urem, 30
1193  ret i1 %cmp
1194}
1195
1196define i1 @srem_unknown(i32 %a) {
1197; CHECK-LABEL: @srem_unknown(
1198; CHECK-NEXT:  entry:
1199; CHECK-NEXT:    [[SREM:%.*]] = srem i32 [[A:%.*]], 30
1200; CHECK-NEXT:    br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1201; CHECK:       exit1:
1202; CHECK-NEXT:    ret i1 true
1203; CHECK:       exit2:
1204; CHECK-NEXT:    ret i1 true
1205;
1206entry:
1207  %srem = srem i32 %a, 30
1208  %cmp1 = icmp slt i32 %srem, 30
1209  %cmp2 = icmp sgt i32 %srem, -30
1210  br i1 undef, label %exit1, label %exit2
1211exit1:
1212  ret i1 %cmp1
1213exit2:
1214  ret i1 %cmp2
1215}
1216
1217define i1 @sdiv_unknown(i32 %a) {
1218; CHECK-LABEL: @sdiv_unknown(
1219; CHECK-NEXT:  entry:
1220; CHECK-NEXT:    [[SREM:%.*]] = sdiv i32 [[A:%.*]], 123
1221; CHECK-NEXT:    br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1222; CHECK:       exit1:
1223; CHECK-NEXT:    ret i1 true
1224; CHECK:       exit2:
1225; CHECK-NEXT:    ret i1 true
1226;
1227entry:
1228  %srem = sdiv i32 %a, 123
1229  %cmp1 = icmp slt i32 %srem, 17459217
1230  %cmp2 = icmp sgt i32 %srem, -17459217
1231  br i1 undef, label %exit1, label %exit2
1232exit1:
1233  ret i1 %cmp1
1234exit2:
1235  ret i1 %cmp2
1236}
1237
1238define i1 @uadd_sat_unknown(i32 %a) {
1239; CHECK-LABEL: @uadd_sat_unknown(
1240; CHECK-NEXT:  entry:
1241; CHECK-NEXT:    [[VAL:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[A:%.*]], i32 100)
1242; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 [[VAL]], 100
1243; CHECK-NEXT:    br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1244; CHECK:       exit1:
1245; CHECK-NEXT:    ret i1 true
1246; CHECK:       exit2:
1247; CHECK-NEXT:    ret i1 [[CMP2]]
1248;
1249entry:
1250  %val = call i32 @llvm.uadd.sat.i32(i32 %a, i32 100)
1251  %cmp1 = icmp uge i32 %val, 100
1252  %cmp2 = icmp ugt i32 %val, 100
1253  br i1 undef, label %exit1, label %exit2
1254exit1:
1255  ret i1 %cmp1
1256exit2:
1257  ret i1 %cmp2
1258}
1259
1260define i1 @usub_sat_unknown(i32 %a) {
1261; CHECK-LABEL: @usub_sat_unknown(
1262; CHECK-NEXT:  entry:
1263; CHECK-NEXT:    [[VAL:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A:%.*]], i32 100)
1264; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[VAL]], -101
1265; CHECK-NEXT:    br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1266; CHECK:       exit1:
1267; CHECK-NEXT:    ret i1 true
1268; CHECK:       exit2:
1269; CHECK-NEXT:    ret i1 [[CMP2]]
1270;
1271entry:
1272  %val = call i32 @llvm.usub.sat.i32(i32 %a, i32 100)
1273  %cmp1 = icmp ule i32 %val, 4294967195
1274  %cmp2 = icmp ult i32 %val, 4294967195
1275  br i1 undef, label %exit1, label %exit2
1276exit1:
1277  ret i1 %cmp1
1278exit2:
1279  ret i1 %cmp2
1280}
1281
1282define i1 @sadd_sat_unknown(i32 %a) {
1283; CHECK-LABEL: @sadd_sat_unknown(
1284; CHECK-NEXT:  entry:
1285; CHECK-NEXT:    [[VAL:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[A:%.*]], i32 100)
1286; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[VAL]], -2147483548
1287; CHECK-NEXT:    br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1288; CHECK:       exit1:
1289; CHECK-NEXT:    ret i1 true
1290; CHECK:       exit2:
1291; CHECK-NEXT:    ret i1 [[CMP2]]
1292;
1293entry:
1294  %val = call i32 @llvm.sadd.sat.i32(i32 %a, i32 100)
1295  %cmp1 = icmp sge i32 %val, -2147483548
1296  %cmp2 = icmp sgt i32 %val, -2147483548
1297  br i1 undef, label %exit1, label %exit2
1298exit1:
1299  ret i1 %cmp1
1300exit2:
1301  ret i1 %cmp2
1302}
1303
1304define i1 @ssub_sat_unknown(i32 %a) {
1305; CHECK-LABEL: @ssub_sat_unknown(
1306; CHECK-NEXT:  entry:
1307; CHECK-NEXT:    [[VAL:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[A:%.*]], i32 100)
1308; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[VAL]], 2147483547
1309; CHECK-NEXT:    br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1310; CHECK:       exit1:
1311; CHECK-NEXT:    ret i1 true
1312; CHECK:       exit2:
1313; CHECK-NEXT:    ret i1 [[CMP2]]
1314;
1315entry:
1316  %val = call i32 @llvm.ssub.sat.i32(i32 %a, i32 100)
1317  %cmp1 = icmp sle i32 %val, 2147483547
1318  %cmp2 = icmp slt i32 %val, 2147483547
1319  br i1 undef, label %exit1, label %exit2
1320exit1:
1321  ret i1 %cmp1
1322exit2:
1323  ret i1 %cmp2
1324}
1325
1326define void @select_and(i32 %a, i1* %p) {
1327; CHECK-LABEL: @select_and(
1328; CHECK-NEXT:  entry:
1329; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[A:%.*]], -10
1330; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[A]], 10
1331; CHECK-NEXT:    [[AND:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1332; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1333; CHECK:       guard:
1334; CHECK-NEXT:    store i1 false, i1* [[P:%.*]], align 1
1335; CHECK-NEXT:    store i1 false, i1* [[P]], align 1
1336; CHECK-NEXT:    br label [[EXIT]]
1337; CHECK:       exit:
1338; CHECK-NEXT:    ret void
1339;
1340entry:
1341  %cmp1 = icmp sgt i32 %a, -10
1342  %cmp2 = icmp slt i32 %a, 10
1343  %and = select i1 %cmp1, i1 %cmp2, i1 false
1344  br i1 %and, label %guard, label %exit
1345
1346guard:
1347  %c1 = icmp sgt i32 %a, 20
1348  store i1 %c1, i1* %p
1349  %c2 = icmp slt i32 %a, -20
1350  store i1 %c2, i1* %p
1351  br label %exit
1352
1353exit:
1354  ret void
1355}
1356
1357define void @select_and_wrong_const(i32 %a, i1* %p) {
1358; CHECK-LABEL: @select_and_wrong_const(
1359; CHECK-NEXT:  entry:
1360; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[A:%.*]], -10
1361; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[A]], 10
1362; CHECK-NEXT:    [[AND:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 true
1363; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1364; CHECK:       guard:
1365; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i32 [[A]], 20
1366; CHECK-NEXT:    store i1 [[C1]], i1* [[P:%.*]], align 1
1367; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[A]], -20
1368; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
1369; CHECK-NEXT:    br label [[EXIT]]
1370; CHECK:       exit:
1371; CHECK-NEXT:    ret void
1372;
1373entry:
1374  %cmp1 = icmp sgt i32 %a, -10
1375  %cmp2 = icmp slt i32 %a, 10
1376  %and = select i1 %cmp1, i1 %cmp2, i1 true
1377  br i1 %and, label %guard, label %exit
1378
1379guard:
1380  %c1 = icmp sgt i32 %a, 20
1381  store i1 %c1, i1* %p
1382  %c2 = icmp slt i32 %a, -20
1383  store i1 %c2, i1* %p
1384  br label %exit
1385
1386exit:
1387  ret void
1388}
1389
1390define void @select_and_wrong_operand(i32 %a, i1* %p) {
1391; CHECK-LABEL: @select_and_wrong_operand(
1392; CHECK-NEXT:  entry:
1393; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[A:%.*]], -10
1394; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[A]], 10
1395; CHECK-NEXT:    [[AND:%.*]] = select i1 [[CMP1]], i1 false, i1 [[CMP2]]
1396; CHECK-NEXT:    br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1397; CHECK:       guard:
1398; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i32 [[A]], 20
1399; CHECK-NEXT:    store i1 [[C1]], i1* [[P:%.*]], align 1
1400; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[A]], -20
1401; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
1402; CHECK-NEXT:    br label [[EXIT]]
1403; CHECK:       exit:
1404; CHECK-NEXT:    ret void
1405;
1406entry:
1407  %cmp1 = icmp sgt i32 %a, -10
1408  %cmp2 = icmp slt i32 %a, 10
1409  %and = select i1 %cmp1, i1 false, i1 %cmp2
1410  br i1 %and, label %guard, label %exit
1411
1412guard:
1413  %c1 = icmp sgt i32 %a, 20
1414  store i1 %c1, i1* %p
1415  %c2 = icmp slt i32 %a, -20
1416  store i1 %c2, i1* %p
1417  br label %exit
1418
1419exit:
1420  ret void
1421}
1422
1423define void @select_or(i32 %a, i1* %p) {
1424; CHECK-LABEL: @select_or(
1425; CHECK-NEXT:  entry:
1426; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], -10
1427; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], 10
1428; CHECK-NEXT:    [[OR:%.*]] = select i1 [[CMP1]], i1 true, i1 [[CMP2]]
1429; CHECK-NEXT:    br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1430; CHECK:       guard:
1431; CHECK-NEXT:    store i1 false, i1* [[P:%.*]], align 1
1432; CHECK-NEXT:    store i1 false, i1* [[P]], align 1
1433; CHECK-NEXT:    br label [[EXIT]]
1434; CHECK:       exit:
1435; CHECK-NEXT:    ret void
1436;
1437entry:
1438  %cmp1 = icmp slt i32 %a, -10
1439  %cmp2 = icmp sgt i32 %a, 10
1440  %or = select i1 %cmp1, i1 true, i1 %cmp2
1441  br i1 %or, label %exit, label %guard
1442
1443guard:
1444  %c1 = icmp sgt i32 %a, 20
1445  store i1 %c1, i1* %p
1446  %c2 = icmp slt i32 %a, -20
1447  store i1 %c2, i1* %p
1448  br label %exit
1449
1450exit:
1451  ret void
1452}
1453
1454define void @select_or_wrong_const(i32 %a, i1* %p) {
1455; CHECK-LABEL: @select_or_wrong_const(
1456; CHECK-NEXT:  entry:
1457; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], -10
1458; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], 10
1459; CHECK-NEXT:    [[OR:%.*]] = select i1 [[CMP1]], i1 false, i1 [[CMP2]]
1460; CHECK-NEXT:    br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1461; CHECK:       guard:
1462; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i32 [[A]], 20
1463; CHECK-NEXT:    store i1 [[C1]], i1* [[P:%.*]], align 1
1464; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[A]], -20
1465; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
1466; CHECK-NEXT:    br label [[EXIT]]
1467; CHECK:       exit:
1468; CHECK-NEXT:    ret void
1469;
1470entry:
1471  %cmp1 = icmp slt i32 %a, -10
1472  %cmp2 = icmp sgt i32 %a, 10
1473  %or = select i1 %cmp1, i1 false, i1 %cmp2
1474  br i1 %or, label %exit, label %guard
1475
1476guard:
1477  %c1 = icmp sgt i32 %a, 20
1478  store i1 %c1, i1* %p
1479  %c2 = icmp slt i32 %a, -20
1480  store i1 %c2, i1* %p
1481  br label %exit
1482
1483exit:
1484  ret void
1485}
1486
1487define void @select_or_wrong_operand(i32 %a, i1* %p) {
1488; CHECK-LABEL: @select_or_wrong_operand(
1489; CHECK-NEXT:  entry:
1490; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], -10
1491; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], 10
1492; CHECK-NEXT:    [[OR:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 true
1493; CHECK-NEXT:    br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1494; CHECK:       guard:
1495; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i32 [[A]], 20
1496; CHECK-NEXT:    store i1 [[C1]], i1* [[P:%.*]], align 1
1497; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[A]], -20
1498; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
1499; CHECK-NEXT:    br label [[EXIT]]
1500; CHECK:       exit:
1501; CHECK-NEXT:    ret void
1502;
1503entry:
1504  %cmp1 = icmp slt i32 %a, -10
1505  %cmp2 = icmp sgt i32 %a, 10
1506  %or = select i1 %cmp1, i1 %cmp2, i1 true
1507  br i1 %or, label %exit, label %guard
1508
1509guard:
1510  %c1 = icmp sgt i32 %a, 20
1511  store i1 %c1, i1* %p
1512  %c2 = icmp slt i32 %a, -20
1513  store i1 %c2, i1* %p
1514  br label %exit
1515
1516exit:
1517  ret void
1518}
1519
1520define void @or_union(i32 %a, i1* %p) {
1521; CHECK-LABEL: @or_union(
1522; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 10
1523; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[A]], 12
1524; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
1525; CHECK-NEXT:    br i1 [[OR]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1526; CHECK:       guard:
1527; CHECK-NEXT:    store i1 false, i1* [[P:%.*]], align 1
1528; CHECK-NEXT:    [[C2:%.*]] = icmp eq i32 [[A]], 10
1529; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
1530; CHECK-NEXT:    [[C3:%.*]] = icmp eq i32 [[A]], 11
1531; CHECK-NEXT:    store i1 [[C3]], i1* [[P]], align 1
1532; CHECK-NEXT:    [[C4:%.*]] = icmp eq i32 [[A]], 12
1533; CHECK-NEXT:    store i1 [[C4]], i1* [[P]], align 1
1534; CHECK-NEXT:    store i1 false, i1* [[P]], align 1
1535; CHECK-NEXT:    br label [[EXIT]]
1536; CHECK:       exit:
1537; CHECK-NEXT:    ret void
1538;
1539  %cmp1 = icmp eq i32 %a, 10
1540  %cmp2 = icmp eq i32 %a, 12
1541  %or = or i1 %cmp1, %cmp2
1542  br i1 %or, label %guard, label %exit
1543
1544guard:
1545  %c1 = icmp eq i32 %a, 9
1546  store i1 %c1, i1* %p
1547  %c2 = icmp eq i32 %a, 10
1548  store i1 %c2, i1* %p
1549  %c3 = icmp eq i32 %a, 11
1550  store i1 %c3, i1* %p
1551  %c4 = icmp eq i32 %a, 12
1552  store i1 %c4, i1* %p
1553  %c5 = icmp eq i32 %a, 13
1554  store i1 %c5, i1* %p
1555  br label %exit
1556
1557exit:
1558  ret void
1559}
1560
1561define i1 @or_union_unknown_cond(i32 %a, i1 %c) {
1562; CHECK-LABEL: @or_union_unknown_cond(
1563; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 10
1564; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP1]], [[C:%.*]]
1565; CHECK-NEXT:    br i1 [[OR]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1566; CHECK:       guard:
1567; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[A]], 10
1568; CHECK-NEXT:    ret i1 [[CMP2]]
1569; CHECK:       exit:
1570; CHECK-NEXT:    ret i1 false
1571;
1572  %cmp1 = icmp eq i32 %a, 10
1573  %or = or i1 %cmp1, %c
1574  br i1 %or, label %guard, label %exit
1575
1576guard:
1577  %cmp2 = icmp eq i32 %a, 10
1578  ret i1 %cmp2
1579
1580exit:
1581  ret i1 false
1582}
1583
1584define void @and_union(i32 %a, i1* %p) {
1585; CHECK-LABEL: @and_union(
1586; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], 10
1587; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i32 [[A]], 12
1588; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1589; CHECK-NEXT:    br i1 [[AND]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1590; CHECK:       guard:
1591; CHECK-NEXT:    store i1 false, i1* [[P:%.*]], align 1
1592; CHECK-NEXT:    [[C2:%.*]] = icmp eq i32 [[A]], 10
1593; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
1594; CHECK-NEXT:    [[C3:%.*]] = icmp eq i32 [[A]], 11
1595; CHECK-NEXT:    store i1 [[C3]], i1* [[P]], align 1
1596; CHECK-NEXT:    [[C4:%.*]] = icmp eq i32 [[A]], 12
1597; CHECK-NEXT:    store i1 [[C4]], i1* [[P]], align 1
1598; CHECK-NEXT:    store i1 false, i1* [[P]], align 1
1599; CHECK-NEXT:    br label [[EXIT]]
1600; CHECK:       exit:
1601; CHECK-NEXT:    ret void
1602;
1603  %cmp1 = icmp ne i32 %a, 10
1604  %cmp2 = icmp ne i32 %a, 12
1605  %and = and i1 %cmp1, %cmp2
1606  br i1 %and, label %exit, label %guard
1607
1608guard:
1609  %c1 = icmp eq i32 %a, 9
1610  store i1 %c1, i1* %p
1611  %c2 = icmp eq i32 %a, 10
1612  store i1 %c2, i1* %p
1613  %c3 = icmp eq i32 %a, 11
1614  store i1 %c3, i1* %p
1615  %c4 = icmp eq i32 %a, 12
1616  store i1 %c4, i1* %p
1617  %c5 = icmp eq i32 %a, 13
1618  store i1 %c5, i1* %p
1619  br label %exit
1620
1621exit:
1622  ret void
1623}
1624
1625define i1 @and_union_unknown_cond(i32 %a, i1 %c) {
1626; CHECK-LABEL: @and_union_unknown_cond(
1627; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], 10
1628; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[C:%.*]]
1629; CHECK-NEXT:    br i1 [[AND]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1630; CHECK:       guard:
1631; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[A]], 10
1632; CHECK-NEXT:    ret i1 [[CMP2]]
1633; CHECK:       exit:
1634; CHECK-NEXT:    ret i1 false
1635;
1636  %cmp1 = icmp ne i32 %a, 10
1637  %and = and i1 %cmp1, %c
1638  br i1 %and, label %exit, label %guard
1639
1640guard:
1641  %cmp2 = icmp eq i32 %a, 10
1642  ret i1 %cmp2
1643
1644exit:
1645  ret i1 false
1646}
1647
1648
1649declare i32 @llvm.uadd.sat.i32(i32, i32)
1650declare i32 @llvm.usub.sat.i32(i32, i32)
1651declare i32 @llvm.sadd.sat.i32(i32, i32)
1652declare i32 @llvm.ssub.sat.i32(i32, i32)
1653declare void @llvm.assume(i1)
1654