Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / monotonic-pointer-phis-custom-datalayout.ll
blobad1c7231a594136df9328cde5882998d0f6f786a
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
4 ; NOTE: The custom datalayout defines i32 to be 64 bit aligned.
6 target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i32:64:64-f80:128-n8:16:32:64-S128"
8 declare void @use(ptr)
9 declare i1 @cond()
11 define void @test_monotonic_ptr_iv_inc_1_element_types_with_different_alloc_type_sizes(ptr %start, i16 %len) {
12 ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_element_types_with_different_alloc_type_sizes(
13 ; CHECK-NEXT:  entry:
14 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds float, ptr [[START:%.*]], i16 [[LEN:%.*]]
15 ; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
16 ; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
17 ; CHECK:       loop.ph:
18 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
19 ; CHECK:       loop.header:
20 ; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
21 ; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
22 ; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
23 ; CHECK:       for.body:
24 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]
25 ; CHECK-NEXT:    [[AND:%.*]] = and i1 true, [[T_2]]
26 ; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
27 ; CHECK:       loop.latch:
28 ; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])
29 ; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1
30 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
31 ; CHECK:       exit:
32 ; CHECK-NEXT:    ret void
34 entry:
35   %upper = getelementptr inbounds float, ptr %start, i16 %len
36   %len.neg = icmp slt i16 %len, 0
37   br i1 %len.neg, label %exit, label %loop.ph
39 loop.ph:
40   br label %loop.header
42 loop.header:
43   %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
44   %c = icmp eq ptr %ptr.iv, %upper
45   br i1 %c, label %exit, label %for.body
47 for.body:
48   %t.1 = icmp uge ptr %ptr.iv, %start
49   %t.2 = icmp ult ptr %ptr.iv, %upper
50   %and = and i1 %t.1, %t.2
51   br i1 %and, label %loop.latch, label %exit
53 loop.latch:
54   call void @use(ptr %ptr.iv)
55   %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1
56   br label %loop.header
58 exit:
59   ret void
62 define void @test_monotonic_ptr_iv_inc_2_element_types_with_different_alloc_type_sizes(ptr %start, i16 %len) {
63 ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_2_element_types_with_different_alloc_type_sizes(
64 ; CHECK-NEXT:  entry:
65 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]
66 ; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
67 ; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
68 ; CHECK:       loop.ph:
69 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
70 ; CHECK:       loop.header:
71 ; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
72 ; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
73 ; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
74 ; CHECK:       for.body:
75 ; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true
76 ; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
77 ; CHECK:       loop.latch:
78 ; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])
79 ; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds float, ptr [[PTR_IV]], i16 1
80 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
81 ; CHECK:       exit:
82 ; CHECK-NEXT:    ret void
84 entry:
85   %upper = getelementptr inbounds i32, ptr %start, i16 %len
86   %len.neg = icmp slt i16 %len, 0
87   br i1 %len.neg, label %exit, label %loop.ph
89 loop.ph:
90   br label %loop.header
92 loop.header:
93   %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
94   %c = icmp eq ptr %ptr.iv, %upper
95   br i1 %c, label %exit, label %for.body
97 for.body:
98   %t.1 = icmp uge ptr %ptr.iv, %start
99   %t.2 = icmp ult ptr %ptr.iv, %upper
100   %and = and i1 %t.1, %t.2
101   br i1 %and, label %loop.latch, label %exit
103 loop.latch:
104   call void @use(ptr %ptr.iv)
105   %ptr.iv.next = getelementptr inbounds float, ptr %ptr.iv, i16 1
106   br label %loop.header
108 exit:
109   ret void
112 define void @test_monotonic_ptr_iv_inc_1_different_element_types_with_same_alloc_type_sizes(ptr %start, i16 %len) {
113 ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_different_element_types_with_same_alloc_type_sizes(
114 ; CHECK-NEXT:  entry:
115 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i5, ptr [[START:%.*]], i16 [[LEN:%.*]]
116 ; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
117 ; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
118 ; CHECK:       loop.ph:
119 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
120 ; CHECK:       loop.header:
121 ; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
122 ; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
123 ; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
124 ; CHECK:       for.body:
125 ; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true
126 ; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
127 ; CHECK:       loop.latch:
128 ; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])
129 ; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i7, ptr [[PTR_IV]], i16 1
130 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
131 ; CHECK:       exit:
132 ; CHECK-NEXT:    ret void
134 entry:
135   %upper = getelementptr inbounds i5, ptr %start, i16 %len
136   %len.neg = icmp slt i16 %len, 0
137   br i1 %len.neg, label %exit, label %loop.ph
139 loop.ph:
140   br label %loop.header
142 loop.header:
143   %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
144   %c = icmp eq ptr %ptr.iv, %upper
145   br i1 %c, label %exit, label %for.body
147 for.body:
148   %t.1 = icmp uge ptr %ptr.iv, %start
149   %t.2 = icmp ult ptr %ptr.iv, %upper
150   %and = and i1 %t.1, %t.2
151   br i1 %and, label %loop.latch, label %exit
153 loop.latch:
154   call void @use(ptr %ptr.iv)
155   %ptr.iv.next = getelementptr inbounds i7, ptr %ptr.iv, i16 1
156   br label %loop.header
158 exit:
159   ret void
162 define void @test_monotonic_ptr_iv_inc_2_different_element_types_with_same_alloc_type_sizes(ptr %start, i16 %len) {
163 ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_2_different_element_types_with_same_alloc_type_sizes(
164 ; CHECK-NEXT:  entry:
165 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i31, ptr [[START:%.*]], i16 [[LEN:%.*]]
166 ; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
167 ; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
168 ; CHECK:       loop.ph:
169 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
170 ; CHECK:       loop.header:
171 ; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
172 ; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
173 ; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
174 ; CHECK:       for.body:
175 ; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true
176 ; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
177 ; CHECK:       loop.latch:
178 ; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])
179 ; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i30, ptr [[PTR_IV]], i16 1
180 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
181 ; CHECK:       exit:
182 ; CHECK-NEXT:    ret void
184 entry:
185   %upper = getelementptr inbounds i31, ptr %start, i16 %len
186   %len.neg = icmp slt i16 %len, 0
187   br i1 %len.neg, label %exit, label %loop.ph
189 loop.ph:
190   br label %loop.header
192 loop.header:
193   %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
194   %c = icmp eq ptr %ptr.iv, %upper
195   br i1 %c, label %exit, label %for.body
197 for.body:
198   %t.1 = icmp uge ptr %ptr.iv, %start
199   %t.2 = icmp ult ptr %ptr.iv, %upper
200   %and = and i1 %t.1, %t.2
201   br i1 %and, label %loop.latch, label %exit
203 loop.latch:
204   call void @use(ptr %ptr.iv)
205   %ptr.iv.next = getelementptr inbounds i30, ptr %ptr.iv, i16 1
206   br label %loop.header
208 exit:
209   ret void
212 define void @test_monotonic_ptr_iv_inc_1_element_types_with_different_alloc_type_sizes_with_early_exit(ptr %start, i16 %len) {
213 ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_element_types_with_different_alloc_type_sizes_with_early_exit(
214 ; CHECK-NEXT:  entry:
215 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds float, ptr [[START:%.*]], i16 [[LEN:%.*]]
216 ; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
217 ; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
218 ; CHECK:       loop.ph:
219 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
220 ; CHECK:       loop.header:
221 ; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
222 ; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
223 ; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
224 ; CHECK:       for.body:
225 ; CHECK-NEXT:    [[C_1:%.*]] = call i1 @cond()
226 ; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
227 ; CHECK:       loop.next:
228 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]
229 ; CHECK-NEXT:    [[AND:%.*]] = and i1 true, [[T_2]]
230 ; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
231 ; CHECK:       loop.latch:
232 ; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])
233 ; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1
234 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
235 ; CHECK:       exit:
236 ; CHECK-NEXT:    ret void
238 entry:
239   %upper = getelementptr inbounds float, ptr %start, i16 %len
240   %len.neg = icmp slt i16 %len, 0
241   br i1 %len.neg, label %exit, label %loop.ph
243 loop.ph:
244   br label %loop.header
246 loop.header:
247   %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
248   %c = icmp eq ptr %ptr.iv, %upper
249   br i1 %c, label %exit, label %for.body
251 for.body:
252   %c.1 = call i1 @cond()
253   br i1 %c.1, label %loop.next, label %exit
255 loop.next:
256   %t.1 = icmp uge ptr %ptr.iv, %start
257   %t.2 = icmp ult ptr %ptr.iv, %upper
258   %and = and i1 %t.1, %t.2
259   br i1 %and, label %loop.latch, label %exit
261 loop.latch:
262   call void @use(ptr %ptr.iv)
263   %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1
264   br label %loop.header
266 exit:
267   ret void
270 define void @test_monotonic_ptr_iv_inc_2_element_types_with_different_alloc_type_sizes_with_early_exit(ptr %start, i16 %len) {
271 ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_2_element_types_with_different_alloc_type_sizes_with_early_exit(
272 ; CHECK-NEXT:  entry:
273 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]
274 ; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
275 ; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
276 ; CHECK:       loop.ph:
277 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
278 ; CHECK:       loop.header:
279 ; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
280 ; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
281 ; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
282 ; CHECK:       for.body:
283 ; CHECK-NEXT:    [[C_1:%.*]] = call i1 @cond()
284 ; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
285 ; CHECK:       loop.next:
286 ; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true
287 ; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
288 ; CHECK:       loop.latch:
289 ; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])
290 ; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds float, ptr [[PTR_IV]], i16 1
291 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
292 ; CHECK:       exit:
293 ; CHECK-NEXT:    ret void
295 entry:
296   %upper = getelementptr inbounds i32, ptr %start, i16 %len
297   %len.neg = icmp slt i16 %len, 0
298   br i1 %len.neg, label %exit, label %loop.ph
300 loop.ph:
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 float, ptr %ptr.iv, i16 1
321   br label %loop.header
323 exit:
324   ret void
327 define void @test_monotonic_ptr_iv_inc_1_different_element_types_with_same_alloc_type_sizes_with_early_exit(ptr %start, i16 %len) {
328 ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_different_element_types_with_same_alloc_type_sizes_with_early_exit(
329 ; CHECK-NEXT:  entry:
330 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i5, ptr [[START:%.*]], i16 [[LEN:%.*]]
331 ; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
332 ; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
333 ; CHECK:       loop.ph:
334 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
335 ; CHECK:       loop.header:
336 ; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
337 ; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
338 ; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
339 ; CHECK:       for.body:
340 ; CHECK-NEXT:    [[C_1:%.*]] = call i1 @cond()
341 ; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
342 ; CHECK:       loop.next:
343 ; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true
344 ; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
345 ; CHECK:       loop.latch:
346 ; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])
347 ; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i7, ptr [[PTR_IV]], i16 1
348 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
349 ; CHECK:       exit:
350 ; CHECK-NEXT:    ret void
352 entry:
353   %upper = getelementptr inbounds i5, ptr %start, i16 %len
354   %len.neg = icmp slt i16 %len, 0
355   br i1 %len.neg, label %exit, label %loop.ph
357 loop.ph:
358   br label %loop.header
360 loop.header:
361   %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
362   %c = icmp eq ptr %ptr.iv, %upper
363   br i1 %c, label %exit, label %for.body
365 for.body:
366   %c.1 = call i1 @cond()
367   br i1 %c.1, label %loop.next, label %exit
369 loop.next:
370   %t.1 = icmp uge ptr %ptr.iv, %start
371   %t.2 = icmp ult ptr %ptr.iv, %upper
372   %and = and i1 %t.1, %t.2
373   br i1 %and, label %loop.latch, label %exit
375 loop.latch:
376   call void @use(ptr %ptr.iv)
377   %ptr.iv.next = getelementptr inbounds i7, ptr %ptr.iv, i16 1
378   br label %loop.header
380 exit:
381   ret void
384 define void @test_monotonic_ptr_iv_inc_2_different_element_types_with_same_alloc_type_sizes_with_early_exit(ptr %start, i16 %len) {
385 ; CHECK-LABEL: @test_monotonic_ptr_iv_inc_2_different_element_types_with_same_alloc_type_sizes_with_early_exit(
386 ; CHECK-NEXT:  entry:
387 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i31, ptr [[START:%.*]], i16 [[LEN:%.*]]
388 ; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
389 ; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
390 ; CHECK:       loop.ph:
391 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
392 ; CHECK:       loop.header:
393 ; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
394 ; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
395 ; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
396 ; CHECK:       for.body:
397 ; CHECK-NEXT:    [[C_1:%.*]] = call i1 @cond()
398 ; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
399 ; CHECK:       loop.next:
400 ; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true
401 ; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
402 ; CHECK:       loop.latch:
403 ; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])
404 ; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i30, ptr [[PTR_IV]], i16 1
405 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
406 ; CHECK:       exit:
407 ; CHECK-NEXT:    ret void
409 entry:
410   %upper = getelementptr inbounds i31, ptr %start, i16 %len
411   %len.neg = icmp slt i16 %len, 0
412   br i1 %len.neg, label %exit, label %loop.ph
414 loop.ph:
415   br label %loop.header
417 loop.header:
418   %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
419   %c = icmp eq ptr %ptr.iv, %upper
420   br i1 %c, label %exit, label %for.body
422 for.body:
423   %c.1 = call i1 @cond()
424   br i1 %c.1, label %loop.next, label %exit
426 loop.next:
427   %t.1 = icmp uge ptr %ptr.iv, %start
428   %t.2 = icmp ult ptr %ptr.iv, %upper
429   %and = and i1 %t.1, %t.2
430   br i1 %and, label %loop.latch, label %exit
432 loop.latch:
433   call void @use(ptr %ptr.iv)
434   %ptr.iv.next = getelementptr inbounds i30, ptr %ptr.iv, i16 1
435   br label %loop.header
437 exit:
438   ret void