xref: /llvm-project/llvm/test/Analysis/ValueTracking/monotonic-phi.ll (revision ec9ccb1668f60ae29e2f6c9627142f5ebfe15080)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=instsimplify -S < %s | FileCheck %s
3
4define i1 @test_add_nsw(i8 %n, i8 %r) {
5; CHECK-LABEL: @test_add_nsw(
6; CHECK-NEXT:  entry:
7; CHECK-NEXT:    br label [[LOOP:%.*]]
8; CHECK:       loop:
9; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 1, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
10; CHECK-NEXT:    [[NEXT]] = add nsw i8 [[A]], 1
11; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
12; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
13; CHECK:       exit:
14; CHECK-NEXT:    ret i1 false
15;
16entry:
17  br label %loop
18loop:
19  %A = phi i8 [ 1, %entry ], [ %next, %loop ]
20  %next = add nsw i8 %A, 1
21  %cmp1 = icmp eq i8 %A, %n
22  br i1 %cmp1, label %exit, label %loop
23exit:
24  %add = or i8 %A, %r
25  %cmp = icmp eq i8 %add, 0
26  ret i1 %cmp
27}
28
29define i1 @test_add_may_wrap(i8 %n, i8 %r) {
30; CHECK-LABEL: @test_add_may_wrap(
31; CHECK-NEXT:  entry:
32; CHECK-NEXT:    br label [[LOOP:%.*]]
33; CHECK:       loop:
34; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 1, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
35; CHECK-NEXT:    [[NEXT]] = add i8 [[A]], 1
36; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
37; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
38; CHECK:       exit:
39; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[A]], [[R:%.*]]
40; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[ADD]], 0
41; CHECK-NEXT:    ret i1 [[CMP]]
42;
43entry:
44  br label %loop
45loop:
46  %A = phi i8 [ 1, %entry ], [ %next, %loop ]
47  %next = add i8 %A, 1
48  %cmp1 = icmp eq i8 %A, %n
49  br i1 %cmp1, label %exit, label %loop
50exit:
51  %add = or i8 %A, %r
52  %cmp = icmp eq i8 %add, 0
53  ret i1 %cmp
54}
55
56define i1 @test_add_nuw(i8 %n, i8 %r) {
57; CHECK-LABEL: @test_add_nuw(
58; CHECK-NEXT:  entry:
59; CHECK-NEXT:    br label [[LOOP:%.*]]
60; CHECK:       loop:
61; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 1, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
62; CHECK-NEXT:    [[NEXT]] = add nuw i8 [[A]], 1
63; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
64; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
65; CHECK:       exit:
66; CHECK-NEXT:    ret i1 false
67;
68entry:
69  br label %loop
70loop:
71  %A = phi i8 [ 1, %entry ], [ %next, %loop ]
72  %next = add nuw i8 %A, 1
73  %cmp1 = icmp eq i8 %A, %n
74  br i1 %cmp1, label %exit, label %loop
75exit:
76  %add = or i8 %A, %r
77  %cmp = icmp eq i8 %add, 0
78  ret i1 %cmp
79}
80
81define i1 @test_add_nuw_unknown_step(i8 %n, i8 %r, i8 %s) {
82; CHECK-LABEL: @test_add_nuw_unknown_step(
83; CHECK-NEXT:  entry:
84; CHECK-NEXT:    br label [[LOOP:%.*]]
85; CHECK:       loop:
86; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 1, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
87; CHECK-NEXT:    [[NEXT]] = add nuw i8 [[A]], [[S:%.*]]
88; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
89; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
90; CHECK:       exit:
91; CHECK-NEXT:    ret i1 false
92;
93entry:
94  br label %loop
95loop:
96  %A = phi i8 [ 1, %entry ], [ %next, %loop ]
97  %next = add nuw i8 %A, %s
98  %cmp1 = icmp eq i8 %A, %n
99  br i1 %cmp1, label %exit, label %loop
100exit:
101  %add = or i8 %A, %r
102  %cmp = icmp eq i8 %add, 0
103  ret i1 %cmp
104}
105
106define i1 @test_add_zero_start(i8 %n, i8 %r) {
107; CHECK-LABEL: @test_add_zero_start(
108; CHECK-NEXT:  entry:
109; CHECK-NEXT:    br label [[LOOP:%.*]]
110; CHECK:       loop:
111; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
112; CHECK-NEXT:    [[NEXT]] = add nuw i8 [[A]], 1
113; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
114; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
115; CHECK:       exit:
116; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[A]], [[R:%.*]]
117; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[ADD]], 0
118; CHECK-NEXT:    ret i1 [[CMP]]
119;
120entry:
121  br label %loop
122loop:
123  %A = phi i8 [ 0, %entry ], [ %next, %loop ]
124  %next = add nuw i8 %A, 1
125  %cmp1 = icmp eq i8 %A, %n
126  br i1 %cmp1, label %exit, label %loop
127exit:
128  %add = or i8 %A, %r
129  %cmp = icmp eq i8 %add, 0
130  ret i1 %cmp
131}
132
133define i1 @test_add_nuw_negative_start(i8 %n, i8 %r) {
134; CHECK-LABEL: @test_add_nuw_negative_start(
135; CHECK-NEXT:  entry:
136; CHECK-NEXT:    br label [[LOOP:%.*]]
137; CHECK:       loop:
138; CHECK-NEXT:    [[A:%.*]] = phi i8 [ -2, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
139; CHECK-NEXT:    [[NEXT]] = add nuw i8 [[A]], 1
140; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
141; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
142; CHECK:       exit:
143; CHECK-NEXT:    ret i1 false
144;
145entry:
146  br label %loop
147loop:
148  %A = phi i8 [ -2, %entry ], [ %next, %loop ]
149  %next = add nuw i8 %A, 1
150  %cmp1 = icmp eq i8 %A, %n
151  br i1 %cmp1, label %exit, label %loop
152exit:
153  %add = or i8 %A, %r
154  %cmp = icmp eq i8 %add, 0
155  ret i1 %cmp
156}
157
158define i1 @test_add_nsw_negative_start(i8 %n, i8 %r) {
159; CHECK-LABEL: @test_add_nsw_negative_start(
160; CHECK-NEXT:  entry:
161; CHECK-NEXT:    br label [[LOOP:%.*]]
162; CHECK:       loop:
163; CHECK-NEXT:    [[A:%.*]] = phi i8 [ -2, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
164; CHECK-NEXT:    [[NEXT]] = add nsw i8 [[A]], 1
165; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
166; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
167; CHECK:       exit:
168; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[A]], [[R:%.*]]
169; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[ADD]], 0
170; CHECK-NEXT:    ret i1 [[CMP]]
171;
172entry:
173  br label %loop
174loop:
175  %A = phi i8 [ -2, %entry ], [ %next, %loop ]
176  %next = add nsw i8 %A, 1
177  %cmp1 = icmp eq i8 %A, %n
178  br i1 %cmp1, label %exit, label %loop
179exit:
180  %add = or i8 %A, %r
181  %cmp = icmp eq i8 %add, 0
182  ret i1 %cmp
183}
184
185define i1 @test_add_nsw_negative_start_and_step(i8 %n, i8 %r) {
186; CHECK-LABEL: @test_add_nsw_negative_start_and_step(
187; CHECK-NEXT:  entry:
188; CHECK-NEXT:    br label [[LOOP:%.*]]
189; CHECK:       loop:
190; CHECK-NEXT:    [[A:%.*]] = phi i8 [ -1, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
191; CHECK-NEXT:    [[NEXT]] = add nsw i8 [[A]], -1
192; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
193; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
194; CHECK:       exit:
195; CHECK-NEXT:    ret i1 false
196;
197entry:
198  br label %loop
199loop:
200  %A = phi i8 [ -1, %entry ], [ %next, %loop ]
201  %next = add nsw i8 %A, -1
202  %cmp1 = icmp eq i8 %A, %n
203  br i1 %cmp1, label %exit, label %loop
204exit:
205  %add = or i8 %A, %r
206  %cmp = icmp eq i8 %add, 0
207  ret i1 %cmp
208}
209
210define i1 @test_mul_nsw(i8 %n) {
211; CHECK-LABEL: @test_mul_nsw(
212; CHECK-NEXT:  entry:
213; CHECK-NEXT:    br label [[LOOP:%.*]]
214; CHECK:       loop:
215; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 2, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
216; CHECK-NEXT:    [[NEXT]] = mul nsw i8 [[A]], 2
217; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
218; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
219; CHECK:       exit:
220; CHECK-NEXT:    ret i1 false
221;
222entry:
223  br label %loop
224loop:
225  %A = phi i8 [ 2, %entry ], [ %next, %loop ]
226  %next = mul nsw i8 %A, 2
227  %cmp1 = icmp eq i8 %A, %n
228  br i1 %cmp1, label %exit, label %loop
229exit:
230  %cmp = icmp eq i8 %A, 0
231  ret i1 %cmp
232}
233
234define i1 @test_mul_may_wrap(i8 %n) {
235; CHECK-LABEL: @test_mul_may_wrap(
236; CHECK-NEXT:  entry:
237; CHECK-NEXT:    br label [[LOOP:%.*]]
238; CHECK:       loop:
239; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 2, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
240; CHECK-NEXT:    [[NEXT]] = mul i8 [[A]], 2
241; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
242; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
243; CHECK:       exit:
244; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A]], 0
245; CHECK-NEXT:    ret i1 [[CMP]]
246;
247entry:
248  br label %loop
249loop:
250  %A = phi i8 [ 2, %entry ], [ %next, %loop ]
251  %next = mul i8 %A, 2
252  %cmp1 = icmp eq i8 %A, %n
253  br i1 %cmp1, label %exit, label %loop
254exit:
255  %cmp = icmp eq i8 %A, 0
256  ret i1 %cmp
257}
258
259define i1 @test_mul_nuw(i8 %n) {
260; CHECK-LABEL: @test_mul_nuw(
261; CHECK-NEXT:  entry:
262; CHECK-NEXT:    br label [[LOOP:%.*]]
263; CHECK:       loop:
264; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 2, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
265; CHECK-NEXT:    [[NEXT]] = mul nuw i8 [[A]], 2
266; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
267; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
268; CHECK:       exit:
269; CHECK-NEXT:    ret i1 false
270;
271entry:
272  br label %loop
273loop:
274  %A = phi i8 [ 2, %entry ], [ %next, %loop ]
275  %next = mul nuw i8 %A, 2
276  %cmp1 = icmp eq i8 %A, %n
277  br i1 %cmp1, label %exit, label %loop
278exit:
279  %cmp = icmp eq i8 %A, 0
280  ret i1 %cmp
281}
282
283define i1 @test_mul_zero_start(i8 %n) {
284; CHECK-LABEL: @test_mul_zero_start(
285; CHECK-NEXT:  entry:
286; CHECK-NEXT:    br label [[LOOP:%.*]]
287; CHECK:       loop:
288; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
289; CHECK-NEXT:    [[NEXT]] = mul nuw i8 [[A]], 2
290; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
291; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
292; CHECK:       exit:
293; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A]], 0
294; CHECK-NEXT:    ret i1 [[CMP]]
295;
296entry:
297  br label %loop
298loop:
299  %A = phi i8 [ 0, %entry ], [ %next, %loop ]
300  %next = mul nuw i8 %A, 2
301  %cmp1 = icmp eq i8 %A, %n
302  br i1 %cmp1, label %exit, label %loop
303exit:
304  %cmp = icmp eq i8 %A, 0
305  ret i1 %cmp
306}
307
308define i1 @test_mul_nuw_negative_step(i8 %n) {
309; CHECK-LABEL: @test_mul_nuw_negative_step(
310; CHECK-NEXT:  entry:
311; CHECK-NEXT:    br label [[LOOP:%.*]]
312; CHECK:       loop:
313; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 2, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
314; CHECK-NEXT:    [[NEXT]] = mul nuw i8 [[A]], -2
315; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
316; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
317; CHECK:       exit:
318; CHECK-NEXT:    ret i1 false
319;
320entry:
321  br label %loop
322loop:
323  %A = phi i8 [ 2, %entry ], [ %next, %loop ]
324  %next = mul nuw i8 %A, -2
325  %cmp1 = icmp eq i8 %A, %n
326  br i1 %cmp1, label %exit, label %loop
327exit:
328  %cmp = icmp eq i8 %A, 0
329  ret i1 %cmp
330}
331
332define i1 @test_mul_nsw_negative_step(i8 %n) {
333; CHECK-LABEL: @test_mul_nsw_negative_step(
334; CHECK-NEXT:  entry:
335; CHECK-NEXT:    br label [[LOOP:%.*]]
336; CHECK:       loop:
337; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 2, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
338; CHECK-NEXT:    [[NEXT]] = mul nsw i8 [[A]], -2
339; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
340; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
341; CHECK:       exit:
342; CHECK-NEXT:    ret i1 false
343;
344entry:
345  br label %loop
346loop:
347  %A = phi i8 [ 2, %entry ], [ %next, %loop ]
348  %next = mul nsw i8 %A, -2
349  %cmp1 = icmp eq i8 %A, %n
350  br i1 %cmp1, label %exit, label %loop
351exit:
352  %cmp = icmp eq i8 %A, 0
353  ret i1 %cmp
354}
355
356define i1 @test_mul_nuw_negative_start(i8 %n) {
357; CHECK-LABEL: @test_mul_nuw_negative_start(
358; CHECK-NEXT:  entry:
359; CHECK-NEXT:    br label [[LOOP:%.*]]
360; CHECK:       loop:
361; CHECK-NEXT:    [[A:%.*]] = phi i8 [ -2, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
362; CHECK-NEXT:    [[NEXT]] = mul nuw i8 [[A]], 2
363; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
364; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
365; CHECK:       exit:
366; CHECK-NEXT:    ret i1 false
367;
368entry:
369  br label %loop
370loop:
371  %A = phi i8 [ -2, %entry ], [ %next, %loop ]
372  %next = mul nuw i8 %A, 2
373  %cmp1 = icmp eq i8 %A, %n
374  br i1 %cmp1, label %exit, label %loop
375exit:
376  %cmp = icmp eq i8 %A, 0
377  ret i1 %cmp
378}
379
380define i1 @test_shl_nuw(i8 %n) {
381; CHECK-LABEL: @test_shl_nuw(
382; CHECK-NEXT:  entry:
383; CHECK-NEXT:    br label [[LOOP:%.*]]
384; CHECK:       loop:
385; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 1, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
386; CHECK-NEXT:    [[NEXT]] = shl nuw i8 [[A]], 1
387; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
388; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
389; CHECK:       exit:
390; CHECK-NEXT:    ret i1 false
391;
392entry:
393  br label %loop
394loop:
395  %A = phi i8 [ 1, %entry ], [ %next, %loop ]
396  %next = shl nuw i8 %A, 1
397  %cmp1 = icmp eq i8 %A, %n
398  br i1 %cmp1, label %exit, label %loop
399exit:
400  %cmp = icmp eq i8 %A, 0
401  ret i1 %cmp
402}
403
404define i1 @test_shl_nsw(i8 %n) {
405; CHECK-LABEL: @test_shl_nsw(
406; CHECK-NEXT:  entry:
407; CHECK-NEXT:    br label [[LOOP:%.*]]
408; CHECK:       loop:
409; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 1, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
410; CHECK-NEXT:    [[NEXT]] = shl nsw i8 [[A]], 1
411; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
412; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
413; CHECK:       exit:
414; CHECK-NEXT:    ret i1 false
415;
416entry:
417  br label %loop
418loop:
419  %A = phi i8 [ 1, %entry ], [ %next, %loop ]
420  %next = shl nsw i8 %A, 1
421  %cmp1 = icmp eq i8 %A, %n
422  br i1 %cmp1, label %exit, label %loop
423exit:
424  %cmp = icmp eq i8 %A, 0
425  ret i1 %cmp
426}
427
428define i1 @test_shl_dynamic_shift(i8 %n, i8 %shift) {
429; CHECK-LABEL: @test_shl_dynamic_shift(
430; CHECK-NEXT:  entry:
431; CHECK-NEXT:    br label [[LOOP:%.*]]
432; CHECK:       loop:
433; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 1, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
434; CHECK-NEXT:    [[NEXT]] = shl nuw i8 [[A]], [[SHIFT:%.*]]
435; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
436; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
437; CHECK:       exit:
438; CHECK-NEXT:    ret i1 false
439;
440entry:
441  br label %loop
442loop:
443  %A = phi i8 [ 1, %entry ], [ %next, %loop ]
444  %next = shl nuw i8 %A, %shift
445  %cmp1 = icmp eq i8 %A, %n
446  br i1 %cmp1, label %exit, label %loop
447exit:
448  %cmp = icmp eq i8 %A, 0
449  ret i1 %cmp
450}
451
452define i1 @test_shl_may_wrap(i8 %n) {
453; CHECK-LABEL: @test_shl_may_wrap(
454; CHECK-NEXT:  entry:
455; CHECK-NEXT:    br label [[LOOP:%.*]]
456; CHECK:       loop:
457; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 1, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
458; CHECK-NEXT:    [[NEXT]] = shl i8 [[A]], 1
459; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
460; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
461; CHECK:       exit:
462; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A]], 0
463; CHECK-NEXT:    ret i1 [[CMP]]
464;
465entry:
466  br label %loop
467loop:
468  %A = phi i8 [ 1, %entry ], [ %next, %loop ]
469  %next = shl i8 %A, 1
470  %cmp1 = icmp eq i8 %A, %n
471  br i1 %cmp1, label %exit, label %loop
472exit:
473  %cmp = icmp eq i8 %A, 0
474  ret i1 %cmp
475}
476
477define i1 @test_shl_zero_start(i8 %n) {
478; CHECK-LABEL: @test_shl_zero_start(
479; CHECK-NEXT:  entry:
480; CHECK-NEXT:    br label [[LOOP:%.*]]
481; CHECK:       loop:
482; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
483; CHECK-NEXT:    [[NEXT]] = shl nuw i8 [[A]], 1
484; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
485; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
486; CHECK:       exit:
487; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A]], 0
488; CHECK-NEXT:    ret i1 [[CMP]]
489;
490entry:
491  br label %loop
492loop:
493  %A = phi i8 [ 0, %entry ], [ %next, %loop ]
494  %next = shl nuw i8 %A, 1
495  %cmp1 = icmp eq i8 %A, %n
496  br i1 %cmp1, label %exit, label %loop
497exit:
498  %cmp = icmp eq i8 %A, 0
499  ret i1 %cmp
500}
501
502
503define i1 @test_lshr_exact(i8 %n) {
504; CHECK-LABEL: @test_lshr_exact(
505; CHECK-NEXT:  entry:
506; CHECK-NEXT:    br label [[LOOP:%.*]]
507; CHECK:       loop:
508; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 64, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
509; CHECK-NEXT:    [[NEXT]] = lshr exact i8 [[A]], 1
510; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
511; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
512; CHECK:       exit:
513; CHECK-NEXT:    ret i1 false
514;
515entry:
516  br label %loop
517loop:
518  %A = phi i8 [ 64, %entry ], [ %next, %loop ]
519  %next = lshr exact i8 %A, 1
520  %cmp1 = icmp eq i8 %A, %n
521  br i1 %cmp1, label %exit, label %loop
522exit:
523  %cmp = icmp eq i8 %A, 0
524  ret i1 %cmp
525}
526
527define i1 @test_lshr_may_wrap(i8 %n) {
528; CHECK-LABEL: @test_lshr_may_wrap(
529; CHECK-NEXT:  entry:
530; CHECK-NEXT:    br label [[LOOP:%.*]]
531; CHECK:       loop:
532; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 1, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
533; CHECK-NEXT:    [[NEXT]] = lshr i8 [[A]], 1
534; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
535; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
536; CHECK:       exit:
537; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A]], 0
538; CHECK-NEXT:    ret i1 [[CMP]]
539;
540entry:
541  br label %loop
542loop:
543  %A = phi i8 [ 1, %entry ], [ %next, %loop ]
544  %next = lshr i8 %A, 1
545  %cmp1 = icmp eq i8 %A, %n
546  br i1 %cmp1, label %exit, label %loop
547exit:
548  %cmp = icmp eq i8 %A, 0
549  ret i1 %cmp
550}
551
552define i1 @test_lshr_zero_start(i8 %n) {
553; CHECK-LABEL: @test_lshr_zero_start(
554; CHECK-NEXT:  entry:
555; CHECK-NEXT:    br label [[LOOP:%.*]]
556; CHECK:       loop:
557; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
558; CHECK-NEXT:    [[NEXT]] = lshr exact i8 [[A]], 1
559; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
560; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
561; CHECK:       exit:
562; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A]], 0
563; CHECK-NEXT:    ret i1 [[CMP]]
564;
565entry:
566  br label %loop
567loop:
568  %A = phi i8 [ 0, %entry ], [ %next, %loop ]
569  %next = lshr exact i8 %A, 1
570  %cmp1 = icmp eq i8 %A, %n
571  br i1 %cmp1, label %exit, label %loop
572exit:
573  %cmp = icmp eq i8 %A, 0
574  ret i1 %cmp
575}
576
577define i1 @test_ashr_exact(i8 %n) {
578; CHECK-LABEL: @test_ashr_exact(
579; CHECK-NEXT:  entry:
580; CHECK-NEXT:    br label [[LOOP:%.*]]
581; CHECK:       loop:
582; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 64, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
583; CHECK-NEXT:    [[NEXT]] = ashr exact i8 [[A]], 1
584; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
585; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
586; CHECK:       exit:
587; CHECK-NEXT:    ret i1 false
588;
589entry:
590  br label %loop
591loop:
592  %A = phi i8 [ 64, %entry ], [ %next, %loop ]
593  %next = ashr exact i8 %A, 1
594  %cmp1 = icmp eq i8 %A, %n
595  br i1 %cmp1, label %exit, label %loop
596exit:
597  %cmp = icmp eq i8 %A, 0
598  ret i1 %cmp
599}
600
601define i1 @test_ashr_may_wrap(i8 %n) {
602; CHECK-LABEL: @test_ashr_may_wrap(
603; CHECK-NEXT:  entry:
604; CHECK-NEXT:    br label [[LOOP:%.*]]
605; CHECK:       loop:
606; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 1, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
607; CHECK-NEXT:    [[NEXT]] = ashr i8 [[A]], 1
608; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
609; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
610; CHECK:       exit:
611; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A]], 0
612; CHECK-NEXT:    ret i1 [[CMP]]
613;
614entry:
615  br label %loop
616loop:
617  %A = phi i8 [ 1, %entry ], [ %next, %loop ]
618  %next = ashr i8 %A, 1
619  %cmp1 = icmp eq i8 %A, %n
620  br i1 %cmp1, label %exit, label %loop
621exit:
622  %cmp = icmp eq i8 %A, 0
623  ret i1 %cmp
624}
625
626define i1 @test_ashr_zero_start(i8 %n) {
627; CHECK-LABEL: @test_ashr_zero_start(
628; CHECK-NEXT:  entry:
629; CHECK-NEXT:    br label [[LOOP:%.*]]
630; CHECK:       loop:
631; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
632; CHECK-NEXT:    [[NEXT]] = ashr exact i8 [[A]], 1
633; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
634; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
635; CHECK:       exit:
636; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A]], 0
637; CHECK-NEXT:    ret i1 [[CMP]]
638;
639entry:
640  br label %loop
641loop:
642  %A = phi i8 [ 0, %entry ], [ %next, %loop ]
643  %next = ashr exact i8 %A, 1
644  %cmp1 = icmp eq i8 %A, %n
645  br i1 %cmp1, label %exit, label %loop
646exit:
647  %cmp = icmp eq i8 %A, 0
648  ret i1 %cmp
649}
650