xref: /llvm-project/llvm/test/Analysis/ValueTracking/phi-known-bits.ll (revision c2fba023475fddb893eac29dc9f34dfbdb221cd5)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=instcombine < %s -S | FileCheck %s
3
4define i8 @phi_ugt_high_bits(i8 %x) {
5; CHECK-LABEL: @phi_ugt_high_bits(
6; CHECK-NEXT:  entry:
7; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], -65
8; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
9; CHECK:       T:
10; CHECK-NEXT:    ret i8 64
11; CHECK:       F:
12; CHECK-NEXT:    br label [[T]]
13;
14entry:
15  %cmp = icmp ugt i8 %x, 191
16  br i1 %cmp, label %T, label %F
17T:
18  %v = phi i8 [ %x, %entry], [-1, %F]
19  %r = and i8 %v, 64
20  ret i8 %r
21F:
22  br label %T
23}
24
25define i8 @phi_ult_low_bits(i8 %x) {
26; CHECK-LABEL: @phi_ult_low_bits(
27; CHECK-NEXT:  entry:
28; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[X:%.*]], -64
29; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
30; CHECK:       T:
31; CHECK-NEXT:    br label [[F]]
32; CHECK:       F:
33; CHECK-NEXT:    ret i8 64
34;
35entry:
36  %cmp = icmp ult i8 %x, 192
37  br i1 %cmp, label %T, label %F
38T:
39  br label %F
40F:
41  %v = phi i8 [ %x, %entry], [-1, %T]
42  %r = and i8 %v, 64
43  ret i8 %r
44}
45
46define i8 @phi_ugt_high_bits_fail(i8 %x) {
47; CHECK-LABEL: @phi_ugt_high_bits_fail(
48; CHECK-NEXT:  entry:
49; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], -66
50; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
51; CHECK:       T:
52; CHECK-NEXT:    [[V:%.*]] = phi i8 [ [[X]], [[ENTRY:%.*]] ], [ -1, [[F]] ]
53; CHECK-NEXT:    [[R:%.*]] = and i8 [[V]], 64
54; CHECK-NEXT:    ret i8 [[R]]
55; CHECK:       F:
56; CHECK-NEXT:    br label [[T]]
57;
58entry:
59  %cmp = icmp ugt i8 %x, 190
60  br i1 %cmp, label %T, label %F
61T:
62  %v = phi i8 [ %x, %entry], [-1, %F]
63  %r = and i8 %v, 64
64  ret i8 %r
65F:
66  br label %T
67}
68
69define i8 @phi_uge_high_bits(i8 %x) {
70; CHECK-LABEL: @phi_uge_high_bits(
71; CHECK-NEXT:  entry:
72; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], -65
73; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
74; CHECK:       T:
75; CHECK-NEXT:    ret i8 64
76; CHECK:       F:
77; CHECK-NEXT:    br label [[T]]
78;
79entry:
80  %cmp = icmp uge i8 %x, 192
81  br i1 %cmp, label %T, label %F
82T:
83  %v = phi i8 [ %x, %entry], [-1, %F]
84  %r = and i8 %v, 64
85  ret i8 %r
86F:
87  br label %T
88}
89
90define i8 @phi_uge_high_bits_fail(i8 %x) {
91; CHECK-LABEL: @phi_uge_high_bits_fail(
92; CHECK-NEXT:  entry:
93; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], 5
94; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
95; CHECK:       T:
96; CHECK-NEXT:    [[V:%.*]] = phi i8 [ [[X]], [[ENTRY:%.*]] ], [ -1, [[F]] ]
97; CHECK-NEXT:    [[R:%.*]] = and i8 [[V]], 1
98; CHECK-NEXT:    ret i8 [[R]]
99; CHECK:       F:
100; CHECK-NEXT:    br label [[T]]
101;
102entry:
103  %cmp = icmp ugt i8 %x, 5
104  br i1 %cmp, label %T, label %F
105T:
106  %v = phi i8 [ %x, %entry], [-1, %F]
107  %r = and i8 %v, 1
108  ret i8 %r
109F:
110  br label %T
111}
112
113define i8 @phi_sge_high_bits(i8 %x) {
114; CHECK-LABEL: @phi_sge_high_bits(
115; CHECK-NEXT:  entry:
116; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], 95
117; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
118; CHECK:       T:
119; CHECK-NEXT:    ret i8 96
120; CHECK:       F:
121; CHECK-NEXT:    br label [[T]]
122;
123entry:
124  %cmp = icmp sge i8 %x, 96
125  br i1 %cmp, label %T, label %F
126T:
127  %v = phi i8 [ %x, %entry], [-1, %F]
128  %r = and i8 %v, 96
129  ret i8 %r
130F:
131  br label %T
132}
133
134define i8 @phi_sge_high_bits_fail(i8 %x) {
135; CHECK-LABEL: @phi_sge_high_bits_fail(
136; CHECK-NEXT:  entry:
137; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -2
138; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
139; CHECK:       T:
140; CHECK-NEXT:    [[V:%.*]] = phi i8 [ [[X]], [[ENTRY:%.*]] ], [ -1, [[F]] ]
141; CHECK-NEXT:    [[R:%.*]] = and i8 [[V]], 1
142; CHECK-NEXT:    ret i8 [[R]]
143; CHECK:       F:
144; CHECK-NEXT:    br label [[T]]
145;
146entry:
147  %cmp = icmp sge i8 %x, -1
148  br i1 %cmp, label %T, label %F
149T:
150  %v = phi i8 [ %x, %entry], [-1, %F]
151  %r = and i8 %v, 1
152  ret i8 %r
153F:
154  br label %T
155}
156
157define i8 @phi_sgt_high_bits(i8 %x) {
158; CHECK-LABEL: @phi_sgt_high_bits(
159; CHECK-NEXT:  entry:
160; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1
161; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
162; CHECK:       T:
163; CHECK-NEXT:    ret i8 0
164; CHECK:       F:
165; CHECK-NEXT:    br label [[T]]
166;
167entry:
168  %cmp = icmp sgt i8 %x, -1
169  br i1 %cmp, label %T, label %F
170T:
171  %v = phi i8 [ %x, %entry], [0, %F]
172  %r = and i8 %v, 128
173  ret i8 %r
174F:
175  br label %T
176}
177
178define i8 @phi_sgt_high_bits2(i8 %x) {
179; CHECK-LABEL: @phi_sgt_high_bits2(
180; CHECK-NEXT:  entry:
181; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], 63
182; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
183; CHECK:       T:
184; CHECK-NEXT:    ret i8 64
185; CHECK:       F:
186; CHECK-NEXT:    br label [[T]]
187;
188entry:
189  %cmp = icmp sgt i8 %x, 63
190  br i1 %cmp, label %T, label %F
191T:
192  %v = phi i8 [ %x, %entry], [-1, %F]
193  %r = and i8 %v, 64
194  ret i8 %r
195F:
196  br label %T
197}
198
199define i8 @phi_sgt_high_bits_fail(i8 %x) {
200; CHECK-LABEL: @phi_sgt_high_bits_fail(
201; CHECK-NEXT:  entry:
202; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], 62
203; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
204; CHECK:       T:
205; CHECK-NEXT:    [[V:%.*]] = phi i8 [ [[X]], [[ENTRY:%.*]] ], [ -1, [[F]] ]
206; CHECK-NEXT:    [[R:%.*]] = and i8 [[V]], 64
207; CHECK-NEXT:    ret i8 [[R]]
208; CHECK:       F:
209; CHECK-NEXT:    br label [[T]]
210;
211entry:
212  %cmp = icmp sgt i8 %x, 62
213  br i1 %cmp, label %T, label %F
214T:
215  %v = phi i8 [ %x, %entry], [-1, %F]
216  %r = and i8 %v, 64
217  ret i8 %r
218F:
219  br label %T
220}
221
222define i8 @phi_slt_high_bits(i8 %x) {
223; CHECK-LABEL: @phi_slt_high_bits(
224; CHECK-NEXT:  entry:
225; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
226; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
227; CHECK:       T:
228; CHECK-NEXT:    ret i8 -128
229; CHECK:       F:
230; CHECK-NEXT:    br label [[T]]
231;
232entry:
233  %cmp = icmp slt i8 %x, 0
234  br i1 %cmp, label %T, label %F
235T:
236  %v = phi i8 [ %x, %entry], [-1, %F]
237  %r = and i8 %v, 128
238  ret i8 %r
239F:
240  br label %T
241}
242
243define i8 @phi_slt_high_bits2(i8 %x) {
244; CHECK-LABEL: @phi_slt_high_bits2(
245; CHECK-NEXT:  entry:
246; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], -64
247; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
248; CHECK:       T:
249; CHECK-NEXT:    ret i8 0
250; CHECK:       F:
251; CHECK-NEXT:    br label [[T]]
252;
253entry:
254  %cmp = icmp slt i8 %x, -64
255  br i1 %cmp, label %T, label %F
256T:
257  %v = phi i8 [ %x, %entry], [0, %F]
258  %r = and i8 %v, 64
259  ret i8 %r
260F:
261  br label %T
262}
263
264define i8 @phi_slt_high_bits_fail(i8 %x) {
265; CHECK-LABEL: @phi_slt_high_bits_fail(
266; CHECK-NEXT:  entry:
267; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], -63
268; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
269; CHECK:       T:
270; CHECK-NEXT:    [[V:%.*]] = phi i8 [ [[X]], [[ENTRY:%.*]] ], [ 0, [[F]] ]
271; CHECK-NEXT:    [[R:%.*]] = and i8 [[V]], 64
272; CHECK-NEXT:    ret i8 [[R]]
273; CHECK:       F:
274; CHECK-NEXT:    br label [[T]]
275;
276entry:
277  %cmp = icmp slt i8 %x, -63
278  br i1 %cmp, label %T, label %F
279T:
280  %v = phi i8 [ %x, %entry], [0, %F]
281  %r = and i8 %v, 64
282  ret i8 %r
283F:
284  br label %T
285}
286
287define i8 @phi_sle_high_bits(i8 %x) {
288; CHECK-LABEL: @phi_sle_high_bits(
289; CHECK-NEXT:  entry:
290; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], -64
291; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
292; CHECK:       T:
293; CHECK-NEXT:    ret i8 0
294; CHECK:       F:
295; CHECK-NEXT:    br label [[T]]
296;
297entry:
298  %cmp = icmp sle i8 %x, -65
299  br i1 %cmp, label %T, label %F
300T:
301  %v = phi i8 [ %x, %entry], [0, %F]
302  %r = and i8 %v, 64
303  ret i8 %r
304F:
305  br label %T
306}
307
308define i8 @phi_sle_low_bits(i8 %x) {
309; CHECK-LABEL: @phi_sle_low_bits(
310; CHECK-NEXT:  entry:
311; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 65
312; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
313; CHECK:       T:
314; CHECK-NEXT:    br label [[F]]
315; CHECK:       F:
316; CHECK-NEXT:    ret i8 64
317;
318entry:
319  %cmp = icmp sle i8 %x, 64
320  br i1 %cmp, label %T, label %F
321T:
322  br label %F
323F:
324  %v = phi i8 [ %x, %entry], [-1, %T]
325  %r = and i8 %v, 64
326  ret i8 %r
327}
328
329define i8 @phi_sle_high_bits_fail(i8 %x) {
330; CHECK-LABEL: @phi_sle_high_bits_fail(
331; CHECK-NEXT:  entry:
332; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 1
333; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
334; CHECK:       T:
335; CHECK-NEXT:    [[V:%.*]] = phi i8 [ [[X]], [[ENTRY:%.*]] ], [ -1, [[F]] ]
336; CHECK-NEXT:    [[R:%.*]] = and i8 [[V]], -128
337; CHECK-NEXT:    ret i8 [[R]]
338; CHECK:       F:
339; CHECK-NEXT:    br label [[T]]
340;
341entry:
342  %cmp = icmp sle i8 %x, 0
343  br i1 %cmp, label %T, label %F
344T:
345  %v = phi i8 [ %x, %entry], [-1, %F]
346  %r = and i8 %v, 128
347  ret i8 %r
348F:
349  br label %T
350}
351
352define i8 @phi_sle_high_bits_fail2(i8 %x) {
353; CHECK-LABEL: @phi_sle_high_bits_fail2(
354; CHECK-NEXT:  entry:
355; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], -63
356; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
357; CHECK:       T:
358; CHECK-NEXT:    [[V:%.*]] = phi i8 [ [[X]], [[ENTRY:%.*]] ], [ -1, [[F]] ]
359; CHECK-NEXT:    [[R:%.*]] = and i8 [[V]], 64
360; CHECK-NEXT:    ret i8 [[R]]
361; CHECK:       F:
362; CHECK-NEXT:    br label [[T]]
363;
364entry:
365  %cmp = icmp sle i8 %x, -64
366  br i1 %cmp, label %T, label %F
367T:
368  %v = phi i8 [ %x, %entry], [-1, %F]
369  %r = and i8 %v, 64
370  ret i8 %r
371F:
372  br label %T
373}
374
375define i8 @phi_ugt_high_bits_and_known(i8 %xx) {
376; CHECK-LABEL: @phi_ugt_high_bits_and_known(
377; CHECK-NEXT:  entry:
378; CHECK-NEXT:    [[X:%.*]] = or i8 [[XX:%.*]], 1
379; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[XX]], -65
380; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
381; CHECK:       T:
382; CHECK-NEXT:    [[V:%.*]] = phi i8 [ [[X]], [[ENTRY:%.*]] ], [ -1, [[F]] ]
383; CHECK-NEXT:    [[R:%.*]] = and i8 [[V]], 65
384; CHECK-NEXT:    ret i8 [[R]]
385; CHECK:       F:
386; CHECK-NEXT:    br label [[T]]
387;
388entry:
389  %x = or i8 %xx, 1
390  %cmp = icmp ugt i8 %x, 191
391  br i1 %cmp, label %T, label %F
392T:
393  %v = phi i8 [ %x, %entry], [-1, %F]
394  %r = and i8 %v, 65
395  ret i8 %r
396F:
397  br label %T
398}
399
400define i8 @phi_ugt_high_bits_and_known_todo_high_depths(i8 %xx, i8 %y, i8 %z) {
401; CHECK-LABEL: @phi_ugt_high_bits_and_known_todo_high_depths(
402; CHECK-NEXT:  entry:
403; CHECK-NEXT:    [[YY:%.*]] = and i8 [[Y:%.*]], -2
404; CHECK-NEXT:    [[XXX:%.*]] = and i8 [[XX:%.*]], [[YY]]
405; CHECK-NEXT:    [[ZZ:%.*]] = or i8 [[Z:%.*]], 1
406; CHECK-NEXT:    [[X:%.*]] = add i8 [[XXX]], [[ZZ]]
407; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[X]], -65
408; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
409; CHECK:       T:
410; CHECK-NEXT:    [[V:%.*]] = phi i8 [ [[X]], [[ENTRY:%.*]] ], [ -1, [[F]] ]
411; CHECK-NEXT:    [[R:%.*]] = and i8 [[V]], 65
412; CHECK-NEXT:    ret i8 [[R]]
413; CHECK:       F:
414; CHECK-NEXT:    br label [[T]]
415;
416entry:
417  %yy = and i8 %y, -2
418  %xxx = and i8 %xx, %yy
419  %zz = or i8 %z, 1
420  %x = add i8 %xxx, %zz
421  %cmp = icmp ugt i8 %x, 191
422  br i1 %cmp, label %T, label %F
423T:
424  %v = phi i8 [ %x, %entry], [-1, %F]
425  %r = and i8 %v, 65
426  ret i8 %r
427F:
428  br label %T
429}
430
431;Illustrate if 2 pointers are non-equal when one of them is a recursive GEP.
432;Cases which folds to a canonical icmp(ptr1, ptr2)
433define i1 @recursiveGEP_withPtrSub1(ptr %val1) {
434; CHECK-LABEL: @recursiveGEP_withPtrSub1(
435; CHECK-NEXT:  entry:
436; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
437; CHECK:       while.cond.i:
438; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ]
439; CHECK-NEXT:    [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1
440; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2
441; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
442; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
443; CHECK:       while.end.i:
444; CHECK-NEXT:    ret i1 false
445;
446entry:
447  br label %while.cond.i
448
449while.cond.i:
450  %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ]
451  %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1
452  %0 = load i8, ptr %test.0.i, align 2
453  %cmp3.not.i = icmp eq i8 %0, 0
454  br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
455
456while.end.i:
457  %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
458  %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64
459  %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
460  %bool = icmp eq i64 %sub.ptr.sub.i, 0
461  ret i1 %bool
462}
463
464define i1 @recursiveGEP_withPtrSub1_PhiOperandsCommuted(ptr %val1) {
465; CHECK-LABEL: @recursiveGEP_withPtrSub1_PhiOperandsCommuted(
466; CHECK-NEXT:  entry:
467; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
468; CHECK:       while.cond.i:
469; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[VAL1:%.*]], [[ENTRY:%.*]] ], [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ]
470; CHECK-NEXT:    [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1
471; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2
472; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
473; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
474; CHECK:       while.end.i:
475; CHECK-NEXT:    ret i1 false
476;
477entry:
478  br label %while.cond.i
479
480while.cond.i:
481  %a.pn.i = phi ptr [ %val1, %entry ], [ %test.0.i, %while.cond.i ]
482  %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1
483  %0 = load i8, ptr %test.0.i, align 2
484  %cmp3.not.i = icmp eq i8 %0, 0
485  br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
486
487while.end.i:
488  %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
489  %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64
490  %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
491  %bool = icmp eq i64 %sub.ptr.sub.i, 0
492  ret i1 %bool
493}
494
495define i1 @recursiveGEP_withPtrSub1_SubOperandsCommuted(ptr %val1) {
496; CHECK-LABEL: @recursiveGEP_withPtrSub1_SubOperandsCommuted(
497; CHECK-NEXT:  entry:
498; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
499; CHECK:       while.cond.i:
500; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ]
501; CHECK-NEXT:    [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1
502; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2
503; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
504; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
505; CHECK:       while.end.i:
506; CHECK-NEXT:    ret i1 false
507;
508entry:
509  br label %while.cond.i
510
511while.cond.i:
512  %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ]
513  %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1
514  %0 = load i8, ptr %test.0.i, align 2
515  %cmp3.not.i = icmp eq i8 %0, 0
516  br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
517
518while.end.i:
519  %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
520  %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64
521  %sub.ptr.sub.i = sub i64 %sub.ptr.rhs.cast.i, %sub.ptr.lhs.cast.i
522  %bool = icmp eq i64 %sub.ptr.sub.i, 0
523  ret i1 %bool
524}
525
526define i1 @recursiveGEP_withPtrSub2(ptr %val1) {
527; CHECK-LABEL: @recursiveGEP_withPtrSub2(
528; CHECK-NEXT:  entry:
529; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
530; CHECK:       while.cond.i:
531; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ]
532; CHECK-NEXT:    [[TEST_0_I]] = getelementptr inbounds i8, ptr [[A_PN_I]], i64 -1
533; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2
534; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
535; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
536; CHECK:       while.end.i:
537; CHECK-NEXT:    ret i1 false
538;
539entry:
540  br label %while.cond.i
541
542while.cond.i:
543  %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ]
544  %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 -1
545  %0 = load i8, ptr %test.0.i, align 2
546  %cmp3.not.i = icmp eq i8 %0, 0
547  br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
548
549while.end.i:
550  %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
551  %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64
552  %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
553  %bool = icmp eq i64 %sub.ptr.sub.i, 0
554  ret i1 %bool
555}
556
557define i1 @recursiveGEP_withPtrSub3(ptr %val1) {
558; CHECK-LABEL: @recursiveGEP_withPtrSub3(
559; CHECK-NEXT:  entry:
560; CHECK-NEXT:    [[TEST_VAL1:%.*]] = getelementptr inbounds nuw i8, ptr [[VAL1:%.*]], i64 7
561; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
562; CHECK:       while.cond.i:
563; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[TEST_VAL1]], [[ENTRY:%.*]] ]
564; CHECK-NEXT:    [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1
565; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2
566; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
567; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
568; CHECK:       while.end.i:
569; CHECK-NEXT:    ret i1 false
570;
571entry:
572  %test.val1 = getelementptr inbounds i8, ptr %val1, i64 7
573  br label %while.cond.i
574
575while.cond.i:
576  %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %test.val1, %entry ]
577  %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1
578  %0 = load i8, ptr %test.0.i, align 2
579  %cmp3.not.i = icmp eq i8 %0, 0
580  br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
581
582while.end.i:
583  %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
584  %1 = getelementptr inbounds i8, ptr %val1, i64 5
585  %sub.ptr.rhs.cast.i = ptrtoint ptr %1 to i64
586  %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
587  %bool = icmp eq i64 %sub.ptr.sub.i, 0
588  ret i1 %bool
589}
590
591define i1 @recursiveGEP_withPtrSub1_notKnownNonEqual1(ptr %val1, i64 %val2) {
592; CHECK-LABEL: @recursiveGEP_withPtrSub1_notKnownNonEqual1(
593; CHECK-NEXT:  entry:
594; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
595; CHECK:       while.cond.i:
596; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ]
597; CHECK-NEXT:    [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1
598; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2
599; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
600; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
601; CHECK:       while.end.i:
602; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[VAL1]], i64 [[VAL2:%.*]]
603; CHECK-NEXT:    [[BOOL:%.*]] = icmp eq ptr [[TEST_0_I]], [[TMP1]]
604; CHECK-NEXT:    ret i1 [[BOOL]]
605;
606entry:
607  br label %while.cond.i
608
609while.cond.i:
610  %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ]
611  %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1
612  %0 = load i8, ptr %test.0.i, align 2
613  %cmp3.not.i = icmp eq i8 %0, 0
614  br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
615
616while.end.i:
617  %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
618  %1 = getelementptr inbounds i8, ptr %val1, i64 %val2
619  %sub.ptr.rhs.cast.i = ptrtoint ptr %1 to i64
620  %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
621  %bool = icmp eq i64 %sub.ptr.sub.i, 0
622  ret i1 %bool
623}
624
625define i1 @recursiveGEP_withPtrSub1_notKnownNonEqual2(ptr %val1) {
626; CHECK-LABEL: @recursiveGEP_withPtrSub1_notKnownNonEqual2(
627; CHECK-NEXT:  entry:
628; CHECK-NEXT:    [[TEST_VAL1:%.*]] = getelementptr inbounds i8, ptr [[VAL1:%.*]], i64 -1
629; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
630; CHECK:       while.cond.i:
631; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[TEST_VAL1]], [[ENTRY:%.*]] ]
632; CHECK-NEXT:    [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1
633; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2
634; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
635; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
636; CHECK:       while.end.i:
637; CHECK-NEXT:    [[BOOL:%.*]] = icmp eq ptr [[TEST_0_I]], [[VAL1]]
638; CHECK-NEXT:    ret i1 [[BOOL]]
639;
640entry:
641  %test.val1 = getelementptr inbounds i8, ptr %val1, i64 -1
642  br label %while.cond.i
643
644while.cond.i:
645  %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %test.val1, %entry ]
646  %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1
647  %0 = load i8, ptr %test.0.i, align 2
648  %cmp3.not.i = icmp eq i8 %0, 0
649  br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
650
651while.end.i:
652  %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
653  %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64
654  %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
655  %bool = icmp eq i64 %sub.ptr.sub.i, 0
656  ret i1 %bool
657}
658
659define i1 @recursiveGEP_withPtrSub1_notKnownNonEqual3(ptr %val1) {
660; CHECK-LABEL: @recursiveGEP_withPtrSub1_notKnownNonEqual3(
661; CHECK-NEXT:  entry:
662; CHECK-NEXT:    [[TEST_VAL1:%.*]] = getelementptr inbounds nuw i8, ptr [[VAL1:%.*]], i64 5
663; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
664; CHECK:       while.cond.i:
665; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[TEST_VAL1]], [[ENTRY:%.*]] ]
666; CHECK-NEXT:    [[TEST_0_I]] = getelementptr inbounds i8, ptr [[A_PN_I]], i64 -1
667; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2
668; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
669; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
670; CHECK:       while.end.i:
671; CHECK-NEXT:    [[BOOL:%.*]] = icmp eq ptr [[TEST_0_I]], [[VAL1]]
672; CHECK-NEXT:    ret i1 [[BOOL]]
673;
674entry:
675  %test.val1 = getelementptr inbounds i8, ptr %val1, i64 5
676  br label %while.cond.i
677
678while.cond.i:
679  %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %test.val1, %entry ]
680  %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 -1
681  %0 = load i8, ptr %test.0.i, align 2
682  %cmp3.not.i = icmp eq i8 %0, 0
683  br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
684
685while.end.i:
686  %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
687  %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64
688  %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
689  %bool = icmp eq i64 %sub.ptr.sub.i, 0
690  ret i1 %bool
691}
692
693define i1 @recursiveGEP_withPtrSub_maybeZero(ptr %val1) {
694; CHECK-LABEL: @recursiveGEP_withPtrSub_maybeZero(
695; CHECK-NEXT:  entry:
696; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
697; CHECK:       while.cond.i:
698; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ]
699; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[A_PN_I]], align 2
700; CHECK-NEXT:    [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1
701; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
702; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
703; CHECK:       while.end.i:
704; CHECK-NEXT:    [[BOOL:%.*]] = icmp eq ptr [[A_PN_I]], [[VAL1]]
705; CHECK-NEXT:    ret i1 [[BOOL]]
706;
707entry:
708  br label %while.cond.i
709
710while.cond.i:
711  %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ]
712  %0 = load i8, ptr %a.pn.i, align 2
713  %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1
714  %cmp3.not.i = icmp eq i8 %0, 0
715  br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
716
717while.end.i:
718  %sub.ptr.lhs.cast.i = ptrtoint ptr %a.pn.i to i64
719  %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64
720  %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
721  %bool = icmp eq i64 %sub.ptr.sub.i, 0
722  ret i1 %bool
723}
724
725;Non-inbounds test.
726;Test where Step is non-inbound.
727define i1 @recursiveGEP_withPtrSub_noninboundStep1(ptr %val1) {
728; CHECK-LABEL: @recursiveGEP_withPtrSub_noninboundStep1(
729; CHECK-NEXT:  entry:
730; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
731; CHECK:       while.cond.i:
732; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ]
733; CHECK-NEXT:    [[TEST_0_I]] = getelementptr i8, ptr [[A_PN_I]], i64 1
734; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2
735; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
736; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
737; CHECK:       while.end.i:
738; CHECK-NEXT:    [[BOOL:%.*]] = icmp eq ptr [[TEST_0_I]], [[VAL1]]
739; CHECK-NEXT:    ret i1 [[BOOL]]
740;
741entry:
742  br label %while.cond.i
743
744while.cond.i:
745  %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ]
746  %test.0.i = getelementptr i8, ptr %a.pn.i, i64 1
747  %0 = load i8, ptr %test.0.i, align 2
748  %cmp3.not.i = icmp eq i8 %0, 0
749  br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
750
751while.end.i:
752  %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
753  %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64
754  %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
755  %bool = icmp eq i64 %sub.ptr.sub.i, 0
756  ret i1 %bool
757}
758
759define i1 @recursiveGEP_withPtrSub_noninboundStep2(ptr %val1) {
760; CHECK-LABEL: @recursiveGEP_withPtrSub_noninboundStep2(
761; CHECK-NEXT:  entry:
762; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
763; CHECK:       while.cond.i:
764; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ]
765; CHECK-NEXT:    [[TEST_0_I]] = getelementptr i8, ptr [[A_PN_I]], i64 -1
766; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2
767; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
768; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
769; CHECK:       while.end.i:
770; CHECK-NEXT:    [[BOOL:%.*]] = icmp eq ptr [[TEST_0_I]], [[VAL1]]
771; CHECK-NEXT:    ret i1 [[BOOL]]
772;
773entry:
774  br label %while.cond.i
775
776while.cond.i:
777  %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ]
778  %test.0.i = getelementptr i8, ptr %a.pn.i, i64 -1
779  %0 = load i8, ptr %test.0.i, align 2
780  %cmp3.not.i = icmp eq i8 %0, 0
781  br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
782
783while.end.i:
784  %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
785  %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64
786  %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
787  %bool = icmp eq i64 %sub.ptr.sub.i, 0
788  ret i1 %bool
789}
790
791;Test where Step and GEP B are non-inbound.
792define i1 @recursiveGEP_withPtrSub_noninboundStepAndB(ptr %val1) {
793; CHECK-LABEL: @recursiveGEP_withPtrSub_noninboundStepAndB(
794; CHECK-NEXT:  entry:
795; CHECK-NEXT:    [[TEST:%.*]] = getelementptr inbounds nuw i8, ptr [[VAL1:%.*]], i64 2
796; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
797; CHECK:       while.cond.i:
798; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[TEST]], [[ENTRY:%.*]] ]
799; CHECK-NEXT:    [[TEST_0_I]] = getelementptr i8, ptr [[A_PN_I]], i64 1
800; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2
801; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
802; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
803; CHECK:       while.end.i:
804; CHECK-NEXT:    [[BOOL:%.*]] = icmp eq ptr [[A_PN_I]], [[VAL1]]
805; CHECK-NEXT:    ret i1 [[BOOL]]
806;
807entry:
808  %test = getelementptr inbounds i8, ptr %val1, i64 2
809  br label %while.cond.i
810
811while.cond.i:
812  %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %test, %entry ]
813  %test.0.i = getelementptr i8, ptr %a.pn.i, i64 1
814  %0 = load i8, ptr %test.0.i, align 2
815  %cmp3.not.i = icmp eq i8 %0, 0
816  br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
817
818while.end.i:
819  %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
820  %test.1.i = getelementptr i8, ptr %val1, i64 1
821  %sub.ptr.rhs.cast.i = ptrtoint ptr %test.1.i to i64
822  %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
823  %bool = icmp eq i64 %sub.ptr.sub.i, 0
824  ret i1 %bool
825}
826
827;Test where Start and Step are non-inbound.
828define i1 @recursiveGEP_withPtrSub_noninboundStartAndStep(ptr %val1) {
829; CHECK-LABEL: @recursiveGEP_withPtrSub_noninboundStartAndStep(
830; CHECK-NEXT:  entry:
831; CHECK-NEXT:    [[TEST:%.*]] = getelementptr i8, ptr [[VAL1:%.*]], i64 1
832; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
833; CHECK:       while.cond.i:
834; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[TEST]], [[ENTRY:%.*]] ]
835; CHECK-NEXT:    [[TEST_0_I]] = getelementptr i8, ptr [[A_PN_I]], i64 1
836; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2
837; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
838; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
839; CHECK:       while.end.i:
840; CHECK-NEXT:    [[BOOL:%.*]] = icmp eq ptr [[TEST_0_I]], [[VAL1]]
841; CHECK-NEXT:    ret i1 [[BOOL]]
842;
843entry:
844  %test = getelementptr i8, ptr %val1, i64 1
845  br label %while.cond.i
846
847while.cond.i:
848  %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %test, %entry ]
849  %test.0.i = getelementptr i8, ptr %a.pn.i, i64 1
850  %0 = load i8, ptr %test.0.i, align 2
851  %cmp3.not.i = icmp eq i8 %0, 0
852  br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
853
854while.end.i:
855  %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
856  %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64
857  %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
858  %bool = icmp eq i64 %sub.ptr.sub.i, 0
859  ret i1 %bool
860}
861
862;Test where Start and GEP B are non-inbounds pointer with same definition.
863define i1 @recursiveGEP_withPtrSub_noninboundSameDefStartAndB(ptr %val1) {
864; CHECK-LABEL: @recursiveGEP_withPtrSub_noninboundSameDefStartAndB(
865; CHECK-NEXT:  entry:
866; CHECK-NEXT:    [[TEST:%.*]] = getelementptr i8, ptr [[VAL1:%.*]], i64 1
867; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
868; CHECK:       while.cond.i:
869; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[TEST]], [[ENTRY:%.*]] ]
870; CHECK-NEXT:    [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1
871; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2
872; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
873; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
874; CHECK:       while.end.i:
875; CHECK-NEXT:    [[BOOL:%.*]] = icmp eq ptr [[A_PN_I]], [[VAL1]]
876; CHECK-NEXT:    ret i1 [[BOOL]]
877;
878entry:
879  %test = getelementptr i8, ptr %val1, i64 1
880  br label %while.cond.i
881
882while.cond.i:
883  %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %test, %entry ]
884  %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1
885  %0 = load i8, ptr %test.0.i, align 2
886  %cmp3.not.i = icmp eq i8 %0, 0
887  br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
888
889while.end.i:
890  %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
891  %test2 = getelementptr i8, ptr %val1, i64 1
892  %sub.ptr.rhs.cast.i = ptrtoint ptr %test2 to i64
893  %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
894  %bool = icmp eq i64 %sub.ptr.sub.i, 0
895  ret i1 %bool
896}
897
898;Test where Start and GEP B are non-inbounds and exactly same pointers.
899define i1 @recursiveGEP_withPtrSub_noninboundSameStartAndB(ptr %val1) {
900; CHECK-LABEL: @recursiveGEP_withPtrSub_noninboundSameStartAndB(
901; CHECK-NEXT:  entry:
902; CHECK-NEXT:    [[TEST:%.*]] = getelementptr i8, ptr [[VAL1:%.*]], i64 1
903; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
904; CHECK:       while.cond.i:
905; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[TEST]], [[ENTRY:%.*]] ]
906; CHECK-NEXT:    [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1
907; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2
908; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
909; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
910; CHECK:       while.end.i:
911; CHECK-NEXT:    ret i1 false
912;
913entry:
914  %test = getelementptr i8, ptr %val1, i64 1
915  br label %while.cond.i
916
917while.cond.i:
918  %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %test, %entry ]
919  %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1
920  %0 = load i8, ptr %test.0.i, align 2
921  %cmp3.not.i = icmp eq i8 %0, 0
922  br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
923
924while.end.i:
925  %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
926  %sub.ptr.rhs.cast.i = ptrtoint ptr %test to i64
927  %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
928  %bool = icmp eq i64 %sub.ptr.sub.i, 0
929  ret i1 %bool
930}
931
932define i1 @recursiveGEP_withPtrSub_scalableGEP(ptr %val1) {
933; CHECK-LABEL: @recursiveGEP_withPtrSub_scalableGEP(
934; CHECK-NEXT:  entry:
935; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
936; CHECK:       while.cond.i:
937; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ]
938; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
939; CHECK-NEXT:    [[TMP1:%.*]] = shl i64 [[TMP0]], 4
940; CHECK-NEXT:    [[TEST_0_I]] = getelementptr i8, ptr [[A_PN_I]], i64 [[TMP1]]
941; CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr [[TEST_0_I]], align 1
942; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP2]], 0
943; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
944; CHECK:       while.end.i:
945; CHECK-NEXT:    [[BOOL:%.*]] = icmp eq ptr [[TEST_0_I]], [[VAL1]]
946; CHECK-NEXT:    ret i1 [[BOOL]]
947;
948entry:
949  br label %while.cond.i
950
951while.cond.i:
952  %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ]
953  %test.0.i = getelementptr <vscale x 16 x i8>, ptr %a.pn.i, i64 1
954  %0 =  load i8, ptr %test.0.i, align 1
955  %cmp3.not.i = icmp eq i8 %0, 0
956  br  i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
957
958while.end.i:
959  %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
960  %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64
961  %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
962  %bool = icmp eq i64 %sub.ptr.sub.i, 0
963  ret i1 %bool
964}
965
966define i1 @recursiveGEP_withPtrSub_scalableGEP_inbounds(ptr %val1) {
967; CHECK-LABEL: @recursiveGEP_withPtrSub_scalableGEP_inbounds(
968; CHECK-NEXT:  entry:
969; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
970; CHECK:       while.cond.i:
971; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ]
972; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
973; CHECK-NEXT:    [[TMP1:%.*]] = shl i64 [[TMP0]], 4
974; CHECK-NEXT:    [[TEST_0_I]] = getelementptr inbounds i8, ptr [[A_PN_I]], i64 [[TMP1]]
975; CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr [[TEST_0_I]], align 1
976; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP2]], 0
977; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
978; CHECK:       while.end.i:
979; CHECK-NEXT:    [[BOOL:%.*]] = icmp eq ptr [[TEST_0_I]], [[VAL1]]
980; CHECK-NEXT:    ret i1 [[BOOL]]
981;
982entry:
983  br label %while.cond.i
984
985while.cond.i:
986  %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ]
987  %test.0.i = getelementptr inbounds <vscale x 16 x i8>, ptr %a.pn.i, i64 1
988  %0 =  load i8, ptr %test.0.i, align 1
989  %cmp3.not.i = icmp eq i8 %0, 0
990  br  i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
991
992while.end.i:
993  %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
994  %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64
995  %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
996  %bool = icmp eq i64 %sub.ptr.sub.i, 0
997  ret i1 %bool
998}
999
1000; Test cmp(or), where one of argument to OR is a SUB of ptr2int with a recursive GEP.
1001define i1 @recursiveGEP_orcmp(ptr %val1, i64 %val2) {
1002; CHECK-LABEL: @recursiveGEP_orcmp(
1003; CHECK-NEXT:  entry:
1004; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
1005; CHECK:       while.cond.i:
1006; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ]
1007; CHECK-NEXT:    [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1
1008; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2
1009; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
1010; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
1011; CHECK:       while.end.i:
1012; CHECK-NEXT:    ret i1 false
1013;
1014entry:
1015  br label %while.cond.i
1016
1017while.cond.i:
1018  %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ]
1019  %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1
1020  %0 = load i8, ptr %test.0.i, align 2
1021  %cmp3.not.i = icmp eq i8 %0, 0
1022  br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
1023
1024while.end.i:
1025  %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
1026  %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64
1027  %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
1028  %orval = or i64 %sub.ptr.sub.i, %val2
1029  %bool = icmp eq i64 %orval, 0
1030  ret i1 %bool
1031}
1032
1033define i1 @recursiveGEP_orcmp_orOperandsCommuted(ptr %val1, i64 %val2) {
1034; CHECK-LABEL: @recursiveGEP_orcmp_orOperandsCommuted(
1035; CHECK-NEXT:  entry:
1036; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
1037; CHECK:       while.cond.i:
1038; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ]
1039; CHECK-NEXT:    [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1
1040; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2
1041; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
1042; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
1043; CHECK:       while.end.i:
1044; CHECK-NEXT:    ret i1 false
1045;
1046entry:
1047  br label %while.cond.i
1048
1049while.cond.i:
1050  %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ]
1051  %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1
1052  %0 = load i8, ptr %test.0.i, align 2
1053  %cmp3.not.i = icmp eq i8 %0, 0
1054  br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
1055
1056while.end.i:
1057  %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
1058  %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64
1059  %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
1060  %orval = or i64 %val2, %sub.ptr.sub.i
1061  %bool = icmp eq i64 %orval, 0
1062  ret i1 %bool
1063}
1064
1065; Test one of the argument to SUB is a ptr2int of a recursive GEP, with multiple use of SUB.
1066define i1 @recursiveGEP_orcmpMultiUse(ptr %val1, i64 %val2, ptr %dv1, ptr %dv2) {
1067; CHECK-LABEL: @recursiveGEP_orcmpMultiUse(
1068; CHECK-NEXT:  entry:
1069; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
1070; CHECK:       while.cond.i:
1071; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ]
1072; CHECK-NEXT:    [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1
1073; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2
1074; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
1075; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
1076; CHECK:       while.end.i:
1077; CHECK-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[IF_END4:%.*]]
1078; CHECK:       if.then:
1079; CHECK-NEXT:    br label [[CLEANUP:%.*]]
1080; CHECK:       if.end4:
1081; CHECK-NEXT:    br label [[CLEANUP]]
1082; CHECK:       cleanup:
1083; CHECK-NEXT:    ret i1 true
1084;
1085entry:
1086  br label %while.cond.i
1087
1088while.cond.i:
1089  %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ]
1090  %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1
1091  %0 = load i8, ptr %test.0.i, align 2
1092  %cmp3.not.i = icmp eq i8 %0, 0
1093  br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
1094
1095while.end.i:
1096  %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
1097  %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64
1098  %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
1099  %orval = or i64 %sub.ptr.sub.i, %val2
1100  %or.cond = icmp eq i64 %orval, 0
1101  br i1 %or.cond, label %if.then, label %if.end4
1102
1103if.then:
1104  %cmp = icmp eq ptr %dv1, %dv2
1105  br label %cleanup
1106
1107if.end4:
1108  %tobool = icmp ne i64 %sub.ptr.sub.i, 0
1109  br label %cleanup
1110
1111cleanup:
1112  %retval.0 = phi i1 [ %cmp, %if.then ], [ %tobool, %if.end4 ]
1113  ret i1 %retval.0
1114}
1115
1116
1117define i32 @issue_124275_wrong_br_direction(i32 noundef %inp) {
1118; CHECK-LABEL: @issue_124275_wrong_br_direction(
1119; CHECK-NEXT:  entry:
1120; CHECK-NEXT:    [[TMP0:%.*]] = xor i32 [[INP:%.*]], -2
1121; CHECK-NEXT:    [[XOR_INP_NEG:%.*]] = add i32 [[TMP0]], 1
1122; CHECK-NEXT:    [[CMP_NE_NOT:%.*]] = icmp eq i32 [[XOR_INP_NEG]], 0
1123; CHECK-NEXT:    br i1 [[CMP_NE_NOT]], label [[B1:%.*]], label [[B0:%.*]]
1124; CHECK:       B0:
1125; CHECK-NEXT:    [[PHI_B0:%.*]] = phi i32 [ [[PHI_B1:%.*]], [[B1]] ], [ [[XOR_INP_NEG]], [[ENTRY:%.*]] ]
1126; CHECK-NEXT:    br label [[B1]]
1127; CHECK:       B1:
1128; CHECK-NEXT:    [[PHI_B1]] = phi i32 [ [[PHI_B0]], [[B0]] ], [ 0, [[ENTRY]] ]
1129; CHECK-NEXT:    [[CMP_NE_B1_NOT:%.*]] = icmp eq i32 [[PHI_B1]], 0
1130; CHECK-NEXT:    br i1 [[CMP_NE_B1_NOT]], label [[B0]], label [[END:%.*]]
1131; CHECK:       end:
1132; CHECK-NEXT:    ret i32 0
1133;
1134entry:
1135  %xor_inp = xor i32 %inp, 1
1136  %sub = sub i32 0, %xor_inp
1137  %cmp_ne = icmp ne i32 %sub, 0
1138  br i1 %cmp_ne, label %B0, label %B1
1139
1140B0:
1141  %phi_B0 = phi i32 [ %phi_B1, %B1 ], [ %sub, %entry ]
1142  br label %B1
1143
1144B1:
1145  %phi_B1 = phi i32 [ %phi_B0, %B0 ], [ 0, %entry ]
1146  %cmp_ne_B1 = icmp ne i32 %phi_B1, 0
1147  %cmp_eq_B1 = xor i1 %cmp_ne_B1, true
1148  br i1 %cmp_eq_B1, label %B0, label %end
1149
1150end:
1151  ret i32 0
1152}
1153