xref: /llvm-project/llvm/test/Analysis/ValueTracking/known-non-equal.ll (revision 3b7f6fd26d3efe28da1ae6af6cde9aa80bc92a2c)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -instsimplify < %s -S | FileCheck %s
3
4define i1 @test(i8* %pq, i8 %B) {
5; CHECK-LABEL: @test(
6; CHECK-NEXT:    ret i1 false
7;
8  %q = load i8, i8* %pq, !range !0 ; %q is known nonzero; no known bits
9  %A = add nsw i8 %B, %q
10  %cmp = icmp eq i8 %A, %B
11  ret i1 %cmp
12}
13
14define i1 @test2(i8 %a, i8 %b) {
15; CHECK-LABEL: @test2(
16; CHECK-NEXT:    ret i1 false
17;
18  %A = or i8 %a, 2    ; %A[1] = 1
19  %B = and i8 %b, -3  ; %B[1] = 0
20  %cmp = icmp eq i8 %A, %B ; %A[1] and %B[1] are contradictory.
21  ret i1 %cmp
22}
23
24define i1 @test3(i8 %B) {
25; CHECK-LABEL: @test3(
26; CHECK-NEXT:    ret i1 false
27;
28  %A = add nsw i8 %B, 1
29  %cmp = icmp eq i8 %A, %B
30  ret i1 %cmp
31}
32
33define i1 @sext(i8 %B) {
34; CHECK-LABEL: @sext(
35; CHECK-NEXT:    ret i1 false
36;
37  %A = add nsw i8 %B, 1
38  %A.cast = sext i8 %A to i32
39  %B.cast = sext i8 %B to i32
40  %cmp = icmp eq i32 %A.cast, %B.cast
41  ret i1 %cmp
42}
43
44define i1 @zext(i8 %B) {
45; CHECK-LABEL: @zext(
46; CHECK-NEXT:    ret i1 false
47;
48  %A = add nsw i8 %B, 1
49  %A.cast = zext i8 %A to i32
50  %B.cast = zext i8 %B to i32
51  %cmp = icmp eq i32 %A.cast, %B.cast
52  ret i1 %cmp
53}
54
55define i1 @inttoptr(i32 %B) {
56; CHECK-LABEL: @inttoptr(
57; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[B:%.*]], 1
58; CHECK-NEXT:    [[A_CAST:%.*]] = inttoptr i32 [[A]] to i8*
59; CHECK-NEXT:    [[B_CAST:%.*]] = inttoptr i32 [[B]] to i8*
60; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8* [[A_CAST]], [[B_CAST]]
61; CHECK-NEXT:    ret i1 [[CMP]]
62;
63  %A = add nsw i32 %B, 1
64  %A.cast = inttoptr i32 %A to i8*
65  %B.cast = inttoptr i32 %B to i8*
66  %cmp = icmp eq i8* %A.cast, %B.cast
67  ret i1 %cmp
68}
69
70define i1 @ptrtoint(i32* %B) {
71; CHECK-LABEL: @ptrtoint(
72; CHECK-NEXT:    [[A:%.*]] = getelementptr inbounds i32, i32* [[B:%.*]], i32 1
73; CHECK-NEXT:    [[A_CAST:%.*]] = ptrtoint i32* [[A]] to i32
74; CHECK-NEXT:    [[B_CAST:%.*]] = ptrtoint i32* [[B]] to i32
75; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A_CAST]], [[B_CAST]]
76; CHECK-NEXT:    ret i1 [[CMP]]
77;
78  %A = getelementptr inbounds i32, i32* %B, i32 1
79  %A.cast = ptrtoint i32* %A to i32
80  %B.cast = ptrtoint i32* %B to i32
81  %cmp = icmp eq i32 %A.cast, %B.cast
82  ret i1 %cmp
83}
84
85define i1 @add1(i8 %B, i8 %C) {
86; CHECK-LABEL: @add1(
87; CHECK-NEXT:    ret i1 false
88;
89  %A = add i8 %B, 1
90  %A.op = add i8 %A, %C
91  %B.op = add i8 %B, %C
92
93  %cmp = icmp eq i8 %A.op, %B.op
94  ret i1 %cmp
95}
96
97define i1 @add2(i8 %B, i8 %C) {
98; CHECK-LABEL: @add2(
99; CHECK-NEXT:    ret i1 false
100;
101  %A = add i8 %B, 1
102  %A.op = add i8 %C, %A
103  %B.op = add i8 %C, %B
104
105  %cmp = icmp eq i8 %A.op, %B.op
106  ret i1 %cmp
107}
108
109define i1 @sub1(i8 %B, i8 %C) {
110; CHECK-LABEL: @sub1(
111; CHECK-NEXT:    ret i1 false
112;
113  %A = add i8 %B, 1
114  %A.op = sub i8 %A, %C
115  %B.op = sub i8 %B, %C
116
117  %cmp = icmp eq i8 %A.op, %B.op
118  ret i1 %cmp
119}
120
121define i1 @sub2(i8 %B, i8 %C) {
122; CHECK-LABEL: @sub2(
123; CHECK-NEXT:    ret i1 false
124;
125  %A = add i8 %B, 1
126  %A.op = sub i8 %C, %A
127  %B.op = sub i8 %C, %B
128
129  %cmp = icmp eq i8 %A.op, %B.op
130  ret i1 %cmp
131}
132
133; op could wrap mapping two values to the same output value.
134define i1 @mul1(i8 %B) {
135; CHECK-LABEL: @mul1(
136; CHECK-NEXT:    [[A:%.*]] = add i8 [[B:%.*]], 1
137; CHECK-NEXT:    [[A_OP:%.*]] = mul i8 [[A]], 27
138; CHECK-NEXT:    [[B_OP:%.*]] = mul i8 [[B]], 27
139; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A_OP]], [[B_OP]]
140; CHECK-NEXT:    ret i1 [[CMP]]
141;
142  %A = add i8 %B, 1
143  %A.op = mul i8 %A, 27
144  %B.op = mul i8 %B, 27
145
146  %cmp = icmp eq i8 %A.op, %B.op
147  ret i1 %cmp
148}
149
150define i1 @mul2(i8 %B) {
151; CHECK-LABEL: @mul2(
152; CHECK-NEXT:    ret i1 false
153;
154  %A = add i8 %B, 1
155  %A.op = mul nuw i8 %A, 27
156  %B.op = mul nuw i8 %B, 27
157
158  %cmp = icmp eq i8 %A.op, %B.op
159  ret i1 %cmp
160}
161
162define i1 @mul3(i8 %B) {
163; CHECK-LABEL: @mul3(
164; CHECK-NEXT:    ret i1 false
165;
166  %A = add i8 %B, 1
167  %A.op = mul nsw i8 %A, 27
168  %B.op = mul nsw i8 %B, 27
169
170  %cmp = icmp eq i8 %A.op, %B.op
171  ret i1 %cmp
172}
173
174; Multiply by zero collapses all values to one
175define i1 @mul4(i8 %B) {
176; CHECK-LABEL: @mul4(
177; CHECK-NEXT:    ret i1 true
178;
179  %A = add i8 %B, 1
180  %A.op = mul nuw i8 %A, 0
181  %B.op = mul nuw i8 %B, 0
182
183  %cmp = icmp eq i8 %A.op, %B.op
184  ret i1 %cmp
185}
186
187; C might be zero, we can't tell
188define i1 @mul5(i8 %B, i8 %C) {
189; CHECK-LABEL: @mul5(
190; CHECK-NEXT:    [[A:%.*]] = add i8 [[B:%.*]], 1
191; CHECK-NEXT:    [[A_OP:%.*]] = mul nuw nsw i8 [[A]], [[C:%.*]]
192; CHECK-NEXT:    [[B_OP:%.*]] = mul nuw nsw i8 [[B]], [[C]]
193; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A_OP]], [[B_OP]]
194; CHECK-NEXT:    ret i1 [[CMP]]
195;
196  %A = add i8 %B, 1
197  %A.op = mul nsw nuw i8 %A, %C
198  %B.op = mul nsw nuw i8 %B, %C
199
200  %cmp = icmp eq i8 %A.op, %B.op
201  ret i1 %cmp
202}
203
204@g = external global i16, align 1
205
206define i1 @mul_constantexpr(i16 %a) {
207; CHECK-LABEL: @mul_constantexpr(
208; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i16 [[A:%.*]], 3
209; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i16 mul nsw (i16 ptrtoint (i16* @g to i16), i16 -1), [[MUL]]
210; CHECK-NEXT:    ret i1 [[CMP]]
211;
212  %mul = mul nsw i16 %a, 3
213  %cmp = icmp eq i16 mul nsw (i16 ptrtoint (i16* @g to i16), i16 -1), %mul
214  ret i1 %cmp
215}
216
217define i1 @mul_nuw(i16 %x) {
218; CHECK-LABEL: @mul_nuw(
219; CHECK-NEXT:    ret i1 false
220;
221  %nz = or i16 %x, 2
222  %mul = mul nuw i16 %nz, 2
223  %cmp = icmp eq i16 %nz, %mul
224  ret i1 %cmp
225}
226
227define i1 @mul_nuw_comm(i16 %x) {
228; CHECK-LABEL: @mul_nuw_comm(
229; CHECK-NEXT:    ret i1 false
230;
231  %nz = or i16 %x, 2
232  %mul = mul nuw i16 %nz, 2
233  %cmp = icmp eq i16 %mul, %nz
234  ret i1 %cmp
235}
236
237define i1 @mul_nsw(i16 %x) {
238; CHECK-LABEL: @mul_nsw(
239; CHECK-NEXT:    ret i1 false
240;
241  %nz = or i16 %x, 2
242  %mul = mul nsw i16 %nz, 2
243  %cmp = icmp eq i16 %nz, %mul
244  ret i1 %cmp
245}
246
247define i1 @mul_nsw_comm(i16 %x) {
248; CHECK-LABEL: @mul_nsw_comm(
249; CHECK-NEXT:    ret i1 false
250;
251  %nz = or i16 %x, 2
252  %mul = mul nsw i16 %nz, 2
253  %cmp = icmp eq i16 %mul, %nz
254  ret i1 %cmp
255}
256
257define i1 @mul_may_wrap(i16 %x) {
258; CHECK-LABEL: @mul_may_wrap(
259; CHECK-NEXT:    [[NZ:%.*]] = or i16 [[X:%.*]], 2
260; CHECK-NEXT:    [[MUL:%.*]] = mul i16 [[NZ]], 2
261; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i16 [[NZ]], [[MUL]]
262; CHECK-NEXT:    ret i1 [[CMP]]
263;
264  %nz = or i16 %x, 2
265  %mul = mul i16 %nz, 2
266  %cmp = icmp eq i16 %nz, %mul
267  ret i1 %cmp
268}
269
270define i1 @mul_may_be_zero(i16 %x) {
271; CHECK-LABEL: @mul_may_be_zero(
272; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i16 [[X:%.*]], 2
273; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i16 [[X]], [[MUL]]
274; CHECK-NEXT:    ret i1 [[CMP]]
275;
276  %mul = mul nuw i16 %x, 2
277  %cmp = icmp eq i16 %x, %mul
278  ret i1 %cmp
279}
280
281define i1 @mul_other_may_be_zero_or_one(i16 %x, i16 %y) {
282; CHECK-LABEL: @mul_other_may_be_zero_or_one(
283; CHECK-NEXT:    [[NZ:%.*]] = or i16 [[X:%.*]], 2
284; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i16 [[NZ]], [[Y:%.*]]
285; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i16 [[NZ]], [[MUL]]
286; CHECK-NEXT:    ret i1 [[CMP]]
287;
288  %nz = or i16 %x, 2
289  %mul = mul nuw i16 %nz, %y
290  %cmp = icmp eq i16 %nz, %mul
291  ret i1 %cmp
292}
293
294define i1 @known_non_equal_phis(i8 %p, i8* %pq, i8 %n, i8 %r) {
295; CHECK-LABEL: @known_non_equal_phis(
296; CHECK-NEXT:  entry:
297; CHECK-NEXT:    br label [[LOOP:%.*]]
298; CHECK:       loop:
299; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 2, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
300; CHECK-NEXT:    [[NEXT]] = mul nsw i8 [[A]], 2
301; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
302; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
303; CHECK:       exit:
304; CHECK-NEXT:    ret i1 true
305;
306entry:
307  br label %loop
308loop:
309  %A = phi i8 [ 2, %entry ], [ %next, %loop ]
310  %B = phi i8 [ 3, %entry ], [ %A, %loop ]
311  %next = mul nsw i8 %A, 2
312  %cmp1 = icmp eq i8 %A, %n
313  br i1 %cmp1, label %exit, label %loop
314exit:
315  %cmp = icmp ne i8 %A, %B
316  ret i1 %cmp
317}
318
319define i1 @known_non_equal_phis_fail(i8 %p, i8* %pq, i8 %n, i8 %r) {
320; CHECK-LABEL: @known_non_equal_phis_fail(
321; CHECK-NEXT:  entry:
322; CHECK-NEXT:    br label [[LOOP:%.*]]
323; CHECK:       loop:
324; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 2, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
325; CHECK-NEXT:    [[B:%.*]] = phi i8 [ 2, [[ENTRY]] ], [ [[A]], [[LOOP]] ]
326; CHECK-NEXT:    [[NEXT]] = mul nsw i8 [[A]], 2
327; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
328; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
329; CHECK:       exit:
330; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[A]], [[B]]
331; CHECK-NEXT:    ret i1 [[CMP]]
332;
333entry:
334  br label %loop
335loop:
336  %A = phi i8 [ 2, %entry ], [ %next, %loop ]
337  %B = phi i8 [ 2, %entry ], [ %A, %loop ]
338  %next = mul nsw i8 %A, 2
339  %cmp1 = icmp eq i8 %A, %n
340  br i1 %cmp1, label %exit, label %loop
341exit:
342  %cmp = icmp ne i8 %A, %B
343  ret i1 %cmp
344}
345
346define i1 @shl_nuw(i16 %x) {
347; CHECK-LABEL: @shl_nuw(
348; CHECK-NEXT:    ret i1 false
349;
350  %nz = or i16 %x, 2
351  %mul = shl nuw i16 %nz, 1
352  %cmp = icmp eq i16 %nz, %mul
353  ret i1 %cmp
354}
355
356define i1 @shl_nsw(i16 %x) {
357; CHECK-LABEL: @shl_nsw(
358; CHECK-NEXT:    ret i1 false
359;
360  %nz = or i16 %x, 2
361  %mul = shl nsw i16 %nz, 1
362  %cmp = icmp eq i16 %nz, %mul
363  ret i1 %cmp
364}
365
366define i1 @shl_may_wrap(i16 %x) {
367; CHECK-LABEL: @shl_may_wrap(
368; CHECK-NEXT:    [[NZ:%.*]] = or i16 [[X:%.*]], 2
369; CHECK-NEXT:    [[MUL:%.*]] = shl i16 [[NZ]], 1
370; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i16 [[NZ]], [[MUL]]
371; CHECK-NEXT:    ret i1 [[CMP]]
372;
373  %nz = or i16 %x, 2
374  %mul = shl i16 %nz, 1
375  %cmp = icmp eq i16 %nz, %mul
376  ret i1 %cmp
377}
378
379define i1 @shl_shift_may_be_zero(i16 %x, i16 %shift) {
380; CHECK-LABEL: @shl_shift_may_be_zero(
381; CHECK-NEXT:    [[NZ:%.*]] = or i16 [[X:%.*]], 2
382; CHECK-NEXT:    [[MUL:%.*]] = shl nuw i16 [[NZ]], [[SHIFT:%.*]]
383; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i16 [[NZ]], [[MUL]]
384; CHECK-NEXT:    ret i1 [[CMP]]
385;
386  %nz = or i16 %x, 2
387  %mul = shl nuw i16 %nz, %shift
388  %cmp = icmp eq i16 %nz, %mul
389  ret i1 %cmp
390}
391
392define i1 @shl_op_may_be_zero(i16 %x) {
393; CHECK-LABEL: @shl_op_may_be_zero(
394; CHECK-NEXT:    [[MUL:%.*]] = shl nuw i16 [[X:%.*]], 1
395; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i16 [[X]], [[MUL]]
396; CHECK-NEXT:    ret i1 [[CMP]]
397;
398  %mul = shl nuw i16 %x, 1
399  %cmp = icmp eq i16 %x, %mul
400  ret i1 %cmp
401}
402
403; The additional muls in these tests are necessary to actually
404; test the isKnownNonEqual() code, rather than InstSimplify's own
405; comparison folding.
406
407define i1 @shl_shl_nuw(i8 %B, i8 %shift) {
408; CHECK-LABEL: @shl_shl_nuw(
409; CHECK-NEXT:    ret i1 false
410;
411  %A = add i8 %B, 1
412  %A.op = shl nuw i8 %A, %shift
413  %B.op = shl nuw i8 %B, %shift
414  %A.op2 = mul nuw i8 %A.op, 3
415  %B.op2 = mul nuw i8 %B.op, 3
416  %cmp = icmp eq i8 %A.op2, %B.op2
417  ret i1 %cmp
418}
419
420define i1 @shl_shl_nsw(i8 %B, i8 %shift) {
421; CHECK-LABEL: @shl_shl_nsw(
422; CHECK-NEXT:    ret i1 false
423;
424  %A = add i8 %B, 1
425  %A.op = shl nsw i8 %A, %shift
426  %B.op = shl nsw i8 %B, %shift
427  %A.op2 = mul nuw i8 %A.op, 3
428  %B.op2 = mul nuw i8 %B.op, 3
429  %cmp = icmp eq i8 %A.op2, %B.op2
430  ret i1 %cmp
431}
432
433define i1 @shl_shl_may_wrap(i8 %B, i8 %shift) {
434; CHECK-LABEL: @shl_shl_may_wrap(
435; CHECK-NEXT:    [[A:%.*]] = add i8 [[B:%.*]], 1
436; CHECK-NEXT:    [[A_OP:%.*]] = shl i8 [[A]], [[SHIFT:%.*]]
437; CHECK-NEXT:    [[B_OP:%.*]] = shl nsw i8 [[B]], [[SHIFT]]
438; CHECK-NEXT:    [[A_OP2:%.*]] = mul nuw i8 [[A_OP]], 3
439; CHECK-NEXT:    [[B_OP2:%.*]] = mul nuw i8 [[B_OP]], 3
440; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A_OP2]], [[B_OP2]]
441; CHECK-NEXT:    ret i1 [[CMP]]
442;
443  %A = add i8 %B, 1
444  %A.op = shl i8 %A, %shift
445  %B.op = shl nsw i8 %B, %shift
446  %A.op2 = mul nuw i8 %A.op, 3
447  %B.op2 = mul nuw i8 %B.op, 3
448  %cmp = icmp eq i8 %A.op2, %B.op2
449  ret i1 %cmp
450}
451
452define i1 @shl_shl_mixed_wrap(i8 %B, i8 %shift) {
453; CHECK-LABEL: @shl_shl_mixed_wrap(
454; CHECK-NEXT:    [[A:%.*]] = add i8 [[B:%.*]], 1
455; CHECK-NEXT:    [[A_OP:%.*]] = shl nuw i8 [[A]], [[SHIFT:%.*]]
456; CHECK-NEXT:    [[B_OP:%.*]] = shl nsw i8 [[B]], [[SHIFT]]
457; CHECK-NEXT:    [[A_OP2:%.*]] = mul nuw i8 [[A_OP]], 3
458; CHECK-NEXT:    [[B_OP2:%.*]] = mul nuw i8 [[B_OP]], 3
459; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A_OP2]], [[B_OP2]]
460; CHECK-NEXT:    ret i1 [[CMP]]
461;
462  %A = add i8 %B, 1
463  %A.op = shl nuw i8 %A, %shift
464  %B.op = shl nsw i8 %B, %shift
465  %A.op2 = mul nuw i8 %A.op, 3
466  %B.op2 = mul nuw i8 %B.op, 3
467  %cmp = icmp eq i8 %A.op2, %B.op2
468  ret i1 %cmp
469}
470
471define i1 @shl_shl_may_be_equal(i8 %A, i8 %B, i8 %shift) {
472; CHECK-LABEL: @shl_shl_may_be_equal(
473; CHECK-NEXT:    [[A_OP:%.*]] = shl nuw i8 [[A:%.*]], [[SHIFT:%.*]]
474; CHECK-NEXT:    [[B_OP:%.*]] = shl nuw i8 [[B:%.*]], [[SHIFT]]
475; CHECK-NEXT:    [[A_OP2:%.*]] = mul nuw i8 [[A_OP]], 3
476; CHECK-NEXT:    [[B_OP2:%.*]] = mul nuw i8 [[B_OP]], 3
477; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A_OP2]], [[B_OP2]]
478; CHECK-NEXT:    ret i1 [[CMP]]
479;
480  %A.op = shl nuw i8 %A, %shift
481  %B.op = shl nuw i8 %B, %shift
482  %A.op2 = mul nuw i8 %A.op, 3
483  %B.op2 = mul nuw i8 %B.op, 3
484  %cmp = icmp eq i8 %A.op2, %B.op2
485  ret i1 %cmp
486}
487
488define i1 @ashr_ashr_exact(i8 %B, i8 %shift) {
489; CHECK-LABEL: @ashr_ashr_exact(
490; CHECK-NEXT:    ret i1 false
491;
492  %A = add i8 %B, 1
493  %A.op = ashr exact i8 %A, %shift
494  %B.op = ashr exact i8 %B, %shift
495  %A.op2 = mul nuw i8 %A.op, 3
496  %B.op2 = mul nuw i8 %B.op, 3
497  %cmp = icmp eq i8 %A.op2, %B.op2
498  ret i1 %cmp
499}
500
501define i1 @ashr_ashr_discard_bits(i8 %B, i8 %shift) {
502; CHECK-LABEL: @ashr_ashr_discard_bits(
503; CHECK-NEXT:    [[A:%.*]] = add i8 [[B:%.*]], 1
504; CHECK-NEXT:    [[A_OP:%.*]] = ashr i8 [[A]], [[SHIFT:%.*]]
505; CHECK-NEXT:    [[B_OP:%.*]] = ashr exact i8 [[B]], [[SHIFT]]
506; CHECK-NEXT:    [[A_OP2:%.*]] = mul nuw i8 [[A_OP]], 3
507; CHECK-NEXT:    [[B_OP2:%.*]] = mul nuw i8 [[B_OP]], 3
508; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A_OP2]], [[B_OP2]]
509; CHECK-NEXT:    ret i1 [[CMP]]
510;
511  %A = add i8 %B, 1
512  %A.op = ashr i8 %A, %shift
513  %B.op = ashr exact i8 %B, %shift
514  %A.op2 = mul nuw i8 %A.op, 3
515  %B.op2 = mul nuw i8 %B.op, 3
516  %cmp = icmp eq i8 %A.op2, %B.op2
517  ret i1 %cmp
518}
519
520define i1 @ashr_ashr_may_be_equal(i8 %A, i8 %B, i8 %shift) {
521; CHECK-LABEL: @ashr_ashr_may_be_equal(
522; CHECK-NEXT:    [[A_OP:%.*]] = ashr exact i8 [[A:%.*]], [[SHIFT:%.*]]
523; CHECK-NEXT:    [[B_OP:%.*]] = ashr exact i8 [[B:%.*]], [[SHIFT]]
524; CHECK-NEXT:    [[A_OP2:%.*]] = mul nuw i8 [[A_OP]], 3
525; CHECK-NEXT:    [[B_OP2:%.*]] = mul nuw i8 [[B_OP]], 3
526; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A_OP2]], [[B_OP2]]
527; CHECK-NEXT:    ret i1 [[CMP]]
528;
529  %A.op = ashr exact i8 %A, %shift
530  %B.op = ashr exact i8 %B, %shift
531  %A.op2 = mul nuw i8 %A.op, 3
532  %B.op2 = mul nuw i8 %B.op, 3
533  %cmp = icmp eq i8 %A.op2, %B.op2
534  ret i1 %cmp
535}
536
537define i1 @lshr_lshr_exact(i8 %B, i8 %shift) {
538; CHECK-LABEL: @lshr_lshr_exact(
539; CHECK-NEXT:    ret i1 false
540;
541  %A = add i8 %B, 1
542  %A.op = lshr exact i8 %A, %shift
543  %B.op = lshr exact i8 %B, %shift
544  %A.op2 = mul nuw i8 %A.op, 3
545  %B.op2 = mul nuw i8 %B.op, 3
546  %cmp = icmp eq i8 %A.op2, %B.op2
547  ret i1 %cmp
548}
549
550define i1 @lshr_lshr_discard_bits(i8 %B, i8 %shift) {
551; CHECK-LABEL: @lshr_lshr_discard_bits(
552; CHECK-NEXT:    [[A:%.*]] = add i8 [[B:%.*]], 1
553; CHECK-NEXT:    [[A_OP:%.*]] = lshr i8 [[A]], [[SHIFT:%.*]]
554; CHECK-NEXT:    [[B_OP:%.*]] = lshr exact i8 [[B]], [[SHIFT]]
555; CHECK-NEXT:    [[A_OP2:%.*]] = mul nuw i8 [[A_OP]], 3
556; CHECK-NEXT:    [[B_OP2:%.*]] = mul nuw i8 [[B_OP]], 3
557; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A_OP2]], [[B_OP2]]
558; CHECK-NEXT:    ret i1 [[CMP]]
559;
560  %A = add i8 %B, 1
561  %A.op = lshr i8 %A, %shift
562  %B.op = lshr exact i8 %B, %shift
563  %A.op2 = mul nuw i8 %A.op, 3
564  %B.op2 = mul nuw i8 %B.op, 3
565  %cmp = icmp eq i8 %A.op2, %B.op2
566  ret i1 %cmp
567}
568
569define i1 @lshr_lshr_may_be_equal(i8 %A, i8 %B, i8 %shift) {
570; CHECK-LABEL: @lshr_lshr_may_be_equal(
571; CHECK-NEXT:    [[A_OP:%.*]] = lshr exact i8 [[A:%.*]], [[SHIFT:%.*]]
572; CHECK-NEXT:    [[B_OP:%.*]] = lshr exact i8 [[B:%.*]], [[SHIFT]]
573; CHECK-NEXT:    [[A_OP2:%.*]] = mul nuw i8 [[A_OP]], 3
574; CHECK-NEXT:    [[B_OP2:%.*]] = mul nuw i8 [[B_OP]], 3
575; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A_OP2]], [[B_OP2]]
576; CHECK-NEXT:    ret i1 [[CMP]]
577;
578  %A.op = lshr exact i8 %A, %shift
579  %B.op = lshr exact i8 %B, %shift
580  %A.op2 = mul nuw i8 %A.op, 3
581  %B.op2 = mul nuw i8 %B.op, 3
582  %cmp = icmp eq i8 %A.op2, %B.op2
583  ret i1 %cmp
584}
585
586define i1 @recurrence_add_neq(i8 %A) {
587; CHECK-LABEL: @recurrence_add_neq(
588; CHECK-NEXT:  entry:
589; CHECK-NEXT:    [[B:%.*]] = add i8 [[A:%.*]], 1
590; CHECK-NEXT:    br label [[LOOP:%.*]]
591; CHECK:       loop:
592; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
593; CHECK-NEXT:    [[A_IV:%.*]] = phi i8 [ [[A]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
594; CHECK-NEXT:    [[B_IV:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
595; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
596; CHECK-NEXT:    [[A_IV_NEXT]] = add i8 [[A_IV]], 1
597; CHECK-NEXT:    [[B_IV_NEXT]] = add i8 [[B_IV]], 1
598; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
599; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
600; CHECK:       exit:
601; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
602; CHECK-NEXT:    ret i1 [[RES]]
603;
604entry:
605  %B = add i8 %A, 1
606  br label %loop
607loop:
608  %iv = phi i64 [0, %entry], [%iv.next, %loop]
609  %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
610  %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
611  %iv.next = add i64 %iv, 1
612  %A.iv.next = add i8 %A.iv, 1
613  %B.iv.next = add i8 %B.iv, 1
614  %cmp = icmp ne i64 %iv.next, 10
615  br i1 %cmp, label %loop, label %exit
616exit:
617  %res = icmp eq i8 %A.iv, %B.iv
618  ret i1 %res
619}
620
621define i1 @recurrence_add_eq(i8 %A) {
622; CHECK-LABEL: @recurrence_add_eq(
623; CHECK-NEXT:  entry:
624; CHECK-NEXT:    br label [[LOOP:%.*]]
625; CHECK:       loop:
626; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
627; CHECK-NEXT:    [[A_IV:%.*]] = phi i8 [ [[A:%.*]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
628; CHECK-NEXT:    [[B_IV:%.*]] = phi i8 [ [[A]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
629; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
630; CHECK-NEXT:    [[A_IV_NEXT]] = add i8 [[A_IV]], 1
631; CHECK-NEXT:    [[B_IV_NEXT]] = add i8 [[B_IV]], 1
632; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
633; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
634; CHECK:       exit:
635; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
636; CHECK-NEXT:    ret i1 [[RES]]
637;
638entry:
639  %B = add i8 %A, 0
640  br label %loop
641loop:
642  %iv = phi i64 [0, %entry], [%iv.next, %loop]
643  %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
644  %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
645  %iv.next = add i64 %iv, 1
646  %A.iv.next = add i8 %A.iv, 1
647  %B.iv.next = add i8 %B.iv, 1
648  %cmp = icmp ne i64 %iv.next, 10
649  br i1 %cmp, label %loop, label %exit
650exit:
651  %res = icmp eq i8 %A.iv, %B.iv
652  ret i1 %res
653}
654
655define i1 @recurrence_add_unknown(i8 %A, i8 %B) {
656; CHECK-LABEL: @recurrence_add_unknown(
657; CHECK-NEXT:  entry:
658; CHECK-NEXT:    br label [[LOOP:%.*]]
659; CHECK:       loop:
660; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
661; CHECK-NEXT:    [[A_IV:%.*]] = phi i8 [ [[A:%.*]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
662; CHECK-NEXT:    [[B_IV:%.*]] = phi i8 [ [[B:%.*]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
663; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
664; CHECK-NEXT:    [[A_IV_NEXT]] = add i8 [[A_IV]], 1
665; CHECK-NEXT:    [[B_IV_NEXT]] = add i8 [[B_IV]], 1
666; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
667; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
668; CHECK:       exit:
669; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
670; CHECK-NEXT:    ret i1 [[RES]]
671;
672entry:
673  br label %loop
674loop:
675  %iv = phi i64 [0, %entry], [%iv.next, %loop]
676  %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
677  %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
678  %iv.next = add i64 %iv, 1
679  %A.iv.next = add i8 %A.iv, 1
680  %B.iv.next = add i8 %B.iv, 1
681  %cmp = icmp ne i64 %iv.next, 10
682  br i1 %cmp, label %loop, label %exit
683exit:
684  %res = icmp eq i8 %A.iv, %B.iv
685  ret i1 %res
686}
687
688
689define i1 @recurrence_sub_neq(i8 %A) {
690; CHECK-LABEL: @recurrence_sub_neq(
691; CHECK-NEXT:  entry:
692; CHECK-NEXT:    [[B:%.*]] = add i8 [[A:%.*]], 1
693; CHECK-NEXT:    br label [[LOOP:%.*]]
694; CHECK:       loop:
695; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
696; CHECK-NEXT:    [[A_IV:%.*]] = phi i8 [ [[A]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
697; CHECK-NEXT:    [[B_IV:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
698; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
699; CHECK-NEXT:    [[A_IV_NEXT]] = sub i8 [[A_IV]], 1
700; CHECK-NEXT:    [[B_IV_NEXT]] = sub i8 [[B_IV]], 1
701; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
702; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
703; CHECK:       exit:
704; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
705; CHECK-NEXT:    ret i1 [[RES]]
706;
707entry:
708  %B = add i8 %A, 1
709  br label %loop
710loop:
711  %iv = phi i64 [0, %entry], [%iv.next, %loop]
712  %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
713  %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
714  %iv.next = add i64 %iv, 1
715  %A.iv.next = sub i8 %A.iv, 1
716  %B.iv.next = sub i8 %B.iv, 1
717  %cmp = icmp ne i64 %iv.next, 10
718  br i1 %cmp, label %loop, label %exit
719exit:
720  %res = icmp eq i8 %A.iv, %B.iv
721  ret i1 %res
722}
723
724define i1 @recurrence_sub_eq(i8 %A) {
725; CHECK-LABEL: @recurrence_sub_eq(
726; CHECK-NEXT:  entry:
727; CHECK-NEXT:    br label [[LOOP:%.*]]
728; CHECK:       loop:
729; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
730; CHECK-NEXT:    [[A_IV:%.*]] = phi i8 [ [[A:%.*]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
731; CHECK-NEXT:    [[B_IV:%.*]] = phi i8 [ [[A]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
732; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
733; CHECK-NEXT:    [[A_IV_NEXT]] = sub i8 [[A_IV]], 1
734; CHECK-NEXT:    [[B_IV_NEXT]] = sub i8 [[B_IV]], 1
735; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
736; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
737; CHECK:       exit:
738; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
739; CHECK-NEXT:    ret i1 [[RES]]
740;
741entry:
742  %B = add i8 %A, 0
743  br label %loop
744loop:
745  %iv = phi i64 [0, %entry], [%iv.next, %loop]
746  %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
747  %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
748  %iv.next = add i64 %iv, 1
749  %A.iv.next = sub i8 %A.iv, 1
750  %B.iv.next = sub i8 %B.iv, 1
751  %cmp = icmp ne i64 %iv.next, 10
752  br i1 %cmp, label %loop, label %exit
753exit:
754  %res = icmp eq i8 %A.iv, %B.iv
755  ret i1 %res
756}
757
758define i1 @recurrence_sub_unknown(i8 %A, i8 %B) {
759; CHECK-LABEL: @recurrence_sub_unknown(
760; CHECK-NEXT:  entry:
761; CHECK-NEXT:    br label [[LOOP:%.*]]
762; CHECK:       loop:
763; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
764; CHECK-NEXT:    [[A_IV:%.*]] = phi i8 [ [[A:%.*]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
765; CHECK-NEXT:    [[B_IV:%.*]] = phi i8 [ [[B:%.*]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
766; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
767; CHECK-NEXT:    [[A_IV_NEXT]] = sub i8 [[A_IV]], 1
768; CHECK-NEXT:    [[B_IV_NEXT]] = sub i8 [[B_IV]], 1
769; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
770; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
771; CHECK:       exit:
772; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
773; CHECK-NEXT:    ret i1 [[RES]]
774;
775entry:
776  br label %loop
777loop:
778  %iv = phi i64 [0, %entry], [%iv.next, %loop]
779  %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
780  %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
781  %iv.next = add i64 %iv, 1
782  %A.iv.next = sub i8 %A.iv, 1
783  %B.iv.next = sub i8 %B.iv, 1
784  %cmp = icmp ne i64 %iv.next, 10
785  br i1 %cmp, label %loop, label %exit
786exit:
787  %res = icmp eq i8 %A.iv, %B.iv
788  ret i1 %res
789}
790
791define i1 @recurrence_mul_neq(i8 %A) {
792; CHECK-LABEL: @recurrence_mul_neq(
793; CHECK-NEXT:  entry:
794; CHECK-NEXT:    [[B:%.*]] = add i8 [[A:%.*]], 1
795; CHECK-NEXT:    br label [[LOOP:%.*]]
796; CHECK:       loop:
797; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
798; CHECK-NEXT:    [[A_IV:%.*]] = phi i8 [ [[A]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
799; CHECK-NEXT:    [[B_IV:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
800; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
801; CHECK-NEXT:    [[A_IV_NEXT]] = mul nuw i8 [[A_IV]], 2
802; CHECK-NEXT:    [[B_IV_NEXT]] = mul nuw i8 [[B_IV]], 2
803; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
804; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
805; CHECK:       exit:
806; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
807; CHECK-NEXT:    ret i1 [[RES]]
808;
809entry:
810  %B = add i8 %A, 1
811  br label %loop
812loop:
813  %iv = phi i64 [0, %entry], [%iv.next, %loop]
814  %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
815  %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
816  %iv.next = add i64 %iv, 1
817  %A.iv.next = mul nuw i8 %A.iv, 2
818  %B.iv.next = mul nuw i8 %B.iv, 2
819  %cmp = icmp ne i64 %iv.next, 10
820  br i1 %cmp, label %loop, label %exit
821exit:
822  %res = icmp eq i8 %A.iv, %B.iv
823  ret i1 %res
824}
825
826define i1 @recurrence_mul_eq(i8 %A) {
827; CHECK-LABEL: @recurrence_mul_eq(
828; CHECK-NEXT:  entry:
829; CHECK-NEXT:    br label [[LOOP:%.*]]
830; CHECK:       loop:
831; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
832; CHECK-NEXT:    [[A_IV:%.*]] = phi i8 [ [[A:%.*]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
833; CHECK-NEXT:    [[B_IV:%.*]] = phi i8 [ [[A]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
834; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
835; CHECK-NEXT:    [[A_IV_NEXT]] = mul nuw i8 [[A_IV]], 2
836; CHECK-NEXT:    [[B_IV_NEXT]] = mul nuw i8 [[B_IV]], 2
837; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
838; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
839; CHECK:       exit:
840; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
841; CHECK-NEXT:    ret i1 [[RES]]
842;
843entry:
844  %B = add i8 %A, 0
845  br label %loop
846loop:
847  %iv = phi i64 [0, %entry], [%iv.next, %loop]
848  %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
849  %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
850  %iv.next = add i64 %iv, 1
851  %A.iv.next = mul nuw i8 %A.iv, 2
852  %B.iv.next = mul nuw i8 %B.iv, 2
853  %cmp = icmp ne i64 %iv.next, 10
854  br i1 %cmp, label %loop, label %exit
855exit:
856  %res = icmp eq i8 %A.iv, %B.iv
857  ret i1 %res
858}
859
860define i1 @recurrence_mul_unknown(i8 %A, i8 %B) {
861; CHECK-LABEL: @recurrence_mul_unknown(
862; CHECK-NEXT:  entry:
863; CHECK-NEXT:    br label [[LOOP:%.*]]
864; CHECK:       loop:
865; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
866; CHECK-NEXT:    [[A_IV:%.*]] = phi i8 [ [[A:%.*]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
867; CHECK-NEXT:    [[B_IV:%.*]] = phi i8 [ [[B:%.*]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
868; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
869; CHECK-NEXT:    [[A_IV_NEXT]] = mul nuw i8 [[A_IV]], 2
870; CHECK-NEXT:    [[B_IV_NEXT]] = mul nuw i8 [[B_IV]], 2
871; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
872; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
873; CHECK:       exit:
874; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
875; CHECK-NEXT:    ret i1 [[RES]]
876;
877entry:
878  br label %loop
879loop:
880  %iv = phi i64 [0, %entry], [%iv.next, %loop]
881  %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
882  %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
883  %iv.next = add i64 %iv, 1
884  %A.iv.next = mul nuw i8 %A.iv, 2
885  %B.iv.next = mul nuw i8 %B.iv, 2
886  %cmp = icmp ne i64 %iv.next, 10
887  br i1 %cmp, label %loop, label %exit
888exit:
889  %res = icmp eq i8 %A.iv, %B.iv
890  ret i1 %res
891}
892
893define i1 @recurrence_mul_noflags(i8 %A) {
894; CHECK-LABEL: @recurrence_mul_noflags(
895; CHECK-NEXT:  entry:
896; CHECK-NEXT:    [[B:%.*]] = add i8 [[A:%.*]], 1
897; CHECK-NEXT:    br label [[LOOP:%.*]]
898; CHECK:       loop:
899; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
900; CHECK-NEXT:    [[A_IV:%.*]] = phi i8 [ [[A]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
901; CHECK-NEXT:    [[B_IV:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
902; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
903; CHECK-NEXT:    [[A_IV_NEXT]] = mul i8 [[A_IV]], 2
904; CHECK-NEXT:    [[B_IV_NEXT]] = mul i8 [[B_IV]], 2
905; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
906; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
907; CHECK:       exit:
908; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
909; CHECK-NEXT:    ret i1 [[RES]]
910;
911entry:
912  %B = add i8 %A, 1
913  br label %loop
914loop:
915  %iv = phi i64 [0, %entry], [%iv.next, %loop]
916  %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
917  %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
918  %iv.next = add i64 %iv, 1
919  %A.iv.next = mul i8 %A.iv, 2
920  %B.iv.next = mul i8 %B.iv, 2
921  %cmp = icmp ne i64 %iv.next, 10
922  br i1 %cmp, label %loop, label %exit
923exit:
924  %res = icmp eq i8 %A.iv, %B.iv
925  ret i1 %res
926}
927
928define i1 @recurrence_shl_neq(i8 %A) {
929; CHECK-LABEL: @recurrence_shl_neq(
930; CHECK-NEXT:  entry:
931; CHECK-NEXT:    [[B:%.*]] = add i8 [[A:%.*]], 1
932; CHECK-NEXT:    br label [[LOOP:%.*]]
933; CHECK:       loop:
934; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
935; CHECK-NEXT:    [[A_IV:%.*]] = phi i8 [ [[A]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
936; CHECK-NEXT:    [[B_IV:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
937; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
938; CHECK-NEXT:    [[A_IV_NEXT]] = shl nuw i8 [[A_IV]], 1
939; CHECK-NEXT:    [[B_IV_NEXT]] = shl nuw i8 [[B_IV]], 1
940; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
941; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
942; CHECK:       exit:
943; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
944; CHECK-NEXT:    ret i1 [[RES]]
945;
946entry:
947  %B = add i8 %A, 1
948  br label %loop
949loop:
950  %iv = phi i64 [0, %entry], [%iv.next, %loop]
951  %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
952  %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
953  %iv.next = add i64 %iv, 1
954  %A.iv.next = shl nuw i8 %A.iv, 1
955  %B.iv.next = shl nuw i8 %B.iv, 1
956  %cmp = icmp ne i64 %iv.next, 10
957  br i1 %cmp, label %loop, label %exit
958exit:
959  %res = icmp eq i8 %A.iv, %B.iv
960  ret i1 %res
961}
962
963define i1 @recurrence_shl_eq(i8 %A) {
964; CHECK-LABEL: @recurrence_shl_eq(
965; CHECK-NEXT:  entry:
966; CHECK-NEXT:    br label [[LOOP:%.*]]
967; CHECK:       loop:
968; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
969; CHECK-NEXT:    [[A_IV:%.*]] = phi i8 [ [[A:%.*]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
970; CHECK-NEXT:    [[B_IV:%.*]] = phi i8 [ [[A]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
971; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
972; CHECK-NEXT:    [[A_IV_NEXT]] = shl nuw i8 [[A_IV]], 1
973; CHECK-NEXT:    [[B_IV_NEXT]] = shl nuw i8 [[B_IV]], 1
974; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
975; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
976; CHECK:       exit:
977; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
978; CHECK-NEXT:    ret i1 [[RES]]
979;
980entry:
981  %B = add i8 %A, 0
982  br label %loop
983loop:
984  %iv = phi i64 [0, %entry], [%iv.next, %loop]
985  %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
986  %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
987  %iv.next = add i64 %iv, 1
988  %A.iv.next = shl nuw i8 %A.iv, 1
989  %B.iv.next = shl nuw i8 %B.iv, 1
990  %cmp = icmp ne i64 %iv.next, 10
991  br i1 %cmp, label %loop, label %exit
992exit:
993  %res = icmp eq i8 %A.iv, %B.iv
994  ret i1 %res
995}
996
997define i1 @recurrence_shl_unknown(i8 %A, i8 %B) {
998; CHECK-LABEL: @recurrence_shl_unknown(
999; CHECK-NEXT:  entry:
1000; CHECK-NEXT:    br label [[LOOP:%.*]]
1001; CHECK:       loop:
1002; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1003; CHECK-NEXT:    [[A_IV:%.*]] = phi i8 [ [[A:%.*]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
1004; CHECK-NEXT:    [[B_IV:%.*]] = phi i8 [ [[B:%.*]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
1005; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
1006; CHECK-NEXT:    [[A_IV_NEXT]] = shl nuw i8 [[A_IV]], 1
1007; CHECK-NEXT:    [[B_IV_NEXT]] = shl nuw i8 [[B_IV]], 1
1008; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
1009; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
1010; CHECK:       exit:
1011; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
1012; CHECK-NEXT:    ret i1 [[RES]]
1013;
1014entry:
1015  br label %loop
1016loop:
1017  %iv = phi i64 [0, %entry], [%iv.next, %loop]
1018  %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
1019  %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
1020  %iv.next = add i64 %iv, 1
1021  %A.iv.next = shl nuw i8 %A.iv, 1
1022  %B.iv.next = shl nuw i8 %B.iv, 1
1023  %cmp = icmp ne i64 %iv.next, 10
1024  br i1 %cmp, label %loop, label %exit
1025exit:
1026  %res = icmp eq i8 %A.iv, %B.iv
1027  ret i1 %res
1028}
1029
1030define i1 @recurrence_shl_noflags(i8 %A) {
1031; CHECK-LABEL: @recurrence_shl_noflags(
1032; CHECK-NEXT:  entry:
1033; CHECK-NEXT:    [[B:%.*]] = add i8 [[A:%.*]], 1
1034; CHECK-NEXT:    br label [[LOOP:%.*]]
1035; CHECK:       loop:
1036; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1037; CHECK-NEXT:    [[A_IV:%.*]] = phi i8 [ [[A]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
1038; CHECK-NEXT:    [[B_IV:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
1039; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
1040; CHECK-NEXT:    [[A_IV_NEXT]] = shl i8 [[A_IV]], 1
1041; CHECK-NEXT:    [[B_IV_NEXT]] = shl i8 [[B_IV]], 1
1042; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
1043; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
1044; CHECK:       exit:
1045; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
1046; CHECK-NEXT:    ret i1 [[RES]]
1047;
1048entry:
1049  %B = add i8 %A, 1
1050  br label %loop
1051loop:
1052  %iv = phi i64 [0, %entry], [%iv.next, %loop]
1053  %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
1054  %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
1055  %iv.next = add i64 %iv, 1
1056  %A.iv.next = shl i8 %A.iv, 1
1057  %B.iv.next = shl i8 %B.iv, 1
1058  %cmp = icmp ne i64 %iv.next, 10
1059  br i1 %cmp, label %loop, label %exit
1060exit:
1061  %res = icmp eq i8 %A.iv, %B.iv
1062  ret i1 %res
1063}
1064
1065define i1 @recurrence_lshr_neq(i8 %A) {
1066; CHECK-LABEL: @recurrence_lshr_neq(
1067; CHECK-NEXT:  entry:
1068; CHECK-NEXT:    [[B:%.*]] = add i8 [[A:%.*]], 1
1069; CHECK-NEXT:    br label [[LOOP:%.*]]
1070; CHECK:       loop:
1071; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1072; CHECK-NEXT:    [[A_IV:%.*]] = phi i8 [ [[A]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
1073; CHECK-NEXT:    [[B_IV:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
1074; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
1075; CHECK-NEXT:    [[A_IV_NEXT]] = lshr exact i8 [[A_IV]], 1
1076; CHECK-NEXT:    [[B_IV_NEXT]] = lshr exact i8 [[B_IV]], 1
1077; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
1078; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
1079; CHECK:       exit:
1080; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
1081; CHECK-NEXT:    ret i1 [[RES]]
1082;
1083entry:
1084  %B = add i8 %A, 1
1085  br label %loop
1086loop:
1087  %iv = phi i64 [0, %entry], [%iv.next, %loop]
1088  %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
1089  %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
1090  %iv.next = add i64 %iv, 1
1091  %A.iv.next = lshr exact i8 %A.iv, 1
1092  %B.iv.next = lshr exact i8 %B.iv, 1
1093  %cmp = icmp ne i64 %iv.next, 10
1094  br i1 %cmp, label %loop, label %exit
1095exit:
1096  %res = icmp eq i8 %A.iv, %B.iv
1097  ret i1 %res
1098}
1099
1100define i1 @recurrence_lshr_eq(i8 %A) {
1101; CHECK-LABEL: @recurrence_lshr_eq(
1102; CHECK-NEXT:  entry:
1103; CHECK-NEXT:    br label [[LOOP:%.*]]
1104; CHECK:       loop:
1105; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1106; CHECK-NEXT:    [[A_IV:%.*]] = phi i8 [ [[A:%.*]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
1107; CHECK-NEXT:    [[B_IV:%.*]] = phi i8 [ [[A]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
1108; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
1109; CHECK-NEXT:    [[A_IV_NEXT]] = lshr exact i8 [[A_IV]], 1
1110; CHECK-NEXT:    [[B_IV_NEXT]] = lshr exact i8 [[B_IV]], 1
1111; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
1112; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
1113; CHECK:       exit:
1114; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
1115; CHECK-NEXT:    ret i1 [[RES]]
1116;
1117entry:
1118  %B = add i8 %A, 0
1119  br label %loop
1120loop:
1121  %iv = phi i64 [0, %entry], [%iv.next, %loop]
1122  %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
1123  %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
1124  %iv.next = add i64 %iv, 1
1125  %A.iv.next = lshr exact i8 %A.iv, 1
1126  %B.iv.next = lshr exact i8 %B.iv, 1
1127  %cmp = icmp ne i64 %iv.next, 10
1128  br i1 %cmp, label %loop, label %exit
1129exit:
1130  %res = icmp eq i8 %A.iv, %B.iv
1131  ret i1 %res
1132}
1133
1134define i1 @recurrence_lshr_unknown(i8 %A, i8 %B) {
1135; CHECK-LABEL: @recurrence_lshr_unknown(
1136; CHECK-NEXT:  entry:
1137; CHECK-NEXT:    br label [[LOOP:%.*]]
1138; CHECK:       loop:
1139; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1140; CHECK-NEXT:    [[A_IV:%.*]] = phi i8 [ [[A:%.*]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
1141; CHECK-NEXT:    [[B_IV:%.*]] = phi i8 [ [[B:%.*]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
1142; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
1143; CHECK-NEXT:    [[A_IV_NEXT]] = lshr exact i8 [[A_IV]], 1
1144; CHECK-NEXT:    [[B_IV_NEXT]] = lshr exact i8 [[B_IV]], 1
1145; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
1146; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
1147; CHECK:       exit:
1148; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
1149; CHECK-NEXT:    ret i1 [[RES]]
1150;
1151entry:
1152  br label %loop
1153loop:
1154  %iv = phi i64 [0, %entry], [%iv.next, %loop]
1155  %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
1156  %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
1157  %iv.next = add i64 %iv, 1
1158  %A.iv.next = lshr exact i8 %A.iv, 1
1159  %B.iv.next = lshr exact i8 %B.iv, 1
1160  %cmp = icmp ne i64 %iv.next, 10
1161  br i1 %cmp, label %loop, label %exit
1162exit:
1163  %res = icmp eq i8 %A.iv, %B.iv
1164  ret i1 %res
1165}
1166
1167define i1 @recurrence_lshr_noflags(i8 %A) {
1168; CHECK-LABEL: @recurrence_lshr_noflags(
1169; CHECK-NEXT:  entry:
1170; CHECK-NEXT:    [[B:%.*]] = add i8 [[A:%.*]], 1
1171; CHECK-NEXT:    br label [[LOOP:%.*]]
1172; CHECK:       loop:
1173; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1174; CHECK-NEXT:    [[A_IV:%.*]] = phi i8 [ [[A]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
1175; CHECK-NEXT:    [[B_IV:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
1176; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
1177; CHECK-NEXT:    [[A_IV_NEXT]] = lshr i8 [[A_IV]], 1
1178; CHECK-NEXT:    [[B_IV_NEXT]] = lshr i8 [[B_IV]], 1
1179; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
1180; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
1181; CHECK:       exit:
1182; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
1183; CHECK-NEXT:    ret i1 [[RES]]
1184;
1185entry:
1186  %B = add i8 %A, 1
1187  br label %loop
1188loop:
1189  %iv = phi i64 [0, %entry], [%iv.next, %loop]
1190  %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
1191  %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
1192  %iv.next = add i64 %iv, 1
1193  %A.iv.next = lshr i8 %A.iv, 1
1194  %B.iv.next = lshr i8 %B.iv, 1
1195  %cmp = icmp ne i64 %iv.next, 10
1196  br i1 %cmp, label %loop, label %exit
1197exit:
1198  %res = icmp eq i8 %A.iv, %B.iv
1199  ret i1 %res
1200}
1201
1202define i1 @recurrence_ashr_neq(i8 %A) {
1203; CHECK-LABEL: @recurrence_ashr_neq(
1204; CHECK-NEXT:  entry:
1205; CHECK-NEXT:    [[B:%.*]] = add i8 [[A:%.*]], 1
1206; CHECK-NEXT:    br label [[LOOP:%.*]]
1207; CHECK:       loop:
1208; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1209; CHECK-NEXT:    [[A_IV:%.*]] = phi i8 [ [[A]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
1210; CHECK-NEXT:    [[B_IV:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
1211; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
1212; CHECK-NEXT:    [[A_IV_NEXT]] = ashr exact i8 [[A_IV]], 1
1213; CHECK-NEXT:    [[B_IV_NEXT]] = ashr exact i8 [[B_IV]], 1
1214; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
1215; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
1216; CHECK:       exit:
1217; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
1218; CHECK-NEXT:    ret i1 [[RES]]
1219;
1220entry:
1221  %B = add i8 %A, 1
1222  br label %loop
1223loop:
1224  %iv = phi i64 [0, %entry], [%iv.next, %loop]
1225  %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
1226  %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
1227  %iv.next = add i64 %iv, 1
1228  %A.iv.next = ashr exact i8 %A.iv, 1
1229  %B.iv.next = ashr exact i8 %B.iv, 1
1230  %cmp = icmp ne i64 %iv.next, 10
1231  br i1 %cmp, label %loop, label %exit
1232exit:
1233  %res = icmp eq i8 %A.iv, %B.iv
1234  ret i1 %res
1235}
1236
1237define i1 @recurrence_ashr_eq(i8 %A) {
1238; CHECK-LABEL: @recurrence_ashr_eq(
1239; CHECK-NEXT:  entry:
1240; CHECK-NEXT:    br label [[LOOP:%.*]]
1241; CHECK:       loop:
1242; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1243; CHECK-NEXT:    [[A_IV:%.*]] = phi i8 [ [[A:%.*]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
1244; CHECK-NEXT:    [[B_IV:%.*]] = phi i8 [ [[A]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
1245; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
1246; CHECK-NEXT:    [[A_IV_NEXT]] = ashr exact i8 [[A_IV]], 1
1247; CHECK-NEXT:    [[B_IV_NEXT]] = ashr exact i8 [[B_IV]], 1
1248; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
1249; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
1250; CHECK:       exit:
1251; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
1252; CHECK-NEXT:    ret i1 [[RES]]
1253;
1254entry:
1255  %B = add i8 %A, 0
1256  br label %loop
1257loop:
1258  %iv = phi i64 [0, %entry], [%iv.next, %loop]
1259  %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
1260  %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
1261  %iv.next = add i64 %iv, 1
1262  %A.iv.next = ashr exact i8 %A.iv, 1
1263  %B.iv.next = ashr exact i8 %B.iv, 1
1264  %cmp = icmp ne i64 %iv.next, 10
1265  br i1 %cmp, label %loop, label %exit
1266exit:
1267  %res = icmp eq i8 %A.iv, %B.iv
1268  ret i1 %res
1269}
1270
1271define i1 @recurrence_ashr_unknown(i8 %A, i8 %B) {
1272; CHECK-LABEL: @recurrence_ashr_unknown(
1273; CHECK-NEXT:  entry:
1274; CHECK-NEXT:    br label [[LOOP:%.*]]
1275; CHECK:       loop:
1276; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1277; CHECK-NEXT:    [[A_IV:%.*]] = phi i8 [ [[A:%.*]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
1278; CHECK-NEXT:    [[B_IV:%.*]] = phi i8 [ [[B:%.*]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
1279; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
1280; CHECK-NEXT:    [[A_IV_NEXT]] = ashr exact i8 [[A_IV]], 1
1281; CHECK-NEXT:    [[B_IV_NEXT]] = ashr exact i8 [[B_IV]], 1
1282; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
1283; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
1284; CHECK:       exit:
1285; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
1286; CHECK-NEXT:    ret i1 [[RES]]
1287;
1288entry:
1289  br label %loop
1290loop:
1291  %iv = phi i64 [0, %entry], [%iv.next, %loop]
1292  %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
1293  %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
1294  %iv.next = add i64 %iv, 1
1295  %A.iv.next = ashr exact i8 %A.iv, 1
1296  %B.iv.next = ashr exact i8 %B.iv, 1
1297  %cmp = icmp ne i64 %iv.next, 10
1298  br i1 %cmp, label %loop, label %exit
1299exit:
1300  %res = icmp eq i8 %A.iv, %B.iv
1301  ret i1 %res
1302}
1303
1304define i1 @recurrence_ashr_noflags(i8 %A) {
1305; CHECK-LABEL: @recurrence_ashr_noflags(
1306; CHECK-NEXT:  entry:
1307; CHECK-NEXT:    [[B:%.*]] = add i8 [[A:%.*]], 1
1308; CHECK-NEXT:    br label [[LOOP:%.*]]
1309; CHECK:       loop:
1310; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1311; CHECK-NEXT:    [[A_IV:%.*]] = phi i8 [ [[A]], [[ENTRY]] ], [ [[A_IV_NEXT:%.*]], [[LOOP]] ]
1312; CHECK-NEXT:    [[B_IV:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[B_IV_NEXT:%.*]], [[LOOP]] ]
1313; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
1314; CHECK-NEXT:    [[A_IV_NEXT]] = ashr i8 [[A_IV]], 1
1315; CHECK-NEXT:    [[B_IV_NEXT]] = ashr i8 [[B_IV]], 1
1316; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[IV_NEXT]], 10
1317; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
1318; CHECK:       exit:
1319; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[A_IV]], [[B_IV]]
1320; CHECK-NEXT:    ret i1 [[RES]]
1321;
1322entry:
1323  %B = add i8 %A, 1
1324  br label %loop
1325loop:
1326  %iv = phi i64 [0, %entry], [%iv.next, %loop]
1327  %A.iv = phi i8 [%A, %entry], [%A.iv.next, %loop]
1328  %B.iv = phi i8 [%B, %entry], [%B.iv.next, %loop]
1329  %iv.next = add i64 %iv, 1
1330  %A.iv.next = ashr i8 %A.iv, 1
1331  %B.iv.next = ashr i8 %B.iv, 1
1332  %cmp = icmp ne i64 %iv.next, 10
1333  br i1 %cmp, label %loop, label %exit
1334exit:
1335  %res = icmp eq i8 %A.iv, %B.iv
1336  ret i1 %res
1337}
1338
1339!0 = !{ i8 1, i8 5 }
1340