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"
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(
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:%.*]]
18 ; CHECK-NEXT: br label [[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:%.*]]
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]]
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]]
32 ; CHECK-NEXT: ret void
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
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
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
54 call void @use(ptr %ptr.iv)
55 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1
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(
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:%.*]]
69 ; CHECK-NEXT: br label [[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:%.*]]
75 ; CHECK-NEXT: [[AND:%.*]] = and i1 true, true
76 ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
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]]
82 ; CHECK-NEXT: ret void
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
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
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
104 call void @use(ptr %ptr.iv)
105 %ptr.iv.next = getelementptr inbounds float, ptr %ptr.iv, i16 1
106 br label %loop.header
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(
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:%.*]]
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:%.*]]
125 ; CHECK-NEXT: [[AND:%.*]] = and i1 true, true
126 ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
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]]
132 ; CHECK-NEXT: ret void
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
140 br label %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
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
154 call void @use(ptr %ptr.iv)
155 %ptr.iv.next = getelementptr inbounds i7, ptr %ptr.iv, i16 1
156 br label %loop.header
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(
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:%.*]]
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:%.*]]
175 ; CHECK-NEXT: [[AND:%.*]] = and i1 true, true
176 ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
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]]
182 ; CHECK-NEXT: ret void
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
190 br label %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
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
204 call void @use(ptr %ptr.iv)
205 %ptr.iv.next = getelementptr inbounds i30, ptr %ptr.iv, i16 1
206 br label %loop.header
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(
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:%.*]]
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:%.*]]
225 ; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()
226 ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
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]]
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]]
236 ; CHECK-NEXT: ret void
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
244 br label %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
252 %c.1 = call i1 @cond()
253 br i1 %c.1, label %loop.next, label %exit
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
262 call void @use(ptr %ptr.iv)
263 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1
264 br label %loop.header
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(
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:%.*]]
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:%.*]]
283 ; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()
284 ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
286 ; CHECK-NEXT: [[AND:%.*]] = and i1 true, true
287 ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
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]]
293 ; CHECK-NEXT: ret void
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
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 float, ptr %ptr.iv, i16 1
321 br label %loop.header
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(
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:%.*]]
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:%.*]]
340 ; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()
341 ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
343 ; CHECK-NEXT: [[AND:%.*]] = and i1 true, true
344 ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
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]]
350 ; CHECK-NEXT: ret void
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
358 br label %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
366 %c.1 = call i1 @cond()
367 br i1 %c.1, label %loop.next, label %exit
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
376 call void @use(ptr %ptr.iv)
377 %ptr.iv.next = getelementptr inbounds i7, ptr %ptr.iv, i16 1
378 br label %loop.header
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(
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:%.*]]
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:%.*]]
397 ; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()
398 ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
400 ; CHECK-NEXT: [[AND:%.*]] = and i1 true, true
401 ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
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]]
407 ; CHECK-NEXT: ret void
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
415 br label %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
423 %c.1 = call i1 @cond()
424 br i1 %c.1, label %loop.next, label %exit
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
433 call void @use(ptr %ptr.iv)
434 %ptr.iv.next = getelementptr inbounds i30, ptr %ptr.iv, i16 1
435 br label %loop.header