[AArch64][NFC] NFC for const vector as Instruction operand (#116790)
[llvm-project.git] / llvm / test / Transforms / InstCombine / sub-gep.ll
blobf7a54ab2141bd7db8b6643f8b9580cef673cf7f6
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
4 target datalayout = "e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-p2:32:32"
6 define i64 @test_inbounds(ptr %base, i64 %idx) {
7 ; CHECK-LABEL: @test_inbounds(
8 ; CHECK-NEXT:    [[P2_IDX:%.*]] = shl nsw i64 [[IDX:%.*]], 2
9 ; CHECK-NEXT:    ret i64 [[P2_IDX]]
11   %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx
12   %i1 = ptrtoint ptr %base to i64
13   %i2 = ptrtoint ptr %p2 to i64
14   %d = sub i64 %i2, %i1
15   ret i64 %d
18 define i64 @test_partial_inbounds1(ptr %base, i64 %idx) {
19 ; CHECK-LABEL: @test_partial_inbounds1(
20 ; CHECK-NEXT:    [[P2_IDX:%.*]] = shl i64 [[IDX:%.*]], 2
21 ; CHECK-NEXT:    ret i64 [[P2_IDX]]
23   %p2 = getelementptr [0 x i32], ptr %base, i64 0, i64 %idx
24   %i1 = ptrtoint ptr %base to i64
25   %i2 = ptrtoint ptr %p2 to i64
26   %d = sub i64 %i2, %i1
27   ret i64 %d
30 define i64 @test_partial_inbounds2(ptr %base, i64 %idx) {
31 ; CHECK-LABEL: @test_partial_inbounds2(
32 ; CHECK-NEXT:    [[P2_IDX:%.*]] = shl nsw i64 [[IDX:%.*]], 2
33 ; CHECK-NEXT:    ret i64 [[P2_IDX]]
35   %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx
36   %i1 = ptrtoint ptr %base to i64
37   %i2 = ptrtoint ptr %p2 to i64
38   %d = sub i64 %i2, %i1
39   ret i64 %d
42 define i64 @test_inbounds_nuw(ptr %base, i64 %idx) {
43 ; CHECK-LABEL: @test_inbounds_nuw(
44 ; CHECK-NEXT:    [[P2_IDX:%.*]] = shl nuw nsw i64 [[IDX:%.*]], 2
45 ; CHECK-NEXT:    ret i64 [[P2_IDX]]
47   %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx
48   %i1 = ptrtoint ptr %base to i64
49   %i2 = ptrtoint ptr %p2 to i64
50   %d = sub nuw i64 %i2, %i1
51   ret i64 %d
54 define i64 @test_nuw(ptr %base, i64 %idx) {
55 ; CHECK-LABEL: @test_nuw(
56 ; CHECK-NEXT:    [[P2_IDX:%.*]] = shl i64 [[IDX:%.*]], 2
57 ; CHECK-NEXT:    ret i64 [[P2_IDX]]
59   %p2 = getelementptr [0 x i32], ptr %base, i64 0, i64 %idx
60   %i1 = ptrtoint ptr %base to i64
61   %i2 = ptrtoint ptr %p2 to i64
62   %d = sub nuw i64 %i2, %i1
63   ret i64 %d
66 define i32 @test_inbounds_nuw_trunc(ptr %base, i64 %idx) {
67 ; CHECK-LABEL: @test_inbounds_nuw_trunc(
68 ; CHECK-NEXT:    [[IDX_TR:%.*]] = trunc i64 [[IDX:%.*]] to i32
69 ; CHECK-NEXT:    [[D:%.*]] = shl i32 [[IDX_TR]], 2
70 ; CHECK-NEXT:    ret i32 [[D]]
72   %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx
73   %i1 = ptrtoint ptr %base to i64
74   %i2 = ptrtoint ptr %p2 to i64
75   %t1 = trunc i64 %i1 to i32
76   %t2 = trunc i64 %i2 to i32
77   %d = sub nuw i32 %t2, %t1
78   ret i32 %d
81 define i64 @test_inbounds_nuw_swapped(ptr %base, i64 %idx) {
82 ; CHECK-LABEL: @test_inbounds_nuw_swapped(
83 ; CHECK-NEXT:    [[P2_IDX_NEG:%.*]] = mul i64 [[IDX:%.*]], -4
84 ; CHECK-NEXT:    ret i64 [[P2_IDX_NEG]]
86   %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx
87   %i1 = ptrtoint ptr %p2 to i64
88   %i2 = ptrtoint ptr %base to i64
89   %d = sub nuw i64 %i2, %i1
90   ret i64 %d
93 define i64 @test_inbounds1_nuw_swapped(ptr %base, i64 %idx) {
94 ; CHECK-LABEL: @test_inbounds1_nuw_swapped(
95 ; CHECK-NEXT:    [[P2_IDX_NEG:%.*]] = mul i64 [[IDX:%.*]], -4
96 ; CHECK-NEXT:    ret i64 [[P2_IDX_NEG]]
98   %p2 = getelementptr [0 x i32], ptr %base, i64 0, i64 %idx
99   %i1 = ptrtoint ptr %p2 to i64
100   %i2 = ptrtoint ptr %base to i64
101   %d = sub nuw i64 %i2, %i1
102   ret i64 %d
105 define i64 @test_inbounds2_nuw_swapped(ptr %base, i64 %idx) {
106 ; CHECK-LABEL: @test_inbounds2_nuw_swapped(
107 ; CHECK-NEXT:    [[P2_IDX_NEG:%.*]] = mul i64 [[IDX:%.*]], -4
108 ; CHECK-NEXT:    ret i64 [[P2_IDX_NEG]]
110   %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx
111   %i1 = ptrtoint ptr %p2 to i64
112   %i2 = ptrtoint ptr %base to i64
113   %d = sub nuw i64 %i2, %i1
114   ret i64 %d
117 define i64 @test_inbounds_two_gep(ptr %base, i64 %idx, i64 %idx2) {
118 ; CHECK-LABEL: @test_inbounds_two_gep(
119 ; CHECK-NEXT:    [[TMP1:%.*]] = sub nsw i64 [[IDX2:%.*]], [[IDX:%.*]]
120 ; CHECK-NEXT:    [[GEPDIFF:%.*]] = shl nsw i64 [[TMP1]], 2
121 ; CHECK-NEXT:    ret i64 [[GEPDIFF]]
123   %p1 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx
124   %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx2
125   %i1 = ptrtoint ptr %p1 to i64
126   %i2 = ptrtoint ptr %p2 to i64
127   %d = sub i64 %i2, %i1
128   ret i64 %d
131 define i64 @test_inbounds_nsw_two_gep(ptr %base, i64 %idx, i64 %idx2) {
132 ; CHECK-LABEL: @test_inbounds_nsw_two_gep(
133 ; CHECK-NEXT:    [[TMP1:%.*]] = sub nsw i64 [[IDX2:%.*]], [[IDX:%.*]]
134 ; CHECK-NEXT:    [[GEPDIFF:%.*]] = shl nsw i64 [[TMP1]], 2
135 ; CHECK-NEXT:    ret i64 [[GEPDIFF]]
137   %p1 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx
138   %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx2
139   %i1 = ptrtoint ptr %p1 to i64
140   %i2 = ptrtoint ptr %p2 to i64
141   %d = sub nsw i64 %i2, %i1
142   ret i64 %d
145 define i64 @test_inbounds_nuw_two_gep(ptr %base, i64 %idx, i64 %idx2) {
146 ; CHECK-LABEL: @test_inbounds_nuw_two_gep(
147 ; CHECK-NEXT:    [[TMP1:%.*]] = sub nsw i64 [[IDX2:%.*]], [[IDX:%.*]]
148 ; CHECK-NEXT:    [[GEPDIFF:%.*]] = shl nsw i64 [[TMP1]], 2
149 ; CHECK-NEXT:    ret i64 [[GEPDIFF]]
151   %p1 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx
152   %p2 = getelementptr inbounds [0 x i32], ptr %base, i64 0, i64 %idx2
153   %i1 = ptrtoint ptr %p1 to i64
154   %i2 = ptrtoint ptr %p2 to i64
155   %d = sub nuw i64 %i2, %i1
156   ret i64 %d
159 define i64 @test_inbounds_nuw_multi_index(ptr %base, i64 %idx, i64 %idx2) {
160 ; CHECK-LABEL: @test_inbounds_nuw_multi_index(
161 ; CHECK-NEXT:    [[P2_IDX:%.*]] = shl nsw i64 [[IDX:%.*]], 3
162 ; CHECK-NEXT:    [[P2_IDX1:%.*]] = shl nsw i64 [[IDX2:%.*]], 2
163 ; CHECK-NEXT:    [[P2_OFFS:%.*]] = add nsw i64 [[P2_IDX]], [[P2_IDX1]]
164 ; CHECK-NEXT:    ret i64 [[P2_OFFS]]
166   %p2 = getelementptr inbounds [0 x [2 x i32]], ptr %base, i64 0, i64 %idx, i64 %idx2
167   %i1 = ptrtoint ptr %base to i64
168   %i2 = ptrtoint ptr %p2 to i64
169   %d = sub nuw i64 %i2, %i1
170   ret i64 %d
173 ; rdar://7362831
174 define i32 @test23(ptr %P, i64 %A){
175 ; CHECK-LABEL: @test23(
176 ; CHECK-NEXT:    [[G:%.*]] = trunc i64 [[A:%.*]] to i32
177 ; CHECK-NEXT:    ret i32 [[G]]
179   %B = getelementptr inbounds i8, ptr %P, i64 %A
180   %C = ptrtoint ptr %B to i64
181   %D = trunc i64 %C to i32
182   %E = ptrtoint ptr %P to i64
183   %F = trunc i64 %E to i32
184   %G = sub i32 %D, %F
185   ret i32 %G
188 define i8 @test23_as1(ptr addrspace(1) %P, i16 %A) {
189 ; CHECK-LABEL: @test23_as1(
190 ; CHECK-NEXT:    [[G:%.*]] = trunc i16 [[A:%.*]] to i8
191 ; CHECK-NEXT:    ret i8 [[G]]
193   %B = getelementptr inbounds i8, ptr addrspace(1) %P, i16 %A
194   %C = ptrtoint ptr addrspace(1) %B to i16
195   %D = trunc i16 %C to i8
196   %E = ptrtoint ptr addrspace(1) %P to i16
197   %F = trunc i16 %E to i8
198   %G = sub i8 %D, %F
199   ret i8 %G
202 define i64 @test24(ptr %P, i64 %A){
203 ; CHECK-LABEL: @test24(
204 ; CHECK-NEXT:    ret i64 [[A:%.*]]
206   %B = getelementptr inbounds i8, ptr %P, i64 %A
207   %C = ptrtoint ptr %B to i64
208   %E = ptrtoint ptr %P to i64
209   %G = sub i64 %C, %E
210   ret i64 %G
213 define i16 @test24_as1(ptr addrspace(1) %P, i16 %A) {
214 ; CHECK-LABEL: @test24_as1(
215 ; CHECK-NEXT:    ret i16 [[A:%.*]]
217   %B = getelementptr inbounds i8, ptr addrspace(1) %P, i16 %A
218   %C = ptrtoint ptr addrspace(1) %B to i16
219   %E = ptrtoint ptr addrspace(1) %P to i16
220   %G = sub i16 %C, %E
221   ret i16 %G
224 define i64 @test24a(ptr %P, i64 %A){
225 ; CHECK-LABEL: @test24a(
226 ; CHECK-NEXT:    [[DIFF_NEG:%.*]] = sub i64 0, [[A:%.*]]
227 ; CHECK-NEXT:    ret i64 [[DIFF_NEG]]
229   %B = getelementptr inbounds i8, ptr %P, i64 %A
230   %C = ptrtoint ptr %B to i64
231   %E = ptrtoint ptr %P to i64
232   %G = sub i64 %E, %C
233   ret i64 %G
236 define i16 @test24a_as1(ptr addrspace(1) %P, i16 %A) {
237 ; CHECK-LABEL: @test24a_as1(
238 ; CHECK-NEXT:    [[DIFF_NEG:%.*]] = sub i16 0, [[A:%.*]]
239 ; CHECK-NEXT:    ret i16 [[DIFF_NEG]]
241   %B = getelementptr inbounds i8, ptr addrspace(1) %P, i16 %A
242   %C = ptrtoint ptr addrspace(1) %B to i16
243   %E = ptrtoint ptr addrspace(1) %P to i16
244   %G = sub i16 %E, %C
245   ret i16 %G
248 @Arr = external global [42 x i16]
250 define i64 @test24b(ptr %P, i64 %A){
251 ; CHECK-LABEL: @test24b(
252 ; CHECK-NEXT:    [[B_IDX:%.*]] = shl nsw i64 [[A:%.*]], 1
253 ; CHECK-NEXT:    ret i64 [[B_IDX]]
255   %B = getelementptr inbounds [42 x i16], ptr @Arr, i64 0, i64 %A
256   %C = ptrtoint ptr %B to i64
257   %G = sub i64 %C, ptrtoint (ptr @Arr to i64)
258   ret i64 %G
261 define i64 @test25(ptr %P, i64 %A){
262 ; CHECK-LABEL: @test25(
263 ; CHECK-NEXT:    [[B_IDX:%.*]] = shl nsw i64 [[A:%.*]], 1
264 ; CHECK-NEXT:    [[GEPDIFF:%.*]] = add nsw i64 [[B_IDX]], -84
265 ; CHECK-NEXT:    ret i64 [[GEPDIFF]]
267   %B = getelementptr inbounds [42 x i16], ptr @Arr, i64 0, i64 %A
268   %C = ptrtoint ptr %B to i64
269   %G = sub i64 %C, ptrtoint (ptr getelementptr ([42 x i16], ptr @Arr, i64 1, i64 0) to i64)
270   ret i64 %G
273 define i64 @zext_ptrtoint_sub_ptrtoint(ptr %p, i32 %offset) {
274 ; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint(
275 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[OFFSET:%.*]] to i64
276 ; CHECK-NEXT:    [[A:%.*]] = getelementptr bfloat, ptr @Arr, i64 [[TMP1]]
277 ; CHECK-NEXT:    [[TMP2:%.*]] = ptrtoint ptr [[A]] to i64
278 ; CHECK-NEXT:    [[C:%.*]] = and i64 [[TMP2]], 4294967294
279 ; CHECK-NEXT:    [[D:%.*]] = sub i64 [[C]], ptrtoint (ptr @Arr to i64)
280 ; CHECK-NEXT:    ret i64 [[D]]
282   %A = getelementptr bfloat, ptr @Arr, i32 %offset
283   %B = ptrtoint ptr %A to i32
284   %C = zext i32 %B to i64
285   %D = sub i64 %C, ptrtoint (ptr @Arr to i64)
286   ret i64 %D
289 define i64 @ptrtoint_sub_zext_ptrtoint(ptr %p, i32 %offset) {
290 ; CHECK-LABEL: @ptrtoint_sub_zext_ptrtoint(
291 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[OFFSET:%.*]] to i64
292 ; CHECK-NEXT:    [[A:%.*]] = getelementptr bfloat, ptr @Arr, i64 [[TMP1]]
293 ; CHECK-NEXT:    [[TMP2:%.*]] = ptrtoint ptr [[A]] to i64
294 ; CHECK-NEXT:    [[C:%.*]] = and i64 [[TMP2]], 4294967294
295 ; CHECK-NEXT:    [[D:%.*]] = sub i64 ptrtoint (ptr @Arr to i64), [[C]]
296 ; CHECK-NEXT:    ret i64 [[D]]
298   %A = getelementptr bfloat, ptr @Arr, i32 %offset
299   %B = ptrtoint ptr %A to i32
300   %C = zext i32 %B to i64
301   %D = sub i64 ptrtoint (ptr @Arr to i64), %C
302   ret i64 %D
305 define i64 @negative_zext_ptrtoint_sub_ptrtoint(ptr %p, i32 %offset) {
306 ; CHECK-LABEL: @negative_zext_ptrtoint_sub_ptrtoint(
307 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[OFFSET:%.*]] to i64
308 ; CHECK-NEXT:    [[A:%.*]] = getelementptr bfloat, ptr @Arr, i64 [[TMP1]]
309 ; CHECK-NEXT:    [[TMP2:%.*]] = ptrtoint ptr [[A]] to i64
310 ; CHECK-NEXT:    [[C:%.*]] = and i64 [[TMP2]], 65534
311 ; CHECK-NEXT:    [[D:%.*]] = sub i64 [[C]], ptrtoint (ptr @Arr to i64)
312 ; CHECK-NEXT:    ret i64 [[D]]
314   %A = getelementptr bfloat, ptr @Arr, i32 %offset
315   %B = ptrtoint ptr %A to i16
316   %C = zext i16 %B to i64
317   %D = sub i64 %C, ptrtoint (ptr @Arr to i64)
318   ret i64 %D
321 define i64 @negative_ptrtoint_sub_zext_ptrtoint(ptr %p, i32 %offset) {
322 ; CHECK-LABEL: @negative_ptrtoint_sub_zext_ptrtoint(
323 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[OFFSET:%.*]] to i64
324 ; CHECK-NEXT:    [[A:%.*]] = getelementptr bfloat, ptr @Arr, i64 [[TMP1]]
325 ; CHECK-NEXT:    [[TMP2:%.*]] = ptrtoint ptr [[A]] to i64
326 ; CHECK-NEXT:    [[C:%.*]] = and i64 [[TMP2]], 65534
327 ; CHECK-NEXT:    [[D:%.*]] = sub i64 ptrtoint (ptr @Arr to i64), [[C]]
328 ; CHECK-NEXT:    ret i64 [[D]]
330   %A = getelementptr bfloat, ptr @Arr, i32 %offset
331   %B = ptrtoint ptr %A to i16
332   %C = zext i16 %B to i64
333   %D = sub i64 ptrtoint (ptr @Arr to i64), %C
334   ret i64 %D
337 @Arr_as1 = external addrspace(1) global [42 x i16]
339 define i16 @test25_as1(ptr addrspace(1) %P, i64 %A) {
340 ; CHECK-LABEL: @test25_as1(
341 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[A:%.*]] to i16
342 ; CHECK-NEXT:    [[B_IDX:%.*]] = shl nsw i16 [[TMP1]], 1
343 ; CHECK-NEXT:    [[GEPDIFF:%.*]] = add nsw i16 [[B_IDX]], -84
344 ; CHECK-NEXT:    ret i16 [[GEPDIFF]]
346   %B = getelementptr inbounds [42 x i16], ptr addrspace(1) @Arr_as1, i64 0, i64 %A
347   %C = ptrtoint ptr addrspace(1) %B to i16
348   %G = sub i16 %C, ptrtoint (ptr addrspace(1) getelementptr ([42 x i16], ptr addrspace(1) @Arr_as1, i64 1, i64 0) to i16)
349   ret i16 %G
352 @Arr_as2 = external addrspace(2) global [42 x i16]
354 define i64 @ptrtoint_sub_zext_ptrtoint_as2_inbounds(i32 %offset) {
355 ; CHECK-LABEL: @ptrtoint_sub_zext_ptrtoint_as2_inbounds(
356 ; CHECK-NEXT:    [[A:%.*]] = getelementptr inbounds bfloat, ptr addrspace(2) @Arr_as2, i32 [[OFFSET:%.*]]
357 ; CHECK-NEXT:    [[B:%.*]] = ptrtoint ptr addrspace(2) [[A]] to i32
358 ; CHECK-NEXT:    [[C:%.*]] = zext i32 [[B]] to i64
359 ; CHECK-NEXT:    [[D:%.*]] = sub nsw i64 ptrtoint (ptr addrspace(2) @Arr_as2 to i64), [[C]]
360 ; CHECK-NEXT:    ret i64 [[D]]
362   %A = getelementptr inbounds bfloat, ptr addrspace(2) @Arr_as2, i32 %offset
363   %B = ptrtoint ptr addrspace(2) %A to i32
364   %C = zext i32 %B to i64
365   %D = sub i64 ptrtoint (ptr addrspace(2) @Arr_as2 to i64), %C
366   ret i64 %D
369 define i64 @zext_ptrtoint_sub_ptrtoint_as2_nusw(i32 %offset) {
370 ; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nusw(
371 ; CHECK-NEXT:    [[A_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 1
372 ; CHECK-NEXT:    [[D:%.*]] = sext i32 [[A_IDX]] to i64
373 ; CHECK-NEXT:    ret i64 [[D]]
375   %A = getelementptr nusw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset
376   %B = ptrtoint ptr addrspace(2) %A to i32
377   %C = zext i32 %B to i64
378   %D = sub i64 %C, ptrtoint (ptr addrspace(2) @Arr_as2 to i64)
379   ret i64 %D
382 define i64 @zext_ptrtoint_sub_ptrtoint_as2_nuw(i32 %offset) {
383 ; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nuw(
384 ; CHECK-NEXT:    [[A_IDX:%.*]] = shl nuw i32 [[OFFSET:%.*]], 1
385 ; CHECK-NEXT:    [[D:%.*]] = zext i32 [[A_IDX]] to i64
386 ; CHECK-NEXT:    ret i64 [[D]]
388   %A = getelementptr nuw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset
389   %B = ptrtoint ptr addrspace(2) %A to i32
390   %C = zext i32 %B to i64
391   %D = sub i64 %C, ptrtoint (ptr addrspace(2) @Arr_as2 to i64)
392   ret i64 %D
395 define i64 @zext_ptrtoint_sub_ptrtoint_as2_nusw_nuw(i32 %offset) {
396 ; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nusw_nuw(
397 ; CHECK-NEXT:    [[A_IDX:%.*]] = shl nuw nsw i32 [[OFFSET:%.*]], 1
398 ; CHECK-NEXT:    [[D:%.*]] = zext nneg i32 [[A_IDX]] to i64
399 ; CHECK-NEXT:    ret i64 [[D]]
401   %A = getelementptr nusw nuw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset
402   %B = ptrtoint ptr addrspace(2) %A to i32
403   %C = zext i32 %B to i64
404   %D = sub i64 %C, ptrtoint (ptr addrspace(2) @Arr_as2 to i64)
405   ret i64 %D
408 define i64 @zext_ptrtoint_sub_zext_ptrtoint_as2_nusw(i32 %offset) {
409 ; CHECK-LABEL: @zext_ptrtoint_sub_zext_ptrtoint_as2_nusw(
410 ; CHECK-NEXT:    [[A_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 1
411 ; CHECK-NEXT:    [[E:%.*]] = sext i32 [[A_IDX]] to i64
412 ; CHECK-NEXT:    ret i64 [[E]]
414   %A = getelementptr nusw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset
415   %B = ptrtoint ptr addrspace(2) %A to i32
416   %C = zext i32 %B to i64
417   %D = zext i32 ptrtoint (ptr addrspace(2) @Arr_as2 to i32) to i64
418   %E = sub i64 %C, %D
419   ret i64 %E
422 define i64 @zext_ptrtoint_sub_zext_ptrtoint_as2_nuw(i32 %offset) {
423 ; CHECK-LABEL: @zext_ptrtoint_sub_zext_ptrtoint_as2_nuw(
424 ; CHECK-NEXT:    [[A_IDX:%.*]] = shl nuw i32 [[OFFSET:%.*]], 1
425 ; CHECK-NEXT:    [[E:%.*]] = zext i32 [[A_IDX]] to i64
426 ; CHECK-NEXT:    ret i64 [[E]]
428   %A = getelementptr nuw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset
429   %B = ptrtoint ptr addrspace(2) %A to i32
430   %C = zext i32 %B to i64
431   %D = zext i32 ptrtoint (ptr addrspace(2) @Arr_as2 to i32) to i64
432   %E = sub i64 %C, %D
433   ret i64 %E
436 define i64 @negative_zext_ptrtoint_sub_ptrtoint_as2_nuw(i32 %offset) {
437 ; CHECK-LABEL: @negative_zext_ptrtoint_sub_ptrtoint_as2_nuw(
438 ; CHECK-NEXT:    [[A:%.*]] = getelementptr nuw bfloat, ptr addrspace(2) @Arr_as2, i32 [[OFFSET:%.*]]
439 ; CHECK-NEXT:    [[TMP1:%.*]] = ptrtoint ptr addrspace(2) [[A]] to i32
440 ; CHECK-NEXT:    [[B_MASK:%.*]] = and i32 [[TMP1]], 65534
441 ; CHECK-NEXT:    [[C:%.*]] = zext nneg i32 [[B_MASK]] to i64
442 ; CHECK-NEXT:    [[D:%.*]] = sub nsw i64 [[C]], ptrtoint (ptr addrspace(2) @Arr_as2 to i64)
443 ; CHECK-NEXT:    ret i64 [[D]]
445   %A = getelementptr nuw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset
446   %B = ptrtoint ptr addrspace(2) %A to i16
447   %C = zext i16 %B to i64
448   %D = sub i64 %C, ptrtoint (ptr addrspace(2) @Arr_as2 to i64)
449   ret i64 %D
452 define i64 @ptrtoint_sub_zext_ptrtoint_as2_inbounds_local(ptr addrspace(2) %p, i32 %offset) {
453 ; CHECK-LABEL: @ptrtoint_sub_zext_ptrtoint_as2_inbounds_local(
454 ; CHECK-NEXT:    [[A:%.*]] = getelementptr inbounds bfloat, ptr addrspace(2) [[P:%.*]], i32 [[OFFSET:%.*]]
455 ; CHECK-NEXT:    [[B:%.*]] = ptrtoint ptr addrspace(2) [[A]] to i32
456 ; CHECK-NEXT:    [[C:%.*]] = zext i32 [[B]] to i64
457 ; CHECK-NEXT:    [[TMP1:%.*]] = ptrtoint ptr addrspace(2) [[P]] to i32
458 ; CHECK-NEXT:    [[CC:%.*]] = zext i32 [[TMP1]] to i64
459 ; CHECK-NEXT:    [[D:%.*]] = sub nsw i64 [[CC]], [[C]]
460 ; CHECK-NEXT:    ret i64 [[D]]
462   %A = getelementptr inbounds bfloat, ptr addrspace(2) %p, i32 %offset
463   %B = ptrtoint ptr addrspace(2) %A to i32
464   %C = zext i32 %B to i64
465   %CC = ptrtoint ptr addrspace(2) %p to i64
466   %D = sub i64 %CC, %C
467   ret i64 %D
470 define i64 @zext_ptrtoint_sub_ptrtoint_as2_nusw_local(ptr addrspace(2) %p, i32 %offset) {
471 ; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nusw_local(
472 ; CHECK-NEXT:    [[A_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 1
473 ; CHECK-NEXT:    [[D:%.*]] = sext i32 [[A_IDX]] to i64
474 ; CHECK-NEXT:    ret i64 [[D]]
476   %A = getelementptr nusw bfloat, ptr addrspace(2) %p, i32 %offset
477   %B = ptrtoint ptr addrspace(2) %A to i32
478   %C = zext i32 %B to i64
479   %CC = ptrtoint ptr addrspace(2) %p to i64
480   %D = sub i64 %C, %CC
481   ret i64 %D
484 define i64 @zext_ptrtoint_sub_ptrtoint_as2_nuw_local(ptr addrspace(2) %p, i32 %offset) {
485 ; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nuw_local(
486 ; CHECK-NEXT:    [[A_IDX:%.*]] = shl nuw i32 [[OFFSET:%.*]], 1
487 ; CHECK-NEXT:    [[D:%.*]] = zext i32 [[A_IDX]] to i64
488 ; CHECK-NEXT:    ret i64 [[D]]
490   %A = getelementptr nuw bfloat, ptr addrspace(2) %p, i32 %offset
491   %B = ptrtoint ptr addrspace(2) %A to i32
492   %C = zext i32 %B to i64
493   %CC = ptrtoint ptr addrspace(2) %p to i64
494   %D = sub i64 %C, %CC
495   ret i64 %D
498 define i64 @zext_ptrtoint_sub_ptrtoint_as2_nusw_nuw_local(ptr addrspace(2) %p, i32 %offset) {
499 ; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nusw_nuw_local(
500 ; CHECK-NEXT:    [[A_IDX:%.*]] = shl nuw nsw i32 [[OFFSET:%.*]], 1
501 ; CHECK-NEXT:    [[D:%.*]] = zext nneg i32 [[A_IDX]] to i64
502 ; CHECK-NEXT:    ret i64 [[D]]
504   %A = getelementptr nusw nuw bfloat, ptr addrspace(2) %p, i32 %offset
505   %B = ptrtoint ptr addrspace(2) %A to i32
506   %C = zext i32 %B to i64
507   %CC = ptrtoint ptr addrspace(2) %p to i64
508   %D = sub i64 %C, %CC
509   ret i64 %D
512 define i64 @zext_ptrtoint_sub_zext_ptrtoint_as2_nusw_local(ptr addrspace(2) %p, i32 %offset) {
513 ; CHECK-LABEL: @zext_ptrtoint_sub_zext_ptrtoint_as2_nusw_local(
514 ; CHECK-NEXT:    [[A_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 1
515 ; CHECK-NEXT:    [[E:%.*]] = sext i32 [[A_IDX]] to i64
516 ; CHECK-NEXT:    ret i64 [[E]]
518   %A = getelementptr nusw bfloat, ptr addrspace(2) %p, i32 %offset
519   %B = ptrtoint ptr addrspace(2) %A to i32
520   %C = zext i32 %B to i64
521   %CC = ptrtoint ptr addrspace(2) %p to i32
522   %D = zext i32 %CC to i64
523   %E = sub i64 %C, %D
524   ret i64 %E
527 define i64 @zext_ptrtoint_sub_zext_ptrtoint_as2_nuw_local(ptr addrspace(2) %p, i32 %offset) {
528 ; CHECK-LABEL: @zext_ptrtoint_sub_zext_ptrtoint_as2_nuw_local(
529 ; CHECK-NEXT:    [[A_IDX:%.*]] = shl nuw i32 [[OFFSET:%.*]], 1
530 ; CHECK-NEXT:    [[E:%.*]] = zext i32 [[A_IDX]] to i64
531 ; CHECK-NEXT:    ret i64 [[E]]
533   %A = getelementptr nuw bfloat, ptr addrspace(2) %p, i32 %offset
534   %B = ptrtoint ptr addrspace(2) %A to i32
535   %C = zext i32 %B to i64
536   %CC = ptrtoint ptr addrspace(2) %p to i32
537   %D = zext i32 %CC to i64
538   %E = sub i64 %C, %D
539   ret i64 %E
542 define i64 @negative_zext_ptrtoint_sub_ptrtoint_as2_nuw_local(ptr addrspace(2) %p, i32 %offset) {
543 ; CHECK-LABEL: @negative_zext_ptrtoint_sub_ptrtoint_as2_nuw_local(
544 ; CHECK-NEXT:    [[A:%.*]] = getelementptr nuw bfloat, ptr addrspace(2) [[P:%.*]], i32 [[OFFSET:%.*]]
545 ; CHECK-NEXT:    [[TMP1:%.*]] = ptrtoint ptr addrspace(2) [[A]] to i32
546 ; CHECK-NEXT:    [[B_MASK:%.*]] = and i32 [[TMP1]], 65535
547 ; CHECK-NEXT:    [[C:%.*]] = zext nneg i32 [[B_MASK]] to i64
548 ; CHECK-NEXT:    [[TMP2:%.*]] = ptrtoint ptr addrspace(2) [[P]] to i32
549 ; CHECK-NEXT:    [[CC:%.*]] = zext i32 [[TMP2]] to i64
550 ; CHECK-NEXT:    [[D:%.*]] = sub nsw i64 [[C]], [[CC]]
551 ; CHECK-NEXT:    ret i64 [[D]]
553   %A = getelementptr nuw bfloat, ptr addrspace(2) %p, i32 %offset
554   %B = ptrtoint ptr addrspace(2) %A to i16
555   %C = zext i16 %B to i64
556   %CC = ptrtoint ptr addrspace(2) %p to i64
557   %D = sub i64 %C, %CC
558   ret i64 %D
561 define i64 @test30(ptr %foo, i64 %i, i64 %j) {
562 ; CHECK-LABEL: @test30(
563 ; CHECK-NEXT:    [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2
564 ; CHECK-NEXT:    [[GEPDIFF:%.*]] = sub nsw i64 [[GEP1_IDX]], [[J:%.*]]
565 ; CHECK-NEXT:    ret i64 [[GEPDIFF]]
567   %gep1 = getelementptr inbounds i32, ptr %foo, i64 %i
568   %gep2 = getelementptr inbounds i8, ptr %foo, i64 %j
569   %cast1 = ptrtoint ptr %gep1 to i64
570   %cast2 = ptrtoint ptr %gep2 to i64
571   %sub = sub i64 %cast1, %cast2
572   ret i64 %sub
575 define i16 @test30_as1(ptr addrspace(1) %foo, i16 %i, i16 %j) {
576 ; CHECK-LABEL: @test30_as1(
577 ; CHECK-NEXT:    [[GEP1_IDX:%.*]] = shl nsw i16 [[I:%.*]], 2
578 ; CHECK-NEXT:    [[GEPDIFF:%.*]] = sub nsw i16 [[GEP1_IDX]], [[J:%.*]]
579 ; CHECK-NEXT:    ret i16 [[GEPDIFF]]
581   %gep1 = getelementptr inbounds i32, ptr addrspace(1) %foo, i16 %i
582   %gep2 = getelementptr inbounds i8, ptr addrspace(1) %foo, i16 %j
583   %cast1 = ptrtoint ptr addrspace(1) %gep1 to i16
584   %cast2 = ptrtoint ptr addrspace(1) %gep2 to i16
585   %sub = sub i16 %cast1, %cast2
586   ret i16 %sub
589 ; Inbounds translates to 'nsw' on sub
591 define i64 @gep_diff_both_inbounds(ptr %foo, i64 %i, i64 %j) {
592 ; CHECK-LABEL: @gep_diff_both_inbounds(
593 ; CHECK-NEXT:    [[GEPDIFF:%.*]] = sub nsw i64 [[I:%.*]], [[J:%.*]]
594 ; CHECK-NEXT:    ret i64 [[GEPDIFF]]
596   %gep1 = getelementptr inbounds i8, ptr %foo, i64 %i
597   %gep2 = getelementptr inbounds i8, ptr %foo, i64 %j
598   %cast1 = ptrtoint ptr %gep1 to i64
599   %cast2 = ptrtoint ptr %gep2 to i64
600   %sub = sub i64 %cast1, %cast2
601   ret i64 %sub
604 ; Negative test for 'nsw' - both geps must be inbounds
606 define i64 @gep_diff_first_inbounds(ptr %foo, i64 %i, i64 %j) {
607 ; CHECK-LABEL: @gep_diff_first_inbounds(
608 ; CHECK-NEXT:    [[GEPDIFF:%.*]] = sub i64 [[I:%.*]], [[J:%.*]]
609 ; CHECK-NEXT:    ret i64 [[GEPDIFF]]
611   %gep1 = getelementptr inbounds i8, ptr %foo, i64 %i
612   %gep2 = getelementptr i8, ptr %foo, i64 %j
613   %cast1 = ptrtoint ptr %gep1 to i64
614   %cast2 = ptrtoint ptr %gep2 to i64
615   %sub = sub i64 %cast1, %cast2
616   ret i64 %sub
619 ; Negative test for 'nsw' - both geps must be inbounds
621 define i64 @gep_diff_second_inbounds(ptr %foo, i64 %i, i64 %j) {
622 ; CHECK-LABEL: @gep_diff_second_inbounds(
623 ; CHECK-NEXT:    [[GEPDIFF:%.*]] = sub i64 [[I:%.*]], [[J:%.*]]
624 ; CHECK-NEXT:    ret i64 [[GEPDIFF]]
626   %gep1 = getelementptr i8, ptr %foo, i64 %i
627   %gep2 = getelementptr inbounds i8, ptr %foo, i64 %j
628   %cast1 = ptrtoint ptr %gep1 to i64
629   %cast2 = ptrtoint ptr %gep2 to i64
630   %sub = sub i64 %cast1, %cast2
631   ret i64 %sub
634 define i64 @gep_diff_with_bitcast(ptr %p, i64 %idx) {
635 ; CHECK-LABEL: @gep_diff_with_bitcast(
636 ; CHECK-NEXT:    ret i64 [[IDX:%.*]]
638   %i1 = getelementptr inbounds [4 x i64], ptr %p, i64 %idx
639   %i3 = ptrtoint ptr %i1 to i64
640   %i4 = ptrtoint ptr %p to i64
641   %i5 = sub nuw i64 %i3, %i4
642   %i6 = lshr i64 %i5, 5
643   ret i64 %i6
646 define i64 @sub_scalable(ptr noundef %val1) {
647 ; CHECK-LABEL: @sub_scalable(
648 ; CHECK-NEXT:  entry:
649 ; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
650 ; CHECK-NEXT:    [[TMP1:%.*]] = shl i64 [[TMP0]], 4
651 ; CHECK-NEXT:    ret i64 [[TMP1]]
653 entry:
654   %gep1 = getelementptr <vscale x 4 x i32>, ptr %val1, i64 1
655   %sub.ptr.lhs.cast.i = ptrtoint ptr %gep1 to i64
656   %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64
657   %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
658   ret i64 %sub.ptr.sub.i
661 define i64 @sub_scalable2(ptr noundef %val1) {
662 ; CHECK-LABEL: @sub_scalable2(
663 ; CHECK-NEXT:  entry:
664 ; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
665 ; CHECK-NEXT:    [[TMP1:%.*]] = shl i64 [[TMP0]], 4
666 ; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.vscale.i64()
667 ; CHECK-NEXT:    [[GEP2_IDX:%.*]] = shl i64 [[TMP2]], 5
668 ; CHECK-NEXT:    [[GEPDIFF:%.*]] = sub i64 [[TMP1]], [[GEP2_IDX]]
669 ; CHECK-NEXT:    ret i64 [[GEPDIFF]]
671 entry:
672   %gep1 = getelementptr <vscale x 4 x i32>, ptr %val1, i64 1
673   %sub.ptr.lhs.cast.i = ptrtoint ptr %gep1 to i64
674   %gep2 = getelementptr <vscale x 4 x i32>, ptr %val1, i64 2
675   %sub.ptr.rhs.cast.i = ptrtoint ptr %gep2 to i64
676   %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
677   ret i64 %sub.ptr.sub.i
680 define i64 @nullptrtoint_scalable_c() {
681 ; CHECK-LABEL: @nullptrtoint_scalable_c(
682 ; CHECK-NEXT:  entry:
683 ; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
684 ; CHECK-NEXT:    [[PTR_IDX:%.*]] = shl i64 [[TMP0]], 7
685 ; CHECK-NEXT:    ret i64 [[PTR_IDX]]
687 entry:
688   %ptr = getelementptr inbounds <vscale x 4 x i32>, ptr null, i64 8
689   %ret = ptrtoint ptr %ptr to i64
690   ret i64 %ret
693 define i64 @nullptrtoint_scalable_x(i64 %x) {
694 ; CHECK-LABEL: @nullptrtoint_scalable_x(
695 ; CHECK-NEXT:  entry:
696 ; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
697 ; CHECK-NEXT:    [[TMP1:%.*]] = shl i64 [[TMP0]], 4
698 ; CHECK-NEXT:    [[PTR_IDX:%.*]] = mul nsw i64 [[X:%.*]], [[TMP1]]
699 ; CHECK-NEXT:    ret i64 [[PTR_IDX]]
701 entry:
702   %ptr = getelementptr inbounds <vscale x 4 x i32>, ptr null, i64 %x
703   %ret = ptrtoint ptr %ptr to i64
704   ret i64 %ret
707 define i1 @_gep_phi1(ptr %str1) {
708 ; CHECK-LABEL: @_gep_phi1(
709 ; CHECK-NEXT:  entry:
710 ; CHECK-NEXT:    [[CMP_I:%.*]] = icmp eq ptr [[STR1:%.*]], null
711 ; CHECK-NEXT:    br i1 [[CMP_I]], label [[_Z3FOOPKC_EXIT:%.*]], label [[LOR_LHS_FALSE_I:%.*]]
712 ; CHECK:       lor.lhs.false.i:
713 ; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[STR1]], align 1
714 ; CHECK-NEXT:    [[CMP1_I:%.*]] = icmp eq i8 [[TMP0]], 0
715 ; CHECK-NEXT:    br i1 [[CMP1_I]], label [[_Z3FOOPKC_EXIT]], label [[WHILE_COND_I:%.*]]
716 ; CHECK:       while.cond.i:
717 ; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[STR1]], [[LOR_LHS_FALSE_I]] ]
718 ; CHECK-NEXT:    [[TEST_0_I]] = getelementptr inbounds i8, ptr [[A_PN_I]], i64 1
719 ; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[TEST_0_I]], align 1
720 ; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP1]], 0
721 ; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
722 ; CHECK:       while.end.i:
723 ; CHECK-NEXT:    br label [[_Z3FOOPKC_EXIT]]
724 ; CHECK:       _Z3fooPKc.exit:
725 ; CHECK-NEXT:    [[TOBOOL:%.*]] = phi i1 [ true, [[WHILE_END_I]] ], [ false, [[LOR_LHS_FALSE_I]] ], [ false, [[ENTRY:%.*]] ]
726 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
728 entry:
729   %cmp.i = icmp eq ptr %str1, null
730   br i1 %cmp.i, label %_Z3fooPKc.exit, label %lor.lhs.false.i
732 lor.lhs.false.i:
733   %0 = load i8, ptr %str1, align 1
734   %cmp1.i = icmp eq i8 %0, 0
735   br i1 %cmp1.i, label %_Z3fooPKc.exit, label %while.cond.i
737 while.cond.i:
738   %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %str1, %lor.lhs.false.i ]
739   %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1
740   %1 = load i8, ptr %test.0.i, align 1
741   %cmp3.not.i = icmp eq i8 %1, 0
742   br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
744 while.end.i:
745   %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
746   %sub.ptr.rhs.cast.i = ptrtoint ptr %str1 to i64
747   %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
748   br label %_Z3fooPKc.exit
750 _Z3fooPKc.exit:
751   %retval.0.i = phi i64 [ %sub.ptr.sub.i, %while.end.i ], [ 0, %lor.lhs.false.i ], [ 0, %entry ]
752   %tobool = icmp ne i64 %retval.0.i, 0
753   ret i1 %tobool
756 define i1 @_gep_phi2(ptr %str1, i64 %val2) {
757 ; CHECK-LABEL: @_gep_phi2(
758 ; CHECK-NEXT:  entry:
759 ; CHECK-NEXT:    [[CMP_I:%.*]] = icmp eq ptr [[STR1:%.*]], null
760 ; CHECK-NEXT:    br i1 [[CMP_I]], label [[_Z3FOOPKC_EXIT:%.*]], label [[LOR_LHS_FALSE_I:%.*]]
761 ; CHECK:       lor.lhs.false.i:
762 ; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[STR1]], align 1
763 ; CHECK-NEXT:    [[CMP1_I:%.*]] = icmp eq i8 [[TMP0]], 0
764 ; CHECK-NEXT:    br i1 [[CMP1_I]], label [[_Z3FOOPKC_EXIT]], label [[WHILE_COND_I:%.*]]
765 ; CHECK:       while.cond.i:
766 ; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[STR1]], [[LOR_LHS_FALSE_I]] ]
767 ; CHECK-NEXT:    [[TEST_0_I]] = getelementptr inbounds i8, ptr [[A_PN_I]], i64 1
768 ; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[TEST_0_I]], align 1
769 ; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP1]], 0
770 ; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
771 ; CHECK:       while.end.i:
772 ; CHECK-NEXT:    br label [[_Z3FOOPKC_EXIT]]
773 ; CHECK:       _Z3fooPKc.exit:
774 ; CHECK-NEXT:    [[RETVAL_0_I:%.*]] = phi i64 [ 1, [[WHILE_END_I]] ], [ 0, [[LOR_LHS_FALSE_I]] ], [ 0, [[ENTRY:%.*]] ]
775 ; CHECK-NEXT:    [[TMP2:%.*]] = or i64 [[RETVAL_0_I]], [[VAL2:%.*]]
776 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[TMP2]], 0
777 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
779 entry:
780   %cmp.i = icmp eq ptr %str1, null
781   br i1 %cmp.i, label %_Z3fooPKc.exit, label %lor.lhs.false.i
783 lor.lhs.false.i:
784   %0 = load i8, ptr %str1, align 1
785   %cmp1.i = icmp eq i8 %0, 0
786   br i1 %cmp1.i, label %_Z3fooPKc.exit, label %while.cond.i
788 while.cond.i:
789   %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %str1, %lor.lhs.false.i ]
790   %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1
791   %1 = load i8, ptr %test.0.i, align 1
792   %cmp3.not.i = icmp eq i8 %1, 0
793   br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
795 while.end.i:
796   %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
797   %sub.ptr.rhs.cast.i = ptrtoint ptr %str1 to i64
798   %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
799   br label %_Z3fooPKc.exit
801 _Z3fooPKc.exit:
802   %retval.0.i = phi i64 [ %sub.ptr.sub.i, %while.end.i ], [ 0, %lor.lhs.false.i ], [ 0, %entry ]
803   %2 = or i64 %retval.0.i, %val2
804   %tobool = icmp eq i64 %2, 0
805   ret i1 %tobool