1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
6 define void @loop_phi_pos_start_value(i32 %y, i1 %c, i32 %n) {
7 ; CHECK-LABEL: @loop_phi_pos_start_value(
9 ; CHECK-NEXT: br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
11 ; CHECK-NEXT: [[X:%.*]] = phi i32 [ 10, [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
12 ; CHECK-NEXT: [[C_1:%.*]] = icmp slt i32 [[X]], [[N:%.*]]
13 ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_LATCH]], label [[EXIT]]
15 ; CHECK-NEXT: [[F_1:%.*]] = icmp sle i32 [[X]], [[N]]
16 ; CHECK-NEXT: call void @use(i1 [[F_1]])
17 ; CHECK-NEXT: [[T_1:%.*]] = icmp sgt i32 [[X]], [[N]]
18 ; CHECK-NEXT: call void @use(i1 [[T_1]])
19 ; CHECK-NEXT: [[T_2:%.*]] = icmp sge i32 [[X]], 10
20 ; CHECK-NEXT: call void @use(i1 [[T_2]])
21 ; CHECK-NEXT: [[C_2:%.*]] = icmp sle i32 [[X]], 9
22 ; CHECK-NEXT: call void @use(i1 [[C_2]])
23 ; CHECK-NEXT: [[C_3:%.*]] = icmp sgt i32 [[X]], 9
24 ; CHECK-NEXT: call void @use(i1 [[C_3]])
25 ; CHECK-NEXT: [[C_4:%.*]] = icmp sge i32 [[X]], 0
26 ; CHECK-NEXT: call void @use(i1 [[C_4]])
27 ; CHECK-NEXT: [[C_5:%.*]] = icmp sge i32 [[X]], 9
28 ; CHECK-NEXT: call void @use(i1 [[C_5]])
29 ; CHECK-NEXT: [[X_NEXT]] = add nsw i32 [[X]], 1
30 ; CHECK-NEXT: br label [[LOOP_HEADER]]
32 ; CHECK-NEXT: [[C_6:%.*]] = icmp sgt i32 [[Y:%.*]], 10
33 ; CHECK-NEXT: call void @use(i1 [[C_6]])
34 ; CHECK-NEXT: ret void
37 br i1 %c, label %loop.header, label %exit
40 %x = phi i32 [ 10, %entry ], [ %x.next, %loop.latch ]
41 %c.1 = icmp slt i32 %x, %n
42 br i1 %c.1, label %loop.latch, label %exit
45 %f.1 = icmp sle i32 %x, %n
46 call void @use(i1 %f.1)
47 %t.1 = icmp sgt i32 %x, %n
48 call void @use(i1 %t.1)
49 %t.2 = icmp sge i32 %x, 10
50 call void @use(i1 %t.2)
52 %c.2 = icmp sle i32 %x, 9
53 call void @use(i1 %c.2)
54 %c.3 = icmp sgt i32 %x, 9
55 call void @use(i1 %c.3)
56 %c.4 = icmp sge i32 %x, 0
57 call void @use(i1 %c.4)
58 %c.5 = icmp sge i32 %x, 9
59 call void @use(i1 %c.5)
61 %x.next = add nsw i32 %x, 1
65 %c.6 = icmp sgt i32 %y, 10
66 call void @use(i1 %c.6)
70 define void @loop_phi_neg_start_value(i32 %y, i1 %c, i32 %n) {
71 ; CHECK-LABEL: @loop_phi_neg_start_value(
73 ; CHECK-NEXT: br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
75 ; CHECK-NEXT: [[X:%.*]] = phi i32 [ -10, [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
76 ; CHECK-NEXT: [[C_1:%.*]] = icmp slt i32 [[X]], [[N:%.*]]
77 ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_LATCH]], label [[EXIT]]
79 ; CHECK-NEXT: [[F_1:%.*]] = icmp sle i32 [[X]], [[N]]
80 ; CHECK-NEXT: call void @use(i1 [[F_1]])
81 ; CHECK-NEXT: [[T_1:%.*]] = icmp sgt i32 [[X]], [[N]]
82 ; CHECK-NEXT: call void @use(i1 [[T_1]])
83 ; CHECK-NEXT: [[T_2:%.*]] = icmp sge i32 [[X]], -10
84 ; CHECK-NEXT: call void @use(i1 [[T_2]])
85 ; CHECK-NEXT: [[C_2:%.*]] = icmp sle i32 [[X]], 9
86 ; CHECK-NEXT: call void @use(i1 [[C_2]])
87 ; CHECK-NEXT: [[C_3:%.*]] = icmp sgt i32 [[X]], 9
88 ; CHECK-NEXT: call void @use(i1 [[C_3]])
89 ; CHECK-NEXT: [[C_4:%.*]] = icmp sge i32 [[X]], 0
90 ; CHECK-NEXT: call void @use(i1 [[C_4]])
91 ; CHECK-NEXT: [[C_5:%.*]] = icmp sge i32 [[X]], 9
92 ; CHECK-NEXT: call void @use(i1 [[C_5]])
93 ; CHECK-NEXT: [[X_NEXT]] = add nsw i32 [[X]], 1
94 ; CHECK-NEXT: br label [[LOOP_HEADER]]
96 ; CHECK-NEXT: [[C_6:%.*]] = icmp sgt i32 [[Y:%.*]], 10
97 ; CHECK-NEXT: call void @use(i1 [[C_6]])
98 ; CHECK-NEXT: ret void
101 br i1 %c, label %loop.header, label %exit
104 %x = phi i32 [ -10, %entry ], [ %x.next, %loop.latch ]
105 %c.1 = icmp slt i32 %x, %n
106 br i1 %c.1, label %loop.latch, label %exit
109 %f.1 = icmp sle i32 %x, %n
110 call void @use(i1 %f.1)
111 %t.1 = icmp sgt i32 %x, %n
112 call void @use(i1 %t.1)
113 %t.2 = icmp sge i32 %x, -10
114 call void @use(i1 %t.2)
116 %c.2 = icmp sle i32 %x, 9
117 call void @use(i1 %c.2)
118 %c.3 = icmp sgt i32 %x, 9
119 call void @use(i1 %c.3)
120 %c.4 = icmp sge i32 %x, 0
121 call void @use(i1 %c.4)
122 %c.5 = icmp sge i32 %x, 9
123 call void @use(i1 %c.5)
125 %x.next = add nsw i32 %x, 1
126 br label %loop.header
129 %c.6 = icmp sgt i32 %y, 10
130 call void @use(i1 %c.6)
134 define void @loop_count_down(i32 %y, i1 %c, i32 %n) {
135 ; CHECK-LABEL: @loop_count_down(
137 ; CHECK-NEXT: br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
138 ; CHECK: loop.header:
139 ; CHECK-NEXT: [[X:%.*]] = phi i32 [ [[N:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
140 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[X]], 0
141 ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_LATCH]], label [[EXIT]]
143 ; CHECK-NEXT: [[F_1:%.*]] = icmp sle i32 [[X]], [[N]]
144 ; CHECK-NEXT: call void @use(i1 [[F_1]])
145 ; CHECK-NEXT: [[T_1:%.*]] = icmp sgt i32 [[X]], [[N]]
146 ; CHECK-NEXT: call void @use(i1 [[T_1]])
147 ; CHECK-NEXT: [[T_2:%.*]] = icmp sge i32 [[X]], 0
148 ; CHECK-NEXT: call void @use(i1 [[T_2]])
149 ; CHECK-NEXT: [[T_3:%.*]] = icmp sge i32 [[X]], -1
150 ; CHECK-NEXT: call void @use(i1 [[T_3]])
151 ; CHECK-NEXT: [[C_2:%.*]] = icmp sle i32 [[X]], 9
152 ; CHECK-NEXT: call void @use(i1 [[C_2]])
153 ; CHECK-NEXT: [[C_3:%.*]] = icmp sgt i32 [[X]], 9
154 ; CHECK-NEXT: call void @use(i1 [[C_3]])
155 ; CHECK-NEXT: [[C_4:%.*]] = icmp sge i32 [[X]], 1
156 ; CHECK-NEXT: call void @use(i1 [[C_4]])
157 ; CHECK-NEXT: [[C_5:%.*]] = icmp sge i32 [[X]], 2
158 ; CHECK-NEXT: call void @use(i1 [[C_5]])
159 ; CHECK-NEXT: [[X_NEXT]] = add nsw i32 [[X]], 1
160 ; CHECK-NEXT: br label [[LOOP_HEADER]]
162 ; CHECK-NEXT: [[C_6:%.*]] = icmp sgt i32 [[Y:%.*]], 10
163 ; CHECK-NEXT: call void @use(i1 [[C_6]])
164 ; CHECK-NEXT: ret void
167 br i1 %c, label %loop.header, label %exit
170 %x = phi i32 [ %n, %entry ], [ %x.next, %loop.latch ]
171 %c.1 = icmp sge i32 %x, 0
172 br i1 %c.1, label %loop.latch, label %exit
175 %f.1 = icmp sle i32 %x, %n
176 call void @use(i1 %f.1)
177 %t.1 = icmp sgt i32 %x, %n
178 call void @use(i1 %t.1)
179 %t.2 = icmp sge i32 %x, 0
180 call void @use(i1 %t.2)
181 %t.3 = icmp sge i32 %x, -1
182 call void @use(i1 %t.3)
184 %c.2 = icmp sle i32 %x, 9
185 call void @use(i1 %c.2)
186 %c.3 = icmp sgt i32 %x, 9
187 call void @use(i1 %c.3)
188 %c.4 = icmp sge i32 %x, 1
189 call void @use(i1 %c.4)
190 %c.5 = icmp sge i32 %x, 2
191 call void @use(i1 %c.5)
193 %x.next = add nsw i32 %x, 1
194 br label %loop.header
197 %c.6 = icmp sgt i32 %y, 10
198 call void @use(i1 %c.6)
202 define void @loop_latch_may_not_executed(i32 %y, i1 %c, i32 %n) {
203 ; CHECK-LABEL: @loop_latch_may_not_executed(
205 ; CHECK-NEXT: br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
206 ; CHECK: loop.header:
207 ; CHECK-NEXT: [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
208 ; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i32 [[X]], [[N:%.*]]
209 ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_LATCH]], label [[EXIT]]
211 ; CHECK-NEXT: [[F_1:%.*]] = icmp ule i32 [[X]], [[N]]
212 ; CHECK-NEXT: call void @use(i1 false)
213 ; CHECK-NEXT: [[T_1:%.*]] = icmp ugt i32 [[X]], [[N]]
214 ; CHECK-NEXT: call void @use(i1 true)
215 ; CHECK-NEXT: [[C_2:%.*]] = icmp ule i32 [[X]], 9
216 ; CHECK-NEXT: call void @use(i1 [[C_2]])
217 ; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i32 [[X]], 9
218 ; CHECK-NEXT: call void @use(i1 [[C_3]])
219 ; CHECK-NEXT: [[X_NEXT]] = add i32 [[X]], 1
220 ; CHECK-NEXT: br label [[LOOP_HEADER]]
222 ; CHECK-NEXT: [[C_4:%.*]] = icmp ugt i32 [[Y:%.*]], 10
223 ; CHECK-NEXT: call void @use(i1 [[C_4]])
224 ; CHECK-NEXT: ret void
227 br i1 %c, label %loop.header, label %exit
230 %x = phi i32 [ 0, %entry ], [ %x.next, %loop.latch ]
231 %c.1 = icmp ugt i32 %x, %n
232 br i1 %c.1, label %loop.latch, label %exit
235 %f.1 = icmp ule i32 %x, %n
236 call void @use(i1 %f.1)
237 %t.1 = icmp ugt i32 %x, %n
238 call void @use(i1 %t.1)
240 %c.2 = icmp ule i32 %x, 9
241 call void @use(i1 %c.2)
242 %c.3 = icmp ugt i32 %x, 9
243 call void @use(i1 %c.3)
245 %x.next = add i32 %x, 1
246 br label %loop.header
249 %c.4 = icmp ugt i32 %y, 10
250 call void @use(i1 %c.4)
254 define void @loop_latch_not_executed_constant_bound(i32 %y, i1 %c) {
255 ; CHECK-LABEL: @loop_latch_not_executed_constant_bound(
257 ; CHECK-NEXT: br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
258 ; CHECK: loop.header:
259 ; CHECK-NEXT: [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
260 ; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i32 [[X]], 10
261 ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_LATCH]], label [[EXIT]]
263 ; CHECK-NEXT: [[T_1:%.*]] = icmp ule i32 [[X]], 10
264 ; CHECK-NEXT: call void @use(i1 false)
265 ; CHECK-NEXT: [[F_1:%.*]] = icmp ugt i32 [[X]], 10
266 ; CHECK-NEXT: call void @use(i1 true)
267 ; CHECK-NEXT: [[C_2:%.*]] = icmp ule i32 [[X]], 9
268 ; CHECK-NEXT: call void @use(i1 false)
269 ; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i32 [[X]], 9
270 ; CHECK-NEXT: call void @use(i1 true)
271 ; CHECK-NEXT: [[X_NEXT]] = add i32 [[X]], 1
272 ; CHECK-NEXT: br label [[LOOP_HEADER]]
274 ; CHECK-NEXT: [[C_4:%.*]] = icmp ugt i32 [[Y:%.*]], 10
275 ; CHECK-NEXT: call void @use(i1 [[C_4]])
276 ; CHECK-NEXT: ret void
279 br i1 %c, label %loop.header, label %exit
282 %x = phi i32 [ 0, %entry ], [ %x.next, %loop.latch ]
283 %c.1 = icmp ugt i32 %x, 10
284 br i1 %c.1, label %loop.latch, label %exit
287 %t.1 = icmp ule i32 %x, 10
288 call void @use(i1 %t.1)
289 %f.1 = icmp ugt i32 %x, 10
290 call void @use(i1 %f.1)
292 %c.2 = icmp ule i32 %x, 9
293 call void @use(i1 %c.2)
294 %c.3 = icmp ugt i32 %x, 9
295 call void @use(i1 %c.3)
297 %x.next = add i32 %x, 1
298 br label %loop.header
301 %c.4 = icmp ugt i32 %y, 10
302 call void @use(i1 %c.4)
307 define void @loop_iv_cond_variable_bound(i32 %n) {
308 ; CHECK-LABEL: @loop_iv_cond_variable_bound(
310 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
311 ; CHECK: loop.header:
312 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
313 ; CHECK-NEXT: [[T_1:%.*]] = icmp ule i32 [[IV]], [[N:%.*]]
314 ; CHECK-NEXT: call void @use(i1 [[T_1]])
315 ; CHECK-NEXT: [[T_2:%.*]] = icmp sge i32 [[IV]], 0
316 ; CHECK-NEXT: call void @use(i1 [[T_2]])
317 ; CHECK-NEXT: [[T_3:%.*]] = icmp sge i32 [[IV]], -1
318 ; CHECK-NEXT: call void @use(i1 [[T_3]])
319 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i32 [[IV]], [[N]]
320 ; CHECK-NEXT: call void @use(i1 [[C_1]])
321 ; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i32 [[IV]], 1
322 ; CHECK-NEXT: call void @use(i1 [[C_2]])
323 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IV]], [[N]]
324 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_LATCH]], label [[EXIT:%.*]]
326 ; CHECK-NEXT: [[T_4:%.*]] = icmp ule i32 [[IV]], [[N]]
327 ; CHECK-NEXT: call void @use(i1 true)
328 ; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 2
329 ; CHECK-NEXT: call void @use(i1 [[C_3]])
330 ; CHECK-NEXT: [[C_4:%.*]] = icmp ugt i32 [[IV]], 1
331 ; CHECK-NEXT: call void @use(i1 [[C_4]])
332 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
333 ; CHECK-NEXT: br label [[LOOP_HEADER]]
335 ; CHECK-NEXT: ret void
338 br label %loop.header
341 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
342 %t.1 = icmp ule i32 %iv, %n
343 call void @use(i1 %t.1)
344 %t.2 = icmp sge i32 %iv, 0
345 call void @use(i1 %t.2)
346 %t.3 = icmp sge i32 %iv, -1
347 call void @use(i1 %t.3)
349 %c.1 = icmp ult i32 %iv, %n
350 call void @use(i1 %c.1)
351 %c.2 = icmp ugt i32 %iv, 1
352 call void @use(i1 %c.2)
354 %cmp = icmp ult i32 %iv, %n
355 br i1 %cmp, label %loop.latch, label %exit
358 %t.4 = icmp ule i32 %iv, %n
359 call void @use(i1 %t.4)
361 %c.3 = icmp ult i32 %iv, 2
362 call void @use(i1 %c.3)
363 %c.4 = icmp ugt i32 %iv, 1
364 call void @use(i1 %c.4)
366 %iv.next = add nuw nsw i32 %iv, 1
367 br label %loop.header
373 define void @loop_iv_cond_constant_bound() {
374 ; CHECK-LABEL: @loop_iv_cond_constant_bound(
376 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
377 ; CHECK: loop.header:
378 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
379 ; CHECK-NEXT: [[T_1:%.*]] = icmp ule i32 [[IV]], 2
380 ; CHECK-NEXT: call void @use(i1 [[T_1]])
381 ; CHECK-NEXT: [[T_2:%.*]] = icmp sge i32 [[IV]], 0
382 ; CHECK-NEXT: call void @use(i1 [[T_2]])
383 ; CHECK-NEXT: [[T_3:%.*]] = icmp sge i32 [[IV]], -1
384 ; CHECK-NEXT: call void @use(i1 [[T_3]])
385 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i32 [[IV]], 2
386 ; CHECK-NEXT: call void @use(i1 [[C_1]])
387 ; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i32 [[IV]], 1
388 ; CHECK-NEXT: call void @use(i1 [[C_2]])
389 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IV]], 2
390 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_LATCH]], label [[EXIT:%.*]]
392 ; CHECK-NEXT: [[T_4:%.*]] = icmp ule i32 [[IV]], 2
393 ; CHECK-NEXT: call void @use(i1 true)
394 ; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 2
395 ; CHECK-NEXT: call void @use(i1 true)
396 ; CHECK-NEXT: [[C_4:%.*]] = icmp ugt i32 [[IV]], 1
397 ; CHECK-NEXT: call void @use(i1 false)
398 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
399 ; CHECK-NEXT: br label [[LOOP_HEADER]]
401 ; CHECK-NEXT: ret void
404 br label %loop.header
407 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
408 %t.1 = icmp ule i32 %iv, 2
409 call void @use(i1 %t.1)
410 %t.2 = icmp sge i32 %iv, 0
411 call void @use(i1 %t.2)
412 %t.3 = icmp sge i32 %iv, -1
413 call void @use(i1 %t.3)
415 %c.1 = icmp ult i32 %iv, 2
416 call void @use(i1 %c.1)
417 %c.2 = icmp ugt i32 %iv, 1
418 call void @use(i1 %c.2)
420 %cmp = icmp ult i32 %iv, 2
421 br i1 %cmp, label %loop.latch, label %exit
424 %t.4 = icmp ule i32 %iv, 2
425 call void @use(i1 %t.4)
427 %c.3 = icmp ult i32 %iv, 2
428 call void @use(i1 %c.3)
429 %c.4 = icmp ugt i32 %iv, 1
430 call void @use(i1 %c.4)
432 %iv.next = add nuw nsw i32 %iv, 1
433 br label %loop.header