xref: /llvm-project/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll (revision f8ab91f74f152c8a6d8aaedb8165109c497a618d)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=correlated-propagation -S %s | FileCheck %s
3
4target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
5target triple = "x86_64-apple-macosx10.10.0"
6
7declare void @check1(i1) #1
8declare void @check2(i1) #1
9declare void @llvm.assume(i1)
10
11; Make sure we propagate the value of %tmp35 to the true/false cases
12
13define void @test1(i64 %tmp35) {
14; CHECK-LABEL: @test1(
15; CHECK-NEXT:  bb:
16; CHECK-NEXT:    [[TMP36:%.*]] = icmp sgt i64 [[TMP35:%.*]], 0
17; CHECK-NEXT:    br i1 [[TMP36]], label [[BB_TRUE:%.*]], label [[BB_FALSE:%.*]]
18; CHECK:       bb_true:
19; CHECK-NEXT:    tail call void @check1(i1 false) #[[ATTR2:[0-9]+]]
20; CHECK-NEXT:    unreachable
21; CHECK:       bb_false:
22; CHECK-NEXT:    tail call void @check2(i1 true) #[[ATTR2]]
23; CHECK-NEXT:    unreachable
24;
25bb:
26  %tmp36 = icmp sgt i64 %tmp35, 0
27  br i1 %tmp36, label %bb_true, label %bb_false
28
29bb_true:
30  %tmp47 = icmp slt i64 %tmp35, 0
31  tail call void @check1(i1 %tmp47) #4
32  unreachable
33
34bb_false:
35  %tmp48 = icmp sle i64 %tmp35, 0
36  tail call void @check2(i1 %tmp48) #4
37  unreachable
38}
39
40; This is the same as test1 but with a diamond to ensure we
41; get %tmp36 from both true and false BBs.
42
43define void @test2(i64 %tmp35, i1 %inner_cmp) {
44; CHECK-LABEL: @test2(
45; CHECK-NEXT:  bb:
46; CHECK-NEXT:    [[TMP36:%.*]] = icmp sgt i64 [[TMP35:%.*]], 0
47; CHECK-NEXT:    br i1 [[TMP36]], label [[BB_TRUE:%.*]], label [[BB_FALSE:%.*]]
48; CHECK:       bb_true:
49; CHECK-NEXT:    br i1 [[INNER_CMP:%.*]], label [[INNER_TRUE:%.*]], label [[INNER_FALSE:%.*]]
50; CHECK:       inner_true:
51; CHECK-NEXT:    br label [[MERGE:%.*]]
52; CHECK:       inner_false:
53; CHECK-NEXT:    br label [[MERGE]]
54; CHECK:       merge:
55; CHECK-NEXT:    tail call void @check1(i1 false)
56; CHECK-NEXT:    unreachable
57; CHECK:       bb_false:
58; CHECK-NEXT:    tail call void @check2(i1 true) #[[ATTR2]]
59; CHECK-NEXT:    unreachable
60;
61bb:
62  %tmp36 = icmp sgt i64 %tmp35, 0
63  br i1 %tmp36, label %bb_true, label %bb_false
64
65bb_true:
66  br i1 %inner_cmp, label %inner_true, label %inner_false
67
68inner_true:
69  br label %merge
70
71inner_false:
72  br label %merge
73
74merge:
75  %tmp47 = icmp slt i64 %tmp35, 0
76  tail call void @check1(i1 %tmp47) #0
77  unreachable
78
79bb_false:
80  %tmp48 = icmp sle i64 %tmp35, 0
81  tail call void @check2(i1 %tmp48) #4
82  unreachable
83}
84
85; Make sure binary operator transfer functions are run when RHS is non-constant
86
87define i1 @test3(i32 %x, i32 %y) #0 {
88; CHECK-LABEL: @test3(
89; CHECK-NEXT:  entry:
90; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 10
91; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
92; CHECK:       cont1:
93; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 10
94; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
95; CHECK:       cont2:
96; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[X]], [[Y]]
97; CHECK-NEXT:    br label [[OUT]]
98; CHECK:       out:
99; CHECK-NEXT:    ret i1 true
100;
101entry:
102  %cmp1 = icmp ult i32 %x, 10
103  br i1 %cmp1, label %cont1, label %out
104
105cont1:
106  %cmp2 = icmp ult i32 %y, 10
107  br i1 %cmp2, label %cont2, label %out
108
109cont2:
110  %add = add i32 %x, %y
111  %cmp3 = icmp ult i32 %add, 25
112  br label %out
113
114out:
115  %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
116  ret i1 %ret
117}
118
119; Same as previous but make sure nobody gets over-zealous
120
121define i1 @test4(i32 %x, i32 %y) #0 {
122; CHECK-LABEL: @test4(
123; CHECK-NEXT:  entry:
124; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 10
125; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
126; CHECK:       cont1:
127; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 10
128; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
129; CHECK:       cont2:
130; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[X]], [[Y]]
131; CHECK-NEXT:    [[CMP3:%.*]] = icmp samesign ult i32 [[ADD]], 15
132; CHECK-NEXT:    br label [[OUT]]
133; CHECK:       out:
134; CHECK-NEXT:    [[RET:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ true, [[CONT1]] ], [ [[CMP3]], [[CONT2]] ]
135; CHECK-NEXT:    ret i1 [[RET]]
136;
137entry:
138  %cmp1 = icmp ult i32 %x, 10
139  br i1 %cmp1, label %cont1, label %out
140
141cont1:
142  %cmp2 = icmp ult i32 %y, 10
143  br i1 %cmp2, label %cont2, label %out
144
145cont2:
146  %add = add i32 %x, %y
147  %cmp3 = icmp ult i32 %add, 15
148  br label %out
149
150out:
151  %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
152  ret i1 %ret
153}
154
155; Make sure binary operator transfer functions are run when RHS is non-constant
156
157define i1 @test5(i32 %x, i32 %y) #0 {
158; CHECK-LABEL: @test5(
159; CHECK-NEXT:  entry:
160; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 5
161; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
162; CHECK:       cont1:
163; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 5
164; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
165; CHECK:       cont2:
166; CHECK-NEXT:    [[SHIFTED:%.*]] = shl nuw nsw i32 [[X]], [[Y]]
167; CHECK-NEXT:    br label [[OUT]]
168; CHECK:       out:
169; CHECK-NEXT:    ret i1 true
170;
171entry:
172  %cmp1 = icmp ult i32 %x, 5
173  br i1 %cmp1, label %cont1, label %out
174
175cont1:
176  %cmp2 = icmp ult i32 %y, 5
177  br i1 %cmp2, label %cont2, label %out
178
179cont2:
180  %shifted = shl i32 %x, %y
181  %cmp3 = icmp ult i32 %shifted, 65536
182  br label %out
183
184out:
185  %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
186  ret i1 %ret
187}
188
189; Same as previous but make sure nobody gets over-zealous
190
191define i1 @test6(i32 %x, i32 %y) #0 {
192; CHECK-LABEL: @test6(
193; CHECK-NEXT:  entry:
194; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 5
195; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
196; CHECK:       cont1:
197; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 15
198; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
199; CHECK:       cont2:
200; CHECK-NEXT:    [[SHIFTED:%.*]] = shl nuw nsw i32 [[X]], [[Y]]
201; CHECK-NEXT:    [[CMP3:%.*]] = icmp samesign ult i32 [[SHIFTED]], 65536
202; CHECK-NEXT:    br label [[OUT]]
203; CHECK:       out:
204; CHECK-NEXT:    [[RET:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ true, [[CONT1]] ], [ [[CMP3]], [[CONT2]] ]
205; CHECK-NEXT:    ret i1 [[RET]]
206;
207entry:
208  %cmp1 = icmp ult i32 %x, 5
209  br i1 %cmp1, label %cont1, label %out
210
211cont1:
212  %cmp2 = icmp ult i32 %y, 15
213  br i1 %cmp2, label %cont2, label %out
214
215cont2:
216  %shifted = shl i32 %x, %y
217  %cmp3 = icmp ult i32 %shifted, 65536
218  br label %out
219
220out:
221  %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
222  ret i1 %ret
223}
224
225define i1 @test7(i32 %a, i32 %b) {
226; CHECK-LABEL: @test7(
227; CHECK-NEXT:  begin:
228; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0
229; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
230; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
231; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
232; CHECK:       bb:
233; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[A]], [[B]]
234; CHECK-NEXT:    [[RES:%.*]] = icmp sge i32 [[ADD]], 0
235; CHECK-NEXT:    br label [[EXIT]]
236; CHECK:       exit:
237; CHECK-NEXT:    [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
238; CHECK-NEXT:    ret i1 [[IV]]
239;
240begin:
241  %cmp0 = icmp sge i32 %a, 0
242  %cmp1 = icmp sge i32 %b, 0
243  %br = and i1 %cmp0, %cmp1
244  br i1 %br, label %bb, label %exit
245
246bb:
247  %add = add i32 %a, %b
248  %res = icmp sge i32 %add, 0
249  br label %exit
250
251exit:
252  %iv = phi i1 [ true, %begin ], [ %res, %bb ]
253  ret i1 %iv
254}
255
256define i1 @test8(i32 %a, i32 %b) {
257; CHECK-LABEL: @test8(
258; CHECK-NEXT:  begin:
259; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0
260; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
261; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
262; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
263; CHECK:       bb:
264; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[A]], [[B]]
265; CHECK-NEXT:    br label [[EXIT]]
266; CHECK:       exit:
267; CHECK-NEXT:    ret i1 true
268;
269begin:
270  %cmp0 = icmp sge i32 %a, 0
271  %cmp1 = icmp sge i32 %b, 0
272  %br = and i1 %cmp0, %cmp1
273  br i1 %br, label %bb, label %exit
274
275bb:
276  %add = add nsw i32 %a, %b
277  %res = icmp sge i32 %add, 0
278  br label %exit
279
280exit:
281  %iv = phi i1 [ true, %begin ], [ %res, %bb ]
282  ret i1 %iv
283}
284
285define i1 @test10(i32 %a, i32 %b) {
286; CHECK-LABEL: @test10(
287; CHECK-NEXT:  begin:
288; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[A:%.*]], -256
289; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
290; CHECK:       bb:
291; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[A]], [[B:%.*]]
292; CHECK-NEXT:    [[RES:%.*]] = icmp uge i32 [[ADD]], -256
293; CHECK-NEXT:    br label [[EXIT]]
294; CHECK:       exit:
295; CHECK-NEXT:    [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
296; CHECK-NEXT:    ret i1 [[IV]]
297;
298begin:
299  %cmp = icmp uge i32 %a, 4294967040
300  br i1 %cmp, label %bb, label %exit
301
302bb:
303  %add = add i32 %a, %b
304  %res = icmp uge i32 %add, 4294967040
305  br label %exit
306
307exit:
308  %iv = phi i1 [ true, %begin ], [ %res, %bb ]
309  ret i1 %iv
310}
311
312define i1 @test11(i32 %a, i32 %b) {
313; CHECK-LABEL: @test11(
314; CHECK-NEXT:  begin:
315; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[A:%.*]], -256
316; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
317; CHECK:       bb:
318; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[A]], [[B:%.*]]
319; CHECK-NEXT:    br label [[EXIT]]
320; CHECK:       exit:
321; CHECK-NEXT:    ret i1 true
322;
323begin:
324  %cmp = icmp uge i32 %a, 4294967040
325  br i1 %cmp, label %bb, label %exit
326
327bb:
328  %add = add nuw i32 %a, %b
329  %res = icmp uge i32 %add, 4294967040
330  br label %exit
331
332exit:
333  %iv = phi i1 [ true, %begin ], [ %res, %bb ]
334  ret i1 %iv
335}
336
337define i1 @test12(i32 %x) {
338; CHECK-LABEL: @test12(
339; CHECK-NEXT:    [[ZEXT:%.*]] = zext i32 [[X:%.*]] to i64
340; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i64 [[ZEXT]], 7
341; CHECK-NEXT:    [[SHR:%.*]] = lshr i64 [[MUL]], 32
342; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i64 [[SHR]] to i32
343; CHECK-NEXT:    ret i1 true
344;
345  %zext = zext i32 %x to i64
346  %mul = mul nuw i64 %zext, 7
347  %shr = lshr i64 %mul, 32
348  %trunc = trunc i64 %shr to i32
349  %cmp = icmp ult i32 %trunc, 7
350  ret i1 %cmp
351}
352
353define i1 @test13(i8 %x, ptr %p) {
354; CHECK-LABEL: @test13(
355; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[X:%.*]] to i64
356; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i64 [[ZEXT]], 128
357; CHECK-NEXT:    store i64 [[ADD]], ptr [[P:%.*]], align 8
358; CHECK-NEXT:    ret i1 true
359;
360  %zext = zext i8 %x to i64
361  %add = add nuw nsw i64 %zext, 128
362  %cmp = icmp ult i64 %add, 384
363  ; Without this extra use, InstSimplify could handle this
364  store i64 %add, ptr %p
365  ret i1 %cmp
366}
367
368define i1 @test14(i32 %a, i32 %b) {
369; CHECK-LABEL: @test14(
370; CHECK-NEXT:  begin:
371; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0
372; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
373; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
374; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
375; CHECK:       bb:
376; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[A]], [[B]]
377; CHECK-NEXT:    [[RES:%.*]] = icmp sge i32 [[SUB]], 0
378; CHECK-NEXT:    br label [[EXIT]]
379; CHECK:       exit:
380; CHECK-NEXT:    [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
381; CHECK-NEXT:    ret i1 [[IV]]
382;
383begin:
384  %cmp0 = icmp sge i32 %a, 0
385  %cmp1 = icmp sge i32 %b, 0
386  %br = and i1 %cmp0, %cmp1
387  br i1 %br, label %bb, label %exit
388
389bb:
390  %sub = sub i32 %a, %b
391  %res = icmp sge i32 %sub, 0
392  br label %exit
393
394exit:
395  %iv = phi i1 [ true, %begin ], [ %res, %bb ]
396  ret i1 %iv
397}
398
399define i1 @test15(i32 %a, i32 %b) {
400; CHECK-LABEL: @test15(
401; CHECK-NEXT:  begin:
402; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0
403; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
404; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
405; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
406; CHECK:       bb:
407; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[A]], [[B]]
408; CHECK-NEXT:    [[RES:%.*]] = icmp sge i32 [[SUB]], 0
409; CHECK-NEXT:    br label [[EXIT]]
410; CHECK:       exit:
411; CHECK-NEXT:    [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
412; CHECK-NEXT:    ret i1 [[IV]]
413;
414begin:
415  %cmp0 = icmp sge i32 %a, 0
416  %cmp1 = icmp sge i32 %b, 0
417  %br = and i1 %cmp0, %cmp1
418  br i1 %br, label %bb, label %exit
419
420bb:
421  %sub = sub nsw i32 %a, %b
422  %res = icmp sge i32 %sub, 0
423  br label %exit
424
425exit:
426  %iv = phi i1 [ true, %begin ], [ %res, %bb ]
427  ret i1 %iv
428}
429
430define i1 @test16(i32 %a, i32 %b) {
431; CHECK-LABEL: @test16(
432; CHECK-NEXT:  begin:
433; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0
434; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
435; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
436; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
437; CHECK:       bb:
438; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 [[A]], [[B]]
439; CHECK-NEXT:    br label [[EXIT]]
440; CHECK:       exit:
441; CHECK-NEXT:    ret i1 true
442;
443begin:
444  %cmp0 = icmp sge i32 %a, 0
445  %cmp1 = icmp sge i32 %b, 0
446  %br = and i1 %cmp0, %cmp1
447  br i1 %br, label %bb, label %exit
448
449bb:
450  %sub = sub nuw i32 %a, %b
451  %res = icmp sge i32 %sub, 0
452  br label %exit
453
454exit:
455  %iv = phi i1 [ true, %begin ], [ %res, %bb ]
456  ret i1 %iv
457}
458
459define i1 @test17(i32 %a, i32 %b) {
460; CHECK-LABEL: @test17(
461; CHECK-NEXT:  begin:
462; CHECK-NEXT:    [[CMP0:%.*]] = icmp sle i32 [[A:%.*]], 0
463; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
464; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
465; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
466; CHECK:       bb:
467; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[A]], [[B]]
468; CHECK-NEXT:    [[RES:%.*]] = icmp sle i32 [[SUB]], 0
469; CHECK-NEXT:    br label [[EXIT]]
470; CHECK:       exit:
471; CHECK-NEXT:    [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
472; CHECK-NEXT:    ret i1 [[IV]]
473;
474begin:
475  %cmp0 = icmp sle i32 %a, 0
476  %cmp1 = icmp sge i32 %b, 0
477  %br = and i1 %cmp0, %cmp1
478  br i1 %br, label %bb, label %exit
479
480bb:
481  %sub = sub i32 %a, %b
482  %res = icmp sle i32 %sub, 0
483  br label %exit
484
485exit:
486  %iv = phi i1 [ true, %begin ], [ %res, %bb ]
487  ret i1 %iv
488}
489
490define i1 @test18(i32 %a, i32 %b) {
491; CHECK-LABEL: @test18(
492; CHECK-NEXT:  begin:
493; CHECK-NEXT:    [[CMP0:%.*]] = icmp sle i32 [[A:%.*]], 0
494; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
495; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
496; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
497; CHECK:       bb:
498; CHECK-NEXT:    [[SUB:%.*]] = sub nuw i32 [[A]], [[B]]
499; CHECK-NEXT:    [[RES:%.*]] = icmp sle i32 [[SUB]], 0
500; CHECK-NEXT:    br label [[EXIT]]
501; CHECK:       exit:
502; CHECK-NEXT:    [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
503; CHECK-NEXT:    ret i1 [[IV]]
504;
505begin:
506  %cmp0 = icmp sle i32 %a, 0
507  %cmp1 = icmp sge i32 %b, 0
508  %br = and i1 %cmp0, %cmp1
509  br i1 %br, label %bb, label %exit
510
511bb:
512  %sub = sub nuw i32 %a, %b
513  %res = icmp sle i32 %sub, 0
514  br label %exit
515
516exit:
517  %iv = phi i1 [ true, %begin ], [ %res, %bb ]
518  ret i1 %iv
519}
520
521define i1 @test19(i32 %a, i32 %b) {
522; CHECK-LABEL: @test19(
523; CHECK-NEXT:  begin:
524; CHECK-NEXT:    [[CMP0:%.*]] = icmp sle i32 [[A:%.*]], 0
525; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
526; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
527; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
528; CHECK:       bb:
529; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[A]], [[B]]
530; CHECK-NEXT:    br label [[EXIT]]
531; CHECK:       exit:
532; CHECK-NEXT:    ret i1 true
533;
534begin:
535  %cmp0 = icmp sle i32 %a, 0
536  %cmp1 = icmp sge i32 %b, 0
537  %br = and i1 %cmp0, %cmp1
538  br i1 %br, label %bb, label %exit
539
540bb:
541  %sub = sub nsw i32 %a, %b
542  %res = icmp sle i32 %sub, 0
543  br label %exit
544
545exit:
546  %iv = phi i1 [ true, %begin ], [ %res, %bb ]
547  ret i1 %iv
548}
549
550define i1 @test_br_cmp_with_offset(i64 %idx) {
551; CHECK-LABEL: @test_br_cmp_with_offset(
552; CHECK-NEXT:    [[IDX_OFF1:%.*]] = add i64 [[IDX:%.*]], -5
553; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[IDX_OFF1]], 3
554; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
555; CHECK:       if.true:
556; CHECK-NEXT:    [[IDX_OFF2:%.*]] = add nsw i64 [[IDX]], -1
557; CHECK-NEXT:    ret i1 true
558; CHECK:       if.false:
559; CHECK-NEXT:    ret i1 undef
560;
561  %idx.off1 = add i64 %idx, -5
562  %cmp1 = icmp ult i64 %idx.off1, 3
563  br i1 %cmp1, label %if.true, label %if.false
564
565if.true:
566  %idx.off2 = add i64 %idx, -1
567  %cmp2 = icmp ult i64 %idx.off2, 10
568  ret i1 %cmp2
569
570if.false:
571  ret i1 undef
572}
573
574define i1 @test_assume_cmp_with_offset(i64 %idx) {
575; CHECK-LABEL: @test_assume_cmp_with_offset(
576; CHECK-NEXT:    [[IDX_OFF1:%.*]] = add i64 [[IDX:%.*]], -5
577; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[IDX_OFF1]], 3
578; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP1]])
579; CHECK-NEXT:    [[IDX_OFF2:%.*]] = add nsw i64 [[IDX]], -1
580; CHECK-NEXT:    ret i1 true
581;
582  %idx.off1 = add i64 %idx, -5
583  %cmp1 = icmp ult i64 %idx.off1, 3
584  tail call void @llvm.assume(i1 %cmp1)
585  %idx.off2 = add i64 %idx, -1
586  %cmp2 = icmp ult i64 %idx.off2, 10
587  ret i1 %cmp2
588}
589
590define i1 @test_assume_cmp_with_offset_or(i64 %idx, i1 %other) {
591; CHECK-LABEL: @test_assume_cmp_with_offset_or(
592; CHECK-NEXT:    [[IDX_OFF1:%.*]] = or disjoint i64 [[IDX:%.*]], 5
593; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt i64 [[IDX_OFF1]], 10
594; CHECK-NEXT:    br i1 [[CMP1]], label [[T:%.*]], label [[F:%.*]]
595; CHECK:       T:
596; CHECK-NEXT:    ret i1 true
597; CHECK:       F:
598; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
599;
600  %idx.off1 = or disjoint i64 %idx, 5
601  %cmp1 = icmp ugt i64 %idx.off1, 10
602  br i1 %cmp1, label %T, label %F
603T:
604  %cmp2 = icmp ugt i64 %idx, 2
605  ret i1 %cmp2
606F:
607  ret i1 %other
608}
609
610define void @test_cmp_phi(i8 %a) {
611; CHECK-LABEL: @test_cmp_phi(
612; CHECK-NEXT:  entry:
613; CHECK-NEXT:    [[C0:%.*]] = icmp ult i8 [[A:%.*]], 2
614; CHECK-NEXT:    br i1 [[C0]], label [[LOOP:%.*]], label [[EXIT:%.*]]
615; CHECK:       loop:
616; CHECK-NEXT:    [[P:%.*]] = phi i8 [ [[A]], [[ENTRY:%.*]] ], [ [[B:%.*]], [[LOOP]] ]
617; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[P]], 0
618; CHECK-NEXT:    [[C4:%.*]] = call i1 @get_bool()
619; CHECK-NEXT:    [[B]] = zext i1 [[C4]] to i8
620; CHECK-NEXT:    br i1 [[C1]], label [[LOOP]], label [[EXIT]]
621; CHECK:       exit:
622; CHECK-NEXT:    ret void
623;
624entry:
625  %c0 = icmp ult i8 %a, 2
626  br i1 %c0, label %loop, label %exit
627
628loop:
629  %p = phi i8 [ %a, %entry ], [ %b, %loop ]
630  %c1 = icmp ne i8 %p, 0
631  %c2 = icmp ne i8 %p, 2
632  %c3 = and i1 %c1, %c2
633  %c4 = call i1 @get_bool()
634  %b = zext i1 %c4 to i8
635  br i1 %c3, label %loop, label %exit
636
637exit:
638  ret void
639}
640
641declare i1 @get_bool()
642
643define void @test_icmp_or_ult(i32 %a, i32 %b) {
644; CHECK-LABEL: @test_icmp_or_ult(
645; CHECK-NEXT:  entry:
646; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
647; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[OR]], 42
648; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
649; CHECK:       if.true:
650; CHECK-NEXT:    call void @check1(i1 true)
651; CHECK-NEXT:    call void @check1(i1 true)
652; CHECK-NEXT:    ret void
653; CHECK:       if.false:
654; CHECK-NEXT:    [[CMP4:%.*]] = icmp uge i32 [[A]], 42
655; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
656; CHECK-NEXT:    [[CMP5:%.*]] = icmp uge i32 [[B]], 42
657; CHECK-NEXT:    call void @check1(i1 [[CMP5]])
658; CHECK-NEXT:    ret void
659;
660entry:
661  %or = or i32 %a, %b
662  %cmp = icmp ult i32 %or, 42
663  br i1 %cmp, label %if.true, label %if.false
664
665if.true:
666  %cmp2 = icmp ult i32 %a, 42
667  call void @check1(i1 %cmp2)
668  %cmp3 = icmp ult i32 %b, 42
669  call void @check1(i1 %cmp3)
670  ret void
671
672if.false:
673  %cmp4 = icmp uge i32 %a, 42
674  call void @check1(i1 %cmp4)
675  %cmp5 = icmp uge i32 %b, 42
676  call void @check1(i1 %cmp5)
677  ret void
678}
679
680define void @test_icmp_or_ule(i32 %a, i32 %b) {
681; CHECK-LABEL: @test_icmp_or_ule(
682; CHECK-NEXT:  entry:
683; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
684; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OR]], 42
685; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
686; CHECK:       if.true:
687; CHECK-NEXT:    call void @check1(i1 true)
688; CHECK-NEXT:    call void @check1(i1 true)
689; CHECK-NEXT:    ret void
690; CHECK:       if.false:
691; CHECK-NEXT:    [[CMP4:%.*]] = icmp ugt i32 [[A]], 42
692; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
693; CHECK-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[B]], 42
694; CHECK-NEXT:    call void @check1(i1 [[CMP5]])
695; CHECK-NEXT:    ret void
696;
697entry:
698  %or = or i32 %a, %b
699  %cmp = icmp ule i32 %or, 42
700  br i1 %cmp, label %if.true, label %if.false
701
702if.true:
703  %cmp2 = icmp ule i32 %a, 42
704  call void @check1(i1 %cmp2)
705  %cmp3 = icmp ule i32 %b, 42
706  call void @check1(i1 %cmp3)
707  ret void
708
709if.false:
710  %cmp4 = icmp ugt i32 %a, 42
711  call void @check1(i1 %cmp4)
712  %cmp5 = icmp ugt i32 %b, 42
713  call void @check1(i1 %cmp5)
714  ret void
715}
716
717define void @test_icmp_or_ugt(i32 %a, i32 %b) {
718; CHECK-LABEL: @test_icmp_or_ugt(
719; CHECK-NEXT:  entry:
720; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
721; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[OR]], 42
722; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
723; CHECK:       if.true:
724; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 [[A]], 42
725; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
726; CHECK-NEXT:    [[CMP3:%.*]] = icmp ugt i32 [[B]], 42
727; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
728; CHECK-NEXT:    ret void
729; CHECK:       if.false:
730; CHECK-NEXT:    call void @check1(i1 true)
731; CHECK-NEXT:    call void @check1(i1 true)
732; CHECK-NEXT:    ret void
733;
734entry:
735  %or = or i32 %a, %b
736  %cmp = icmp ugt i32 %or, 42
737  br i1 %cmp, label %if.true, label %if.false
738
739if.true:
740  %cmp2 = icmp ugt i32 %a, 42
741  call void @check1(i1 %cmp2)
742  %cmp3 = icmp ugt i32 %b, 42
743  call void @check1(i1 %cmp3)
744  ret void
745
746if.false:
747  %cmp4 = icmp ule i32 %a, 42
748  call void @check1(i1 %cmp4)
749  %cmp5 = icmp ule i32 %b, 42
750  call void @check1(i1 %cmp5)
751  ret void
752}
753
754define void @test_icmp_or_uge(i32 %a, i32 %b) {
755; CHECK-LABEL: @test_icmp_or_uge(
756; CHECK-NEXT:  entry:
757; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
758; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[OR]], 42
759; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
760; CHECK:       if.true:
761; CHECK-NEXT:    [[CMP2:%.*]] = icmp uge i32 [[A]], 42
762; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
763; CHECK-NEXT:    [[CMP3:%.*]] = icmp uge i32 [[B]], 42
764; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
765; CHECK-NEXT:    ret void
766; CHECK:       if.false:
767; CHECK-NEXT:    call void @check1(i1 true)
768; CHECK-NEXT:    call void @check1(i1 true)
769; CHECK-NEXT:    ret void
770;
771entry:
772  %or = or i32 %a, %b
773  %cmp = icmp uge i32 %or, 42
774  br i1 %cmp, label %if.true, label %if.false
775
776if.true:
777  %cmp2 = icmp uge i32 %a, 42
778  call void @check1(i1 %cmp2)
779  %cmp3 = icmp uge i32 %b, 42
780  call void @check1(i1 %cmp3)
781  ret void
782
783if.false:
784  %cmp4 = icmp ult i32 %a, 42
785  call void @check1(i1 %cmp4)
786  %cmp5 = icmp ult i32 %b, 42
787  call void @check1(i1 %cmp5)
788  ret void
789}
790
791define void @test_icmp_or_slt(i32 %a, i32 %b) {
792; CHECK-LABEL: @test_icmp_or_slt(
793; CHECK-NEXT:  entry:
794; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
795; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[OR]], 42
796; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
797; CHECK:       if.true:
798; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[A]], 42
799; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
800; CHECK-NEXT:    [[CMP3:%.*]] = icmp slt i32 [[B]], 42
801; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
802; CHECK-NEXT:    ret void
803; CHECK:       if.false:
804; CHECK-NEXT:    [[CMP4:%.*]] = icmp sge i32 [[A]], 42
805; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
806; CHECK-NEXT:    [[CMP5:%.*]] = icmp sge i32 [[B]], 42
807; CHECK-NEXT:    call void @check1(i1 [[CMP5]])
808; CHECK-NEXT:    ret void
809;
810entry:
811  %or = or i32 %a, %b
812  %cmp = icmp slt i32 %or, 42
813  br i1 %cmp, label %if.true, label %if.false
814
815if.true:
816  %cmp2 = icmp slt i32 %a, 42
817  call void @check1(i1 %cmp2)
818  %cmp3 = icmp slt i32 %b, 42
819  call void @check1(i1 %cmp3)
820  ret void
821
822if.false:
823  %cmp4 = icmp sge i32 %a, 42
824  call void @check1(i1 %cmp4)
825  %cmp5 = icmp sge i32 %b, 42
826  call void @check1(i1 %cmp5)
827  ret void
828}
829
830define void @test_icmp_and_ugt(i32 %a, i32 %b) {
831; CHECK-LABEL: @test_icmp_and_ugt(
832; CHECK-NEXT:  entry:
833; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
834; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[AND]], 42
835; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
836; CHECK:       if.true:
837; CHECK-NEXT:    call void @check1(i1 true)
838; CHECK-NEXT:    call void @check1(i1 true)
839; CHECK-NEXT:    ret void
840; CHECK:       if.false:
841; CHECK-NEXT:    [[CMP4:%.*]] = icmp ule i32 [[A]], 42
842; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
843; CHECK-NEXT:    [[CMP5:%.*]] = icmp ule i32 [[B]], 42
844; CHECK-NEXT:    call void @check1(i1 [[CMP5]])
845; CHECK-NEXT:    ret void
846;
847entry:
848  %and = and i32 %a, %b
849  %cmp = icmp ugt i32 %and, 42
850  br i1 %cmp, label %if.true, label %if.false
851
852if.true:
853  %cmp2 = icmp ugt i32 %a, 42
854  call void @check1(i1 %cmp2)
855  %cmp3 = icmp ugt i32 %b, 42
856  call void @check1(i1 %cmp3)
857  ret void
858
859if.false:
860  %cmp4 = icmp ule i32 %a, 42
861  call void @check1(i1 %cmp4)
862  %cmp5 = icmp ule i32 %b, 42
863  call void @check1(i1 %cmp5)
864  ret void
865}
866
867define void @test_icmp_and_uge(i32 %a, i32 %b) {
868; CHECK-LABEL: @test_icmp_and_uge(
869; CHECK-NEXT:  entry:
870; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
871; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[AND]], 42
872; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
873; CHECK:       if.true:
874; CHECK-NEXT:    call void @check1(i1 true)
875; CHECK-NEXT:    call void @check1(i1 true)
876; CHECK-NEXT:    ret void
877; CHECK:       if.false:
878; CHECK-NEXT:    [[CMP4:%.*]] = icmp ult i32 [[A]], 42
879; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
880; CHECK-NEXT:    [[CMP5:%.*]] = icmp ult i32 [[B]], 42
881; CHECK-NEXT:    call void @check1(i1 [[CMP5]])
882; CHECK-NEXT:    ret void
883;
884entry:
885  %and = and i32 %a, %b
886  %cmp = icmp uge i32 %and, 42
887  br i1 %cmp, label %if.true, label %if.false
888
889if.true:
890  %cmp2 = icmp uge i32 %a, 42
891  call void @check1(i1 %cmp2)
892  %cmp3 = icmp uge i32 %b, 42
893  call void @check1(i1 %cmp3)
894  ret void
895
896if.false:
897  %cmp4 = icmp ult i32 %a, 42
898  call void @check1(i1 %cmp4)
899  %cmp5 = icmp ult i32 %b, 42
900  call void @check1(i1 %cmp5)
901  ret void
902}
903
904define void @test_icmp_and_ult(i32 %a, i32 %b) {
905; CHECK-LABEL: @test_icmp_and_ult(
906; CHECK-NEXT:  entry:
907; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
908; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[AND]], 42
909; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
910; CHECK:       if.true:
911; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[A]], 42
912; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
913; CHECK-NEXT:    [[CMP3:%.*]] = icmp ult i32 [[B]], 42
914; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
915; CHECK-NEXT:    ret void
916; CHECK:       if.false:
917; CHECK-NEXT:    call void @check1(i1 true)
918; CHECK-NEXT:    call void @check1(i1 true)
919; CHECK-NEXT:    ret void
920;
921entry:
922  %and = and i32 %a, %b
923  %cmp = icmp ult i32 %and, 42
924  br i1 %cmp, label %if.true, label %if.false
925
926if.true:
927  %cmp2 = icmp ult i32 %a, 42
928  call void @check1(i1 %cmp2)
929  %cmp3 = icmp ult i32 %b, 42
930  call void @check1(i1 %cmp3)
931  ret void
932
933if.false:
934  %cmp4 = icmp uge i32 %a, 42
935  call void @check1(i1 %cmp4)
936  %cmp5 = icmp uge i32 %b, 42
937  call void @check1(i1 %cmp5)
938  ret void
939}
940
941define void @test_icmp_and_sgt(i32 %a, i32 %b) {
942; CHECK-LABEL: @test_icmp_and_sgt(
943; CHECK-NEXT:  entry:
944; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
945; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[AND]], 42
946; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
947; CHECK:       if.true:
948; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], 42
949; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
950; CHECK-NEXT:    [[CMP3:%.*]] = icmp sgt i32 [[B]], 42
951; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
952; CHECK-NEXT:    ret void
953; CHECK:       if.false:
954; CHECK-NEXT:    [[CMP4:%.*]] = icmp sle i32 [[A]], 42
955; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
956; CHECK-NEXT:    [[CMP5:%.*]] = icmp sle i32 [[B]], 42
957; CHECK-NEXT:    call void @check1(i1 [[CMP5]])
958; CHECK-NEXT:    ret void
959;
960entry:
961  %and = and i32 %a, %b
962  %cmp = icmp sgt i32 %and, 42
963  br i1 %cmp, label %if.true, label %if.false
964
965if.true:
966  %cmp2 = icmp sgt i32 %a, 42
967  call void @check1(i1 %cmp2)
968  %cmp3 = icmp sgt i32 %b, 42
969  call void @check1(i1 %cmp3)
970  ret void
971
972if.false:
973  %cmp4 = icmp sle i32 %a, 42
974  call void @check1(i1 %cmp4)
975  %cmp5 = icmp sle i32 %b, 42
976  call void @check1(i1 %cmp5)
977  ret void
978}
979
980define void @test_icmp_mask_eq_two_values(i32 %a) {
981; CHECK-LABEL: @test_icmp_mask_eq_two_values(
982; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], -2
983; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 10
984; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
985; CHECK:       if.true:
986; CHECK-NEXT:    call void @check1(i1 true)
987; CHECK-NEXT:    call void @check1(i1 true)
988; CHECK-NEXT:    call void @check1(i1 false)
989; CHECK-NEXT:    call void @check1(i1 false)
990; CHECK-NEXT:    ret void
991; CHECK:       if.false:
992; CHECK-NEXT:    ret void
993;
994  %and = and i32 %a, -2
995  %cmp = icmp eq i32 %and, 10
996  br i1 %cmp, label %if.true, label %if.false
997
998if.true:
999  %cmp2 = icmp uge i32 %a, 10
1000  call void @check1(i1 %cmp2)
1001  %cmp3 = icmp ule i32 %a, 11
1002  call void @check1(i1 %cmp3)
1003  %cmp4 = icmp ult i32 %a, 10
1004  call void @check1(i1 %cmp4)
1005  %cmp5 = icmp ugt i32 %a, 11
1006  call void @check1(i1 %cmp5)
1007  ret void
1008
1009if.false:
1010  ret void
1011}
1012
1013define void @test_icmp_mask_eq_bit_set(i32 %a) {
1014; CHECK-LABEL: @test_icmp_mask_eq_bit_set(
1015; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 32
1016; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 32
1017; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1018; CHECK:       if.true:
1019; CHECK-NEXT:    call void @check1(i1 true)
1020; CHECK-NEXT:    [[CMP3:%.*]] = icmp uge i32 [[A]], 33
1021; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
1022; CHECK-NEXT:    ret void
1023; CHECK:       if.false:
1024; CHECK-NEXT:    ret void
1025;
1026  %and = and i32 %a, 32
1027  %cmp = icmp eq i32 %and, 32
1028  br i1 %cmp, label %if.true, label %if.false
1029
1030if.true:
1031  %cmp2 = icmp uge i32 %a, 32
1032  call void @check1(i1 %cmp2)
1033  %cmp3 = icmp uge i32 %a, 33
1034  call void @check1(i1 %cmp3)
1035  ret void
1036
1037if.false:
1038  ret void
1039}
1040
1041define void @test_icmp_mask_eq_bit_unset(i32 %a) {
1042; CHECK-LABEL: @test_icmp_mask_eq_bit_unset(
1043; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 32
1044; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
1045; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1046; CHECK:       if.true:
1047; CHECK-NEXT:    call void @check1(i1 true)
1048; CHECK-NEXT:    [[CMP3:%.*]] = icmp ule i32 [[A]], -34
1049; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
1050; CHECK-NEXT:    ret void
1051; CHECK:       if.false:
1052; CHECK-NEXT:    ret void
1053;
1054  %and = and i32 %a, 32
1055  %cmp = icmp eq i32 %and, 0
1056  br i1 %cmp, label %if.true, label %if.false
1057
1058if.true:
1059  %cmp2 = icmp ule i32 %a, -33
1060  call void @check1(i1 %cmp2)
1061  %cmp3 = icmp ule i32 %a, -34
1062  call void @check1(i1 %cmp3)
1063  ret void
1064
1065if.false:
1066  ret void
1067}
1068
1069define void @test_icmp_mask_eq_wrong_predicate(i32 %a) {
1070; CHECK-LABEL: @test_icmp_mask_eq_wrong_predicate(
1071; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], -2
1072; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 10
1073; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1074; CHECK:       if.true:
1075; CHECK-NEXT:    [[CMP2:%.*]] = icmp uge i32 [[A]], 10
1076; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
1077; CHECK-NEXT:    [[CMP3:%.*]] = icmp ule i32 [[A]], 11
1078; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
1079; CHECK-NEXT:    [[CMP4:%.*]] = icmp ult i32 [[A]], 10
1080; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
1081; CHECK-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[A]], 11
1082; CHECK-NEXT:    call void @check1(i1 [[CMP5]])
1083; CHECK-NEXT:    ret void
1084; CHECK:       if.false:
1085; CHECK-NEXT:    ret void
1086;
1087  %and = and i32 %a, -2
1088  %cmp = icmp ne i32 %and, 10
1089  br i1 %cmp, label %if.true, label %if.false
1090
1091if.true:
1092  %cmp2 = icmp uge i32 %a, 10
1093  call void @check1(i1 %cmp2)
1094  %cmp3 = icmp ule i32 %a, 11
1095  call void @check1(i1 %cmp3)
1096  %cmp4 = icmp ult i32 %a, 10
1097  call void @check1(i1 %cmp4)
1098  %cmp5 = icmp ugt i32 %a, 11
1099  call void @check1(i1 %cmp5)
1100  ret void
1101
1102if.false:
1103  ret void
1104}
1105
1106define void @test_icmp_mask_ne(i32 %a) {
1107; CHECK-LABEL: @test_icmp_mask_ne(
1108; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 6
1109; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 0
1110; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1111; CHECK:       if.true:
1112; CHECK-NEXT:    call void @check1(i1 true)
1113; CHECK-NEXT:    [[CMP3:%.*]] = icmp ugt i32 [[A]], 2
1114; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
1115; CHECK-NEXT:    [[CMP4:%.*]] = icmp ult i32 [[A]], -1
1116; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
1117; CHECK-NEXT:    ret void
1118; CHECK:       if.false:
1119; CHECK-NEXT:    ret void
1120;
1121  %and = and i32 %a, 6
1122  %cmp = icmp ne i32 %and, 0
1123  br i1 %cmp, label %if.true, label %if.false
1124
1125if.true:
1126  %cmp2 = icmp uge i32 %a, 2
1127  call void @check1(i1 %cmp2)
1128  %cmp3 = icmp ugt i32 %a, 2
1129  call void @check1(i1 %cmp3)
1130  %cmp4 = icmp ult i32 %a, -1
1131  call void @check1(i1 %cmp4)
1132  ret void
1133
1134if.false:
1135  ret void
1136}
1137
1138define void @test_icmp_mask_ne_nonzero_cmp(i32 %a) {
1139; CHECK-LABEL: @test_icmp_mask_ne_nonzero_cmp(
1140; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 6
1141; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 6
1142; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1143; CHECK:       if.true:
1144; CHECK-NEXT:    [[CMP2:%.*]] = icmp uge i32 [[A]], 2
1145; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
1146; CHECK-NEXT:    [[CMP3:%.*]] = icmp ugt i32 [[A]], 2
1147; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
1148; CHECK-NEXT:    [[CMP4:%.*]] = icmp ult i32 [[A]], -1
1149; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
1150; CHECK-NEXT:    ret void
1151; CHECK:       if.false:
1152; CHECK-NEXT:    ret void
1153;
1154  %and = and i32 %a, 6
1155  %cmp = icmp ne i32 %and, 6
1156  br i1 %cmp, label %if.true, label %if.false
1157
1158if.true:
1159  %cmp2 = icmp uge i32 %a, 2
1160  call void @check1(i1 %cmp2)
1161  %cmp3 = icmp ugt i32 %a, 2
1162  call void @check1(i1 %cmp3)
1163  %cmp4 = icmp ult i32 %a, -1
1164  call void @check1(i1 %cmp4)
1165  ret void
1166
1167if.false:
1168  ret void
1169}
1170
1171define void @test_icmp_mask_ne_zero_mask(i32 %a) {
1172; CHECK-LABEL: @test_icmp_mask_ne_zero_mask(
1173; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 0
1174; CHECK-NEXT:    br i1 false, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1175; CHECK:       if.true:
1176; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i32 [[A]], 0
1177; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
1178; CHECK-NEXT:    ret void
1179; CHECK:       if.false:
1180; CHECK-NEXT:    ret void
1181;
1182  %and = and i32 %a, 0
1183  %cmp = icmp ne i32 %and, 0
1184  br i1 %cmp, label %if.true, label %if.false
1185
1186if.true:
1187  %cmp2 = icmp ne i32 %a, 0
1188  call void @check1(i1 %cmp2)
1189  ret void
1190
1191if.false:
1192  ret void
1193}
1194
1195define void @non_const_range(i32 %a, i32 %b) {
1196; CHECK-LABEL: @non_const_range(
1197; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[A:%.*]], 11
1198; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[B:%.*]], 21
1199; CHECK-NEXT:    [[AND:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1200; CHECK-NEXT:    br i1 [[AND]], label [[IF:%.*]], label [[ELSE:%.*]]
1201; CHECK:       if:
1202; CHECK-NEXT:    [[A_100:%.*]] = add nuw nsw i32 [[A]], 100
1203; CHECK-NEXT:    call void @check1(i1 true)
1204; CHECK-NEXT:    call void @check1(i1 false)
1205; CHECK-NEXT:    [[A_10:%.*]] = add nuw nsw i32 [[A]], 10
1206; CHECK-NEXT:    [[CMP5:%.*]] = icmp ne i32 [[A_10]], [[B]]
1207; CHECK-NEXT:    call void @check1(i1 [[CMP5]])
1208; CHECK-NEXT:    [[CMP6:%.*]] = icmp eq i32 [[A_10]], [[B]]
1209; CHECK-NEXT:    call void @check1(i1 [[CMP6]])
1210; CHECK-NEXT:    ret void
1211; CHECK:       else:
1212; CHECK-NEXT:    ret void
1213;
1214  %cmp1 = icmp ult i32 %a, 11
1215  %cmp2 = icmp ult i32 %b, 21
1216  %and = select i1 %cmp1, i1 %cmp2, i1 false
1217  br i1 %and, label %if, label %else
1218
1219if:
1220  %a.100 = add nuw nsw i32 %a, 100
1221  %cmp3 = icmp ne i32 %a.100, %b
1222  call void @check1(i1 %cmp3)
1223  %cmp4 = icmp eq i32 %a.100, %b
1224  call void @check1(i1 %cmp4)
1225
1226  %a.10 = add nuw nsw i32 %a, 10
1227  %cmp5 = icmp ne i32 %a.10, %b
1228  call void @check1(i1 %cmp5)
1229  %cmp6 = icmp eq i32 %a.10, %b
1230  call void @check1(i1 %cmp6)
1231  ret void
1232
1233else:
1234  ret void
1235}
1236
1237define i1 @non_const_range_minmax(i8 %a, i8 %b) {
1238; CHECK-LABEL: @non_const_range_minmax(
1239; CHECK-NEXT:    [[A2:%.*]] = call i8 @llvm.umin.i8(i8 [[A:%.*]], i8 10)
1240; CHECK-NEXT:    [[B2:%.*]] = call i8 @llvm.umax.i8(i8 [[B:%.*]], i8 11)
1241; CHECK-NEXT:    ret i1 true
1242;
1243  %a2 = call i8 @llvm.umin.i8(i8 %a, i8 10)
1244  %b2 = call i8 @llvm.umax.i8(i8 %b, i8 11)
1245  %cmp1 = icmp ult i8 %a2, %b2
1246  ret i1 %cmp1
1247}
1248
1249define <2 x i1> @non_const_range_minmax_vec(<2 x i8> %a, <2 x i8> %b) {
1250; CHECK-LABEL: @non_const_range_minmax_vec(
1251; CHECK-NEXT:    [[A2:%.*]] = call <2 x i8> @llvm.umin.v2i8(<2 x i8> [[A:%.*]], <2 x i8> splat (i8 10))
1252; CHECK-NEXT:    [[B2:%.*]] = call <2 x i8> @llvm.umax.v2i8(<2 x i8> [[B:%.*]], <2 x i8> splat (i8 11))
1253; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
1254;
1255  %a2 = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %a, <2 x i8> <i8 10, i8 10>)
1256  %b2 = call <2 x i8> @llvm.umax.v2i8(<2 x i8> %b, <2 x i8> <i8 11, i8 11>)
1257  %cmp1 = icmp ult <2 x i8> %a2, %b2
1258  ret <2 x i1> %cmp1
1259}
1260
1261define void @ashr_sgt(i8 %x) {
1262; CHECK-LABEL: @ashr_sgt(
1263; CHECK-NEXT:    [[S:%.*]] = ashr i8 [[X:%.*]], 2
1264; CHECK-NEXT:    [[C:%.*]] = icmp sgt i8 [[S]], 1
1265; CHECK-NEXT:    br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
1266; CHECK:       if:
1267; CHECK-NEXT:    call void @check1(i1 true)
1268; CHECK-NEXT:    [[C3:%.*]] = icmp samesign ugt i8 [[X]], 8
1269; CHECK-NEXT:    call void @check1(i1 [[C3]])
1270; CHECK-NEXT:    ret void
1271; CHECK:       else:
1272; CHECK-NEXT:    ret void
1273;
1274  %s = ashr i8 %x, 2
1275  %c = icmp sgt i8 %s, 1
1276  br i1 %c, label %if, label %else
1277if:
1278  %c2 = icmp sgt i8 %x, 7
1279  call void @check1(i1 %c2)
1280  %c3 = icmp sgt i8 %x, 8
1281  call void @check1(i1 %c3)
1282  ret void
1283else:
1284  ret void
1285}
1286
1287define void @ashr_sge(i8 %x) {
1288; CHECK-LABEL: @ashr_sge(
1289; CHECK-NEXT:    [[S:%.*]] = ashr i8 [[X:%.*]], 2
1290; CHECK-NEXT:    [[C:%.*]] = icmp sge i8 [[S]], 1
1291; CHECK-NEXT:    br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
1292; CHECK:       if:
1293; CHECK-NEXT:    call void @check1(i1 true)
1294; CHECK-NEXT:    [[C3:%.*]] = icmp samesign uge i8 [[X]], 5
1295; CHECK-NEXT:    call void @check1(i1 [[C3]])
1296; CHECK-NEXT:    ret void
1297; CHECK:       else:
1298; CHECK-NEXT:    ret void
1299;
1300  %s = ashr i8 %x, 2
1301  %c = icmp sge i8 %s, 1
1302  br i1 %c, label %if, label %else
1303if:
1304  %c2 = icmp sge i8 %x, 4
1305  call void @check1(i1 %c2)
1306  %c3 = icmp sge i8 %x, 5
1307  call void @check1(i1 %c3)
1308  ret void
1309else:
1310  ret void
1311}
1312
1313define void @ashr_slt(i8 %x) {
1314; CHECK-LABEL: @ashr_slt(
1315; CHECK-NEXT:    [[S:%.*]] = ashr i8 [[X:%.*]], 2
1316; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 [[S]], 1
1317; CHECK-NEXT:    br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
1318; CHECK:       if:
1319; CHECK-NEXT:    call void @check1(i1 true)
1320; CHECK-NEXT:    [[C3:%.*]] = icmp slt i8 [[X]], 3
1321; CHECK-NEXT:    call void @check1(i1 [[C3]])
1322; CHECK-NEXT:    ret void
1323; CHECK:       else:
1324; CHECK-NEXT:    ret void
1325;
1326  %s = ashr i8 %x, 2
1327  %c = icmp slt i8 %s, 1
1328  br i1 %c, label %if, label %else
1329if:
1330  %c2 = icmp slt i8 %x, 4
1331  call void @check1(i1 %c2)
1332  %c3 = icmp slt i8 %x, 3
1333  call void @check1(i1 %c3)
1334  ret void
1335else:
1336  ret void
1337}
1338
1339define void @ashr_sle(i8 %x) {
1340; CHECK-LABEL: @ashr_sle(
1341; CHECK-NEXT:    [[S:%.*]] = ashr i8 [[X:%.*]], 2
1342; CHECK-NEXT:    [[C:%.*]] = icmp sle i8 [[S]], 1
1343; CHECK-NEXT:    br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
1344; CHECK:       if:
1345; CHECK-NEXT:    call void @check1(i1 true)
1346; CHECK-NEXT:    [[C3:%.*]] = icmp sle i8 [[X]], 6
1347; CHECK-NEXT:    call void @check1(i1 [[C3]])
1348; CHECK-NEXT:    ret void
1349; CHECK:       else:
1350; CHECK-NEXT:    ret void
1351;
1352  %s = ashr i8 %x, 2
1353  %c = icmp sle i8 %s, 1
1354  br i1 %c, label %if, label %else
1355if:
1356  %c2 = icmp sle i8 %x, 7
1357  call void @check1(i1 %c2)
1358  %c3 = icmp sle i8 %x, 6
1359  call void @check1(i1 %c3)
1360  ret void
1361else:
1362  ret void
1363}
1364
1365declare i8 @llvm.umin.i8(i8, i8)
1366declare i8 @llvm.umax.i8(i8, i8)
1367declare <2 x i8> @llvm.umin.v2i8(<2 x i8>, <2 x i8>)
1368declare <2 x i8> @llvm.umax.v2i8(<2 x i8>, <2 x i8>)
1369
1370attributes #4 = { noreturn }
1371
1372define i1 @pr69928(i64 noundef %arg, i64 noundef %arg1) {
1373; CHECK-LABEL: @pr69928(
1374; CHECK-NEXT:  entry:
1375; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[ARG:%.*]], 64424509440
1376; CHECK-NEXT:    [[AND:%.*]] = and i64 [[ARG1:%.*]], 4294967295
1377; CHECK-NEXT:    [[CMP2:%.*]] = icmp samesign ult i64 [[ARG]], [[AND]]
1378; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1379; CHECK-NEXT:    ret i1 [[SELECT]]
1380;
1381entry:
1382  %cmp1 = icmp ult i64 %arg, 64424509440
1383  %and = and i64 %arg1, 4294967295
1384  %cmp2 = icmp slt i64 %arg, %and
1385  %select = select i1 %cmp1, i1 %cmp2, i1 false
1386  ret i1 %select
1387}
1388
1389define i1 @test_select_flip(i64 noundef %arg) {
1390; CHECK-LABEL: @test_select_flip(
1391; CHECK-NEXT:  entry:
1392; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[ARG:%.*]], 1000
1393; CHECK-NEXT:    [[CMP2:%.*]] = icmp samesign ult i64 [[ARG]], 100
1394; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1395; CHECK-NEXT:    ret i1 [[SELECT]]
1396;
1397entry:
1398  %cmp1 = icmp ult i64 %arg, 1000
1399  %cmp2 = icmp slt i64 %arg, 100
1400  %select = select i1 %cmp1, i1 %cmp2, i1 false
1401  ret i1 %select
1402}
1403
1404define i1 @test_select_flip_fail1(i64 noundef %arg) {
1405; CHECK-LABEL: @test_select_flip_fail1(
1406; CHECK-NEXT:  entry:
1407; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i64 [[ARG:%.*]], 1000
1408; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i64 [[ARG]], 100
1409; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1410; CHECK-NEXT:    ret i1 [[SELECT]]
1411;
1412entry:
1413  %cmp1 = icmp slt i64 %arg, 1000
1414  %cmp2 = icmp slt i64 %arg, 100
1415  %select = select i1 %cmp1, i1 %cmp2, i1 false
1416  ret i1 %select
1417}
1418
1419define i1 @test_select_flip_fail2(i64 noundef %arg) {
1420; CHECK-LABEL: @test_select_flip_fail2(
1421; CHECK-NEXT:  entry:
1422; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[ARG:%.*]], 1000
1423; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i64 [[ARG]], 100
1424; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP1]], i1 false, i1 [[CMP2]]
1425; CHECK-NEXT:    ret i1 [[SELECT]]
1426;
1427entry:
1428  %cmp1 = icmp ult i64 %arg, 1000
1429  %cmp2 = icmp slt i64 %arg, 100
1430  %select = select i1 %cmp1, i1 false, i1 %cmp2
1431  ret i1 %select
1432}
1433
1434define i1 @test_select_flip_fail3(i64 noundef %arg, i64 noundef %arg1) {
1435; CHECK-LABEL: @test_select_flip_fail3(
1436; CHECK-NEXT:  entry:
1437; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[ARG1:%.*]], 1000
1438; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i64 [[ARG:%.*]], 100
1439; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1440; CHECK-NEXT:    ret i1 [[SELECT]]
1441;
1442entry:
1443  %cmp1 = icmp ult i64 %arg1, 1000
1444  %cmp2 = icmp slt i64 %arg, 100
1445  %select = select i1 %cmp1, i1 %cmp2, i1 false
1446  ret i1 %select
1447}
1448
1449define i1 @test_select_flip_fail4(i64 noundef %arg) {
1450; CHECK-LABEL: @test_select_flip_fail4(
1451; CHECK-NEXT:  entry:
1452; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i64 [[ARG:%.*]], 100
1453; CHECK-NEXT:    [[SELECT:%.*]] = select i1 true, i1 [[CMP2]], i1 false
1454; CHECK-NEXT:    ret i1 [[SELECT]]
1455;
1456entry:
1457  %cmp2 = icmp slt i64 %arg, 100
1458  %select = select i1 true, i1 %cmp2, i1 false
1459  ret i1 %select
1460}
1461
1462define i1 @test_select_flip_fail5(i64 noundef %arg, i64 noundef %arg1) {
1463; CHECK-LABEL: @test_select_flip_fail5(
1464; CHECK-NEXT:  entry:
1465; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[ARG:%.*]], 1000
1466; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i64 [[ARG]], [[ARG1:%.*]]
1467; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1468; CHECK-NEXT:    ret i1 [[SELECT]]
1469;
1470entry:
1471  %cmp1 = icmp ult i64 %arg, 1000
1472  %cmp2 = icmp slt i64 %arg, %arg1
1473  %select = select i1 %cmp1, i1 %cmp2, i1 false
1474  ret i1 %select
1475}
1476
1477declare void @opaque()
1478
1479define void @test_icmp_ne_from_implied_range(i32 noundef %arg) {
1480; CHECK-LABEL: @test_icmp_ne_from_implied_range(
1481; CHECK-NEXT:    [[AND_MASK:%.*]] = and i32 [[ARG:%.*]], -8
1482; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND_MASK]], -16
1483; CHECK-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[ELSE:%.*]]
1484; CHECK:       else:
1485; CHECK-NEXT:    br label [[END]]
1486; CHECK:       sw.case:
1487; CHECK-NEXT:    call void @opaque()
1488; CHECK-NEXT:    br label [[END]]
1489; CHECK:       end:
1490; CHECK-NEXT:    ret void
1491;
1492  %and.mask = and i32 %arg, -8
1493  %cmp = icmp eq i32 %and.mask, -16
1494  br i1 %cmp, label %end, label %else
1495
1496else:
1497  ; %arg is within [-8, -16).
1498  switch i32 %arg, label %end [
1499  i32 -16, label %sw.case
1500  i32 -12, label %sw.case
1501  i32 -9, label %sw.case
1502  ]
1503
1504sw.case:
1505  call void @opaque()
1506  br label %end
1507
1508end:
1509  ; %arg is within [-16, -8).
1510  ret void
1511}
1512
1513define void @test_trunc_bittest(i8 %a) {
1514; CHECK-LABEL: @test_trunc_bittest(
1515; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i8 [[A:%.*]] to i1
1516; CHECK-NEXT:    br i1 [[TRUNC]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1517; CHECK:       if.true:
1518; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i8 [[A]], 0
1519; CHECK-NEXT:    call void @check1(i1 [[CMP1]])
1520; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i8 [[A]], 0
1521; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
1522; CHECK-NEXT:    ret void
1523; CHECK:       if.false:
1524; CHECK-NEXT:    ret void
1525;
1526  %trunc = trunc i8 %a to i1
1527  br i1 %trunc, label %if.true, label %if.false
1528
1529if.true:
1530  %cmp1 = icmp ne i8 %a, 0
1531  call void @check1(i1 %cmp1)
1532  %cmp2 = icmp eq i8 %a, 0
1533  call void @check1(i1 %cmp2)
1534  ret void
1535
1536if.false:
1537  ret void
1538}
1539
1540define void @test_trunc_not_bittest(i8 %a) {
1541; CHECK-LABEL: @test_trunc_not_bittest(
1542; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i8 [[A:%.*]] to i1
1543; CHECK-NEXT:    [[NOT:%.*]] = xor i1 [[TRUNC]], true
1544; CHECK-NEXT:    br i1 [[NOT]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]]
1545; CHECK:       if.true:
1546; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i8 [[A]], -1
1547; CHECK-NEXT:    call void @check1(i1 [[CMP1]])
1548; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i8 [[A]], -1
1549; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
1550; CHECK-NEXT:    ret void
1551; CHECK:       if.false:
1552; CHECK-NEXT:    ret void
1553;
1554  %trunc = trunc i8 %a to i1
1555  %not = xor i1 %trunc, true
1556  br i1 %not, label %if.true, label %if.false
1557
1558if.true:
1559  %cmp1 = icmp ne i8 %a, -1
1560  call void @check1(i1 %cmp1)
1561  %cmp2 = icmp eq i8 %a, -1
1562  call void @check1(i1 %cmp2)
1563  ret void
1564
1565if.false:
1566  ret void
1567}
1568
1569define void @test_icmp_trunc(i8 %a) {
1570; CHECK-LABEL: @test_icmp_trunc(
1571; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i8 [[A:%.*]], 0
1572; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1573; CHECK:       if.true:
1574; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i8 [[A]] to i1
1575; CHECK-NEXT:    call void @check1(i1 [[TRUNC]])
1576; CHECK-NEXT:    ret void
1577; CHECK:       if.false:
1578; CHECK-NEXT:    ret void
1579;
1580  %cmp1 = icmp ne i8 %a, 0
1581  br i1 %cmp1, label %if.true, label %if.false
1582
1583if.true:
1584  %trunc = trunc i8 %a to i1
1585  call void @check1(i1 %trunc)
1586  ret void
1587
1588if.false:
1589  ret void
1590}
1591
1592define void @test_icmp_trunc_not(i8 %a) {
1593; CHECK-LABEL: @test_icmp_trunc_not(
1594; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A:%.*]], -1
1595; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1596; CHECK:       if.true:
1597; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i8 [[A]] to i1
1598; CHECK-NEXT:    [[NOT:%.*]] = xor i1 [[TRUNC]], true
1599; CHECK-NEXT:    call void @check1(i1 [[TRUNC]])
1600; CHECK-NEXT:    ret void
1601; CHECK:       if.false:
1602; CHECK-NEXT:    ret void
1603;
1604  %cmp1 = icmp eq i8 %a, -1
1605  br i1 %cmp1, label %if.true, label %if.false
1606
1607if.true:
1608  %trunc = trunc i8 %a to i1
1609  %not = xor i1 %trunc, true
1610  call void @check1(i1 %trunc)
1611  ret void
1612
1613if.false:
1614  ret void
1615}
1616