[rtsan] Add fork/execve interceptors (#117198)
[llvm-project.git] / llvm / test / Analysis / ValueTracking / phi-known-bits.ll
blob8691e63a4f3ee14e85eddb82ea18c8da78daf5a6
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=instcombine < %s -S | FileCheck %s
4 define 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]]
14 entry:
15   %cmp = icmp ugt i8 %x, 191
16   br i1 %cmp, label %T, label %F
18   %v = phi i8 [ %x, %entry], [-1, %F]
19   %r = and i8 %v, 64
20   ret i8 %r
22   br label %T
25 define 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
35 entry:
36   %cmp = icmp ult i8 %x, 192
37   br i1 %cmp, label %T, label %F
39   br label %F
41   %v = phi i8 [ %x, %entry], [-1, %T]
42   %r = and i8 %v, 64
43   ret i8 %r
46 define 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]]
58 entry:
59   %cmp = icmp ugt i8 %x, 190
60   br i1 %cmp, label %T, label %F
62   %v = phi i8 [ %x, %entry], [-1, %F]
63   %r = and i8 %v, 64
64   ret i8 %r
66   br label %T
69 define 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]]
79 entry:
80   %cmp = icmp uge i8 %x, 192
81   br i1 %cmp, label %T, label %F
83   %v = phi i8 [ %x, %entry], [-1, %F]
84   %r = and i8 %v, 64
85   ret i8 %r
87   br label %T
90 define 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]]
102 entry:
103   %cmp = icmp ugt i8 %x, 5
104   br i1 %cmp, label %T, label %F
106   %v = phi i8 [ %x, %entry], [-1, %F]
107   %r = and i8 %v, 1
108   ret i8 %r
110   br label %T
113 define 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]]
123 entry:
124   %cmp = icmp sge i8 %x, 96
125   br i1 %cmp, label %T, label %F
127   %v = phi i8 [ %x, %entry], [-1, %F]
128   %r = and i8 %v, 96
129   ret i8 %r
131   br label %T
134 define 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]]
146 entry:
147   %cmp = icmp sge i8 %x, -1
148   br i1 %cmp, label %T, label %F
150   %v = phi i8 [ %x, %entry], [-1, %F]
151   %r = and i8 %v, 1
152   ret i8 %r
154   br label %T
157 define 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]]
167 entry:
168   %cmp = icmp sgt i8 %x, -1
169   br i1 %cmp, label %T, label %F
171   %v = phi i8 [ %x, %entry], [0, %F]
172   %r = and i8 %v, 128
173   ret i8 %r
175   br label %T
178 define 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]]
188 entry:
189   %cmp = icmp sgt i8 %x, 63
190   br i1 %cmp, label %T, label %F
192   %v = phi i8 [ %x, %entry], [-1, %F]
193   %r = and i8 %v, 64
194   ret i8 %r
196   br label %T
199 define 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]]
211 entry:
212   %cmp = icmp sgt i8 %x, 62
213   br i1 %cmp, label %T, label %F
215   %v = phi i8 [ %x, %entry], [-1, %F]
216   %r = and i8 %v, 64
217   ret i8 %r
219   br label %T
222 define 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]]
232 entry:
233   %cmp = icmp slt i8 %x, 0
234   br i1 %cmp, label %T, label %F
236   %v = phi i8 [ %x, %entry], [-1, %F]
237   %r = and i8 %v, 128
238   ret i8 %r
240   br label %T
243 define 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]]
253 entry:
254   %cmp = icmp slt i8 %x, -64
255   br i1 %cmp, label %T, label %F
257   %v = phi i8 [ %x, %entry], [0, %F]
258   %r = and i8 %v, 64
259   ret i8 %r
261   br label %T
264 define 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]]
276 entry:
277   %cmp = icmp slt i8 %x, -63
278   br i1 %cmp, label %T, label %F
280   %v = phi i8 [ %x, %entry], [0, %F]
281   %r = and i8 %v, 64
282   ret i8 %r
284   br label %T
287 define 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]]
297 entry:
298   %cmp = icmp sle i8 %x, -65
299   br i1 %cmp, label %T, label %F
301   %v = phi i8 [ %x, %entry], [0, %F]
302   %r = and i8 %v, 64
303   ret i8 %r
305   br label %T
308 define 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
318 entry:
319   %cmp = icmp sle i8 %x, 64
320   br i1 %cmp, label %T, label %F
322   br label %F
324   %v = phi i8 [ %x, %entry], [-1, %T]
325   %r = and i8 %v, 64
326   ret i8 %r
329 define 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]]
341 entry:
342   %cmp = icmp sle i8 %x, 0
343   br i1 %cmp, label %T, label %F
345   %v = phi i8 [ %x, %entry], [-1, %F]
346   %r = and i8 %v, 128
347   ret i8 %r
349   br label %T
352 define 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]]
364 entry:
365   %cmp = icmp sle i8 %x, -64
366   br i1 %cmp, label %T, label %F
368   %v = phi i8 [ %x, %entry], [-1, %F]
369   %r = and i8 %v, 64
370   ret i8 %r
372   br label %T
375 define 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]]
388 entry:
389   %x = or i8 %xx, 1
390   %cmp = icmp ugt i8 %x, 191
391   br i1 %cmp, label %T, label %F
393   %v = phi i8 [ %x, %entry], [-1, %F]
394   %r = and i8 %v, 65
395   ret i8 %r
397   br label %T
400 define 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]]
416 entry:
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
424   %v = phi i8 [ %x, %entry], [-1, %F]
425   %r = and i8 %v, 65
426   ret i8 %r
428   br label %T
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)
433 define 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 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
446 entry:
447   br label %while.cond.i
449 while.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
456 while.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
464 define 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 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
477 entry:
478   br label %while.cond.i
480 while.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
487 while.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
495 define 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 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
508 entry:
509   br label %while.cond.i
511 while.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
518 while.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
526 define 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
539 entry:
540   br label %while.cond.i
542 while.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
549 while.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
557 define i1 @recursiveGEP_withPtrSub3(ptr %val1) {
558 ; CHECK-LABEL: @recursiveGEP_withPtrSub3(
559 ; CHECK-NEXT:  entry:
560 ; CHECK-NEXT:    [[TEST_VAL1:%.*]] = getelementptr inbounds 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 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
571 entry:
572   %test.val1 = getelementptr inbounds i8, ptr %val1, i64 7
573   br label %while.cond.i
575 while.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
582 while.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
591 define 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 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]]
606 entry:
607   br label %while.cond.i
609 while.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
616 while.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
625 define 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 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]]
640 entry:
641   %test.val1 = getelementptr inbounds i8, ptr %val1, i64 -1
642   br label %while.cond.i
644 while.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
651 while.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
659 define i1 @recursiveGEP_withPtrSub1_notKnownNonEqual3(ptr %val1) {
660 ; CHECK-LABEL: @recursiveGEP_withPtrSub1_notKnownNonEqual3(
661 ; CHECK-NEXT:  entry:
662 ; CHECK-NEXT:    [[TEST_VAL1:%.*]] = getelementptr inbounds 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]]
674 entry:
675   %test.val1 = getelementptr inbounds i8, ptr %val1, i64 5
676   br label %while.cond.i
678 while.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
685 while.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
693 define 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 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]]
707 entry:
708   br label %while.cond.i
710 while.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
717 while.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
725 ;Non-inbounds test.
726 ;Test where Step is non-inbound.
727 define 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]]
741 entry:
742   br label %while.cond.i
744 while.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
751 while.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
759 define 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]]
773 entry:
774   br label %while.cond.i
776 while.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
783 while.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
791 ;Test where Step and GEP B are non-inbound.
792 define i1 @recursiveGEP_withPtrSub_noninboundStepAndB(ptr %val1) {
793 ; CHECK-LABEL: @recursiveGEP_withPtrSub_noninboundStepAndB(
794 ; CHECK-NEXT:  entry:
795 ; CHECK-NEXT:    [[TEST:%.*]] = getelementptr inbounds 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]]
807 entry:
808   %test = getelementptr inbounds i8, ptr %val1, i64 2
809   br label %while.cond.i
811 while.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
818 while.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
827 ;Test where Start and Step are non-inbound.
828 define 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]]
843 entry:
844   %test = getelementptr i8, ptr %val1, i64 1
845   br label %while.cond.i
847 while.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
854 while.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
862 ;Test where Start and GEP B are non-inbounds pointer with same definition.
863 define 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 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]]
878 entry:
879   %test = getelementptr i8, ptr %val1, i64 1
880   br label %while.cond.i
882 while.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
889 while.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
898 ;Test where Start and GEP B are non-inbounds and exactly same pointers.
899 define 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 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
913 entry:
914   %test = getelementptr i8, ptr %val1, i64 1
915   br label %while.cond.i
917 while.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
924 while.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
932 define 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]]
948 entry:
949   br label %while.cond.i
951 while.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
958 while.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
966 define 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]]
982 entry:
983   br label %while.cond.i
985 while.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
992 while.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
1000 ; Test cmp(or), where one of argument to OR is a SUB of ptr2int with a recursive GEP.
1001 define 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 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
1014 entry:
1015   br label %while.cond.i
1017 while.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
1024 while.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
1033 define 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 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
1046 entry:
1047   br label %while.cond.i
1049 while.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
1056 while.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
1065 ; Test one of the argument to SUB is a ptr2int of a recursive GEP, with multiple use of SUB.
1066 define 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 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
1085 entry:
1086   br label %while.cond.i
1088 while.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
1095 while.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
1103 if.then:
1104   %cmp = icmp eq ptr %dv1, %dv2
1105   br label %cleanup
1107 if.end4:
1108   %tobool = icmp ne i64 %sub.ptr.sub.i, 0
1109   br label %cleanup
1111 cleanup:
1112   %retval.0 = phi i1 [ %cmp, %if.then ], [ %tobool, %if.end4 ]
1113   ret i1 %retval.0