xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/loops-header-tested-base.ll (revision fbcf8a8cbb2461730bfd0603b396842925a88ef2)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3
4declare void @use(i1)
5
6define void @loop_phi_pos_start_value(i32 %y, i1 %c, i32 %n) {
7; CHECK-LABEL: @loop_phi_pos_start_value(
8; CHECK-NEXT:  entry:
9; CHECK-NEXT:    br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
10; CHECK:       loop.header:
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]]
14; CHECK:       loop.latch:
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]]
28; CHECK:       exit:
29; CHECK-NEXT:    [[C_6:%.*]] = icmp sgt i32 [[Y:%.*]], 10
30; CHECK-NEXT:    call void @use(i1 [[C_6]])
31; CHECK-NEXT:    ret void
32;
33entry:
34  br i1 %c, label %loop.header, label %exit
35
36loop.header:
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
40
41loop.latch:
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)
48
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)
57
58  %x.next = add nsw i32 %x, 1
59  br label %loop.header
60
61exit:
62  %c.6 = icmp sgt i32 %y, 10
63  call void @use(i1 %c.6)
64  ret void
65}
66
67define void @loop_phi_neg_start_value(i32 %y, i1 %c, i32 %n) {
68; CHECK-LABEL: @loop_phi_neg_start_value(
69; CHECK-NEXT:  entry:
70; CHECK-NEXT:    br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
71; CHECK:       loop.header:
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]]
75; CHECK:       loop.latch:
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]]
90; CHECK:       exit:
91; CHECK-NEXT:    [[C_6:%.*]] = icmp sgt i32 [[Y:%.*]], 10
92; CHECK-NEXT:    call void @use(i1 [[C_6]])
93; CHECK-NEXT:    ret void
94;
95entry:
96  br i1 %c, label %loop.header, label %exit
97
98loop.header:
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
102
103loop.latch:
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)
110
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)
119
120  %x.next = add nsw i32 %x, 1
121  br label %loop.header
122
123exit:
124  %c.6 = icmp sgt i32 %y, 10
125  call void @use(i1 %c.6)
126  ret void
127}
128
129define void @loop_count_down(i32 %y, i1 %c, i32 %n) {
130; CHECK-LABEL: @loop_count_down(
131; CHECK-NEXT:  entry:
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]]
137; CHECK:       loop.latch:
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]]
154; CHECK:       exit:
155; CHECK-NEXT:    [[C_6:%.*]] = icmp sgt i32 [[Y:%.*]], 10
156; CHECK-NEXT:    call void @use(i1 [[C_6]])
157; CHECK-NEXT:    ret void
158;
159entry:
160  br i1 %c, label %loop.header, label %exit
161
162loop.header:
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
166
167loop.latch:
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)
176
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)
185
186  %x.next = add nsw i32 %x, 1
187  br label %loop.header
188
189exit:
190  %c.6 = icmp sgt i32 %y, 10
191  call void @use(i1 %c.6)
192  ret void
193}
194
195define void @loop_latch_may_not_executed(i32 %y, i1 %c, i32 %n) {
196; CHECK-LABEL: @loop_latch_may_not_executed(
197; CHECK-NEXT:  entry:
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]]
203; CHECK:       loop.latch:
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]]
212; CHECK:       exit:
213; CHECK-NEXT:    [[C_4:%.*]] = icmp ugt i32 [[Y:%.*]], 10
214; CHECK-NEXT:    call void @use(i1 [[C_4]])
215; CHECK-NEXT:    ret void
216;
217entry:
218  br i1 %c, label %loop.header, label %exit
219
220loop.header:
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
224
225loop.latch:
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)
230
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)
235
236  %x.next = add i32 %x, 1
237  br label %loop.header
238
239exit:
240  %c.4 = icmp ugt i32 %y, 10
241  call void @use(i1 %c.4)
242  ret void
243}
244
245define void @loop_latch_not_executed_constant_bound(i32 %y, i1 %c) {
246; CHECK-LABEL: @loop_latch_not_executed_constant_bound(
247; CHECK-NEXT:  entry:
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]]
253; CHECK:       loop.latch:
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]]
260; CHECK:       exit:
261; CHECK-NEXT:    [[C_4:%.*]] = icmp ugt i32 [[Y:%.*]], 10
262; CHECK-NEXT:    call void @use(i1 [[C_4]])
263; CHECK-NEXT:    ret void
264;
265entry:
266  br i1 %c, label %loop.header, label %exit
267
268loop.header:
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
272
273loop.latch:
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)
278
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)
283
284  %x.next = add i32 %x, 1
285  br label %loop.header
286
287exit:
288  %c.4 = icmp ugt i32 %y, 10
289  call void @use(i1 %c.4)
290  ret void
291}
292
293
294define void @loop_iv_cond_variable_bound(i32 %n) {
295; CHECK-LABEL: @loop_iv_cond_variable_bound(
296; CHECK-NEXT:  entry:
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:%.*]]
312; CHECK:       loop.latch:
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]]
320; CHECK:       exit:
321; CHECK-NEXT:    ret void
322;
323entry:
324  br label %loop.header
325
326loop.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)
334
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)
339
340  %cmp = icmp ult i32 %iv, %n
341  br i1 %cmp, label %loop.latch, label %exit
342
343loop.latch:
344  %t.4 = icmp ule  i32 %iv, %n
345  call void @use(i1 %t.4)
346
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)
351
352  %iv.next = add nuw nsw i32 %iv, 1
353  br label %loop.header
354
355exit:
356  ret void
357}
358
359define void @loop_iv_cond_constant_bound() {
360; CHECK-LABEL: @loop_iv_cond_constant_bound(
361; CHECK-NEXT:  entry:
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:%.*]]
377; CHECK:       loop.latch:
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]]
383; CHECK:       exit:
384; CHECK-NEXT:    ret void
385;
386entry:
387  br label %loop.header
388
389loop.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)
397
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)
402
403  %cmp = icmp ult i32 %iv, 2
404  br i1 %cmp, label %loop.latch, label %exit
405
406loop.latch:
407  %t.4 = icmp ule  i32 %iv, 2
408  call void @use(i1 %t.4)
409
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)
414
415  %iv.next = add nuw nsw i32 %iv, 1
416  br label %loop.header
417
418exit:
419  ret void
420}
421