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: call void @use(i1 true)
16 ; CHECK-NEXT: call void @use(i1 false)
17 ; CHECK-NEXT: [[T_2:%.*]] = icmp sge i32 [[X]], 10
18 ; CHECK-NEXT: call void @use(i1 [[T_2]])
19 ; CHECK-NEXT: [[C_2:%.*]] = icmp sle i32 [[X]], 9
20 ; CHECK-NEXT: call void @use(i1 [[C_2]])
21 ; CHECK-NEXT: [[C_3:%.*]] = icmp sgt i32 [[X]], 9
22 ; CHECK-NEXT: call void @use(i1 [[C_3]])
23 ; CHECK-NEXT: call void @use(i1 true)
24 ; CHECK-NEXT: [[C_5:%.*]] = icmp sge i32 [[X]], 9
25 ; CHECK-NEXT: call void @use(i1 [[C_5]])
26 ; CHECK-NEXT: [[X_NEXT]] = add nsw i32 [[X]], 1
27 ; CHECK-NEXT: br label [[LOOP_HEADER]]
29 ; CHECK-NEXT: [[C_6:%.*]] = icmp sgt i32 [[Y:%.*]], 10
30 ; CHECK-NEXT: call void @use(i1 [[C_6]])
31 ; CHECK-NEXT: ret void
34 br i1 %c, label %loop.header, label %exit
37 %x = phi i32 [ 10, %entry ], [ %x.next, %loop.latch ]
38 %c.1 = icmp slt i32 %x, %n
39 br i1 %c.1, label %loop.latch, label %exit
42 %f.1 = icmp sle i32 %x, %n
43 call void @use(i1 %f.1)
44 %t.1 = icmp sgt i32 %x, %n
45 call void @use(i1 %t.1)
46 %t.2 = icmp sge i32 %x, 10
47 call void @use(i1 %t.2)
49 %c.2 = icmp sle i32 %x, 9
50 call void @use(i1 %c.2)
51 %c.3 = icmp sgt i32 %x, 9
52 call void @use(i1 %c.3)
53 %c.4 = icmp sge i32 %x, 0
54 call void @use(i1 %c.4)
55 %c.5 = icmp sge i32 %x, 9
56 call void @use(i1 %c.5)
58 %x.next = add nsw i32 %x, 1
62 %c.6 = icmp sgt i32 %y, 10
63 call void @use(i1 %c.6)
67 define void @loop_phi_neg_start_value(i32 %y, i1 %c, i32 %n) {
68 ; CHECK-LABEL: @loop_phi_neg_start_value(
70 ; CHECK-NEXT: br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
72 ; CHECK-NEXT: [[X:%.*]] = phi i32 [ -10, [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
73 ; CHECK-NEXT: [[C_1:%.*]] = icmp slt i32 [[X]], [[N:%.*]]
74 ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_LATCH]], label [[EXIT]]
76 ; CHECK-NEXT: call void @use(i1 true)
77 ; CHECK-NEXT: call void @use(i1 false)
78 ; CHECK-NEXT: [[T_2:%.*]] = icmp sge i32 [[X]], -10
79 ; CHECK-NEXT: call void @use(i1 [[T_2]])
80 ; CHECK-NEXT: [[C_2:%.*]] = icmp sle i32 [[X]], 9
81 ; CHECK-NEXT: call void @use(i1 [[C_2]])
82 ; CHECK-NEXT: [[C_3:%.*]] = icmp sgt i32 [[X]], 9
83 ; CHECK-NEXT: call void @use(i1 [[C_3]])
84 ; CHECK-NEXT: [[C_4:%.*]] = icmp sge i32 [[X]], 0
85 ; CHECK-NEXT: call void @use(i1 [[C_4]])
86 ; CHECK-NEXT: [[C_5:%.*]] = icmp sge i32 [[X]], 9
87 ; CHECK-NEXT: call void @use(i1 [[C_5]])
88 ; CHECK-NEXT: [[X_NEXT]] = add nsw i32 [[X]], 1
89 ; CHECK-NEXT: br label [[LOOP_HEADER]]
91 ; CHECK-NEXT: [[C_6:%.*]] = icmp sgt i32 [[Y:%.*]], 10
92 ; CHECK-NEXT: call void @use(i1 [[C_6]])
93 ; CHECK-NEXT: ret void
96 br i1 %c, label %loop.header, label %exit
99 %x = phi i32 [ -10, %entry ], [ %x.next, %loop.latch ]
100 %c.1 = icmp slt i32 %x, %n
101 br i1 %c.1, label %loop.latch, label %exit
104 %f.1 = icmp sle i32 %x, %n
105 call void @use(i1 %f.1)
106 %t.1 = icmp sgt i32 %x, %n
107 call void @use(i1 %t.1)
108 %t.2 = icmp sge i32 %x, -10
109 call void @use(i1 %t.2)
111 %c.2 = icmp sle i32 %x, 9
112 call void @use(i1 %c.2)
113 %c.3 = icmp sgt i32 %x, 9
114 call void @use(i1 %c.3)
115 %c.4 = icmp sge i32 %x, 0
116 call void @use(i1 %c.4)
117 %c.5 = icmp sge i32 %x, 9
118 call void @use(i1 %c.5)
120 %x.next = add nsw i32 %x, 1
121 br label %loop.header
124 %c.6 = icmp sgt i32 %y, 10
125 call void @use(i1 %c.6)
129 define void @loop_count_down(i32 %y, i1 %c, i32 %n) {
130 ; CHECK-LABEL: @loop_count_down(
132 ; CHECK-NEXT: br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
133 ; CHECK: loop.header:
134 ; CHECK-NEXT: [[X:%.*]] = phi i32 [ [[N:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
135 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[X]], 0
136 ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_LATCH]], label [[EXIT]]
138 ; CHECK-NEXT: [[F_1:%.*]] = icmp sle i32 [[X]], [[N]]
139 ; CHECK-NEXT: call void @use(i1 [[F_1]])
140 ; CHECK-NEXT: [[T_1:%.*]] = icmp sgt i32 [[X]], [[N]]
141 ; CHECK-NEXT: call void @use(i1 [[T_1]])
142 ; CHECK-NEXT: call void @use(i1 true)
143 ; CHECK-NEXT: call void @use(i1 true)
144 ; CHECK-NEXT: [[C_2:%.*]] = icmp sle i32 [[X]], 9
145 ; CHECK-NEXT: call void @use(i1 [[C_2]])
146 ; CHECK-NEXT: [[C_3:%.*]] = icmp sgt i32 [[X]], 9
147 ; CHECK-NEXT: call void @use(i1 [[C_3]])
148 ; CHECK-NEXT: [[C_4:%.*]] = icmp sge i32 [[X]], 1
149 ; CHECK-NEXT: call void @use(i1 [[C_4]])
150 ; CHECK-NEXT: [[C_5:%.*]] = icmp sge i32 [[X]], 2
151 ; CHECK-NEXT: call void @use(i1 [[C_5]])
152 ; CHECK-NEXT: [[X_NEXT]] = add nsw i32 [[X]], 1
153 ; CHECK-NEXT: br label [[LOOP_HEADER]]
155 ; CHECK-NEXT: [[C_6:%.*]] = icmp sgt i32 [[Y:%.*]], 10
156 ; CHECK-NEXT: call void @use(i1 [[C_6]])
157 ; CHECK-NEXT: ret void
160 br i1 %c, label %loop.header, label %exit
163 %x = phi i32 [ %n, %entry ], [ %x.next, %loop.latch ]
164 %c.1 = icmp sge i32 %x, 0
165 br i1 %c.1, label %loop.latch, label %exit
168 %f.1 = icmp sle i32 %x, %n
169 call void @use(i1 %f.1)
170 %t.1 = icmp sgt i32 %x, %n
171 call void @use(i1 %t.1)
172 %t.2 = icmp sge i32 %x, 0
173 call void @use(i1 %t.2)
174 %t.3 = icmp sge i32 %x, -1
175 call void @use(i1 %t.3)
177 %c.2 = icmp sle i32 %x, 9
178 call void @use(i1 %c.2)
179 %c.3 = icmp sgt i32 %x, 9
180 call void @use(i1 %c.3)
181 %c.4 = icmp sge i32 %x, 1
182 call void @use(i1 %c.4)
183 %c.5 = icmp sge i32 %x, 2
184 call void @use(i1 %c.5)
186 %x.next = add nsw i32 %x, 1
187 br label %loop.header
190 %c.6 = icmp sgt i32 %y, 10
191 call void @use(i1 %c.6)
195 define void @loop_latch_may_not_executed(i32 %y, i1 %c, i32 %n) {
196 ; CHECK-LABEL: @loop_latch_may_not_executed(
198 ; CHECK-NEXT: br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
199 ; CHECK: loop.header:
200 ; CHECK-NEXT: [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
201 ; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i32 [[X]], [[N:%.*]]
202 ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_LATCH]], label [[EXIT]]
204 ; CHECK-NEXT: call void @use(i1 false)
205 ; CHECK-NEXT: call void @use(i1 true)
206 ; CHECK-NEXT: [[C_2:%.*]] = icmp ule i32 [[X]], 9
207 ; CHECK-NEXT: call void @use(i1 [[C_2]])
208 ; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i32 [[X]], 9
209 ; CHECK-NEXT: call void @use(i1 [[C_3]])
210 ; CHECK-NEXT: [[X_NEXT]] = add i32 [[X]], 1
211 ; CHECK-NEXT: br label [[LOOP_HEADER]]
213 ; CHECK-NEXT: [[C_4:%.*]] = icmp ugt i32 [[Y:%.*]], 10
214 ; CHECK-NEXT: call void @use(i1 [[C_4]])
215 ; CHECK-NEXT: ret void
218 br i1 %c, label %loop.header, label %exit
221 %x = phi i32 [ 0, %entry ], [ %x.next, %loop.latch ]
222 %c.1 = icmp ugt i32 %x, %n
223 br i1 %c.1, label %loop.latch, label %exit
226 %f.1 = icmp ule i32 %x, %n
227 call void @use(i1 %f.1)
228 %t.1 = icmp ugt i32 %x, %n
229 call void @use(i1 %t.1)
231 %c.2 = icmp ule i32 %x, 9
232 call void @use(i1 %c.2)
233 %c.3 = icmp ugt i32 %x, 9
234 call void @use(i1 %c.3)
236 %x.next = add i32 %x, 1
237 br label %loop.header
240 %c.4 = icmp ugt i32 %y, 10
241 call void @use(i1 %c.4)
245 define void @loop_latch_not_executed_constant_bound(i32 %y, i1 %c) {
246 ; CHECK-LABEL: @loop_latch_not_executed_constant_bound(
248 ; CHECK-NEXT: br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
249 ; CHECK: loop.header:
250 ; CHECK-NEXT: [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
251 ; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i32 [[X]], 10
252 ; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_LATCH]], label [[EXIT]]
254 ; CHECK-NEXT: call void @use(i1 false)
255 ; CHECK-NEXT: call void @use(i1 true)
256 ; CHECK-NEXT: call void @use(i1 false)
257 ; CHECK-NEXT: call void @use(i1 true)
258 ; CHECK-NEXT: [[X_NEXT]] = add i32 [[X]], 1
259 ; CHECK-NEXT: br label [[LOOP_HEADER]]
261 ; CHECK-NEXT: [[C_4:%.*]] = icmp ugt i32 [[Y:%.*]], 10
262 ; CHECK-NEXT: call void @use(i1 [[C_4]])
263 ; CHECK-NEXT: ret void
266 br i1 %c, label %loop.header, label %exit
269 %x = phi i32 [ 0, %entry ], [ %x.next, %loop.latch ]
270 %c.1 = icmp ugt i32 %x, 10
271 br i1 %c.1, label %loop.latch, label %exit
274 %t.1 = icmp ule i32 %x, 10
275 call void @use(i1 %t.1)
276 %f.1 = icmp ugt i32 %x, 10
277 call void @use(i1 %f.1)
279 %c.2 = icmp ule i32 %x, 9
280 call void @use(i1 %c.2)
281 %c.3 = icmp ugt i32 %x, 9
282 call void @use(i1 %c.3)
284 %x.next = add i32 %x, 1
285 br label %loop.header
288 %c.4 = icmp ugt i32 %y, 10
289 call void @use(i1 %c.4)
294 define void @loop_iv_cond_variable_bound(i32 %n) {
295 ; CHECK-LABEL: @loop_iv_cond_variable_bound(
297 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
298 ; CHECK: loop.header:
299 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
300 ; CHECK-NEXT: [[T_1:%.*]] = icmp ule i32 [[IV]], [[N:%.*]]
301 ; CHECK-NEXT: call void @use(i1 [[T_1]])
302 ; CHECK-NEXT: [[T_2:%.*]] = icmp sge i32 [[IV]], 0
303 ; CHECK-NEXT: call void @use(i1 [[T_2]])
304 ; CHECK-NEXT: [[T_3:%.*]] = icmp sge i32 [[IV]], -1
305 ; CHECK-NEXT: call void @use(i1 [[T_3]])
306 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i32 [[IV]], [[N]]
307 ; CHECK-NEXT: call void @use(i1 [[C_1]])
308 ; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i32 [[IV]], 1
309 ; CHECK-NEXT: call void @use(i1 [[C_2]])
310 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IV]], [[N]]
311 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_LATCH]], label [[EXIT:%.*]]
313 ; CHECK-NEXT: call void @use(i1 true)
314 ; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 2
315 ; CHECK-NEXT: call void @use(i1 [[C_3]])
316 ; CHECK-NEXT: [[C_4:%.*]] = icmp ugt i32 [[IV]], 1
317 ; CHECK-NEXT: call void @use(i1 [[C_4]])
318 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
319 ; CHECK-NEXT: br label [[LOOP_HEADER]]
321 ; CHECK-NEXT: ret void
324 br label %loop.header
327 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
328 %t.1 = icmp ule i32 %iv, %n
329 call void @use(i1 %t.1)
330 %t.2 = icmp sge i32 %iv, 0
331 call void @use(i1 %t.2)
332 %t.3 = icmp sge i32 %iv, -1
333 call void @use(i1 %t.3)
335 %c.1 = icmp ult i32 %iv, %n
336 call void @use(i1 %c.1)
337 %c.2 = icmp ugt i32 %iv, 1
338 call void @use(i1 %c.2)
340 %cmp = icmp ult i32 %iv, %n
341 br i1 %cmp, label %loop.latch, label %exit
344 %t.4 = icmp ule i32 %iv, %n
345 call void @use(i1 %t.4)
347 %c.3 = icmp ult i32 %iv, 2
348 call void @use(i1 %c.3)
349 %c.4 = icmp ugt i32 %iv, 1
350 call void @use(i1 %c.4)
352 %iv.next = add nuw nsw i32 %iv, 1
353 br label %loop.header
359 define void @loop_iv_cond_constant_bound() {
360 ; CHECK-LABEL: @loop_iv_cond_constant_bound(
362 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
363 ; CHECK: loop.header:
364 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
365 ; CHECK-NEXT: [[T_1:%.*]] = icmp ule i32 [[IV]], 2
366 ; CHECK-NEXT: call void @use(i1 [[T_1]])
367 ; CHECK-NEXT: [[T_2:%.*]] = icmp sge i32 [[IV]], 0
368 ; CHECK-NEXT: call void @use(i1 [[T_2]])
369 ; CHECK-NEXT: [[T_3:%.*]] = icmp sge i32 [[IV]], -1
370 ; CHECK-NEXT: call void @use(i1 [[T_3]])
371 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i32 [[IV]], 2
372 ; CHECK-NEXT: call void @use(i1 [[C_1]])
373 ; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i32 [[IV]], 1
374 ; CHECK-NEXT: call void @use(i1 [[C_2]])
375 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IV]], 2
376 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_LATCH]], label [[EXIT:%.*]]
378 ; CHECK-NEXT: call void @use(i1 true)
379 ; CHECK-NEXT: call void @use(i1 true)
380 ; CHECK-NEXT: call void @use(i1 false)
381 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
382 ; CHECK-NEXT: br label [[LOOP_HEADER]]
384 ; CHECK-NEXT: ret void
387 br label %loop.header
390 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
391 %t.1 = icmp ule i32 %iv, 2
392 call void @use(i1 %t.1)
393 %t.2 = icmp sge i32 %iv, 0
394 call void @use(i1 %t.2)
395 %t.3 = icmp sge i32 %iv, -1
396 call void @use(i1 %t.3)
398 %c.1 = icmp ult i32 %iv, 2
399 call void @use(i1 %c.1)
400 %c.2 = icmp ugt i32 %iv, 1
401 call void @use(i1 %c.2)
403 %cmp = icmp ult i32 %iv, 2
404 br i1 %cmp, label %loop.latch, label %exit
407 %t.4 = icmp ule i32 %iv, 2
408 call void @use(i1 %t.4)
410 %c.3 = icmp ult i32 %iv, 2
411 call void @use(i1 %c.3)
412 %c.4 = icmp ugt i32 %iv, 1
413 call void @use(i1 %c.4)
415 %iv.next = add nuw nsw i32 %iv, 1
416 br label %loop.header