1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
6 ; Make sure conditions in loops are not used to simplify themselves.
8 define void @loop1(ptr %T, ptr %x, i32 %points, i32 %trigint) {
11 ; CHECK-NEXT: [[IDX_EXT:%.*]] = sext i32 [[POINTS:%.*]] to i64
12 ; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds float, ptr [[X:%.*]], i64 [[IDX_EXT]]
13 ; CHECK-NEXT: [[ADD_PTR1:%.*]] = getelementptr inbounds float, ptr [[ADD_PTR]], i64 -8
14 ; CHECK-NEXT: [[SHR:%.*]] = ashr i32 [[POINTS]], 1
15 ; CHECK-NEXT: [[IDX_EXT2:%.*]] = sext i32 [[SHR]] to i64
16 ; CHECK-NEXT: [[ADD_PTR3:%.*]] = getelementptr inbounds float, ptr [[X]], i64 [[IDX_EXT2]]
17 ; CHECK-NEXT: [[ADD_PTR4:%.*]] = getelementptr inbounds float, ptr [[ADD_PTR3]], i64 -8
18 ; CHECK-NEXT: br label [[DO_BODY:%.*]]
20 ; CHECK-NEXT: [[X2_0:%.*]] = phi ptr [ [[ADD_PTR4]], [[ENTRY:%.*]] ], [ [[ADD_PTR106:%.*]], [[DO_BODY]] ]
21 ; CHECK-NEXT: [[X1_0:%.*]] = phi ptr [ [[ADD_PTR1]], [[ENTRY]] ], [ [[ADD_PTR105:%.*]], [[DO_BODY]] ]
22 ; CHECK-NEXT: [[ADD_PTR105]] = getelementptr inbounds float, ptr [[X1_0]], i64 -8
23 ; CHECK-NEXT: [[ADD_PTR106]] = getelementptr inbounds float, ptr [[X2_0]], i64 -8
24 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge ptr [[ADD_PTR106]], [[X]]
25 ; CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY]], label [[DO_END:%.*]]
27 ; CHECK-NEXT: ret void
30 %idx.ext = sext i32 %points to i64
31 %add.ptr = getelementptr inbounds float, ptr %x, i64 %idx.ext
32 %add.ptr1 = getelementptr inbounds float, ptr %add.ptr, i64 -8
33 %shr = ashr i32 %points, 1
34 %idx.ext2 = sext i32 %shr to i64
35 %add.ptr3 = getelementptr inbounds float, ptr %x, i64 %idx.ext2
36 %add.ptr4 = getelementptr inbounds float, ptr %add.ptr3, i64 -8
39 do.body: ; preds = %do.body, %entry
40 %x2.0 = phi ptr [ %add.ptr4, %entry ], [ %add.ptr106, %do.body ]
41 %x1.0 = phi ptr [ %add.ptr1, %entry ], [ %add.ptr105, %do.body ]
42 %add.ptr105 = getelementptr inbounds float, ptr %x1.0, i64 -8
43 %add.ptr106 = getelementptr inbounds float, ptr %x2.0, i64 -8
44 %cmp = icmp uge ptr %add.ptr106, %x
45 br i1 %cmp, label %do.body, label %do.end
47 do.end: ; preds = %do.body
52 ; Some tests with loops with conditions in the header.
54 define i32 @loop_header_dom(i32 %y, i1 %c) {
55 ; CHECK-LABEL: @loop_header_dom(
57 ; CHECK-NEXT: br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
59 ; CHECK-NEXT: [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
60 ; CHECK-NEXT: [[C_1:%.*]] = icmp ule i32 [[X]], 10
61 ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_LATCH]], label [[EXIT]]
63 ; CHECK-NEXT: call void @use(i1 true)
64 ; CHECK-NEXT: call void @use(i1 false)
65 ; CHECK-NEXT: [[C_2:%.*]] = icmp ule i32 [[X]], 9
66 ; CHECK-NEXT: call void @use(i1 [[C_2]])
67 ; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i32 [[X]], 9
68 ; CHECK-NEXT: call void @use(i1 [[C_3]])
69 ; CHECK-NEXT: [[X_NEXT]] = add i32 [[X]], 1
70 ; CHECK-NEXT: br label [[LOOP_HEADER]]
72 ; CHECK-NEXT: [[C_4:%.*]] = icmp ugt i32 [[Y:%.*]], 10
73 ; CHECK-NEXT: call void @use(i1 [[C_4]])
74 ; CHECK-NEXT: ret i32 20
77 br i1 %c, label %loop.header, label %exit
80 %x = phi i32 [ 0, %entry ], [ %x.next, %loop.latch ]
81 %c.1 = icmp ule i32 %x, 10
82 br i1 %c.1, label %loop.latch, label %exit
85 %t.1 = icmp ule i32 %x, 10
86 call void @use(i1 %t.1)
87 %f.1 = icmp ugt i32 %x, 10
88 call void @use(i1 %f.1)
90 %c.2 = icmp ule i32 %x, 9
91 call void @use(i1 %c.2)
92 %c.3 = icmp ugt i32 %x, 9
93 call void @use(i1 %c.3)
95 %x.next = add i32 %x, 1
99 %c.4 = icmp ugt i32 %y, 10
100 call void @use(i1 %c.4)
104 define i32 @loop_header_dom_successors_flipped(i32 %y, i1 %c) {
105 ; CHECK-LABEL: @loop_header_dom_successors_flipped(
107 ; CHECK-NEXT: br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
108 ; CHECK: loop.header:
109 ; CHECK-NEXT: [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
110 ; CHECK-NEXT: [[C_1:%.*]] = icmp ule i32 [[X]], 10
111 ; CHECK-NEXT: br i1 [[C_1]], label [[EXIT]], label [[LOOP_LATCH]]
113 ; CHECK-NEXT: call void @use(i1 false)
114 ; CHECK-NEXT: call void @use(i1 true)
115 ; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i32 [[X]], 11
116 ; CHECK-NEXT: call void @use(i1 [[C_2]])
117 ; CHECK-NEXT: [[C_3:%.*]] = icmp ule i32 [[X]], 11
118 ; CHECK-NEXT: call void @use(i1 [[C_3]])
119 ; CHECK-NEXT: [[X_NEXT]] = add i32 [[X]], 1
120 ; CHECK-NEXT: br label [[LOOP_HEADER]]
122 ; CHECK-NEXT: [[C_4:%.*]] = icmp ugt i32 [[Y:%.*]], 10
123 ; CHECK-NEXT: call void @use(i1 [[C_4]])
124 ; CHECK-NEXT: ret i32 20
127 br i1 %c, label %loop.header, label %exit
130 %x = phi i32 [ 0, %entry ], [ %x.next, %loop.latch ]
131 %c.1 = icmp ule i32 %x, 10
132 br i1 %c.1, label %exit, label %loop.latch
135 %f.1 = icmp ule i32 %x, 10
136 call void @use(i1 %f.1)
137 %t.1 = icmp ugt i32 %x, 10
138 call void @use(i1 %t.1)
140 %c.2 = icmp ugt i32 %x, 11
141 call void @use(i1 %c.2)
142 %c.3 = icmp ule i32 %x,11
143 call void @use(i1 %c.3)
145 %x.next = add i32 %x, 1
146 br label %loop.header
149 %c.4 = icmp ugt i32 %y, 10
150 call void @use(i1 %c.4)
154 define void @loop_header_dom_or(i32 %y, i1 %c, i32 %start) {
155 ; CHECK-LABEL: @loop_header_dom_or(
157 ; CHECK-NEXT: br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
158 ; CHECK: loop.header:
159 ; CHECK-NEXT: [[X:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
160 ; CHECK-NEXT: [[X_1:%.*]] = icmp ule i32 [[X]], 10
161 ; CHECK-NEXT: [[Y_1:%.*]] = icmp ugt i32 [[Y:%.*]], 99
162 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[X_1]], [[Y_1]]
163 ; CHECK-NEXT: br i1 [[OR]], label [[EXIT]], label [[LOOP_LATCH]]
165 ; CHECK-NEXT: call void @use(i1 true)
166 ; CHECK-NEXT: call void @use(i1 false)
167 ; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i32 [[X]], 11
168 ; CHECK-NEXT: call void @use(i1 [[C_1]])
169 ; CHECK-NEXT: [[C_2:%.*]] = icmp ule i32 [[X]], 11
170 ; CHECK-NEXT: call void @use(i1 [[C_2]])
171 ; CHECK-NEXT: call void @use(i1 true)
172 ; CHECK-NEXT: call void @use(i1 false)
173 ; CHECK-NEXT: [[C_3:%.*]] = icmp ule i32 [[Y]], 98
174 ; CHECK-NEXT: call void @use(i1 [[C_3]])
175 ; CHECK-NEXT: [[C_4:%.*]] = icmp ule i32 [[Y]], 98
176 ; CHECK-NEXT: call void @use(i1 [[C_4]])
177 ; CHECK-NEXT: [[X_NEXT]] = add i32 [[X]], 1
178 ; CHECK-NEXT: br label [[LOOP_HEADER]]
180 ; CHECK-NEXT: [[C_5:%.*]] = icmp ugt i32 [[Y]], 10
181 ; CHECK-NEXT: call void @use(i1 [[C_5]])
182 ; CHECK-NEXT: ret void
185 br i1 %c, label %loop.header, label %exit
188 %x = phi i32 [ %start, %entry ], [ %x.next, %loop.latch ]
189 %x.1 = icmp ule i32 %x, 10
190 %y.1 = icmp ugt i32 %y, 99
191 %or = or i1 %x.1, %y.1
192 br i1 %or, label %exit, label %loop.latch
195 %t.1 = icmp ugt i32 %x, 10
196 call void @use(i1 %t.1)
197 %f.1 = icmp ule i32 %x, 10
198 call void @use(i1 %f.1)
199 %c.1 = icmp ugt i32 %x, 11
200 call void @use(i1 %c.1)
201 %c.2 = icmp ule i32 %x, 11
202 call void @use(i1 %c.2)
205 %t.2 = icmp ule i32 %y, 99
206 call void @use(i1 %t.2)
207 %f.2 = icmp ugt i32 %y, 99
208 call void @use(i1 %f.2)
210 %c.3 = icmp ule i32 %y, 98
211 call void @use(i1 %c.3)
212 %c.4 = icmp ule i32 %y, 98
213 call void @use(i1 %c.4)
215 %x.next = add i32 %x, 1
216 br label %loop.header
219 %c.5 = icmp ugt i32 %y, 10
220 call void @use(i1 %c.5)
224 define void @loop_header_dom_or_successors_flipped(i32 %y, i1 %c) {
225 ; CHECK-LABEL: @loop_header_dom_or_successors_flipped(
227 ; CHECK-NEXT: br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
228 ; CHECK: loop.header:
229 ; CHECK-NEXT: [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
230 ; CHECK-NEXT: [[X_1:%.*]] = icmp ule i32 [[X]], 10
231 ; CHECK-NEXT: [[Y_1:%.*]] = icmp ugt i32 [[Y:%.*]], 99
232 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[X_1]], [[Y_1]]
233 ; CHECK-NEXT: br i1 [[OR]], label [[LOOP_LATCH]], label [[EXIT]]
235 ; CHECK-NEXT: [[C_1:%.*]] = icmp ule i32 [[X]], 10
236 ; CHECK-NEXT: call void @use(i1 [[C_1]])
237 ; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i32 [[X]], 10
238 ; CHECK-NEXT: call void @use(i1 [[C_2]])
239 ; CHECK-NEXT: [[C_3:%.*]] = icmp ule i32 [[X]], 9
240 ; CHECK-NEXT: call void @use(i1 [[C_3]])
241 ; CHECK-NEXT: [[C_4:%.*]] = icmp ugt i32 [[X]], 9
242 ; CHECK-NEXT: call void @use(i1 [[C_4]])
243 ; CHECK-NEXT: [[C_5:%.*]] = icmp ugt i32 [[Y]], 99
244 ; CHECK-NEXT: call void @use(i1 [[C_5]])
245 ; CHECK-NEXT: [[C_6:%.*]] = icmp ule i32 [[Y]], 99
246 ; CHECK-NEXT: call void @use(i1 [[C_6]])
247 ; CHECK-NEXT: [[C_7:%.*]] = icmp ugt i32 [[Y]], 100
248 ; CHECK-NEXT: call void @use(i1 [[C_7]])
249 ; CHECK-NEXT: [[C_8:%.*]] = icmp ugt i32 [[Y]], 100
250 ; CHECK-NEXT: call void @use(i1 [[C_8]])
251 ; CHECK-NEXT: [[X_NEXT]] = add i32 [[X]], 1
252 ; CHECK-NEXT: br label [[LOOP_HEADER]]
254 ; CHECK-NEXT: [[T_1:%.*]] = icmp ugt i32 [[Y]], 10
255 ; CHECK-NEXT: call void @use(i1 [[T_1]])
256 ; CHECK-NEXT: ret void
259 br i1 %c, label %loop.header, label %exit
262 %x = phi i32 [ 0, %entry ], [ %x.next, %loop.latch ]
263 %x.1 = icmp ule i32 %x, 10
264 %y.1 = icmp ugt i32 %y, 99
265 %or = or i1 %x.1, %y.1
266 br i1 %or, label %loop.latch, label %exit
269 %c.1 = icmp ule i32 %x, 10
270 call void @use(i1 %c.1)
271 %c.2 = icmp ugt i32 %x, 10
272 call void @use(i1 %c.2)
273 %c.3 = icmp ule i32 %x, 9
274 call void @use(i1 %c.3)
275 %c.4 = icmp ugt i32 %x, 9
276 call void @use(i1 %c.4)
279 %c.5 = icmp ugt i32 %y, 99
280 call void @use(i1 %c.5)
281 %c.6 = icmp ule i32 %y, 99
282 call void @use(i1 %c.6)
284 %c.7 = icmp ugt i32 %y, 100
285 call void @use(i1 %c.7)
286 %c.8 = icmp ugt i32 %y, 100
287 call void @use(i1 %c.8)
289 %x.next = add i32 %x, 1
290 br label %loop.header
293 %t.1 = icmp ugt i32 %y, 10
294 call void @use(i1 %t.1)
299 define void @loop_header_dom_and(i32 %y, i1 %c) {
300 ; CHECK-LABEL: @loop_header_dom_and(
302 ; CHECK-NEXT: br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
304 ; CHECK-NEXT: [[C_5:%.*]] = icmp ugt i32 [[Y:%.*]], 10
305 ; CHECK-NEXT: call void @use(i1 [[C_5]])
306 ; CHECK-NEXT: ret void
307 ; CHECK: loop.header:
308 ; CHECK-NEXT: [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
309 ; CHECK-NEXT: [[X_1:%.*]] = icmp ule i32 [[X]], 10
310 ; CHECK-NEXT: [[Y_1:%.*]] = icmp ugt i32 [[Y]], 99
311 ; CHECK-NEXT: [[AND:%.*]] = and i1 [[X_1]], [[Y_1]]
312 ; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT_1:%.*]]
314 ; CHECK-NEXT: call void @use(i1 true)
315 ; CHECK-NEXT: call void @use(i1 false)
316 ; CHECK-NEXT: [[C_1:%.*]] = icmp ule i32 [[X]], 9
317 ; CHECK-NEXT: call void @use(i1 [[C_1]])
318 ; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i32 [[X]], 9
319 ; CHECK-NEXT: call void @use(i1 [[C_2]])
320 ; CHECK-NEXT: call void @use(i1 true)
321 ; CHECK-NEXT: call void @use(i1 false)
322 ; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i32 [[Y]], 100
323 ; CHECK-NEXT: call void @use(i1 [[C_3]])
324 ; CHECK-NEXT: [[C_4:%.*]] = icmp ugt i32 [[Y]], 100
325 ; CHECK-NEXT: call void @use(i1 [[C_4]])
326 ; CHECK-NEXT: [[X_NEXT]] = add i32 [[X]], 1
327 ; CHECK-NEXT: br label [[LOOP_HEADER]]
329 ; CHECK-NEXT: [[C_6:%.*]] = icmp ugt i32 [[Y]], 10
330 ; CHECK-NEXT: call void @use(i1 [[C_6]])
331 ; CHECK-NEXT: ret void
334 br i1 %c, label %loop.header, label %exit
337 %c.5 = icmp ugt i32 %y, 10
338 call void @use(i1 %c.5)
342 %x = phi i32 [ 0, %entry ], [ %x.next, %loop.latch ]
343 %x.1 = icmp ule i32 %x, 10
344 %y.1 = icmp ugt i32 %y, 99
345 %and = and i1 %x.1, %y.1
346 br i1 %and, label %loop.latch, label %exit.1
349 %t.1 = icmp ule i32 %x, 10
350 call void @use(i1 %t.1)
351 %f.1 = icmp ugt i32 %x, 10
352 call void @use(i1 %f.1)
353 %c.1 = icmp ule i32 %x, 9
354 call void @use(i1 %c.1)
355 %c.2 = icmp ugt i32 %x, 9
356 call void @use(i1 %c.2)
359 %t.2 = icmp ugt i32 %y, 99
360 call void @use(i1 %t.2)
361 %f.2 = icmp ule i32 %y, 99
362 call void @use(i1 %f.2)
364 %c.3 = icmp ugt i32 %y, 100
365 call void @use(i1 %c.3)
366 %c.4 = icmp ugt i32 %y, 100
367 call void @use(i1 %c.4)
369 %x.next = add i32 %x, 1
370 br label %loop.header
373 %c.6 = icmp ugt i32 %y, 10
374 call void @use(i1 %c.6)
378 define void @loop_header_dom_and_successors_flipped(i32 %y, i1 %c) {
379 ; CHECK-LABEL: @loop_header_dom_and_successors_flipped(
381 ; CHECK-NEXT: br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
383 ; CHECK-NEXT: [[C_9:%.*]] = icmp ugt i32 [[Y:%.*]], 10
384 ; CHECK-NEXT: call void @use(i1 [[C_9]])
385 ; CHECK-NEXT: ret void
386 ; CHECK: loop.header:
387 ; CHECK-NEXT: [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
388 ; CHECK-NEXT: [[X_1:%.*]] = icmp ule i32 [[X]], 10
389 ; CHECK-NEXT: [[Y_1:%.*]] = icmp ugt i32 [[Y]], 99
390 ; CHECK-NEXT: [[AND:%.*]] = and i1 [[X_1]], [[Y_1]]
391 ; CHECK-NEXT: br i1 [[AND]], label [[EXIT_1:%.*]], label [[LOOP_LATCH]]
393 ; CHECK-NEXT: [[C_1:%.*]] = icmp ule i32 [[X]], 10
394 ; CHECK-NEXT: call void @use(i1 [[C_1]])
395 ; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i32 [[X]], 10
396 ; CHECK-NEXT: call void @use(i1 [[C_2]])
397 ; CHECK-NEXT: [[C_3:%.*]] = icmp ule i32 [[X]], 9
398 ; CHECK-NEXT: call void @use(i1 [[C_3]])
399 ; CHECK-NEXT: [[C_4:%.*]] = icmp ugt i32 [[X]], 9
400 ; CHECK-NEXT: call void @use(i1 [[C_4]])
401 ; CHECK-NEXT: [[C_5:%.*]] = icmp ugt i32 [[Y]], 99
402 ; CHECK-NEXT: call void @use(i1 [[C_5]])
403 ; CHECK-NEXT: [[C_6:%.*]] = icmp ule i32 [[Y]], 99
404 ; CHECK-NEXT: call void @use(i1 [[C_6]])
405 ; CHECK-NEXT: [[C_7:%.*]] = icmp ugt i32 [[Y]], 100
406 ; CHECK-NEXT: call void @use(i1 [[C_7]])
407 ; CHECK-NEXT: [[C_8:%.*]] = icmp ugt i32 [[Y]], 100
408 ; CHECK-NEXT: call void @use(i1 [[C_8]])
409 ; CHECK-NEXT: [[X_NEXT]] = add i32 [[X]], 1
410 ; CHECK-NEXT: br label [[LOOP_HEADER]]
412 ; CHECK-NEXT: call void @use(i1 true)
413 ; CHECK-NEXT: ret void
416 br i1 %c, label %loop.header, label %exit
419 %c.9 = icmp ugt i32 %y, 10
420 call void @use(i1 %c.9)
424 %x = phi i32 [ 0, %entry ], [ %x.next, %loop.latch ]
425 %x.1 = icmp ule i32 %x, 10
426 %y.1 = icmp ugt i32 %y, 99
427 %and = and i1 %x.1, %y.1
428 br i1 %and, label %exit.1, label %loop.latch
431 %c.1 = icmp ule i32 %x, 10
432 call void @use(i1 %c.1)
433 %c.2 = icmp ugt i32 %x, 10
434 call void @use(i1 %c.2)
435 %c.3 = icmp ule i32 %x, 9
436 call void @use(i1 %c.3)
437 %c.4 = icmp ugt i32 %x, 9
438 call void @use(i1 %c.4)
441 %c.5 = icmp ugt i32 %y, 99
442 call void @use(i1 %c.5)
443 %c.6 = icmp ule i32 %y, 99
444 call void @use(i1 %c.6)
446 %c.7 = icmp ugt i32 %y, 100
447 call void @use(i1 %c.7)
448 %c.8 = icmp ugt i32 %y, 100
449 call void @use(i1 %c.8)
451 %x.next = add i32 %x, 1
452 br label %loop.header
455 %t.1 = icmp ugt i32 %y, 10
456 call void @use(i1 %t.1)