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