Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / monotonic-pointer-phis-constant-upper-offset.ll
blob7a2cc35389a2ba07f3cf1607b2727f0b11cd0cef
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"
7 declare void @use(ptr)
8 declare i1 @cond()
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:%.*]]
15 ; CHECK:       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:%.*]]
19 ; CHECK:       for.body:
20 ; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true
21 ; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
22 ; CHECK:       loop.latch:
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]]
26 ; CHECK:       exit:
27 ; CHECK-NEXT:    ret void
29 loop.ph:
30   %upper = getelementptr inbounds i32, ptr %start, i16 10
31   br label %loop.header
33 loop.header:
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
38 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
44 loop.latch:
45   call void @use(ptr %ptr.iv)
46   %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1
47   br label %loop.header
49 exit:
50   ret void
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:%.*]]
58 ; CHECK:       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:%.*]]
62 ; CHECK:       for.body:
63 ; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true
64 ; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
65 ; CHECK:       loop.latch:
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]]
69 ; CHECK:       exit:
70 ; CHECK-NEXT:    ret void
72 loop.ph:
73   %upper = getelementptr inbounds i8, ptr %start, i16 15
74   br label %loop.header
76 loop.header:
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
81 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
87 loop.latch:
88   call void @use(ptr %ptr.iv)
89   %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1
90   br label %loop.header
92 exit:
93   ret void
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:%.*]]
105 ; CHECK:       for.body:
106 ; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true
107 ; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
108 ; CHECK:       loop.latch:
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]]
112 ; CHECK:       exit:
113 ; CHECK-NEXT:    ret void
115 loop.ph:
116   %upper = getelementptr inbounds i8, ptr %start, i16 16
117   br label %loop.header
119 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
124 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
130 loop.latch:
131   call void @use(ptr %ptr.iv)
132   %ptr.iv.next = getelementptr inbounds i16, ptr %ptr.iv, i16 1
133   br label %loop.header
135 exit:
136   ret void
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:%.*]]
148 ; CHECK:       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]]
152 ; CHECK:       loop.latch:
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]]
156 ; CHECK:       exit:
157 ; CHECK-NEXT:    ret void
159 loop.ph:
160   %upper = getelementptr inbounds i8, ptr %start, i16 15
161   br label %loop.header
163 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
168 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
174 loop.latch:
175   call void @use(ptr %ptr.iv)
176   %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1
177   br label %loop.header
179 exit:
180   ret void
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:%.*]]
192 ; CHECK:       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]]
196 ; CHECK:       loop.latch:
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]]
200 ; CHECK:       exit:
201 ; CHECK-NEXT:    ret void
203 loop.ph:
204   %upper = getelementptr inbounds i8, ptr %start, i16 15
205   br label %loop.header
207 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
212 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
218 loop.latch:
219   call void @use(ptr %ptr.iv)
220   %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1
221   br label %loop.header
223 exit:
224   ret void
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:%.*]]
236 ; CHECK:       for.body:
237 ; CHECK-NEXT:    [[C_1:%.*]] = call i1 @cond()
238 ; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
239 ; CHECK:       loop.next:
240 ; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true
241 ; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
242 ; CHECK:       loop.latch:
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]]
246 ; CHECK:       exit:
247 ; CHECK-NEXT:    ret void
249 loop.ph:
250   %upper = getelementptr inbounds i8, ptr %start, i16 10
251   br label %loop.header
253 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
258 for.body:
259   %c.1 = call i1 @cond()
260   br i1 %c.1, label %loop.next, label %exit
262 loop.next:
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
268 loop.latch:
269   call void @use(ptr %ptr.iv)
270   %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1
271   br label %loop.header
273 exit:
274   ret void
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:%.*]]
286 ; CHECK:       for.body:
287 ; CHECK-NEXT:    [[C_1:%.*]] = call i1 @cond()
288 ; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
289 ; CHECK:       loop.next:
290 ; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true
291 ; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
292 ; CHECK:       loop.latch:
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]]
296 ; CHECK:       exit:
297 ; CHECK-NEXT:    ret void
299 loop.ph:
300   %upper = getelementptr inbounds i8, ptr %start, i16 10
301   br label %loop.header
303 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
308 for.body:
309   %c.1 = call i1 @cond()
310   br i1 %c.1, label %loop.next, label %exit
312 loop.next:
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
318 loop.latch:
319   call void @use(ptr %ptr.iv)
320   %ptr.iv.next = getelementptr inbounds i16, ptr %ptr.iv, i16 1
321   br label %loop.header
323 exit:
324   ret void
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:%.*]]
336 ; CHECK:       for.body:
337 ; CHECK-NEXT:    [[C_1:%.*]] = call i1 @cond()
338 ; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
339 ; CHECK:       loop.next:
340 ; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true
341 ; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
342 ; CHECK:       loop.latch:
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]]
346 ; CHECK:       exit:
347 ; CHECK-NEXT:    ret void
349 loop.ph:
350   %upper = getelementptr inbounds i16, ptr %start, i16 16
351   br label %loop.header
353 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
358 for.body:
359   %c.1 = call i1 @cond()
360   br i1 %c.1, label %loop.next, label %exit
362 loop.next:
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
368 loop.latch:
369   call void @use(ptr %ptr.iv)
370   %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1
371   br label %loop.header
373 exit:
374   ret void
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:%.*]]
386 ; CHECK:       for.body:
387 ; CHECK-NEXT:    [[C_1:%.*]] = call i1 @cond()
388 ; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
389 ; CHECK:       loop.next:
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]]
393 ; CHECK:       loop.latch:
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]]
397 ; CHECK:       exit:
398 ; CHECK-NEXT:    ret void
400 loop.ph:
401   %upper = getelementptr inbounds i8, ptr %start, i16 10
402   br label %loop.header
404 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
409 for.body:
410   %c.1 = call i1 @cond()
411   br i1 %c.1, label %loop.next, label %exit
413 loop.next:
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
419 loop.latch:
420   call void @use(ptr %ptr.iv)
421   %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1
422   br label %loop.header
424 exit:
425   ret void
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:%.*]]
437 ; CHECK:       for.body:
438 ; CHECK-NEXT:    [[C_1:%.*]] = call i1 @cond()
439 ; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
440 ; CHECK:       loop.next:
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]]
444 ; CHECK:       loop.latch:
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]]
448 ; CHECK:       exit:
449 ; CHECK-NEXT:    ret void
451 loop.ph:
452   %upper = getelementptr inbounds i8, ptr %start, i16 11
453   br label %loop.header
455 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
460 for.body:
461   %c.1 = call i1 @cond()
462   br i1 %c.1, label %loop.next, label %exit
464 loop.next:
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
470 loop.latch:
471   call void @use(ptr %ptr.iv)
472   %ptr.iv.next = getelementptr inbounds i16, ptr %ptr.iv, i16 1
473   br label %loop.header
475 exit:
476   ret void
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:%.*]]
488 ; CHECK:       for.body:
489 ; CHECK-NEXT:    [[C_1:%.*]] = call i1 @cond()
490 ; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
491 ; CHECK:       loop.next:
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]]
495 ; CHECK:       loop.latch:
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]]
499 ; CHECK:       exit:
500 ; CHECK-NEXT:    ret void
502 loop.ph:
503   %upper = getelementptr inbounds i16, ptr %start, i16 9
504   br label %loop.header
506 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
511 for.body:
512   %c.1 = call i1 @cond()
513   br i1 %c.1, label %loop.next, label %exit
515 loop.next:
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
521 loop.latch:
522   call void @use(ptr %ptr.iv)
523   %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1
524   br label %loop.header
526 exit:
527   ret void