1; RUN: opt < %s -disable-output "-passes=print<scalar-evolution>" -scalar-evolution-max-iterations=0  -scalar-evolution-classify-expressions=0  2>&1 | FileCheck %s
2
3define void @slt(i16 %a, i16 %b, i1 %c) {
4; CHECK-LABEL: 'slt'
5; CHECK-NEXT:  Determining loop execution counts for: @slt
6; CHECK-NEXT:  Loop %loop: backedge-taken count is (19 + (-1 * %count)<nsw>)<nsw>
7; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i16 18
8; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (19 + (-1 * %count)<nsw>)<nsw>
9; CHECK-NEXT:  Loop %loop: Trip multiple is 1
10entry:
11  br i1 %c, label %b1, label %b2
12
13b1:
14  %cmp1 = icmp slt i16 %a, 1
15  br i1 %cmp1, label %exit, label %preheader
16
17b2:
18  %cmp2 = icmp slt i16 %b, 4
19  br i1 %cmp2, label %exit, label %preheader
20
21preheader:
22  %count = phi i16 [ %a, %b1 ], [ %b, %b2 ]
23  %cmp3 = icmp sle i16 %count, 19
24  br i1 %cmp3, label %loop, label %exit
25
26loop:
27  %iv = phi i16 [ %iv.next, %loop ], [ %count, %preheader ]
28  %iv.next = add i16 %iv, 1
29  %exitcond = icmp eq i16 %iv.next, 20
30  br i1 %exitcond, label %exit, label %loop
31
32exit:
33  ret void
34}
35
36define void @ult(i16 %a, i16 %b, i1 %c) {
37; CHECK-LABEL: 'ult'
38; CHECK-NEXT:  Determining loop execution counts for: @ult
39; CHECK-NEXT:  Loop %loop: backedge-taken count is (21 + (-1 * %count))
40; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i16 19
41; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (21 + (-1 * %count))
42; CHECK-NEXT:  Loop %loop: Trip multiple is 1
43entry:
44  br i1 %c, label %b1, label %b2
45
46b1:
47  %cmp1 = icmp ult i16 %a, 2
48  br i1 %cmp1, label %exit, label %preheader
49
50b2:
51  %cmp2 = icmp ult i16 %b, 5
52  br i1 %cmp2, label %exit, label %preheader
53
54preheader:
55  %count = phi i16 [ %a, %b1 ], [ %b, %b2 ]
56  %cmp3 = icmp ule i16 %count, 20
57  br i1 %cmp3, label %loop, label %exit
58
59loop:
60  %iv = phi i16 [ %iv.next, %loop ], [ %count, %preheader ]
61  %iv.next = add i16 %iv, 1
62  %exitcond = icmp eq i16 %iv.next, 22
63  br i1 %exitcond, label %exit, label %loop
64
65exit:
66  ret void
67}
68
69define void @sgt(i16 %a, i16 %b, i1 %c) {
70; CHECK-LABEL: 'sgt'
71; CHECK-NEXT:  Determining loop execution counts for: @sgt
72; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
73; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i16 9
74; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %count)
75; CHECK-NEXT:  Loop %loop: Trip multiple is 1
76entry:
77  br i1 %c, label %b1, label %b2
78
79b1:
80  %cmp1 = icmp sgt i16 %a, 10
81  br i1 %cmp1, label %exit, label %preheader
82
83b2:
84  %cmp2 = icmp sgt i16 %b, 8
85  br i1 %cmp2, label %exit, label %preheader
86
87preheader:
88  %count = phi i16 [ %a, %b1 ], [ %b, %b2 ]
89  %cmp3 = icmp sge i16 %count, 1
90  br i1 %cmp3, label %loop, label %exit
91
92loop:
93  %iv = phi i16 [ %iv.next, %loop ], [ %count, %preheader ]
94  %iv.next = add i16 %iv, -1
95  %exitcond = icmp eq i16 %iv.next, 0
96  br i1 %exitcond, label %exit, label %loop
97
98exit:
99  ret void
100}
101
102define void @ugt(i16 %a, i16 %b, i1 %c) {
103; CHECK-LABEL: 'ugt'
104; CHECK-NEXT:  Determining loop execution counts for: @ugt
105; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)<nsw>
106; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i16 10
107; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %count)<nsw>
108; CHECK-NEXT:  Loop %loop: Trip multiple is 1
109entry:
110  br i1 %c, label %b1, label %b2
111
112b1:
113  %cmp1 = icmp ugt i16 %a, 11
114  br i1 %cmp1, label %exit, label %preheader
115
116b2:
117  %cmp2 = icmp ugt i16 %b, 7
118  br i1 %cmp2, label %exit, label %preheader
119
120preheader:
121  %count = phi i16 [ %a, %b1 ], [ %b, %b2 ]
122  %cmp3 = icmp ne i16 %count, 0
123  br i1 %cmp3, label %loop, label %exit
124
125loop:
126  %iv = phi i16 [ %iv.next, %loop ], [ %count, %preheader ]
127  %iv.next = add i16 %iv, -1
128  %exitcond = icmp eq i16 %iv.next, 0
129  br i1 %exitcond, label %exit, label %loop
130
131exit:
132  ret void
133}
134
135define void @three_incoming(i16 %a, i16 %b, i1 %c, i1 %d) {
136; CHECK-LABEL: 'three_incoming'
137; CHECK-NEXT:  Determining loop execution counts for: @three_incoming
138; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)<nsw>
139; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i16 11
140; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %count)<nsw>
141; CHECK-NEXT:  Loop %loop: Trip multiple is 1
142entry:
143  br i1 %c, label %b1, label %entry2
144
145entry2:
146  br i1 %d, label %b2, label %b3
147
148b1:
149  %cmp1 = icmp ugt i16 %a, 10
150  br i1 %cmp1, label %exit, label %preheader
151
152b2:
153  %cmp2 = icmp ugt i16 %b, 8
154  br i1 %cmp2, label %exit, label %preheader
155
156b3:
157  %cmp3 = icmp ugt i16 %b, 12
158  br i1 %cmp3, label %exit, label %preheader
159
160preheader:
161  %count = phi i16 [ %a, %b1 ], [ %b, %b2 ], [ %b, %b3 ]
162  %cmp4 = icmp ne i16 %count, 0
163  br i1 %cmp4, label %loop, label %exit
164
165loop:
166  %iv = phi i16 [ %iv.next, %loop ], [ %count, %preheader ]
167  %iv.next = add i16 %iv, -1
168  %exitcond = icmp eq i16 %iv.next, 0
169  br i1 %exitcond, label %exit, label %loop
170
171exit:
172  ret void
173}
174
175define void @mixed(i16 %a, i16 %b, i1 %c) {
176; CHECK-LABEL: 'mixed'
177; CHECK-NEXT:  Determining loop execution counts for: @mixed
178; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
179; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i16 -2
180; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %count)
181; CHECK-NEXT:  Loop %loop: Trip multiple is 1
182entry:
183  br i1 %c, label %b1, label %b2
184
185b1:
186  %cmp1 = icmp ugt i16 %a, 10
187  br i1 %cmp1, label %exit, label %preheader
188
189b2:
190  %cmp2 = icmp sgt i16 %b, 8
191  br i1 %cmp2, label %exit, label %preheader
192
193preheader:
194  %count = phi i16 [ %a, %b1 ], [ %b, %b2 ]
195  %cmp3 = icmp ne i16 %count, 0
196  br i1 %cmp3, label %loop, label %exit
197
198loop:
199  %iv = phi i16 [ %iv.next, %loop ], [ %count, %preheader ]
200  %iv.next = add i16 %iv, -1
201  %exitcond = icmp eq i16 %iv.next, 0
202  br i1 %exitcond, label %exit, label %loop
203
204exit:
205  ret void
206}
207
208define void @one_constant(i16 %a, i16 %b, i1 %c, i16 %d) {
209; CHECK-LABEL: 'one_constant'
210; CHECK-NEXT:  Determining loop execution counts for: @one_constant
211; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
212; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i16 -2
213; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %count)
214; CHECK-NEXT:  Loop %loop: Trip multiple is 1
215entry:
216  br i1 %c, label %b1, label %b2
217
218b1:
219  %cmp1 = icmp ugt i16 %a, 10
220  br i1 %cmp1, label %exit, label %preheader
221
222b2:
223  %cmp2 = icmp ugt i16 %b, %d
224  br i1 %cmp2, label %exit, label %preheader
225
226preheader:
227  %count = phi i16 [ %a, %b1 ], [ %b, %b2 ]
228  %cmp3 = icmp ne i16 %count, 0
229  br i1 %cmp3, label %loop, label %exit
230
231loop:
232  %iv = phi i16 [ %iv.next, %loop ], [ %count, %preheader ]
233  %iv.next = add i16 %iv, -1
234  %exitcond = icmp eq i16 %iv.next, 0
235  br i1 %exitcond, label %exit, label %loop
236
237exit:
238  ret void
239}
240
241define void @epilogue(i64 %count) {
242; CHECK-LABEL: 'epilogue'
243; CHECK-NEXT:  Determining loop execution counts for: @epilogue
244; CHECK-NEXT:  Loop %epilogue: backedge-taken count is (-1 + %count.epilogue)
245; CHECK-NEXT:  Loop %epilogue: constant max backedge-taken count is i64 6
246; CHECK-NEXT:  Loop %epilogue: symbolic max backedge-taken count is (-1 + %count.epilogue)
247; CHECK-NEXT:  Loop %epilogue: Trip multiple is 1
248; CHECK-NEXT:  Loop %while.body: backedge-taken count is ((-8 + %count) /u 8)
249; CHECK-NEXT:  Loop %while.body: constant max backedge-taken count is i64 2305843009213693951
250; CHECK-NEXT:  Loop %while.body: symbolic max backedge-taken count is ((-8 + %count) /u 8)
251; CHECK-NEXT:  Loop %while.body: Trip multiple is 1
252entry:
253  %cmp = icmp ugt i64 %count, 7
254  br i1 %cmp, label %while.body, label %epilogue.preheader
255
256while.body:
257  %iv = phi i64 [ %sub, %while.body ], [ %count, %entry ]
258  %sub = add i64 %iv, -8
259  %exitcond.not = icmp ugt i64 %sub, 7
260  br i1 %exitcond.not, label %while.body, label %while.loopexit
261
262while.loopexit:
263  %sub.exit = phi i64 [ %sub, %while.body ]
264  br label %epilogue.preheader
265
266epilogue.preheader:
267  %count.epilogue = phi i64 [ %count, %entry ], [ %sub.exit, %while.loopexit ]
268  %epilogue.cmp = icmp eq i64 %count.epilogue, 0
269  br i1 %epilogue.cmp, label %exit, label %epilogue
270
271epilogue:
272  %iv.epilogue = phi i64 [ %dec, %epilogue ], [ %count.epilogue, %epilogue.preheader ]
273  %dec = add i64 %iv.epilogue, -1
274  %exitcond.epilogue = icmp eq i64 %dec, 0
275  br i1 %exitcond.epilogue, label %exit, label %epilogue
276
277exit:
278  ret void
279}
280
281declare void @llvm.assume(i1)
282
283; Checks that the presence of assumptions does not interfere with
284; exiting loop guard collection via following loop predecessors.
285define void @pr120442(i1 %c.1, i1 %c.2) {
286; CHECK-LABEL: 'pr120442'
287; CHECK-NEXT:  Determining loop execution counts for: @pr120442
288; CHECK-NEXT:  Loop %inner.header: backedge-taken count is i32 0
289; CHECK-NEXT:  Loop %inner.header: constant max backedge-taken count is i32 0
290; CHECK-NEXT:  Loop %inner.header: symbolic max backedge-taken count is i32 0
291; CHECK-NEXT:  Loop %inner.header: Trip multiple is 1
292entry:
293  call void @llvm.assume(i1 %c.1)
294  call void @llvm.assume(i1 %c.2)
295  br label %outer.header
296
297outer.header:
298  %phi7 = phi i32 [ 0, %bb ], [ 0, %entry ]
299  br label %inner.header
300
301bb:
302  br i1 false, label %outer.header, label %bb
303
304inner.header:
305  %phi = phi i32 [ %add, %inner.header ], [ 0, %outer.header ]
306  %add = add i32 %phi, 1
307  %icmp = icmp ugt i32 %add, 0
308  br i1 %icmp, label %exit, label %inner.header
309
310exit:
311  ret void
312}
313
314; Checks correct traversal for loops without a unique predecessor
315; outside the loop.
316define void @pr120615() {
317; CHECK-LABEL: pr120615
318; CHECK-NEXT:  Determining loop execution counts for: @pr120615
319; CHECK-NEXT:  Loop %header: backedge-taken count is i32 0
320; CHECK-NEXT:  Loop %header: constant max backedge-taken count is i32 0
321; CHECK-NEXT:  Loop %header: symbolic max backedge-taken count is i32 0
322; CHECK-NEXT:  Loop %header: Trip multiple is 1
323entry:
324  br label %header
325
326bb:
327  br label %header
328
329header:
330  %0 = phi i32 [ %1, %header ], [ 0, %bb ], [ 0, %entry ]
331  %1 = add i32 %0, 1
332  %icmp = icmp slt i32 %0, 0
333  br i1 %icmp, label %header, label %exit
334
335exit:
336  ret void
337
338}
339
340; Checks correct traversal for loops without a unique predecessor
341; outside the loop.
342define void @pr122913() {
343; CHECK-LABEL: pr122913
344; CHECK-NEXT:  Determining loop execution counts for: @pr122913
345; CHECK-NEXT:  Loop %header: backedge-taken count is i1 false
346; CHECK-NEXT:  Loop %header: constant max backedge-taken count is i1 false
347; CHECK-NEXT:  Loop %header: symbolic max backedge-taken count is i1 false
348; CHECK-NEXT:  Loop %header: Trip multiple is 1
349entry:
350  br i1 1, label %bb, label %header
351
352bb:
353  br i1 1, label %exit, label %header
354
355header:
356  %0 = phi i32 [ %1, %body ], [ 0, %bb ], [ 0, %entry ]
357  br label %body
358
359body:
360  %1 = add i32 %0, 1
361  %2 = icmp ult i32 %1, 0
362  br i1 %2, label %header, label %exit
363
364exit:
365  ret void
366}
367