1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -correlated-propagation -S %s | FileCheck %s
3; RUN: opt -passes=correlated-propagation -S %s | FileCheck %s
4
5target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
6target triple = "x86_64-apple-macosx10.10.0"
7
8declare void @check1(i1) #1
9declare void @check2(i1) #1
10declare void @llvm.assume(i1)
11
12; Make sure we propagate the value of %tmp35 to the true/false cases
13
14define void @test1(i64 %tmp35) {
15; CHECK-LABEL: @test1(
16; CHECK-NEXT:  bb:
17; CHECK-NEXT:    [[TMP36:%.*]] = icmp sgt i64 [[TMP35:%.*]], 0
18; CHECK-NEXT:    br i1 [[TMP36]], label [[BB_TRUE:%.*]], label [[BB_FALSE:%.*]]
19; CHECK:       bb_true:
20; CHECK-NEXT:    tail call void @check1(i1 false) #[[ATTR1:[0-9]+]]
21; CHECK-NEXT:    unreachable
22; CHECK:       bb_false:
23; CHECK-NEXT:    tail call void @check2(i1 true) #[[ATTR1]]
24; CHECK-NEXT:    unreachable
25;
26bb:
27  %tmp36 = icmp sgt i64 %tmp35, 0
28  br i1 %tmp36, label %bb_true, label %bb_false
29
30bb_true:
31  %tmp47 = icmp slt i64 %tmp35, 0
32  tail call void @check1(i1 %tmp47) #4
33  unreachable
34
35bb_false:
36  %tmp48 = icmp sle i64 %tmp35, 0
37  tail call void @check2(i1 %tmp48) #4
38  unreachable
39}
40
41; This is the same as test1 but with a diamond to ensure we
42; get %tmp36 from both true and false BBs.
43
44define void @test2(i64 %tmp35, i1 %inner_cmp) {
45; CHECK-LABEL: @test2(
46; CHECK-NEXT:  bb:
47; CHECK-NEXT:    [[TMP36:%.*]] = icmp sgt i64 [[TMP35:%.*]], 0
48; CHECK-NEXT:    br i1 [[TMP36]], label [[BB_TRUE:%.*]], label [[BB_FALSE:%.*]]
49; CHECK:       bb_true:
50; CHECK-NEXT:    br i1 [[INNER_CMP:%.*]], label [[INNER_TRUE:%.*]], label [[INNER_FALSE:%.*]]
51; CHECK:       inner_true:
52; CHECK-NEXT:    br label [[MERGE:%.*]]
53; CHECK:       inner_false:
54; CHECK-NEXT:    br label [[MERGE]]
55; CHECK:       merge:
56; CHECK-NEXT:    tail call void @check1(i1 false)
57; CHECK-NEXT:    unreachable
58; CHECK:       bb_false:
59; CHECK-NEXT:    tail call void @check2(i1 true) #[[ATTR1]]
60; CHECK-NEXT:    unreachable
61;
62bb:
63  %tmp36 = icmp sgt i64 %tmp35, 0
64  br i1 %tmp36, label %bb_true, label %bb_false
65
66bb_true:
67  br i1 %inner_cmp, label %inner_true, label %inner_false
68
69inner_true:
70  br label %merge
71
72inner_false:
73  br label %merge
74
75merge:
76  %tmp47 = icmp slt i64 %tmp35, 0
77  tail call void @check1(i1 %tmp47) #0
78  unreachable
79
80bb_false:
81  %tmp48 = icmp sle i64 %tmp35, 0
82  tail call void @check2(i1 %tmp48) #4
83  unreachable
84}
85
86; Make sure binary operator transfer functions are run when RHS is non-constant
87
88define i1 @test3(i32 %x, i32 %y) #0 {
89; CHECK-LABEL: @test3(
90; CHECK-NEXT:  entry:
91; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 10
92; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
93; CHECK:       cont1:
94; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 10
95; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
96; CHECK:       cont2:
97; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[X]], [[Y]]
98; CHECK-NEXT:    br label [[OUT]]
99; CHECK:       out:
100; CHECK-NEXT:    ret i1 true
101;
102entry:
103  %cmp1 = icmp ult i32 %x, 10
104  br i1 %cmp1, label %cont1, label %out
105
106cont1:
107  %cmp2 = icmp ult i32 %y, 10
108  br i1 %cmp2, label %cont2, label %out
109
110cont2:
111  %add = add i32 %x, %y
112  %cmp3 = icmp ult i32 %add, 25
113  br label %out
114
115out:
116  %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
117  ret i1 %ret
118}
119
120; Same as previous but make sure nobody gets over-zealous
121
122define i1 @test4(i32 %x, i32 %y) #0 {
123; CHECK-LABEL: @test4(
124; CHECK-NEXT:  entry:
125; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 10
126; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
127; CHECK:       cont1:
128; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 10
129; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
130; CHECK:       cont2:
131; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[X]], [[Y]]
132; CHECK-NEXT:    [[CMP3:%.*]] = icmp ult i32 [[ADD]], 15
133; CHECK-NEXT:    br label [[OUT]]
134; CHECK:       out:
135; CHECK-NEXT:    [[RET:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ true, [[CONT1]] ], [ [[CMP3]], [[CONT2]] ]
136; CHECK-NEXT:    ret i1 [[RET]]
137;
138entry:
139  %cmp1 = icmp ult i32 %x, 10
140  br i1 %cmp1, label %cont1, label %out
141
142cont1:
143  %cmp2 = icmp ult i32 %y, 10
144  br i1 %cmp2, label %cont2, label %out
145
146cont2:
147  %add = add i32 %x, %y
148  %cmp3 = icmp ult i32 %add, 15
149  br label %out
150
151out:
152  %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
153  ret i1 %ret
154}
155
156; Make sure binary operator transfer functions are run when RHS is non-constant
157
158define i1 @test5(i32 %x, i32 %y) #0 {
159; CHECK-LABEL: @test5(
160; CHECK-NEXT:  entry:
161; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 5
162; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
163; CHECK:       cont1:
164; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 5
165; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
166; CHECK:       cont2:
167; CHECK-NEXT:    [[SHIFTED:%.*]] = shl nuw nsw i32 [[X]], [[Y]]
168; CHECK-NEXT:    br label [[OUT]]
169; CHECK:       out:
170; CHECK-NEXT:    ret i1 true
171;
172entry:
173  %cmp1 = icmp ult i32 %x, 5
174  br i1 %cmp1, label %cont1, label %out
175
176cont1:
177  %cmp2 = icmp ult i32 %y, 5
178  br i1 %cmp2, label %cont2, label %out
179
180cont2:
181  %shifted = shl i32 %x, %y
182  %cmp3 = icmp ult i32 %shifted, 65536
183  br label %out
184
185out:
186  %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
187  ret i1 %ret
188}
189
190; Same as previous but make sure nobody gets over-zealous
191
192define i1 @test6(i32 %x, i32 %y) #0 {
193; CHECK-LABEL: @test6(
194; CHECK-NEXT:  entry:
195; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 5
196; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
197; CHECK:       cont1:
198; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 15
199; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
200; CHECK:       cont2:
201; CHECK-NEXT:    [[SHIFTED:%.*]] = shl nuw nsw i32 [[X]], [[Y]]
202; CHECK-NEXT:    [[CMP3:%.*]] = icmp ult i32 [[SHIFTED]], 65536
203; CHECK-NEXT:    br label [[OUT]]
204; CHECK:       out:
205; CHECK-NEXT:    [[RET:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ true, [[CONT1]] ], [ [[CMP3]], [[CONT2]] ]
206; CHECK-NEXT:    ret i1 [[RET]]
207;
208entry:
209  %cmp1 = icmp ult i32 %x, 5
210  br i1 %cmp1, label %cont1, label %out
211
212cont1:
213  %cmp2 = icmp ult i32 %y, 15
214  br i1 %cmp2, label %cont2, label %out
215
216cont2:
217  %shifted = shl i32 %x, %y
218  %cmp3 = icmp ult i32 %shifted, 65536
219  br label %out
220
221out:
222  %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont2 ]
223  ret i1 %ret
224}
225
226define i1 @test7(i32 %a, i32 %b) {
227; CHECK-LABEL: @test7(
228; CHECK-NEXT:  begin:
229; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0
230; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
231; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
232; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
233; CHECK:       bb:
234; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[A]], [[B]]
235; CHECK-NEXT:    [[RES:%.*]] = icmp sge i32 [[ADD]], 0
236; CHECK-NEXT:    br label [[EXIT]]
237; CHECK:       exit:
238; CHECK-NEXT:    [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
239; CHECK-NEXT:    ret i1 [[IV]]
240;
241begin:
242  %cmp0 = icmp sge i32 %a, 0
243  %cmp1 = icmp sge i32 %b, 0
244  %br = and i1 %cmp0, %cmp1
245  br i1 %br, label %bb, label %exit
246
247bb:
248  %add = add i32 %a, %b
249  %res = icmp sge i32 %add, 0
250  br label %exit
251
252exit:
253  %iv = phi i1 [ true, %begin ], [ %res, %bb ]
254  ret i1 %iv
255}
256
257define i1 @test8(i32 %a, i32 %b) {
258; CHECK-LABEL: @test8(
259; CHECK-NEXT:  begin:
260; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0
261; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
262; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
263; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
264; CHECK:       bb:
265; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[A]], [[B]]
266; CHECK-NEXT:    br label [[EXIT]]
267; CHECK:       exit:
268; CHECK-NEXT:    ret i1 true
269;
270begin:
271  %cmp0 = icmp sge i32 %a, 0
272  %cmp1 = icmp sge i32 %b, 0
273  %br = and i1 %cmp0, %cmp1
274  br i1 %br, label %bb, label %exit
275
276bb:
277  %add = add nsw i32 %a, %b
278  %res = icmp sge i32 %add, 0
279  br label %exit
280
281exit:
282  %iv = phi i1 [ true, %begin ], [ %res, %bb ]
283  ret i1 %iv
284}
285
286define i1 @test10(i32 %a, i32 %b) {
287; CHECK-LABEL: @test10(
288; CHECK-NEXT:  begin:
289; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[A:%.*]], -256
290; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
291; CHECK:       bb:
292; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[A]], [[B:%.*]]
293; CHECK-NEXT:    [[RES:%.*]] = icmp uge i32 [[ADD]], -256
294; CHECK-NEXT:    br label [[EXIT]]
295; CHECK:       exit:
296; CHECK-NEXT:    [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
297; CHECK-NEXT:    ret i1 [[IV]]
298;
299begin:
300  %cmp = icmp uge i32 %a, 4294967040
301  br i1 %cmp, label %bb, label %exit
302
303bb:
304  %add = add i32 %a, %b
305  %res = icmp uge i32 %add, 4294967040
306  br label %exit
307
308exit:
309  %iv = phi i1 [ true, %begin ], [ %res, %bb ]
310  ret i1 %iv
311}
312
313define i1 @test11(i32 %a, i32 %b) {
314; CHECK-LABEL: @test11(
315; CHECK-NEXT:  begin:
316; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[A:%.*]], -256
317; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
318; CHECK:       bb:
319; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[A]], [[B:%.*]]
320; CHECK-NEXT:    br label [[EXIT]]
321; CHECK:       exit:
322; CHECK-NEXT:    ret i1 true
323;
324begin:
325  %cmp = icmp uge i32 %a, 4294967040
326  br i1 %cmp, label %bb, label %exit
327
328bb:
329  %add = add nuw i32 %a, %b
330  %res = icmp uge i32 %add, 4294967040
331  br label %exit
332
333exit:
334  %iv = phi i1 [ true, %begin ], [ %res, %bb ]
335  ret i1 %iv
336}
337
338define i1 @test12(i32 %x) {
339; CHECK-LABEL: @test12(
340; CHECK-NEXT:    [[ZEXT:%.*]] = zext i32 [[X:%.*]] to i64
341; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i64 [[ZEXT]], 7
342; CHECK-NEXT:    [[SHR:%.*]] = lshr i64 [[MUL]], 32
343; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i64 [[SHR]] to i32
344; CHECK-NEXT:    ret i1 true
345;
346  %zext = zext i32 %x to i64
347  %mul = mul nuw i64 %zext, 7
348  %shr = lshr i64 %mul, 32
349  %trunc = trunc i64 %shr to i32
350  %cmp = icmp ult i32 %trunc, 7
351  ret i1 %cmp
352}
353
354define i1 @test13(i8 %x, i64* %p) {
355; CHECK-LABEL: @test13(
356; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[X:%.*]] to i64
357; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i64 [[ZEXT]], 128
358; CHECK-NEXT:    store i64 [[ADD]], i64* [[P:%.*]], align 8
359; CHECK-NEXT:    ret i1 true
360;
361  %zext = zext i8 %x to i64
362  %add = add nuw nsw i64 %zext, 128
363  %cmp = icmp ult i64 %add, 384
364  ; Without this extra use, InstSimplify could handle this
365  store i64 %add, i64* %p
366  ret i1 %cmp
367}
368
369define i1 @test14(i32 %a, i32 %b) {
370; CHECK-LABEL: @test14(
371; CHECK-NEXT:  begin:
372; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0
373; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
374; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
375; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
376; CHECK:       bb:
377; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[A]], [[B]]
378; CHECK-NEXT:    [[RES:%.*]] = icmp sge i32 [[SUB]], 0
379; CHECK-NEXT:    br label [[EXIT]]
380; CHECK:       exit:
381; CHECK-NEXT:    [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
382; CHECK-NEXT:    ret i1 [[IV]]
383;
384begin:
385  %cmp0 = icmp sge i32 %a, 0
386  %cmp1 = icmp sge i32 %b, 0
387  %br = and i1 %cmp0, %cmp1
388  br i1 %br, label %bb, label %exit
389
390bb:
391  %sub = sub i32 %a, %b
392  %res = icmp sge i32 %sub, 0
393  br label %exit
394
395exit:
396  %iv = phi i1 [ true, %begin ], [ %res, %bb ]
397  ret i1 %iv
398}
399
400define i1 @test15(i32 %a, i32 %b) {
401; CHECK-LABEL: @test15(
402; CHECK-NEXT:  begin:
403; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0
404; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
405; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
406; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
407; CHECK:       bb:
408; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[A]], [[B]]
409; CHECK-NEXT:    [[RES:%.*]] = icmp sge i32 [[SUB]], 0
410; CHECK-NEXT:    br label [[EXIT]]
411; CHECK:       exit:
412; CHECK-NEXT:    [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
413; CHECK-NEXT:    ret i1 [[IV]]
414;
415begin:
416  %cmp0 = icmp sge i32 %a, 0
417  %cmp1 = icmp sge i32 %b, 0
418  %br = and i1 %cmp0, %cmp1
419  br i1 %br, label %bb, label %exit
420
421bb:
422  %sub = sub nsw i32 %a, %b
423  %res = icmp sge i32 %sub, 0
424  br label %exit
425
426exit:
427  %iv = phi i1 [ true, %begin ], [ %res, %bb ]
428  ret i1 %iv
429}
430
431define i1 @test16(i32 %a, i32 %b) {
432; CHECK-LABEL: @test16(
433; CHECK-NEXT:  begin:
434; CHECK-NEXT:    [[CMP0:%.*]] = icmp sge i32 [[A:%.*]], 0
435; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
436; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
437; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
438; CHECK:       bb:
439; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 [[A]], [[B]]
440; CHECK-NEXT:    br label [[EXIT]]
441; CHECK:       exit:
442; CHECK-NEXT:    ret i1 true
443;
444begin:
445  %cmp0 = icmp sge i32 %a, 0
446  %cmp1 = icmp sge i32 %b, 0
447  %br = and i1 %cmp0, %cmp1
448  br i1 %br, label %bb, label %exit
449
450bb:
451  %sub = sub nuw i32 %a, %b
452  %res = icmp sge i32 %sub, 0
453  br label %exit
454
455exit:
456  %iv = phi i1 [ true, %begin ], [ %res, %bb ]
457  ret i1 %iv
458}
459
460define i1 @test17(i32 %a, i32 %b) {
461; CHECK-LABEL: @test17(
462; CHECK-NEXT:  begin:
463; CHECK-NEXT:    [[CMP0:%.*]] = icmp sle i32 [[A:%.*]], 0
464; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
465; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
466; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
467; CHECK:       bb:
468; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[A]], [[B]]
469; CHECK-NEXT:    [[RES:%.*]] = icmp sle i32 [[SUB]], 0
470; CHECK-NEXT:    br label [[EXIT]]
471; CHECK:       exit:
472; CHECK-NEXT:    [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
473; CHECK-NEXT:    ret i1 [[IV]]
474;
475begin:
476  %cmp0 = icmp sle i32 %a, 0
477  %cmp1 = icmp sge i32 %b, 0
478  %br = and i1 %cmp0, %cmp1
479  br i1 %br, label %bb, label %exit
480
481bb:
482  %sub = sub i32 %a, %b
483  %res = icmp sle i32 %sub, 0
484  br label %exit
485
486exit:
487  %iv = phi i1 [ true, %begin ], [ %res, %bb ]
488  ret i1 %iv
489}
490
491define i1 @test18(i32 %a, i32 %b) {
492; CHECK-LABEL: @test18(
493; CHECK-NEXT:  begin:
494; CHECK-NEXT:    [[CMP0:%.*]] = icmp sle i32 [[A:%.*]], 0
495; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
496; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
497; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
498; CHECK:       bb:
499; CHECK-NEXT:    [[SUB:%.*]] = sub nuw i32 [[A]], [[B]]
500; CHECK-NEXT:    [[RES:%.*]] = icmp sle i32 [[SUB]], 0
501; CHECK-NEXT:    br label [[EXIT]]
502; CHECK:       exit:
503; CHECK-NEXT:    [[IV:%.*]] = phi i1 [ true, [[BEGIN:%.*]] ], [ [[RES]], [[BB]] ]
504; CHECK-NEXT:    ret i1 [[IV]]
505;
506begin:
507  %cmp0 = icmp sle i32 %a, 0
508  %cmp1 = icmp sge i32 %b, 0
509  %br = and i1 %cmp0, %cmp1
510  br i1 %br, label %bb, label %exit
511
512bb:
513  %sub = sub nuw i32 %a, %b
514  %res = icmp sle i32 %sub, 0
515  br label %exit
516
517exit:
518  %iv = phi i1 [ true, %begin ], [ %res, %bb ]
519  ret i1 %iv
520}
521
522define i1 @test19(i32 %a, i32 %b) {
523; CHECK-LABEL: @test19(
524; CHECK-NEXT:  begin:
525; CHECK-NEXT:    [[CMP0:%.*]] = icmp sle i32 [[A:%.*]], 0
526; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[B:%.*]], 0
527; CHECK-NEXT:    [[BR:%.*]] = and i1 [[CMP0]], [[CMP1]]
528; CHECK-NEXT:    br i1 [[BR]], label [[BB:%.*]], label [[EXIT:%.*]]
529; CHECK:       bb:
530; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[A]], [[B]]
531; CHECK-NEXT:    br label [[EXIT]]
532; CHECK:       exit:
533; CHECK-NEXT:    ret i1 true
534;
535begin:
536  %cmp0 = icmp sle i32 %a, 0
537  %cmp1 = icmp sge i32 %b, 0
538  %br = and i1 %cmp0, %cmp1
539  br i1 %br, label %bb, label %exit
540
541bb:
542  %sub = sub nsw i32 %a, %b
543  %res = icmp sle i32 %sub, 0
544  br label %exit
545
546exit:
547  %iv = phi i1 [ true, %begin ], [ %res, %bb ]
548  ret i1 %iv
549}
550
551define i1 @test_br_cmp_with_offset(i64 %idx) {
552; CHECK-LABEL: @test_br_cmp_with_offset(
553; CHECK-NEXT:    [[IDX_OFF1:%.*]] = add i64 [[IDX:%.*]], -5
554; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[IDX_OFF1]], 3
555; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
556; CHECK:       if.true:
557; CHECK-NEXT:    [[IDX_OFF2:%.*]] = add nsw i64 [[IDX]], -1
558; CHECK-NEXT:    ret i1 true
559; CHECK:       if.false:
560; CHECK-NEXT:    ret i1 undef
561;
562  %idx.off1 = add i64 %idx, -5
563  %cmp1 = icmp ult i64 %idx.off1, 3
564  br i1 %cmp1, label %if.true, label %if.false
565
566if.true:
567  %idx.off2 = add i64 %idx, -1
568  %cmp2 = icmp ult i64 %idx.off2, 10
569  ret i1 %cmp2
570
571if.false:
572  ret i1 undef
573}
574
575define i1 @test_assume_cmp_with_offset(i64 %idx) {
576; CHECK-LABEL: @test_assume_cmp_with_offset(
577; CHECK-NEXT:    [[IDX_OFF1:%.*]] = add i64 [[IDX:%.*]], -5
578; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[IDX_OFF1]], 3
579; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP1]])
580; CHECK-NEXT:    [[IDX_OFF2:%.*]] = add nsw i64 [[IDX]], -1
581; CHECK-NEXT:    ret i1 true
582;
583  %idx.off1 = add i64 %idx, -5
584  %cmp1 = icmp ult i64 %idx.off1, 3
585  tail call void @llvm.assume(i1 %cmp1)
586  %idx.off2 = add i64 %idx, -1
587  %cmp2 = icmp ult i64 %idx.off2, 10
588  ret i1 %cmp2
589}
590
591define void @test_cmp_phi(i8 %a) {
592; CHECK-LABEL: @test_cmp_phi(
593; CHECK-NEXT:  entry:
594; CHECK-NEXT:    [[C0:%.*]] = icmp ult i8 [[A:%.*]], 2
595; CHECK-NEXT:    br i1 [[C0]], label [[LOOP:%.*]], label [[EXIT:%.*]]
596; CHECK:       loop:
597; CHECK-NEXT:    [[P:%.*]] = phi i8 [ [[A]], [[ENTRY:%.*]] ], [ [[B:%.*]], [[LOOP]] ]
598; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[P]], 0
599; CHECK-NEXT:    [[C4:%.*]] = call i1 @get_bool()
600; CHECK-NEXT:    [[B]] = zext i1 [[C4]] to i8
601; CHECK-NEXT:    br i1 [[C1]], label [[LOOP]], label [[EXIT]]
602; CHECK:       exit:
603; CHECK-NEXT:    ret void
604;
605entry:
606  %c0 = icmp ult i8 %a, 2
607  br i1 %c0, label %loop, label %exit
608
609loop:
610  %p = phi i8 [ %a, %entry ], [ %b, %loop ]
611  %c1 = icmp ne i8 %p, 0
612  %c2 = icmp ne i8 %p, 2
613  %c3 = and i1 %c1, %c2
614  %c4 = call i1 @get_bool()
615  %b = zext i1 %c4 to i8
616  br i1 %c3, label %loop, label %exit
617
618exit:
619  ret void
620}
621
622declare i1 @get_bool()
623
624define void @test_icmp_or_ult(i32 %a, i32 %b) {
625; CHECK-LABEL: @test_icmp_or_ult(
626; CHECK-NEXT:  entry:
627; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
628; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[OR]], 42
629; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
630; CHECK:       if.true:
631; CHECK-NEXT:    call void @check1(i1 true)
632; CHECK-NEXT:    call void @check1(i1 true)
633; CHECK-NEXT:    ret void
634; CHECK:       if.false:
635; CHECK-NEXT:    [[CMP4:%.*]] = icmp uge i32 [[A]], 42
636; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
637; CHECK-NEXT:    [[CMP5:%.*]] = icmp uge i32 [[B]], 42
638; CHECK-NEXT:    call void @check1(i1 [[CMP5]])
639; CHECK-NEXT:    ret void
640;
641entry:
642  %or = or i32 %a, %b
643  %cmp = icmp ult i32 %or, 42
644  br i1 %cmp, label %if.true, label %if.false
645
646if.true:
647  %cmp2 = icmp ult i32 %a, 42
648  call void @check1(i1 %cmp2)
649  %cmp3 = icmp ult i32 %b, 42
650  call void @check1(i1 %cmp3)
651  ret void
652
653if.false:
654  %cmp4 = icmp uge i32 %a, 42
655  call void @check1(i1 %cmp4)
656  %cmp5 = icmp uge i32 %b, 42
657  call void @check1(i1 %cmp5)
658  ret void
659}
660
661define void @test_icmp_or_ule(i32 %a, i32 %b) {
662; CHECK-LABEL: @test_icmp_or_ule(
663; CHECK-NEXT:  entry:
664; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
665; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OR]], 42
666; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
667; CHECK:       if.true:
668; CHECK-NEXT:    call void @check1(i1 true)
669; CHECK-NEXT:    call void @check1(i1 true)
670; CHECK-NEXT:    ret void
671; CHECK:       if.false:
672; CHECK-NEXT:    [[CMP4:%.*]] = icmp ugt i32 [[A]], 42
673; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
674; CHECK-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[B]], 42
675; CHECK-NEXT:    call void @check1(i1 [[CMP5]])
676; CHECK-NEXT:    ret void
677;
678entry:
679  %or = or i32 %a, %b
680  %cmp = icmp ule i32 %or, 42
681  br i1 %cmp, label %if.true, label %if.false
682
683if.true:
684  %cmp2 = icmp ule i32 %a, 42
685  call void @check1(i1 %cmp2)
686  %cmp3 = icmp ule i32 %b, 42
687  call void @check1(i1 %cmp3)
688  ret void
689
690if.false:
691  %cmp4 = icmp ugt i32 %a, 42
692  call void @check1(i1 %cmp4)
693  %cmp5 = icmp ugt i32 %b, 42
694  call void @check1(i1 %cmp5)
695  ret void
696}
697
698define void @test_icmp_or_ugt(i32 %a, i32 %b) {
699; CHECK-LABEL: @test_icmp_or_ugt(
700; CHECK-NEXT:  entry:
701; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
702; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[OR]], 42
703; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
704; CHECK:       if.true:
705; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 [[A]], 42
706; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
707; CHECK-NEXT:    [[CMP3:%.*]] = icmp ugt i32 [[B]], 42
708; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
709; CHECK-NEXT:    ret void
710; CHECK:       if.false:
711; CHECK-NEXT:    call void @check1(i1 true)
712; CHECK-NEXT:    call void @check1(i1 true)
713; CHECK-NEXT:    ret void
714;
715entry:
716  %or = or i32 %a, %b
717  %cmp = icmp ugt i32 %or, 42
718  br i1 %cmp, label %if.true, label %if.false
719
720if.true:
721  %cmp2 = icmp ugt i32 %a, 42
722  call void @check1(i1 %cmp2)
723  %cmp3 = icmp ugt i32 %b, 42
724  call void @check1(i1 %cmp3)
725  ret void
726
727if.false:
728  %cmp4 = icmp ule i32 %a, 42
729  call void @check1(i1 %cmp4)
730  %cmp5 = icmp ule i32 %b, 42
731  call void @check1(i1 %cmp5)
732  ret void
733}
734
735define void @test_icmp_or_uge(i32 %a, i32 %b) {
736; CHECK-LABEL: @test_icmp_or_uge(
737; CHECK-NEXT:  entry:
738; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
739; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[OR]], 42
740; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
741; CHECK:       if.true:
742; CHECK-NEXT:    [[CMP2:%.*]] = icmp uge i32 [[A]], 42
743; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
744; CHECK-NEXT:    [[CMP3:%.*]] = icmp uge i32 [[B]], 42
745; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
746; CHECK-NEXT:    ret void
747; CHECK:       if.false:
748; CHECK-NEXT:    call void @check1(i1 true)
749; CHECK-NEXT:    call void @check1(i1 true)
750; CHECK-NEXT:    ret void
751;
752entry:
753  %or = or i32 %a, %b
754  %cmp = icmp uge i32 %or, 42
755  br i1 %cmp, label %if.true, label %if.false
756
757if.true:
758  %cmp2 = icmp uge i32 %a, 42
759  call void @check1(i1 %cmp2)
760  %cmp3 = icmp uge i32 %b, 42
761  call void @check1(i1 %cmp3)
762  ret void
763
764if.false:
765  %cmp4 = icmp ult i32 %a, 42
766  call void @check1(i1 %cmp4)
767  %cmp5 = icmp ult i32 %b, 42
768  call void @check1(i1 %cmp5)
769  ret void
770}
771
772define void @test_icmp_or_slt(i32 %a, i32 %b) {
773; CHECK-LABEL: @test_icmp_or_slt(
774; CHECK-NEXT:  entry:
775; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
776; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[OR]], 42
777; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
778; CHECK:       if.true:
779; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[A]], 42
780; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
781; CHECK-NEXT:    [[CMP3:%.*]] = icmp slt i32 [[B]], 42
782; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
783; CHECK-NEXT:    ret void
784; CHECK:       if.false:
785; CHECK-NEXT:    [[CMP4:%.*]] = icmp sge i32 [[A]], 42
786; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
787; CHECK-NEXT:    [[CMP5:%.*]] = icmp sge i32 [[B]], 42
788; CHECK-NEXT:    call void @check1(i1 [[CMP5]])
789; CHECK-NEXT:    ret void
790;
791entry:
792  %or = or i32 %a, %b
793  %cmp = icmp slt i32 %or, 42
794  br i1 %cmp, label %if.true, label %if.false
795
796if.true:
797  %cmp2 = icmp slt i32 %a, 42
798  call void @check1(i1 %cmp2)
799  %cmp3 = icmp slt i32 %b, 42
800  call void @check1(i1 %cmp3)
801  ret void
802
803if.false:
804  %cmp4 = icmp sge i32 %a, 42
805  call void @check1(i1 %cmp4)
806  %cmp5 = icmp sge i32 %b, 42
807  call void @check1(i1 %cmp5)
808  ret void
809}
810
811define void @test_icmp_and_ugt(i32 %a, i32 %b) {
812; CHECK-LABEL: @test_icmp_and_ugt(
813; CHECK-NEXT:  entry:
814; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
815; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[AND]], 42
816; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
817; CHECK:       if.true:
818; CHECK-NEXT:    call void @check1(i1 true)
819; CHECK-NEXT:    call void @check1(i1 true)
820; CHECK-NEXT:    ret void
821; CHECK:       if.false:
822; CHECK-NEXT:    [[CMP4:%.*]] = icmp ule i32 [[A]], 42
823; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
824; CHECK-NEXT:    [[CMP5:%.*]] = icmp ule i32 [[B]], 42
825; CHECK-NEXT:    call void @check1(i1 [[CMP5]])
826; CHECK-NEXT:    ret void
827;
828entry:
829  %and = and i32 %a, %b
830  %cmp = icmp ugt i32 %and, 42
831  br i1 %cmp, label %if.true, label %if.false
832
833if.true:
834  %cmp2 = icmp ugt i32 %a, 42
835  call void @check1(i1 %cmp2)
836  %cmp3 = icmp ugt i32 %b, 42
837  call void @check1(i1 %cmp3)
838  ret void
839
840if.false:
841  %cmp4 = icmp ule i32 %a, 42
842  call void @check1(i1 %cmp4)
843  %cmp5 = icmp ule i32 %b, 42
844  call void @check1(i1 %cmp5)
845  ret void
846}
847
848define void @test_icmp_and_uge(i32 %a, i32 %b) {
849; CHECK-LABEL: @test_icmp_and_uge(
850; CHECK-NEXT:  entry:
851; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
852; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[AND]], 42
853; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
854; CHECK:       if.true:
855; CHECK-NEXT:    call void @check1(i1 true)
856; CHECK-NEXT:    call void @check1(i1 true)
857; CHECK-NEXT:    ret void
858; CHECK:       if.false:
859; CHECK-NEXT:    [[CMP4:%.*]] = icmp ult i32 [[A]], 42
860; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
861; CHECK-NEXT:    [[CMP5:%.*]] = icmp ult i32 [[B]], 42
862; CHECK-NEXT:    call void @check1(i1 [[CMP5]])
863; CHECK-NEXT:    ret void
864;
865entry:
866  %and = and i32 %a, %b
867  %cmp = icmp uge i32 %and, 42
868  br i1 %cmp, label %if.true, label %if.false
869
870if.true:
871  %cmp2 = icmp uge i32 %a, 42
872  call void @check1(i1 %cmp2)
873  %cmp3 = icmp uge i32 %b, 42
874  call void @check1(i1 %cmp3)
875  ret void
876
877if.false:
878  %cmp4 = icmp ult i32 %a, 42
879  call void @check1(i1 %cmp4)
880  %cmp5 = icmp ult i32 %b, 42
881  call void @check1(i1 %cmp5)
882  ret void
883}
884
885define void @test_icmp_and_ult(i32 %a, i32 %b) {
886; CHECK-LABEL: @test_icmp_and_ult(
887; CHECK-NEXT:  entry:
888; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
889; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[AND]], 42
890; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
891; CHECK:       if.true:
892; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[A]], 42
893; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
894; CHECK-NEXT:    [[CMP3:%.*]] = icmp ult i32 [[B]], 42
895; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
896; CHECK-NEXT:    ret void
897; CHECK:       if.false:
898; CHECK-NEXT:    call void @check1(i1 true)
899; CHECK-NEXT:    call void @check1(i1 true)
900; CHECK-NEXT:    ret void
901;
902entry:
903  %and = and i32 %a, %b
904  %cmp = icmp ult i32 %and, 42
905  br i1 %cmp, label %if.true, label %if.false
906
907if.true:
908  %cmp2 = icmp ult i32 %a, 42
909  call void @check1(i1 %cmp2)
910  %cmp3 = icmp ult i32 %b, 42
911  call void @check1(i1 %cmp3)
912  ret void
913
914if.false:
915  %cmp4 = icmp uge i32 %a, 42
916  call void @check1(i1 %cmp4)
917  %cmp5 = icmp uge i32 %b, 42
918  call void @check1(i1 %cmp5)
919  ret void
920}
921
922define void @test_icmp_and_sgt(i32 %a, i32 %b) {
923; CHECK-LABEL: @test_icmp_and_sgt(
924; CHECK-NEXT:  entry:
925; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
926; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[AND]], 42
927; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
928; CHECK:       if.true:
929; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[A]], 42
930; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
931; CHECK-NEXT:    [[CMP3:%.*]] = icmp sgt i32 [[B]], 42
932; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
933; CHECK-NEXT:    ret void
934; CHECK:       if.false:
935; CHECK-NEXT:    [[CMP4:%.*]] = icmp sle i32 [[A]], 42
936; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
937; CHECK-NEXT:    [[CMP5:%.*]] = icmp sle i32 [[B]], 42
938; CHECK-NEXT:    call void @check1(i1 [[CMP5]])
939; CHECK-NEXT:    ret void
940;
941entry:
942  %and = and i32 %a, %b
943  %cmp = icmp sgt i32 %and, 42
944  br i1 %cmp, label %if.true, label %if.false
945
946if.true:
947  %cmp2 = icmp sgt i32 %a, 42
948  call void @check1(i1 %cmp2)
949  %cmp3 = icmp sgt i32 %b, 42
950  call void @check1(i1 %cmp3)
951  ret void
952
953if.false:
954  %cmp4 = icmp sle i32 %a, 42
955  call void @check1(i1 %cmp4)
956  %cmp5 = icmp sle i32 %b, 42
957  call void @check1(i1 %cmp5)
958  ret void
959}
960
961define void @test_icmp_mask_eq_two_values(i32 %a) {
962; CHECK-LABEL: @test_icmp_mask_eq_two_values(
963; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], -2
964; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 10
965; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
966; CHECK:       if.true:
967; CHECK-NEXT:    call void @check1(i1 true)
968; CHECK-NEXT:    call void @check1(i1 true)
969; CHECK-NEXT:    call void @check1(i1 false)
970; CHECK-NEXT:    call void @check1(i1 false)
971; CHECK-NEXT:    ret void
972; CHECK:       if.false:
973; CHECK-NEXT:    ret void
974;
975  %and = and i32 %a, -2
976  %cmp = icmp eq i32 %and, 10
977  br i1 %cmp, label %if.true, label %if.false
978
979if.true:
980  %cmp2 = icmp uge i32 %a, 10
981  call void @check1(i1 %cmp2)
982  %cmp3 = icmp ule i32 %a, 11
983  call void @check1(i1 %cmp3)
984  %cmp4 = icmp ult i32 %a, 10
985  call void @check1(i1 %cmp4)
986  %cmp5 = icmp ugt i32 %a, 11
987  call void @check1(i1 %cmp5)
988  ret void
989
990if.false:
991  ret void
992}
993
994define void @test_icmp_mask_eq_bit_set(i32 %a) {
995; CHECK-LABEL: @test_icmp_mask_eq_bit_set(
996; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 32
997; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 32
998; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
999; CHECK:       if.true:
1000; CHECK-NEXT:    call void @check1(i1 true)
1001; CHECK-NEXT:    [[CMP3:%.*]] = icmp uge i32 [[A]], 33
1002; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
1003; CHECK-NEXT:    ret void
1004; CHECK:       if.false:
1005; CHECK-NEXT:    ret void
1006;
1007  %and = and i32 %a, 32
1008  %cmp = icmp eq i32 %and, 32
1009  br i1 %cmp, label %if.true, label %if.false
1010
1011if.true:
1012  %cmp2 = icmp uge i32 %a, 32
1013  call void @check1(i1 %cmp2)
1014  %cmp3 = icmp uge i32 %a, 33
1015  call void @check1(i1 %cmp3)
1016  ret void
1017
1018if.false:
1019  ret void
1020}
1021
1022define void @test_icmp_mask_eq_bit_unset(i32 %a) {
1023; CHECK-LABEL: @test_icmp_mask_eq_bit_unset(
1024; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 32
1025; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
1026; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1027; CHECK:       if.true:
1028; CHECK-NEXT:    call void @check1(i1 true)
1029; CHECK-NEXT:    [[CMP3:%.*]] = icmp ule i32 [[A]], -34
1030; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
1031; CHECK-NEXT:    ret void
1032; CHECK:       if.false:
1033; CHECK-NEXT:    ret void
1034;
1035  %and = and i32 %a, 32
1036  %cmp = icmp eq i32 %and, 0
1037  br i1 %cmp, label %if.true, label %if.false
1038
1039if.true:
1040  %cmp2 = icmp ule i32 %a, -33
1041  call void @check1(i1 %cmp2)
1042  %cmp3 = icmp ule i32 %a, -34
1043  call void @check1(i1 %cmp3)
1044  ret void
1045
1046if.false:
1047  ret void
1048}
1049
1050define void @test_icmp_mask_eq_wrong_predicate(i32 %a) {
1051; CHECK-LABEL: @test_icmp_mask_eq_wrong_predicate(
1052; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], -2
1053; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 10
1054; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1055; CHECK:       if.true:
1056; CHECK-NEXT:    [[CMP2:%.*]] = icmp uge i32 [[A]], 10
1057; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
1058; CHECK-NEXT:    [[CMP3:%.*]] = icmp ule i32 [[A]], 11
1059; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
1060; CHECK-NEXT:    [[CMP4:%.*]] = icmp ult i32 [[A]], 10
1061; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
1062; CHECK-NEXT:    [[CMP5:%.*]] = icmp ugt i32 [[A]], 11
1063; CHECK-NEXT:    call void @check1(i1 [[CMP5]])
1064; CHECK-NEXT:    ret void
1065; CHECK:       if.false:
1066; CHECK-NEXT:    ret void
1067;
1068  %and = and i32 %a, -2
1069  %cmp = icmp ne i32 %and, 10
1070  br i1 %cmp, label %if.true, label %if.false
1071
1072if.true:
1073  %cmp2 = icmp uge i32 %a, 10
1074  call void @check1(i1 %cmp2)
1075  %cmp3 = icmp ule i32 %a, 11
1076  call void @check1(i1 %cmp3)
1077  %cmp4 = icmp ult i32 %a, 10
1078  call void @check1(i1 %cmp4)
1079  %cmp5 = icmp ugt i32 %a, 11
1080  call void @check1(i1 %cmp5)
1081  ret void
1082
1083if.false:
1084  ret void
1085}
1086
1087define void @test_icmp_mask_ne(i32 %a) {
1088; CHECK-LABEL: @test_icmp_mask_ne(
1089; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 6
1090; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 0
1091; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1092; CHECK:       if.true:
1093; CHECK-NEXT:    call void @check1(i1 true)
1094; CHECK-NEXT:    [[CMP3:%.*]] = icmp ugt i32 [[A]], 2
1095; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
1096; CHECK-NEXT:    [[CMP4:%.*]] = icmp ult i32 [[A]], -1
1097; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
1098; CHECK-NEXT:    ret void
1099; CHECK:       if.false:
1100; CHECK-NEXT:    ret void
1101;
1102  %and = and i32 %a, 6
1103  %cmp = icmp ne i32 %and, 0
1104  br i1 %cmp, label %if.true, label %if.false
1105
1106if.true:
1107  %cmp2 = icmp uge i32 %a, 2
1108  call void @check1(i1 %cmp2)
1109  %cmp3 = icmp ugt i32 %a, 2
1110  call void @check1(i1 %cmp3)
1111  %cmp4 = icmp ult i32 %a, -1
1112  call void @check1(i1 %cmp4)
1113  ret void
1114
1115if.false:
1116  ret void
1117}
1118
1119define void @test_icmp_mask_ne_nonzero_cmp(i32 %a) {
1120; CHECK-LABEL: @test_icmp_mask_ne_nonzero_cmp(
1121; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 6
1122; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 6
1123; CHECK-NEXT:    br i1 [[CMP]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1124; CHECK:       if.true:
1125; CHECK-NEXT:    [[CMP2:%.*]] = icmp uge i32 [[A]], 2
1126; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
1127; CHECK-NEXT:    [[CMP3:%.*]] = icmp ugt i32 [[A]], 2
1128; CHECK-NEXT:    call void @check1(i1 [[CMP3]])
1129; CHECK-NEXT:    [[CMP4:%.*]] = icmp ult i32 [[A]], -1
1130; CHECK-NEXT:    call void @check1(i1 [[CMP4]])
1131; CHECK-NEXT:    ret void
1132; CHECK:       if.false:
1133; CHECK-NEXT:    ret void
1134;
1135  %and = and i32 %a, 6
1136  %cmp = icmp ne i32 %and, 6
1137  br i1 %cmp, label %if.true, label %if.false
1138
1139if.true:
1140  %cmp2 = icmp uge i32 %a, 2
1141  call void @check1(i1 %cmp2)
1142  %cmp3 = icmp ugt i32 %a, 2
1143  call void @check1(i1 %cmp3)
1144  %cmp4 = icmp ult i32 %a, -1
1145  call void @check1(i1 %cmp4)
1146  ret void
1147
1148if.false:
1149  ret void
1150}
1151
1152define void @test_icmp_mask_ne_zero_mask(i32 %a) {
1153; CHECK-LABEL: @test_icmp_mask_ne_zero_mask(
1154; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 0
1155; CHECK-NEXT:    br i1 false, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1156; CHECK:       if.true:
1157; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i32 [[A]], 0
1158; CHECK-NEXT:    call void @check1(i1 [[CMP2]])
1159; CHECK-NEXT:    ret void
1160; CHECK:       if.false:
1161; CHECK-NEXT:    ret void
1162;
1163  %and = and i32 %a, 0
1164  %cmp = icmp ne i32 %and, 0
1165  br i1 %cmp, label %if.true, label %if.false
1166
1167if.true:
1168  %cmp2 = icmp ne i32 %a, 0
1169  call void @check1(i1 %cmp2)
1170  ret void
1171
1172if.false:
1173  ret void
1174}
1175
1176attributes #4 = { noreturn }
1177