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"
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
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)
273 @Arr_as1 = external addrspace(1) global [42 x i16]
275 define i16 @test25_as1(ptr addrspace(1) %P, i64 %A) {
276 ; CHECK-LABEL: @test25_as1(
277 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[A:%.*]] to i16
278 ; CHECK-NEXT: [[B_IDX:%.*]] = shl nsw i16 [[TMP1]], 1
279 ; CHECK-NEXT: [[GEPDIFF:%.*]] = add nsw i16 [[B_IDX]], -84
280 ; CHECK-NEXT: ret i16 [[GEPDIFF]]
282 %B = getelementptr inbounds [42 x i16], ptr addrspace(1) @Arr_as1, i64 0, i64 %A
283 %C = ptrtoint ptr addrspace(1) %B to i16
284 %G = sub i16 %C, ptrtoint (ptr addrspace(1) getelementptr ([42 x i16], ptr addrspace(1) @Arr_as1, i64 1, i64 0) to i16)
288 define i64 @test30(ptr %foo, i64 %i, i64 %j) {
289 ; CHECK-LABEL: @test30(
290 ; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2
291 ; CHECK-NEXT: [[GEPDIFF:%.*]] = sub nsw i64 [[GEP1_IDX]], [[J:%.*]]
292 ; CHECK-NEXT: ret i64 [[GEPDIFF]]
294 %gep1 = getelementptr inbounds i32, ptr %foo, i64 %i
295 %gep2 = getelementptr inbounds i8, ptr %foo, i64 %j
296 %cast1 = ptrtoint ptr %gep1 to i64
297 %cast2 = ptrtoint ptr %gep2 to i64
298 %sub = sub i64 %cast1, %cast2
302 define i16 @test30_as1(ptr addrspace(1) %foo, i16 %i, i16 %j) {
303 ; CHECK-LABEL: @test30_as1(
304 ; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i16 [[I:%.*]], 2
305 ; CHECK-NEXT: [[GEPDIFF:%.*]] = sub nsw i16 [[GEP1_IDX]], [[J:%.*]]
306 ; CHECK-NEXT: ret i16 [[GEPDIFF]]
308 %gep1 = getelementptr inbounds i32, ptr addrspace(1) %foo, i16 %i
309 %gep2 = getelementptr inbounds i8, ptr addrspace(1) %foo, i16 %j
310 %cast1 = ptrtoint ptr addrspace(1) %gep1 to i16
311 %cast2 = ptrtoint ptr addrspace(1) %gep2 to i16
312 %sub = sub i16 %cast1, %cast2
316 ; Inbounds translates to 'nsw' on sub
318 define i64 @gep_diff_both_inbounds(ptr %foo, i64 %i, i64 %j) {
319 ; CHECK-LABEL: @gep_diff_both_inbounds(
320 ; CHECK-NEXT: [[GEPDIFF:%.*]] = sub nsw i64 [[I:%.*]], [[J:%.*]]
321 ; CHECK-NEXT: ret i64 [[GEPDIFF]]
323 %gep1 = getelementptr inbounds i8, ptr %foo, i64 %i
324 %gep2 = getelementptr inbounds i8, ptr %foo, i64 %j
325 %cast1 = ptrtoint ptr %gep1 to i64
326 %cast2 = ptrtoint ptr %gep2 to i64
327 %sub = sub i64 %cast1, %cast2
331 ; Negative test for 'nsw' - both geps must be inbounds
333 define i64 @gep_diff_first_inbounds(ptr %foo, i64 %i, i64 %j) {
334 ; CHECK-LABEL: @gep_diff_first_inbounds(
335 ; CHECK-NEXT: [[GEPDIFF:%.*]] = sub i64 [[I:%.*]], [[J:%.*]]
336 ; CHECK-NEXT: ret i64 [[GEPDIFF]]
338 %gep1 = getelementptr inbounds i8, ptr %foo, i64 %i
339 %gep2 = getelementptr i8, ptr %foo, i64 %j
340 %cast1 = ptrtoint ptr %gep1 to i64
341 %cast2 = ptrtoint ptr %gep2 to i64
342 %sub = sub i64 %cast1, %cast2
346 ; Negative test for 'nsw' - both geps must be inbounds
348 define i64 @gep_diff_second_inbounds(ptr %foo, i64 %i, i64 %j) {
349 ; CHECK-LABEL: @gep_diff_second_inbounds(
350 ; CHECK-NEXT: [[GEPDIFF:%.*]] = sub i64 [[I:%.*]], [[J:%.*]]
351 ; CHECK-NEXT: ret i64 [[GEPDIFF]]
353 %gep1 = getelementptr i8, ptr %foo, i64 %i
354 %gep2 = getelementptr inbounds i8, ptr %foo, i64 %j
355 %cast1 = ptrtoint ptr %gep1 to i64
356 %cast2 = ptrtoint ptr %gep2 to i64
357 %sub = sub i64 %cast1, %cast2
361 define i64 @gep_diff_with_bitcast(ptr %p, i64 %idx) {
362 ; CHECK-LABEL: @gep_diff_with_bitcast(
363 ; CHECK-NEXT: ret i64 [[IDX:%.*]]
365 %i1 = getelementptr inbounds [4 x i64], ptr %p, i64 %idx
366 %i3 = ptrtoint ptr %i1 to i64
367 %i4 = ptrtoint ptr %p to i64
368 %i5 = sub nuw i64 %i3, %i4
369 %i6 = lshr i64 %i5, 5
373 define i64 @sub_scalable(ptr noundef %val1) {
374 ; CHECK-LABEL: @sub_scalable(
376 ; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
377 ; CHECK-NEXT: [[TMP1:%.*]] = shl i64 [[TMP0]], 4
378 ; CHECK-NEXT: ret i64 [[TMP1]]
381 %gep1 = getelementptr <vscale x 4 x i32>, ptr %val1, i64 1
382 %sub.ptr.lhs.cast.i = ptrtoint ptr %gep1 to i64
383 %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64
384 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
385 ret i64 %sub.ptr.sub.i
388 define i64 @sub_scalable2(ptr noundef %val1) {
389 ; CHECK-LABEL: @sub_scalable2(
391 ; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
392 ; CHECK-NEXT: [[TMP1:%.*]] = shl i64 [[TMP0]], 4
393 ; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.vscale.i64()
394 ; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl i64 [[TMP2]], 5
395 ; CHECK-NEXT: [[GEPDIFF:%.*]] = sub i64 [[TMP1]], [[GEP2_IDX]]
396 ; CHECK-NEXT: ret i64 [[GEPDIFF]]
399 %gep1 = getelementptr <vscale x 4 x i32>, ptr %val1, i64 1
400 %sub.ptr.lhs.cast.i = ptrtoint ptr %gep1 to i64
401 %gep2 = getelementptr <vscale x 4 x i32>, ptr %val1, i64 2
402 %sub.ptr.rhs.cast.i = ptrtoint ptr %gep2 to i64
403 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
404 ret i64 %sub.ptr.sub.i
407 define i64 @nullptrtoint_scalable_c() {
408 ; CHECK-LABEL: @nullptrtoint_scalable_c(
410 ; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
411 ; CHECK-NEXT: [[PTR_IDX:%.*]] = shl i64 [[TMP0]], 7
412 ; CHECK-NEXT: ret i64 [[PTR_IDX]]
415 %ptr = getelementptr inbounds <vscale x 4 x i32>, ptr null, i64 8
416 %ret = ptrtoint ptr %ptr to i64
420 define i64 @nullptrtoint_scalable_x(i64 %x) {
421 ; CHECK-LABEL: @nullptrtoint_scalable_x(
423 ; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
424 ; CHECK-NEXT: [[TMP1:%.*]] = shl i64 [[TMP0]], 4
425 ; CHECK-NEXT: [[PTR_IDX:%.*]] = mul nsw i64 [[TMP1]], [[X:%.*]]
426 ; CHECK-NEXT: ret i64 [[PTR_IDX]]
429 %ptr = getelementptr inbounds <vscale x 4 x i32>, ptr null, i64 %x
430 %ret = ptrtoint ptr %ptr to i64
434 define i1 @_gep_phi1(ptr %str1) {
435 ; CHECK-LABEL: @_gep_phi1(
437 ; CHECK-NEXT: [[CMP_I:%.*]] = icmp eq ptr [[STR1:%.*]], null
438 ; CHECK-NEXT: br i1 [[CMP_I]], label [[_Z3FOOPKC_EXIT:%.*]], label [[LOR_LHS_FALSE_I:%.*]]
439 ; CHECK: lor.lhs.false.i:
440 ; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[STR1]], align 1
441 ; CHECK-NEXT: [[CMP1_I:%.*]] = icmp eq i8 [[TMP0]], 0
442 ; CHECK-NEXT: br i1 [[CMP1_I]], label [[_Z3FOOPKC_EXIT]], label [[WHILE_COND_I:%.*]]
443 ; CHECK: while.cond.i:
444 ; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[STR1]], [[LOR_LHS_FALSE_I]] ]
445 ; CHECK-NEXT: [[TEST_0_I]] = getelementptr inbounds i8, ptr [[A_PN_I]], i64 1
446 ; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[TEST_0_I]], align 1
447 ; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP1]], 0
448 ; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
449 ; CHECK: while.end.i:
450 ; CHECK-NEXT: br label [[_Z3FOOPKC_EXIT]]
451 ; CHECK: _Z3fooPKc.exit:
452 ; CHECK-NEXT: [[TOBOOL:%.*]] = phi i1 [ true, [[WHILE_END_I]] ], [ false, [[LOR_LHS_FALSE_I]] ], [ false, [[ENTRY:%.*]] ]
453 ; CHECK-NEXT: ret i1 [[TOBOOL]]
456 %cmp.i = icmp eq ptr %str1, null
457 br i1 %cmp.i, label %_Z3fooPKc.exit, label %lor.lhs.false.i
460 %0 = load i8, ptr %str1, align 1
461 %cmp1.i = icmp eq i8 %0, 0
462 br i1 %cmp1.i, label %_Z3fooPKc.exit, label %while.cond.i
465 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %str1, %lor.lhs.false.i ]
466 %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1
467 %1 = load i8, ptr %test.0.i, align 1
468 %cmp3.not.i = icmp eq i8 %1, 0
469 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
472 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
473 %sub.ptr.rhs.cast.i = ptrtoint ptr %str1 to i64
474 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
475 br label %_Z3fooPKc.exit
478 %retval.0.i = phi i64 [ %sub.ptr.sub.i, %while.end.i ], [ 0, %lor.lhs.false.i ], [ 0, %entry ]
479 %tobool = icmp ne i64 %retval.0.i, 0
483 define i1 @_gep_phi2(ptr %str1, i64 %val2) {
484 ; CHECK-LABEL: @_gep_phi2(
486 ; CHECK-NEXT: [[CMP_I:%.*]] = icmp eq ptr [[STR1:%.*]], null
487 ; CHECK-NEXT: br i1 [[CMP_I]], label [[_Z3FOOPKC_EXIT:%.*]], label [[LOR_LHS_FALSE_I:%.*]]
488 ; CHECK: lor.lhs.false.i:
489 ; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[STR1]], align 1
490 ; CHECK-NEXT: [[CMP1_I:%.*]] = icmp eq i8 [[TMP0]], 0
491 ; CHECK-NEXT: br i1 [[CMP1_I]], label [[_Z3FOOPKC_EXIT]], label [[WHILE_COND_I:%.*]]
492 ; CHECK: while.cond.i:
493 ; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[STR1]], [[LOR_LHS_FALSE_I]] ]
494 ; CHECK-NEXT: [[TEST_0_I]] = getelementptr inbounds i8, ptr [[A_PN_I]], i64 1
495 ; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[TEST_0_I]], align 1
496 ; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP1]], 0
497 ; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
498 ; CHECK: while.end.i:
499 ; CHECK-NEXT: br label [[_Z3FOOPKC_EXIT]]
500 ; CHECK: _Z3fooPKc.exit:
501 ; CHECK-NEXT: [[RETVAL_0_I:%.*]] = phi i64 [ 1, [[WHILE_END_I]] ], [ 0, [[LOR_LHS_FALSE_I]] ], [ 0, [[ENTRY:%.*]] ]
502 ; CHECK-NEXT: [[TMP2:%.*]] = or i64 [[RETVAL_0_I]], [[VAL2:%.*]]
503 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[TMP2]], 0
504 ; CHECK-NEXT: ret i1 [[TOBOOL]]
507 %cmp.i = icmp eq ptr %str1, null
508 br i1 %cmp.i, label %_Z3fooPKc.exit, label %lor.lhs.false.i
511 %0 = load i8, ptr %str1, align 1
512 %cmp1.i = icmp eq i8 %0, 0
513 br i1 %cmp1.i, label %_Z3fooPKc.exit, label %while.cond.i
516 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %str1, %lor.lhs.false.i ]
517 %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1
518 %1 = load i8, ptr %test.0.i, align 1
519 %cmp3.not.i = icmp eq i8 %1, 0
520 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
523 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
524 %sub.ptr.rhs.cast.i = ptrtoint ptr %str1 to i64
525 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
526 br label %_Z3fooPKc.exit
529 %retval.0.i = phi i64 [ %sub.ptr.sub.i, %while.end.i ], [ 0, %lor.lhs.false.i ], [ 0, %entry ]
530 %2 = or i64 %retval.0.i, %val2
531 %tobool = icmp eq i64 %2, 0