[Coverage] MCDC: Move findIndependencePairs deferred into MCDCRecord (#121188)
[llvm-project.git] / llvm / test / Analysis / ValueTracking / monotonic-phi.ll
blobd55d2ed3d114ff1fedd53f9db0d93f71d9c49000
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=instsimplify -S < %s | FileCheck %s
4 define 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
16 entry:
17   br label %loop
18 loop:
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
23 exit:
24   %add = or i8 %A, %r
25   %cmp = icmp eq i8 %add, 0
26   ret i1 %cmp
29 define 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]]
43 entry:
44   br label %loop
45 loop:
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
50 exit:
51   %add = or i8 %A, %r
52   %cmp = icmp eq i8 %add, 0
53   ret i1 %cmp
56 define 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
68 entry:
69   br label %loop
70 loop:
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
75 exit:
76   %add = or i8 %A, %r
77   %cmp = icmp eq i8 %add, 0
78   ret i1 %cmp
81 define 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
93 entry:
94   br label %loop
95 loop:
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
100 exit:
101   %add = or i8 %A, %r
102   %cmp = icmp eq i8 %add, 0
103   ret i1 %cmp
106 define 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]]
120 entry:
121   br label %loop
122 loop:
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
127 exit:
128   %add = or i8 %A, %r
129   %cmp = icmp eq i8 %add, 0
130   ret i1 %cmp
133 define 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
145 entry:
146   br label %loop
147 loop:
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
152 exit:
153   %add = or i8 %A, %r
154   %cmp = icmp eq i8 %add, 0
155   ret i1 %cmp
158 define 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]]
172 entry:
173   br label %loop
174 loop:
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
179 exit:
180   %add = or i8 %A, %r
181   %cmp = icmp eq i8 %add, 0
182   ret i1 %cmp
185 define 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
197 entry:
198   br label %loop
199 loop:
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
204 exit:
205   %add = or i8 %A, %r
206   %cmp = icmp eq i8 %add, 0
207   ret i1 %cmp
210 define 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
222 entry:
223   br label %loop
224 loop:
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
229 exit:
230   %cmp = icmp eq i8 %A, 0
231   ret i1 %cmp
234 define 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]]
247 entry:
248   br label %loop
249 loop:
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
254 exit:
255   %cmp = icmp eq i8 %A, 0
256   ret i1 %cmp
259 define 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
271 entry:
272   br label %loop
273 loop:
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
278 exit:
279   %cmp = icmp eq i8 %A, 0
280   ret i1 %cmp
283 define 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]]
296 entry:
297   br label %loop
298 loop:
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
303 exit:
304   %cmp = icmp eq i8 %A, 0
305   ret i1 %cmp
308 define 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
320 entry:
321   br label %loop
322 loop:
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
327 exit:
328   %cmp = icmp eq i8 %A, 0
329   ret i1 %cmp
332 define 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
344 entry:
345   br label %loop
346 loop:
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
351 exit:
352   %cmp = icmp eq i8 %A, 0
353   ret i1 %cmp
356 define 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
368 entry:
369   br label %loop
370 loop:
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
375 exit:
376   %cmp = icmp eq i8 %A, 0
377   ret i1 %cmp
380 define 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
392 entry:
393   br label %loop
394 loop:
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
399 exit:
400   %cmp = icmp eq i8 %A, 0
401   ret i1 %cmp
404 define 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
416 entry:
417   br label %loop
418 loop:
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
423 exit:
424   %cmp = icmp eq i8 %A, 0
425   ret i1 %cmp
428 define 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
440 entry:
441   br label %loop
442 loop:
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
447 exit:
448   %cmp = icmp eq i8 %A, 0
449   ret i1 %cmp
452 define 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]]
465 entry:
466   br label %loop
467 loop:
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
472 exit:
473   %cmp = icmp eq i8 %A, 0
474   ret i1 %cmp
477 define 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]]
490 entry:
491   br label %loop
492 loop:
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
497 exit:
498   %cmp = icmp eq i8 %A, 0
499   ret i1 %cmp
503 define 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
515 entry:
516   br label %loop
517 loop:
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
522 exit:
523   %cmp = icmp eq i8 %A, 0
524   ret i1 %cmp
527 define 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]]
540 entry:
541   br label %loop
542 loop:
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
547 exit:
548   %cmp = icmp eq i8 %A, 0
549   ret i1 %cmp
552 define 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]]
565 entry:
566   br label %loop
567 loop:
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
572 exit:
573   %cmp = icmp eq i8 %A, 0
574   ret i1 %cmp
577 define 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
589 entry:
590   br label %loop
591 loop:
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
596 exit:
597   %cmp = icmp eq i8 %A, 0
598   ret i1 %cmp
601 define 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]]
614 entry:
615   br label %loop
616 loop:
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
621 exit:
622   %cmp = icmp eq i8 %A, 0
623   ret i1 %cmp
626 define 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]]
639 entry:
640   br label %loop
641 loop:
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
646 exit:
647   %cmp = icmp eq i8 %A, 0
648   ret i1 %cmp