1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
4 target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
10 define void @test_monotonic_ptr_iv_inc_1_eq_to_uge(ptr %start) {
11 ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_eq_to_uge(
12 ; CHECK-NEXT: loop.ph:
13 ; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 10
14 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
16 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
17 ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
18 ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
20 ; CHECK-NEXT: [[AND:%.*]] = and i1 true, true
21 ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
23 ; CHECK-NEXT: call void @use(ptr [[PTR_IV]])
24 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1
25 ; CHECK-NEXT: br label [[LOOP_HEADER]]
27 ; CHECK-NEXT: ret void
30 %upper = getelementptr inbounds i32, ptr %start, i16 10
34 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
35 %c = icmp eq ptr %ptr.iv, %upper
36 br i1 %c, label %exit, label %for.body
39 %t.1 = icmp uge ptr %ptr.iv, %start
40 %t.2 = icmp ult ptr %ptr.iv, %upper
41 %and = and i1 %t.1, %t.2
42 br i1 %and, label %loop.latch, label %exit
45 call void @use(ptr %ptr.iv)
46 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1
53 define void @test_monotonic_ptr_iv_inc_1_upper_is_multiple_1(ptr %start) {
54 ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_multiple_1(
55 ; CHECK-NEXT: loop.ph:
56 ; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 15
57 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
59 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
60 ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
61 ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
63 ; CHECK-NEXT: [[AND:%.*]] = and i1 true, true
64 ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
66 ; CHECK-NEXT: call void @use(ptr [[PTR_IV]])
67 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1
68 ; CHECK-NEXT: br label [[LOOP_HEADER]]
70 ; CHECK-NEXT: ret void
73 %upper = getelementptr inbounds i8, ptr %start, i16 15
77 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
78 %c = icmp eq ptr %ptr.iv, %upper
79 br i1 %c, label %exit, label %for.body
82 %t.1 = icmp uge ptr %ptr.iv, %start
83 %t.2 = icmp ult ptr %ptr.iv, %upper
84 %and = and i1 %t.1, %t.2
85 br i1 %and, label %loop.latch, label %exit
88 call void @use(ptr %ptr.iv)
89 %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1
96 define void @test_monotonic_ptr_iv_inc_1_upper_is_multiple_2(ptr %start) {
97 ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_multiple_2(
98 ; CHECK-NEXT: loop.ph:
99 ; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 16
100 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
101 ; CHECK: loop.header:
102 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
103 ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
104 ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
106 ; CHECK-NEXT: [[AND:%.*]] = and i1 true, true
107 ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
109 ; CHECK-NEXT: call void @use(ptr [[PTR_IV]])
110 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i16, ptr [[PTR_IV]], i16 1
111 ; CHECK-NEXT: br label [[LOOP_HEADER]]
113 ; CHECK-NEXT: ret void
116 %upper = getelementptr inbounds i8, ptr %start, i16 16
117 br label %loop.header
120 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
121 %c = icmp eq ptr %ptr.iv, %upper
122 br i1 %c, label %exit, label %for.body
125 %t.1 = icmp uge ptr %ptr.iv, %start
126 %t.2 = icmp ult ptr %ptr.iv, %upper
127 %and = and i1 %t.1, %t.2
128 br i1 %and, label %loop.latch, label %exit
131 call void @use(ptr %ptr.iv)
132 %ptr.iv.next = getelementptr inbounds i16, ptr %ptr.iv, i16 1
133 br label %loop.header
139 define void @test_monotonic_ptr_iv_inc_upper_is_not_multiple_1(ptr %start) {
140 ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_upper_is_not_multiple_1(
141 ; CHECK-NEXT: loop.ph:
142 ; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 15
143 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
144 ; CHECK: loop.header:
145 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
146 ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
147 ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
149 ; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]
150 ; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]]
151 ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
153 ; CHECK-NEXT: call void @use(ptr [[PTR_IV]])
154 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1
155 ; CHECK-NEXT: br label [[LOOP_HEADER]]
157 ; CHECK-NEXT: ret void
160 %upper = getelementptr inbounds i8, ptr %start, i16 15
161 br label %loop.header
164 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
165 %c = icmp eq ptr %ptr.iv, %upper
166 br i1 %c, label %exit, label %for.body
169 %t.1 = icmp uge ptr %ptr.iv, %start
170 %t.2 = icmp ult ptr %ptr.iv, %upper
171 %and = and i1 %t.1, %t.2
172 br i1 %and, label %loop.latch, label %exit
175 call void @use(ptr %ptr.iv)
176 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1
177 br label %loop.header
183 define void @test_monotonic_ptr_iv_inc_upper_is_not_multiple_2(ptr %start) {
184 ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_upper_is_not_multiple_2(
185 ; CHECK-NEXT: loop.ph:
186 ; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 15
187 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
188 ; CHECK: loop.header:
189 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
190 ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
191 ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
193 ; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]
194 ; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]]
195 ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
197 ; CHECK-NEXT: call void @use(ptr [[PTR_IV]])
198 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1
199 ; CHECK-NEXT: br label [[LOOP_HEADER]]
201 ; CHECK-NEXT: ret void
204 %upper = getelementptr inbounds i8, ptr %start, i16 15
205 br label %loop.header
208 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
209 %c = icmp eq ptr %ptr.iv, %upper
210 br i1 %c, label %exit, label %for.body
213 %t.1 = icmp uge ptr %ptr.iv, %start
214 %t.2 = icmp ult ptr %ptr.iv, %upper
215 %and = and i1 %t.1, %t.2
216 br i1 %and, label %loop.latch, label %exit
219 call void @use(ptr %ptr.iv)
220 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1
221 br label %loop.header
227 define void @test_monotonic_ptr_iv_inc_1_upper_is_multiple_with_early_exit_1(ptr %start) {
228 ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_multiple_with_early_exit_1(
229 ; CHECK-NEXT: loop.ph:
230 ; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 10
231 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
232 ; CHECK: loop.header:
233 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
234 ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
235 ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
237 ; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()
238 ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
240 ; CHECK-NEXT: [[AND:%.*]] = and i1 true, true
241 ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
243 ; CHECK-NEXT: call void @use(ptr [[PTR_IV]])
244 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1
245 ; CHECK-NEXT: br label [[LOOP_HEADER]]
247 ; CHECK-NEXT: ret void
250 %upper = getelementptr inbounds i8, ptr %start, i16 10
251 br label %loop.header
254 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
255 %c = icmp eq ptr %ptr.iv, %upper
256 br i1 %c, label %exit, label %for.body
259 %c.1 = call i1 @cond()
260 br i1 %c.1, label %loop.next, label %exit
263 %t.1 = icmp uge ptr %ptr.iv, %start
264 %t.2 = icmp ult ptr %ptr.iv, %upper
265 %and = and i1 %t.1, %t.2
266 br i1 %and, label %loop.latch, label %exit
269 call void @use(ptr %ptr.iv)
270 %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1
271 br label %loop.header
277 define void @test_monotonic_ptr_iv_inc_1_upper_is_multiple_with_early_exit_2(ptr %start) {
278 ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_multiple_with_early_exit_2(
279 ; CHECK-NEXT: loop.ph:
280 ; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 10
281 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
282 ; CHECK: loop.header:
283 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
284 ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
285 ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
287 ; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()
288 ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
290 ; CHECK-NEXT: [[AND:%.*]] = and i1 true, true
291 ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
293 ; CHECK-NEXT: call void @use(ptr [[PTR_IV]])
294 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i16, ptr [[PTR_IV]], i16 1
295 ; CHECK-NEXT: br label [[LOOP_HEADER]]
297 ; CHECK-NEXT: ret void
300 %upper = getelementptr inbounds i8, ptr %start, i16 10
301 br label %loop.header
304 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
305 %c = icmp eq ptr %ptr.iv, %upper
306 br i1 %c, label %exit, label %for.body
309 %c.1 = call i1 @cond()
310 br i1 %c.1, label %loop.next, label %exit
313 %t.1 = icmp uge ptr %ptr.iv, %start
314 %t.2 = icmp ult ptr %ptr.iv, %upper
315 %and = and i1 %t.1, %t.2
316 br i1 %and, label %loop.latch, label %exit
319 call void @use(ptr %ptr.iv)
320 %ptr.iv.next = getelementptr inbounds i16, ptr %ptr.iv, i16 1
321 br label %loop.header
327 define void @test_monotonic_ptr_iv_inc_1_upper_is_multiple_with_early_exit_3(ptr %start) {
328 ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_multiple_with_early_exit_3(
329 ; CHECK-NEXT: loop.ph:
330 ; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i16, ptr [[START:%.*]], i16 16
331 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
332 ; CHECK: loop.header:
333 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
334 ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
335 ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
337 ; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()
338 ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
340 ; CHECK-NEXT: [[AND:%.*]] = and i1 true, true
341 ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
343 ; CHECK-NEXT: call void @use(ptr [[PTR_IV]])
344 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1
345 ; CHECK-NEXT: br label [[LOOP_HEADER]]
347 ; CHECK-NEXT: ret void
350 %upper = getelementptr inbounds i16, ptr %start, i16 16
351 br label %loop.header
354 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
355 %c = icmp eq ptr %ptr.iv, %upper
356 br i1 %c, label %exit, label %for.body
359 %c.1 = call i1 @cond()
360 br i1 %c.1, label %loop.next, label %exit
363 %t.1 = icmp uge ptr %ptr.iv, %start
364 %t.2 = icmp ult ptr %ptr.iv, %upper
365 %and = and i1 %t.1, %t.2
366 br i1 %and, label %loop.latch, label %exit
369 call void @use(ptr %ptr.iv)
370 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1
371 br label %loop.header
377 define void @test_monotonic_ptr_iv_inc_1_upper_is_no_multiple_with_early_exit_1(ptr %start) {
378 ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_no_multiple_with_early_exit_1(
379 ; CHECK-NEXT: loop.ph:
380 ; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 10
381 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
382 ; CHECK: loop.header:
383 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
384 ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
385 ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
387 ; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()
388 ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
390 ; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]
391 ; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]]
392 ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
394 ; CHECK-NEXT: call void @use(ptr [[PTR_IV]])
395 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1
396 ; CHECK-NEXT: br label [[LOOP_HEADER]]
398 ; CHECK-NEXT: ret void
401 %upper = getelementptr inbounds i8, ptr %start, i16 10
402 br label %loop.header
405 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
406 %c = icmp eq ptr %ptr.iv, %upper
407 br i1 %c, label %exit, label %for.body
410 %c.1 = call i1 @cond()
411 br i1 %c.1, label %loop.next, label %exit
414 %t.1 = icmp uge ptr %ptr.iv, %start
415 %t.2 = icmp ult ptr %ptr.iv, %upper
416 %and = and i1 %t.1, %t.2
417 br i1 %and, label %loop.latch, label %exit
420 call void @use(ptr %ptr.iv)
421 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1
422 br label %loop.header
428 define void @test_monotonic_ptr_iv_inc_1_upper_is_no_multiple_with_early_exit_2(ptr %start) {
429 ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_no_multiple_with_early_exit_2(
430 ; CHECK-NEXT: loop.ph:
431 ; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 11
432 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
433 ; CHECK: loop.header:
434 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
435 ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
436 ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
438 ; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()
439 ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
441 ; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]
442 ; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]]
443 ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
445 ; CHECK-NEXT: call void @use(ptr [[PTR_IV]])
446 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i16, ptr [[PTR_IV]], i16 1
447 ; CHECK-NEXT: br label [[LOOP_HEADER]]
449 ; CHECK-NEXT: ret void
452 %upper = getelementptr inbounds i8, ptr %start, i16 11
453 br label %loop.header
456 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
457 %c = icmp eq ptr %ptr.iv, %upper
458 br i1 %c, label %exit, label %for.body
461 %c.1 = call i1 @cond()
462 br i1 %c.1, label %loop.next, label %exit
465 %t.1 = icmp uge ptr %ptr.iv, %start
466 %t.2 = icmp ult ptr %ptr.iv, %upper
467 %and = and i1 %t.1, %t.2
468 br i1 %and, label %loop.latch, label %exit
471 call void @use(ptr %ptr.iv)
472 %ptr.iv.next = getelementptr inbounds i16, ptr %ptr.iv, i16 1
473 br label %loop.header
479 define void @test_monotonic_ptr_iv_inc_1_upper_is_no_multiple_with_early_exit_3(ptr %start) {
480 ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_no_multiple_with_early_exit_3(
481 ; CHECK-NEXT: loop.ph:
482 ; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i16, ptr [[START:%.*]], i16 9
483 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
484 ; CHECK: loop.header:
485 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
486 ; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
487 ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
489 ; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()
490 ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
492 ; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]
493 ; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]]
494 ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
496 ; CHECK-NEXT: call void @use(ptr [[PTR_IV]])
497 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1
498 ; CHECK-NEXT: br label [[LOOP_HEADER]]
500 ; CHECK-NEXT: ret void
503 %upper = getelementptr inbounds i16, ptr %start, i16 9
504 br label %loop.header
507 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
508 %c = icmp eq ptr %ptr.iv, %upper
509 br i1 %c, label %exit, label %for.body
512 %c.1 = call i1 @cond()
513 br i1 %c.1, label %loop.next, label %exit
516 %t.1 = icmp uge ptr %ptr.iv, %start
517 %t.2 = icmp ult ptr %ptr.iv, %upper
518 %and = and i1 %t.1, %t.2
519 br i1 %and, label %loop.latch, label %exit
522 call void @use(ptr %ptr.iv)
523 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1
524 br label %loop.header