1 ; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
2 ; RUN: opt -passes='print<scalar-evolution>' -disable-output %s 2>&1 | FileCheck %s
4 ; Test case for PR40961. The loop guard limit the constant max backedge-taken count.
6 define void @test_guard_less_than_16(ptr nocapture %a, i64 %i) {
7 ; CHECK-LABEL: 'test_guard_less_than_16'
8 ; CHECK-NEXT: Classifying expressions for: @test_guard_less_than_16
9 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
10 ; CHECK-NEXT: --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 15 LoopDispositions: { %loop: Computable }
11 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
12 ; CHECK-NEXT: --> {((4 * %i) + %a),+,4}<%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
13 ; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
14 ; CHECK-NEXT: --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 16 LoopDispositions: { %loop: Computable }
15 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_less_than_16
16 ; CHECK-NEXT: Loop %loop: backedge-taken count is (15 + (-1 * %i))
17 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 15
18 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (15 + (-1 * %i))
19 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
22 %cmp3 = icmp ult i64 %i, 16
23 br i1 %cmp3, label %loop, label %exit
26 %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
27 %idx = getelementptr inbounds i32, ptr %a, i64 %iv
28 store i32 1, ptr %idx, align 4
29 %iv.next = add nuw nsw i64 %iv, 1
30 %exitcond = icmp eq i64 %iv.next, 16
31 br i1 %exitcond, label %exit, label %loop
37 define void @test_guard_less_than_16_operands_swapped(ptr nocapture %a, i64 %i) {
38 ; CHECK-LABEL: 'test_guard_less_than_16_operands_swapped'
39 ; CHECK-NEXT: Classifying expressions for: @test_guard_less_than_16_operands_swapped
40 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
41 ; CHECK-NEXT: --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 15 LoopDispositions: { %loop: Computable }
42 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
43 ; CHECK-NEXT: --> {((4 * %i) + %a),+,4}<%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
44 ; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
45 ; CHECK-NEXT: --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 16 LoopDispositions: { %loop: Computable }
46 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_less_than_16_operands_swapped
47 ; CHECK-NEXT: Loop %loop: backedge-taken count is (15 + (-1 * %i))
48 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 15
49 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (15 + (-1 * %i))
50 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
53 %cmp3 = icmp ugt i64 16, %i
54 br i1 %cmp3, label %loop, label %exit
57 %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
58 %idx = getelementptr inbounds i32, ptr %a, i64 %iv
59 store i32 1, ptr %idx, align 4
60 %iv.next = add nuw nsw i64 %iv, 1
61 %exitcond = icmp eq i64 %iv.next, 16
62 br i1 %exitcond, label %exit, label %loop
68 define void @test_guard_less_than_16_branches_flipped(ptr nocapture %a, i64 %i) {
69 ; CHECK-LABEL: 'test_guard_less_than_16_branches_flipped'
70 ; CHECK-NEXT: Classifying expressions for: @test_guard_less_than_16_branches_flipped
71 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
72 ; CHECK-NEXT: --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 15 LoopDispositions: { %loop: Computable }
73 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
74 ; CHECK-NEXT: --> {((4 * %i) + %a),+,4}<%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
75 ; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
76 ; CHECK-NEXT: --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 16 LoopDispositions: { %loop: Computable }
77 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_less_than_16_branches_flipped
78 ; CHECK-NEXT: Loop %loop: backedge-taken count is (15 + (-1 * %i))
79 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1
80 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (15 + (-1 * %i))
81 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
84 %cmp3 = icmp ult i64 %i, 16
85 br i1 %cmp3, label %exit, label %loop
88 %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
89 %idx = getelementptr inbounds i32, ptr %a, i64 %iv
90 store i32 1, ptr %idx, align 4
91 %iv.next = add nuw nsw i64 %iv, 1
92 %exitcond = icmp eq i64 %iv.next, 16
93 br i1 %exitcond, label %exit, label %loop
99 define void @test_guard_uge_16_branches_flipped(ptr nocapture %a, i64 %i) {
100 ; CHECK-LABEL: 'test_guard_uge_16_branches_flipped'
101 ; CHECK-NEXT: Classifying expressions for: @test_guard_uge_16_branches_flipped
102 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
103 ; CHECK-NEXT: --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 15 LoopDispositions: { %loop: Computable }
104 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
105 ; CHECK-NEXT: --> {((4 * %i) + %a),+,4}<%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
106 ; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
107 ; CHECK-NEXT: --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 16 LoopDispositions: { %loop: Computable }
108 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_uge_16_branches_flipped
109 ; CHECK-NEXT: Loop %loop: backedge-taken count is (15 + (-1 * %i))
110 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 15
111 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (15 + (-1 * %i))
112 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
115 %cmp3 = icmp uge i64 %i, 16
116 br i1 %cmp3, label %exit, label %loop
119 %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
120 %idx = getelementptr inbounds i32, ptr %a, i64 %iv
121 store i32 1, ptr %idx, align 4
122 %iv.next = add nuw nsw i64 %iv, 1
123 %exitcond = icmp eq i64 %iv.next, 16
124 br i1 %exitcond, label %exit, label %loop
130 define void @test_guard_eq_12(ptr nocapture %a, i64 %N) {
131 ; CHECK-LABEL: 'test_guard_eq_12'
132 ; CHECK-NEXT: Classifying expressions for: @test_guard_eq_12
133 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
134 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: %N LoopDispositions: { %loop: Computable }
135 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
136 ; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %N) + %a) LoopDispositions: { %loop: Computable }
137 ; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
138 ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,14) S: [1,14) Exits: (1 + %N) LoopDispositions: { %loop: Computable }
139 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_eq_12
140 ; CHECK-NEXT: Loop %loop: backedge-taken count is %N
141 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 12
142 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %N
143 ; CHECK-NEXT: Loop %loop: Trip multiple is 13
146 %c.1 = icmp eq i64 %N, 12
147 br i1 %c.1, label %loop, label %exit
150 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
151 %idx = getelementptr inbounds i32, ptr %a, i64 %iv
152 store i32 1, ptr %idx, align 4
153 %iv.next = add nuw nsw i64 %iv, 1
154 %exitcond = icmp eq i64 %iv, %N
155 br i1 %exitcond, label %exit, label %loop
161 define void @test_guard_ule_12(ptr nocapture %a, i64 %N) {
162 ; CHECK-LABEL: 'test_guard_ule_12'
163 ; CHECK-NEXT: Classifying expressions for: @test_guard_ule_12
164 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
165 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: %N LoopDispositions: { %loop: Computable }
166 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
167 ; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %N) + %a) LoopDispositions: { %loop: Computable }
168 ; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
169 ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,14) S: [1,14) Exits: (1 + %N) LoopDispositions: { %loop: Computable }
170 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_ule_12
171 ; CHECK-NEXT: Loop %loop: backedge-taken count is %N
172 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 12
173 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %N
174 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
177 %c.1 = icmp ule i64 %N, 12
178 br i1 %c.1, label %loop, label %exit
181 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
182 %idx = getelementptr inbounds i32, ptr %a, i64 %iv
183 store i32 1, ptr %idx, align 4
184 %iv.next = add nuw nsw i64 %iv, 1
185 %exitcond = icmp eq i64 %iv, %N
186 br i1 %exitcond, label %exit, label %loop
192 define void @test_guard_ule_12_step2(ptr nocapture %a, i64 %N) {
193 ; CHECK-LABEL: 'test_guard_ule_12_step2'
194 ; CHECK-NEXT: Classifying expressions for: @test_guard_ule_12_step2
195 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
196 ; CHECK-NEXT: --> {0,+,2}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (2 * (%N /u 2))<nuw> LoopDispositions: { %loop: Computable }
197 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
198 ; CHECK-NEXT: --> {%a,+,8}<nuw><%loop> U: full-set S: full-set Exits: ((8 * (%N /u 2)) + %a) LoopDispositions: { %loop: Computable }
199 ; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 2
200 ; CHECK-NEXT: --> {2,+,2}<nuw><nsw><%loop> U: [2,15) S: [2,15) Exits: (2 + (2 * (%N /u 2))<nuw>) LoopDispositions: { %loop: Computable }
201 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_ule_12_step2
202 ; CHECK-NEXT: Loop %loop: backedge-taken count is (%N /u 2)
203 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 6
204 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%N /u 2)
205 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
208 %c.1 = icmp ule i64 %N, 12
209 br i1 %c.1, label %loop, label %exit
212 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
213 %idx = getelementptr inbounds i32, ptr %a, i64 %iv
214 store i32 1, ptr %idx, align 4
215 %iv.next = add nuw nsw i64 %iv, 2
216 %exitcond = icmp eq i64 %iv, %N
217 br i1 %exitcond, label %exit, label %loop
223 define void @test_multiple_const_guards_order1(ptr nocapture %a, i64 %i) {
224 ; CHECK-LABEL: 'test_multiple_const_guards_order1'
225 ; CHECK-NEXT: Classifying expressions for: @test_multiple_const_guards_order1
226 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
227 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,10) S: [0,10) Exits: %i LoopDispositions: { %loop: Computable }
228 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
229 ; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
230 ; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
231 ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,11) S: [1,11) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
232 ; CHECK-NEXT: Determining loop execution counts for: @test_multiple_const_guards_order1
233 ; CHECK-NEXT: Loop %loop: backedge-taken count is %i
234 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 9
235 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %i
236 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
239 %c.1 = icmp ult i64 %i, 16
240 br i1 %c.1, label %guardbb, label %exit
243 %c.2 = icmp ult i64 %i, 10
244 br i1 %c.2, label %loop, label %exit
247 %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
248 %idx = getelementptr inbounds i32, ptr %a, i64 %iv
249 store i32 1, ptr %idx, align 4
250 %iv.next = add nuw nsw i64 %iv, 1
251 %exitcond = icmp eq i64 %iv, %i
252 br i1 %exitcond, label %exit, label %loop
258 define void @test_multiple_const_guards_order2(ptr nocapture %a, i64 %i) {
259 ; CHECK-LABEL: 'test_multiple_const_guards_order2'
260 ; CHECK-NEXT: Classifying expressions for: @test_multiple_const_guards_order2
261 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
262 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,10) S: [0,10) Exits: %i LoopDispositions: { %loop: Computable }
263 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
264 ; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
265 ; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
266 ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,11) S: [1,11) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
267 ; CHECK-NEXT: Determining loop execution counts for: @test_multiple_const_guards_order2
268 ; CHECK-NEXT: Loop %loop: backedge-taken count is %i
269 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 9
270 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %i
271 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
274 %c.1 = icmp ult i64 %i, 10
275 br i1 %c.1, label %guardbb, label %exit
278 %c.2 = icmp ult i64 %i, 16
279 br i1 %c.2, label %loop, label %exit
282 %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
283 %idx = getelementptr inbounds i32, ptr %a, i64 %iv
284 store i32 1, ptr %idx, align 4
285 %iv.next = add nuw nsw i64 %iv, 1
286 %exitcond = icmp eq i64 %iv, %i
287 br i1 %exitcond, label %exit, label %loop
293 define void @test_multiple_var_guards_order1(ptr nocapture %a, i64 %i, i64 %N) {
294 ; CHECK-LABEL: 'test_multiple_var_guards_order1'
295 ; CHECK-NEXT: Classifying expressions for: @test_multiple_var_guards_order1
296 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
297 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,11) S: [0,11) Exits: %i LoopDispositions: { %loop: Computable }
298 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
299 ; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
300 ; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
301 ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,12) S: [1,12) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
302 ; CHECK-NEXT: Determining loop execution counts for: @test_multiple_var_guards_order1
303 ; CHECK-NEXT: Loop %loop: backedge-taken count is %i
304 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 10
305 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %i
306 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
309 %c.1 = icmp ult i64 %N, 12
310 br i1 %c.1, label %guardbb, label %exit
313 %c.2 = icmp ult i64 %i, %N
314 br i1 %c.2, label %loop, label %exit
317 %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
318 %idx = getelementptr inbounds i32, ptr %a, i64 %iv
319 store i32 1, ptr %idx, align 4
320 %iv.next = add nuw nsw i64 %iv, 1
321 %exitcond = icmp eq i64 %iv, %i
322 br i1 %exitcond, label %exit, label %loop
328 define void @test_multiple_var_guards_order2(ptr nocapture %a, i64 %i, i64 %N) {
329 ; CHECK-LABEL: 'test_multiple_var_guards_order2'
330 ; CHECK-NEXT: Classifying expressions for: @test_multiple_var_guards_order2
331 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
332 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,11) S: [0,11) Exits: %i LoopDispositions: { %loop: Computable }
333 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
334 ; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
335 ; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
336 ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,12) S: [1,12) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
337 ; CHECK-NEXT: Determining loop execution counts for: @test_multiple_var_guards_order2
338 ; CHECK-NEXT: Loop %loop: backedge-taken count is %i
339 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 10
340 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %i
341 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
344 %c.1 = icmp ult i64 %i, %N
345 br i1 %c.1, label %guardbb, label %exit
348 %c.2 = icmp ult i64 %N, 12
349 br i1 %c.2, label %loop, label %exit
352 %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
353 %idx = getelementptr inbounds i32, ptr %a, i64 %iv
354 store i32 1, ptr %idx, align 4
355 %iv.next = add nuw nsw i64 %iv, 1
356 %exitcond = icmp eq i64 %iv, %i
357 br i1 %exitcond, label %exit, label %loop
363 ; The guards here reference each other in a cycle.
364 define void @test_multiple_var_guards_cycle(ptr nocapture %a, i64 %i, i64 %N) {
365 ; CHECK-LABEL: 'test_multiple_var_guards_cycle'
366 ; CHECK-NEXT: Classifying expressions for: @test_multiple_var_guards_cycle
367 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
368 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-9223372036854775808) S: [0,-9223372036854775808) Exits: %N LoopDispositions: { %loop: Computable }
369 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
370 ; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %N) + %a) LoopDispositions: { %loop: Computable }
371 ; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
372 ; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,-1) S: [1,-1) Exits: (1 + %N) LoopDispositions: { %loop: Computable }
373 ; CHECK-NEXT: Determining loop execution counts for: @test_multiple_var_guards_cycle
374 ; CHECK-NEXT: Loop %loop: backedge-taken count is %N
375 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -3
376 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %N
377 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
380 %c.1 = icmp ult i64 %N, %i
381 br i1 %c.1, label %guardbb, label %exit
384 %c.2 = icmp ult i64 %i, %N
385 br i1 %c.2, label %loop, label %exit
388 %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
389 %idx = getelementptr inbounds i32, ptr %a, i64 %iv
390 store i32 1, ptr %idx, align 4
391 %iv.next = add nuw nsw i64 %iv, 1
392 %exitcond = icmp eq i64 %iv, %N
393 br i1 %exitcond, label %exit, label %loop
399 define void @test_guard_ult_ne(ptr nocapture readonly %data, i64 %count) {
400 ; CHECK-LABEL: 'test_guard_ult_ne'
401 ; CHECK-NEXT: Classifying expressions for: @test_guard_ult_ne
402 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
403 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
404 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
405 ; CHECK-NEXT: --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
406 ; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
407 ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
408 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_ult_ne
409 ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
410 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
411 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
412 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
415 %cmp.ult = icmp ult i64 %count, 5
416 br i1 %cmp.ult, label %guardbb, label %exit
419 %cmp.ne = icmp ne i64 %count, 0
420 br i1 %cmp.ne, label %loop, label %exit
423 %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
424 %idx = getelementptr inbounds i32, ptr %data, i64 %iv
425 store i32 1, ptr %idx, align 4
426 %iv.next = add nuw i64 %iv, 1
427 %exitcond.not = icmp eq i64 %iv.next, %count
428 br i1 %exitcond.not, label %exit, label %loop
434 define void @test_guard_ne_ult(ptr nocapture readonly %data, i64 %count) {
435 ; CHECK-LABEL: 'test_guard_ne_ult'
436 ; CHECK-NEXT: Classifying expressions for: @test_guard_ne_ult
437 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
438 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
439 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
440 ; CHECK-NEXT: --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
441 ; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
442 ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
443 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_ne_ult
444 ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
445 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
446 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
447 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
450 %cmp.ne = icmp ne i64 %count, 0
451 br i1 %cmp.ne, label %guardbb, label %exit
454 %cmp.ult = icmp ult i64 %count, 5
455 br i1 %cmp.ult, label %loop, label %exit
458 %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
459 %idx = getelementptr inbounds i32, ptr %data, i64 %iv
460 store i32 1, ptr %idx, align 4
461 %iv.next = add nuw i64 %iv, 1
462 %exitcond.not = icmp eq i64 %iv.next, %count
463 br i1 %exitcond.not, label %exit, label %loop
469 define void @test_guard_if_and_enter(ptr nocapture readonly %data, i64 %count) {
470 ; CHECK-LABEL: 'test_guard_if_and_enter'
471 ; CHECK-NEXT: Classifying expressions for: @test_guard_if_and_enter
472 ; CHECK-NEXT: %cmp.and = and i1 %cmp.ult, %cmp.ne
473 ; CHECK-NEXT: --> (%cmp.ult umin %cmp.ne) U: full-set S: full-set
474 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
475 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
476 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
477 ; CHECK-NEXT: --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
478 ; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
479 ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
480 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_if_and_enter
481 ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
482 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
483 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
484 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
487 %cmp.ult = icmp ult i64 %count, 5
488 %cmp.ne = icmp ne i64 %count, 0
489 %cmp.and = and i1 %cmp.ult, %cmp.ne
490 br i1 %cmp.and, label %loop, label %exit
493 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
494 %idx = getelementptr inbounds i32, ptr %data, i64 %iv
495 store i32 1, ptr %idx, align 4
496 %iv.next = add nuw i64 %iv, 1
497 %exitcond.not = icmp eq i64 %iv.next, %count
498 br i1 %exitcond.not, label %exit, label %loop
504 define void @test_guard_if_and_skip(ptr nocapture readonly %data, i64 %count) {
505 ; CHECK-LABEL: 'test_guard_if_and_skip'
506 ; CHECK-NEXT: Classifying expressions for: @test_guard_if_and_skip
507 ; CHECK-NEXT: %cmp.and = and i1 %cmp.ult, %cmp.ne
508 ; CHECK-NEXT: --> (%cmp.ult umin %cmp.ne) U: full-set S: full-set
509 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
510 ; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
511 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
512 ; CHECK-NEXT: --> {%data,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
513 ; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
514 ; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %count LoopDispositions: { %loop: Computable }
515 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_if_and_skip
516 ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
517 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1
518 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
519 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
522 %cmp.ult = icmp ult i64 %count, 5
523 %cmp.ne = icmp ne i64 %count, 0
524 %cmp.and = and i1 %cmp.ult, %cmp.ne
525 br i1 %cmp.and, label %exit, label %loop
528 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
529 %idx = getelementptr inbounds i32, ptr %data, i64 %iv
530 store i32 1, ptr %idx, align 4
531 %iv.next = add nuw i64 %iv, 1
532 %exitcond.not = icmp eq i64 %iv.next, %count
533 br i1 %exitcond.not, label %exit, label %loop
539 define void @test_guard_if_and_and(ptr nocapture readonly %data, i64 %count, i1 %c) {
540 ; CHECK-LABEL: 'test_guard_if_and_and'
541 ; CHECK-NEXT: Classifying expressions for: @test_guard_if_and_and
542 ; CHECK-NEXT: %cmp.and1 = and i1 %c, %cmp.ne
543 ; CHECK-NEXT: --> (%c umin %cmp.ne) U: full-set S: full-set
544 ; CHECK-NEXT: %cmp.and = and i1 %cmp.ult, %cmp.and1
545 ; CHECK-NEXT: --> (%c umin %cmp.ult umin %cmp.ne) U: full-set S: full-set
546 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
547 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
548 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
549 ; CHECK-NEXT: --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
550 ; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
551 ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
552 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_if_and_and
553 ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
554 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
555 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
556 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
559 %cmp.ult = icmp ult i64 %count, 5
560 %cmp.ne = icmp ne i64 %count, 0
561 %cmp.and1 = and i1 %c, %cmp.ne
562 %cmp.and = and i1 %cmp.ult, %cmp.and1
563 br i1 %cmp.and, label %loop, label %exit
566 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
567 %idx = getelementptr inbounds i32, ptr %data, i64 %iv
568 store i32 1, ptr %idx, align 4
569 %iv.next = add nuw i64 %iv, 1
570 %exitcond.not = icmp eq i64 %iv.next, %count
571 br i1 %exitcond.not, label %exit, label %loop
577 define void @test_guard_if_and_or(ptr nocapture readonly %data, i64 %count, i1 %c) {
578 ; CHECK-LABEL: 'test_guard_if_and_or'
579 ; CHECK-NEXT: Classifying expressions for: @test_guard_if_and_or
580 ; CHECK-NEXT: %cmp.or = or i1 %c, %cmp.ne
581 ; CHECK-NEXT: --> (%c umax %cmp.ne) U: full-set S: full-set
582 ; CHECK-NEXT: %cmp.and = and i1 %cmp.ult, %cmp.or
583 ; CHECK-NEXT: --> ((%c umax %cmp.ne) umin %cmp.ult) U: full-set S: full-set
584 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
585 ; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
586 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
587 ; CHECK-NEXT: --> {%data,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
588 ; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
589 ; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %count LoopDispositions: { %loop: Computable }
590 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_if_and_or
591 ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
592 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1
593 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
594 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
597 %cmp.ult = icmp ult i64 %count, 5
598 %cmp.ne = icmp ne i64 %count, 0
599 %cmp.or = or i1 %c, %cmp.ne
600 %cmp.and = and i1 %cmp.ult, %cmp.or
601 br i1 %cmp.and, label %loop, label %exit
604 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
605 %idx = getelementptr inbounds i32, ptr %data, i64 %iv
606 store i32 1, ptr %idx, align 4
607 %iv.next = add nuw i64 %iv, 1
608 %exitcond.not = icmp eq i64 %iv.next, %count
609 br i1 %exitcond.not, label %exit, label %loop
615 define void @test_guard_if_or_skip(ptr nocapture readonly %data, i64 %count) {
616 ; CHECK-LABEL: 'test_guard_if_or_skip'
617 ; CHECK-NEXT: Classifying expressions for: @test_guard_if_or_skip
618 ; CHECK-NEXT: %cmp.or = or i1 %cmp.uge, %cmp.eq
619 ; CHECK-NEXT: --> (%cmp.uge umax %cmp.eq) U: full-set S: full-set
620 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
621 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
622 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
623 ; CHECK-NEXT: --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
624 ; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
625 ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
626 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_if_or_skip
627 ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
628 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
629 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
630 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
633 %cmp.uge = icmp uge i64 %count, 5
634 %cmp.eq = icmp eq i64 %count, 0
635 %cmp.or = or i1 %cmp.uge, %cmp.eq
636 br i1 %cmp.or, label %exit, label %loop
639 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
640 %idx = getelementptr inbounds i32, ptr %data, i64 %iv
641 store i32 1, ptr %idx, align 4
642 %iv.next = add nuw i64 %iv, 1
643 %exitcond.not = icmp eq i64 %iv.next, %count
644 br i1 %exitcond.not, label %exit, label %loop
650 define void @test_guard_if_or_enter(ptr nocapture readonly %data, i64 %count) {
651 ; CHECK-LABEL: 'test_guard_if_or_enter'
652 ; CHECK-NEXT: Classifying expressions for: @test_guard_if_or_enter
653 ; CHECK-NEXT: %cmp.or = or i1 %cmp.uge, %cmp.eq
654 ; CHECK-NEXT: --> (%cmp.uge umax %cmp.eq) U: full-set S: full-set
655 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
656 ; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
657 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
658 ; CHECK-NEXT: --> {%data,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
659 ; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
660 ; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %count LoopDispositions: { %loop: Computable }
661 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_if_or_enter
662 ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
663 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1
664 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
665 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
668 %cmp.uge = icmp uge i64 %count, 5
669 %cmp.eq = icmp eq i64 %count, 0
670 %cmp.or = or i1 %cmp.uge, %cmp.eq
671 br i1 %cmp.or, label %loop, label %exit
674 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
675 %idx = getelementptr inbounds i32, ptr %data, i64 %iv
676 store i32 1, ptr %idx, align 4
677 %iv.next = add nuw i64 %iv, 1
678 %exitcond.not = icmp eq i64 %iv.next, %count
679 br i1 %exitcond.not, label %exit, label %loop
685 define void @test_guard_if_or_or(ptr nocapture readonly %data, i64 %count, i1 %c) {
686 ; CHECK-LABEL: 'test_guard_if_or_or'
687 ; CHECK-NEXT: Classifying expressions for: @test_guard_if_or_or
688 ; CHECK-NEXT: %cmp.or1 = or i1 %c, %cmp.eq
689 ; CHECK-NEXT: --> (%c umax %cmp.eq) U: full-set S: full-set
690 ; CHECK-NEXT: %cmp.or = or i1 %cmp.uge, %cmp.or1
691 ; CHECK-NEXT: --> (%c umax %cmp.uge umax %cmp.eq) U: full-set S: full-set
692 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
693 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
694 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
695 ; CHECK-NEXT: --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
696 ; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
697 ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
698 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_if_or_or
699 ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
700 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
701 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
702 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
705 %cmp.uge = icmp uge i64 %count, 5
706 %cmp.eq = icmp eq i64 %count, 0
707 %cmp.or1 = or i1 %c, %cmp.eq
708 %cmp.or = or i1 %cmp.uge, %cmp.or1
709 br i1 %cmp.or, label %exit, label %loop
712 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
713 %idx = getelementptr inbounds i32, ptr %data, i64 %iv
714 store i32 1, ptr %idx, align 4
715 %iv.next = add nuw i64 %iv, 1
716 %exitcond.not = icmp eq i64 %iv.next, %count
717 br i1 %exitcond.not, label %exit, label %loop
723 define void @test_guard_if_or_and(ptr nocapture readonly %data, i64 %count, i1 %c) {
724 ; CHECK-LABEL: 'test_guard_if_or_and'
725 ; CHECK-NEXT: Classifying expressions for: @test_guard_if_or_and
726 ; CHECK-NEXT: %cmp.and = and i1 %c, %cmp.eq
727 ; CHECK-NEXT: --> (%c umin %cmp.eq) U: full-set S: full-set
728 ; CHECK-NEXT: %cmp.or = or i1 %cmp.uge, %cmp.and
729 ; CHECK-NEXT: --> ((%c umin %cmp.eq) umax %cmp.uge) U: full-set S: full-set
730 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
731 ; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
732 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
733 ; CHECK-NEXT: --> {%data,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
734 ; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
735 ; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %count LoopDispositions: { %loop: Computable }
736 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_if_or_and
737 ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
738 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1
739 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
740 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
743 %cmp.uge = icmp uge i64 %count, 5
744 %cmp.eq = icmp eq i64 %count, 0
745 %cmp.and = and i1 %c, %cmp.eq
746 %cmp.or = or i1 %cmp.uge, %cmp.and
747 br i1 %cmp.or, label %exit, label %loop
750 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
751 %idx = getelementptr inbounds i32, ptr %data, i64 %iv
752 store i32 1, ptr %idx, align 4
753 %iv.next = add nuw i64 %iv, 1
754 %exitcond.not = icmp eq i64 %iv.next, %count
755 br i1 %exitcond.not, label %exit, label %loop
761 ; Test case for PR47247. Both the guard condition and the assume limit the
762 ; constant max backedge-taken count.
764 define void @test_guard_and_assume(ptr nocapture readonly %data, i64 %count) {
765 ; CHECK-LABEL: 'test_guard_and_assume'
766 ; CHECK-NEXT: Classifying expressions for: @test_guard_and_assume
767 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
768 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
769 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
770 ; CHECK-NEXT: --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
771 ; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
772 ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
773 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_and_assume
774 ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
775 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
776 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
777 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
780 %cmp = icmp ult i64 %count, 5
781 tail call void @llvm.assume(i1 %cmp)
782 %cmp18.not = icmp eq i64 %count, 0
783 br i1 %cmp18.not, label %exit, label %loop
786 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
787 %idx = getelementptr inbounds i32, ptr %data, i64 %iv
788 store i32 1, ptr %idx, align 4
789 %iv.next = add nuw i64 %iv, 1
790 %exitcond.not = icmp eq i64 %iv.next, %count
791 br i1 %exitcond.not, label %exit, label %loop
797 define void @test_guard_assume_and(ptr nocapture readonly %data, i64 %count) {
798 ; CHECK-LABEL: 'test_guard_assume_and'
799 ; CHECK-NEXT: Classifying expressions for: @test_guard_assume_and
800 ; CHECK-NEXT: %cmp.and = and i1 %cmp.ult, %cmp.ne
801 ; CHECK-NEXT: --> (%cmp.ult umin %cmp.ne) U: full-set S: full-set
802 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
803 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
804 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
805 ; CHECK-NEXT: --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
806 ; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
807 ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
808 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_assume_and
809 ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
810 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
811 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
812 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
815 %cmp.ult = icmp ult i64 %count, 5
816 %cmp.ne = icmp ne i64 %count, 0
817 %cmp.and = and i1 %cmp.ult, %cmp.ne
818 call void @llvm.assume(i1 %cmp.and)
822 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
823 %idx = getelementptr inbounds i32, ptr %data, i64 %iv
824 store i32 1, ptr %idx, align 4
825 %iv.next = add nuw i64 %iv, 1
826 %exitcond.not = icmp eq i64 %iv.next, %count
827 br i1 %exitcond.not, label %exit, label %loop
833 ; Function Attrs: nounwind willreturn
834 declare void @llvm.assume(i1 noundef)
836 define void @guard_pessimizes_analysis_step1(i1 %c, i32 %N) {
837 ; CHECK-LABEL: 'guard_pessimizes_analysis_step1'
838 ; CHECK-NEXT: Classifying expressions for: @guard_pessimizes_analysis_step1
839 ; CHECK-NEXT: %init = phi i32 [ 2, %entry ], [ 3, %bb1 ]
840 ; CHECK-NEXT: --> %init U: [2,4) S: [2,4)
841 ; CHECK-NEXT: %iv = phi i32 [ %iv.next, %loop ], [ %init, %loop.ph ]
842 ; CHECK-NEXT: --> {%init,+,1}<nuw><nsw><%loop> U: [2,11) S: [2,11) Exits: 9 LoopDispositions: { %loop: Computable }
843 ; CHECK-NEXT: %iv.next = add i32 %iv, 1
844 ; CHECK-NEXT: --> {(1 + %init)<nuw><nsw>,+,1}<nuw><nsw><%loop> U: [3,12) S: [3,12) Exits: 10 LoopDispositions: { %loop: Computable }
845 ; CHECK-NEXT: Determining loop execution counts for: @guard_pessimizes_analysis_step1
846 ; CHECK-NEXT: Loop %loop: backedge-taken count is (9 + (-1 * %init)<nsw>)<nsw>
847 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 7
848 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (9 + (-1 * %init)<nsw>)<nsw>
849 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
852 br i1 %c, label %bb1, label %guard
858 %init = phi i32 [ 2, %entry ], [ 3, %bb1 ]
859 %c.1 = icmp ult i32 %init, %N
860 br i1 %c.1, label %loop.ph, label %exit
866 %iv = phi i32 [ %iv.next, %loop ], [ %init, %loop.ph ]
867 %iv.next = add i32 %iv, 1
868 %exitcond = icmp eq i32 %iv.next, 10
869 br i1 %exitcond, label %exit, label %loop
875 define void @guard_pessimizes_analysis_step2(i1 %c, i32 %N) {
876 ; CHECK-LABEL: 'guard_pessimizes_analysis_step2'
877 ; CHECK-NEXT: Classifying expressions for: @guard_pessimizes_analysis_step2
878 ; CHECK-NEXT: %init = phi i32 [ 2, %entry ], [ 3, %bb1 ]
879 ; CHECK-NEXT: --> %init U: [2,4) S: [2,4)
880 ; CHECK-NEXT: %iv = phi i32 [ %iv.next, %loop ], [ %init, %loop.ph ]
881 ; CHECK-NEXT: --> {%init,+,2}<nuw><nsw><%loop> U: [2,10) S: [2,10) Exits: ((2 * ((8 + (-1 * %init)<nsw>)<nsw> /u 2))<nuw><nsw> + %init) LoopDispositions: { %loop: Computable }
882 ; CHECK-NEXT: %iv.next = add nuw nsw i32 %iv, 2
883 ; CHECK-NEXT: --> {(2 + %init)<nuw><nsw>,+,2}<nuw><nsw><%loop> U: [4,12) S: [4,12) Exits: (2 + (2 * ((8 + (-1 * %init)<nsw>)<nsw> /u 2))<nuw><nsw> + %init) LoopDispositions: { %loop: Computable }
884 ; CHECK-NEXT: Determining loop execution counts for: @guard_pessimizes_analysis_step2
885 ; CHECK-NEXT: Loop %loop: backedge-taken count is ((8 + (-1 * %init)<nsw>)<nsw> /u 2)
886 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 3
887 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((8 + (-1 * %init)<nsw>)<nsw> /u 2)
888 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
891 br i1 %c, label %bb1, label %guard
897 %init = phi i32 [ 2, %entry ], [ 3, %bb1 ]
898 %c.1 = icmp ult i32 %init, %N
899 br i1 %c.1, label %loop.ph, label %exit
905 %iv = phi i32 [ %iv.next, %loop ], [ %init, %loop.ph ]
906 %iv.next = add nuw nsw i32 %iv, 2
907 %exitcond = icmp eq i32 %iv.next, 10
908 br i1 %exitcond, label %exit, label %loop
913 define void @crash(ptr %ptr) {
914 ; CHECK-LABEL: 'crash'
915 ; CHECK-NEXT: Classifying expressions for: @crash
916 ; CHECK-NEXT: %text.addr.5 = phi ptr [ %incdec.ptr112, %while.cond111 ], [ null, %while.body ]
917 ; CHECK-NEXT: --> {null,+,-1}<nw><%while.cond111> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %while.cond111: Computable, %while.body: Variant }
918 ; CHECK-NEXT: %incdec.ptr112 = getelementptr inbounds i8, ptr %text.addr.5, i64 -1
919 ; CHECK-NEXT: --> {(-1 + null)<nuw><nsw>,+,-1}<nw><%while.cond111> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %while.cond111: Computable, %while.body: Variant }
920 ; CHECK-NEXT: %lastout.2271 = phi ptr [ %incdec.ptr126, %while.body125 ], [ %ptr, %while.end117 ]
921 ; CHECK-NEXT: --> {%ptr,+,1}<nuw><%while.body125> U: full-set S: full-set Exits: {(-2 + (-1 * (ptrtoint ptr %ptr to i64)) + %ptr),+,-1}<nw><%while.cond111> LoopDispositions: { %while.body125: Computable }
922 ; CHECK-NEXT: %incdec.ptr126 = getelementptr inbounds i8, ptr %lastout.2271, i64 1
923 ; CHECK-NEXT: --> {(1 + %ptr),+,1}<nuw><%while.body125> U: full-set S: full-set Exits: {(-1 + (-1 * (ptrtoint ptr %ptr to i64)) + %ptr),+,-1}<nw><%while.cond111> LoopDispositions: { %while.body125: Computable }
924 ; CHECK-NEXT: Determining loop execution counts for: @crash
925 ; CHECK-NEXT: Loop %while.body125: backedge-taken count is {(-2 + (-1 * (ptrtoint ptr %ptr to i64))),+,-1}<nw><%while.cond111>
926 ; CHECK-NEXT: Loop %while.body125: constant max backedge-taken count is i64 -2
927 ; CHECK-NEXT: Loop %while.body125: symbolic max backedge-taken count is {(-2 + (-1 * (ptrtoint ptr %ptr to i64))),+,-1}<nw><%while.cond111>
928 ; CHECK-NEXT: Loop %while.body125: Trip multiple is 1
929 ; CHECK-NEXT: Loop %while.cond111: Unpredictable backedge-taken count.
930 ; CHECK-NEXT: Loop %while.cond111: Unpredictable constant max backedge-taken count.
931 ; CHECK-NEXT: Loop %while.cond111: Unpredictable symbolic max backedge-taken count.
932 ; CHECK-NEXT: Loop %while.body: Unpredictable backedge-taken count.
933 ; CHECK-NEXT: Loop %while.body: Unpredictable constant max backedge-taken count.
934 ; CHECK-NEXT: Loop %while.body: Unpredictable symbolic max backedge-taken count.
940 br label %while.cond111
943 %text.addr.5 = phi ptr [ %incdec.ptr112, %while.cond111 ], [ null, %while.body ]
944 %incdec.ptr112 = getelementptr inbounds i8, ptr %text.addr.5, i64 -1
945 br i1 false, label %while.end117, label %while.cond111
948 %cmp118 = icmp ult ptr %ptr, %incdec.ptr112
949 br i1 %cmp118, label %while.body125, label %while.cond134.preheader
952 while.cond134.preheader:
956 %lastout.2271 = phi ptr [ %incdec.ptr126, %while.body125 ], [ %ptr, %while.end117 ]
957 %incdec.ptr126 = getelementptr inbounds i8, ptr %lastout.2271, i64 1
958 %exitcond.not = icmp eq ptr %incdec.ptr126, %incdec.ptr112
959 br i1 %exitcond.not, label %while.end129, label %while.body125
961 while.end129: ; preds = %while.body125
965 define void @test_guard_uge(i32 %blockSize) {
966 ; CHECK-LABEL: 'test_guard_uge'
967 ; CHECK-NEXT: Classifying expressions for: @test_guard_uge
968 ; CHECK-NEXT: %shr = lshr i32 %blockSize, 2
969 ; CHECK-NEXT: --> (%blockSize /u 4) U: [0,1073741824) S: [0,1073741824)
970 ; CHECK-NEXT: %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
971 ; CHECK-NEXT: --> {(%blockSize /u 4),+,-1}<nsw><%while.body> U: [-1073741822,1073741824) S: [-1073741822,1073741824) Exits: 1 LoopDispositions: { %while.body: Computable }
972 ; CHECK-NEXT: %dec = add i32 %iv, -1
973 ; CHECK-NEXT: --> {(-1 + (%blockSize /u 4))<nsw>,+,-1}<nsw><%while.body> U: [-1073741823,1073741823) S: [-1073741823,1073741823) Exits: 0 LoopDispositions: { %while.body: Computable }
974 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_uge
975 ; CHECK-NEXT: Loop %while.body: backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
976 ; CHECK-NEXT: Loop %while.body: constant max backedge-taken count is i32 1073741822
977 ; CHECK-NEXT: Loop %while.body: symbolic max backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
978 ; CHECK-NEXT: Loop %while.body: Trip multiple is 1
980 %shr = lshr i32 %blockSize, 2
981 %guard = icmp uge i32 %blockSize, 4
982 br i1 %guard, label %while.body.preheader, label %while.end
984 while.body.preheader:
988 %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
989 %dec = add i32 %iv, -1
990 %cmp.not = icmp eq i32 %dec, 0
991 br i1 %cmp.not, label %while.end.loopexit, label %while.body
1000 define void @test_guard_ugt(i32 %blockSize) {
1001 ; CHECK-LABEL: 'test_guard_ugt'
1002 ; CHECK-NEXT: Classifying expressions for: @test_guard_ugt
1003 ; CHECK-NEXT: %shr = lshr i32 %blockSize, 2
1004 ; CHECK-NEXT: --> (%blockSize /u 4) U: [0,1073741824) S: [0,1073741824)
1005 ; CHECK-NEXT: %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1006 ; CHECK-NEXT: --> {(%blockSize /u 4),+,-1}<nsw><%while.body> U: [-1073741822,1073741824) S: [-1073741822,1073741824) Exits: 1 LoopDispositions: { %while.body: Computable }
1007 ; CHECK-NEXT: %dec = add i32 %iv, -1
1008 ; CHECK-NEXT: --> {(-1 + (%blockSize /u 4))<nsw>,+,-1}<nsw><%while.body> U: [-1073741823,1073741823) S: [-1073741823,1073741823) Exits: 0 LoopDispositions: { %while.body: Computable }
1009 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_ugt
1010 ; CHECK-NEXT: Loop %while.body: backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1011 ; CHECK-NEXT: Loop %while.body: constant max backedge-taken count is i32 1073741822
1012 ; CHECK-NEXT: Loop %while.body: symbolic max backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1013 ; CHECK-NEXT: Loop %while.body: Trip multiple is 1
1015 %shr = lshr i32 %blockSize, 2
1016 %guard = icmp ugt i32 %blockSize, 3
1017 br i1 %guard, label %while.body.preheader, label %while.end
1019 while.body.preheader:
1020 br label %while.body
1023 %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1024 %dec = add i32 %iv, -1
1025 %cmp.not = icmp eq i32 %dec, 0
1026 br i1 %cmp.not, label %while.end.loopexit, label %while.body
1035 define void @test_guard_uge_and_ule(i32 %blockSize) {
1036 ; CHECK-LABEL: 'test_guard_uge_and_ule'
1037 ; CHECK-NEXT: Classifying expressions for: @test_guard_uge_and_ule
1038 ; CHECK-NEXT: %shr = lshr i32 %blockSize, 2
1039 ; CHECK-NEXT: --> (%blockSize /u 4) U: [0,1073741824) S: [0,1073741824)
1040 ; CHECK-NEXT: %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1041 ; CHECK-NEXT: --> {(%blockSize /u 4),+,-1}<nsw><%while.body> U: [-255,1073741824) S: [-255,1073741824) Exits: 1 LoopDispositions: { %while.body: Computable }
1042 ; CHECK-NEXT: %dec = add i32 %iv, -1
1043 ; CHECK-NEXT: --> {(-1 + (%blockSize /u 4))<nsw>,+,-1}<nsw><%while.body> U: [-256,1073741823) S: [-256,1073741823) Exits: 0 LoopDispositions: { %while.body: Computable }
1044 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_uge_and_ule
1045 ; CHECK-NEXT: Loop %while.body: backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1046 ; CHECK-NEXT: Loop %while.body: constant max backedge-taken count is i32 255
1047 ; CHECK-NEXT: Loop %while.body: symbolic max backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1048 ; CHECK-NEXT: Loop %while.body: Trip multiple is 1
1050 %shr = lshr i32 %blockSize, 2
1051 %guard1 = icmp uge i32 %blockSize, 4
1052 br i1 %guard1, label %while.guard, label %while.end
1055 %guard2 = icmp ule i32 %blockSize, 1024
1056 br i1 %guard2, label %while.body.preheader, label %while.end
1058 while.body.preheader:
1059 br label %while.body
1062 %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1063 %dec = add i32 %iv, -1
1064 %cmp.not = icmp eq i32 %dec, 0
1065 br i1 %cmp.not, label %while.end.loopexit, label %while.body
1074 define void @test_guard_ugt_and_ult(i32 %blockSize) {
1075 ; CHECK-LABEL: 'test_guard_ugt_and_ult'
1076 ; CHECK-NEXT: Classifying expressions for: @test_guard_ugt_and_ult
1077 ; CHECK-NEXT: %shr = lshr i32 %blockSize, 2
1078 ; CHECK-NEXT: --> (%blockSize /u 4) U: [0,1073741824) S: [0,1073741824)
1079 ; CHECK-NEXT: %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1080 ; CHECK-NEXT: --> {(%blockSize /u 4),+,-1}<nsw><%while.body> U: [-255,1073741824) S: [-255,1073741824) Exits: 1 LoopDispositions: { %while.body: Computable }
1081 ; CHECK-NEXT: %dec = add i32 %iv, -1
1082 ; CHECK-NEXT: --> {(-1 + (%blockSize /u 4))<nsw>,+,-1}<nsw><%while.body> U: [-256,1073741823) S: [-256,1073741823) Exits: 0 LoopDispositions: { %while.body: Computable }
1083 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_ugt_and_ult
1084 ; CHECK-NEXT: Loop %while.body: backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1085 ; CHECK-NEXT: Loop %while.body: constant max backedge-taken count is i32 255
1086 ; CHECK-NEXT: Loop %while.body: symbolic max backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1087 ; CHECK-NEXT: Loop %while.body: Trip multiple is 1
1089 %shr = lshr i32 %blockSize, 2
1090 %guard1 = icmp ugt i32 %blockSize, 3
1091 br i1 %guard1, label %while.guard, label %while.end
1094 %guard2 = icmp ult i32 %blockSize, 1025
1095 br i1 %guard2, label %while.body.preheader, label %while.end
1097 while.body.preheader:
1098 br label %while.body
1101 %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1102 %dec = add i32 %iv, -1
1103 %cmp.not = icmp eq i32 %dec, 0
1104 br i1 %cmp.not, label %while.end.loopexit, label %while.body
1113 define void @test_guard_slt_sgt_1(ptr nocapture %a, i64 %N) {
1114 ; CHECK-LABEL: 'test_guard_slt_sgt_1'
1115 ; CHECK-NEXT: Classifying expressions for: @test_guard_slt_sgt_1
1116 ; CHECK-NEXT: %and = and i1 %c.0, %c.1
1117 ; CHECK-NEXT: --> (%c.0 umin %c.1) U: full-set S: full-set
1118 ; CHECK-NEXT: %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
1119 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,11) S: [0,11) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1120 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
1121 ; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %N) + %a) LoopDispositions: { %loop: Computable }
1122 ; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
1123 ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,12) S: [1,12) Exits: %N LoopDispositions: { %loop: Computable }
1124 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_slt_sgt_1
1125 ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %N)
1126 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 10
1127 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %N)
1128 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
1131 %c.0 = icmp slt i64 %N, 12
1132 %c.1 = icmp sgt i64 %N, 0
1133 %and = and i1 %c.0, %c.1
1134 br i1 %and, label %loop, label %exit
1137 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
1138 %idx = getelementptr inbounds i32, ptr %a, i64 %iv
1139 store i32 1, ptr %idx, align 4
1140 %iv.next = add nuw nsw i64 %iv, 1
1141 %exitcond = icmp eq i64 %iv.next, %N
1142 br i1 %exitcond, label %exit, label %loop
1148 define void @test_guard_slt_sgt_2(ptr nocapture %a, i64 %i) {
1149 ; CHECK-LABEL: 'test_guard_slt_sgt_2'
1150 ; CHECK-NEXT: Classifying expressions for: @test_guard_slt_sgt_2
1151 ; CHECK-NEXT: %and = and i1 %c.0, %c.1
1152 ; CHECK-NEXT: --> (%c.0 umin %c.1) U: full-set S: full-set
1153 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
1154 ; CHECK-NEXT: --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 17 LoopDispositions: { %loop: Computable }
1155 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
1156 ; CHECK-NEXT: --> {((4 * %i) + %a),+,4}<%loop> U: full-set S: full-set Exits: (68 + %a) LoopDispositions: { %loop: Computable }
1157 ; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
1158 ; CHECK-NEXT: --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 18 LoopDispositions: { %loop: Computable }
1159 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_slt_sgt_2
1160 ; CHECK-NEXT: Loop %loop: backedge-taken count is (17 + (-1 * %i))
1161 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 12
1162 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (17 + (-1 * %i))
1163 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
1166 %c.0 = icmp slt i64 %i, 16
1167 %c.1 = icmp sgt i64 %i, 4
1168 %and = and i1 %c.0, %c.1
1169 br i1 %and, label %loop, label %exit
1172 %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
1173 %idx = getelementptr inbounds i32, ptr %a, i64 %iv
1174 store i32 1, ptr %idx, align 4
1175 %iv.next = add nuw nsw i64 %iv, 1
1176 %exitcond = icmp eq i64 %iv.next, 18
1177 br i1 %exitcond, label %exit, label %loop
1183 define void @test_guard_sle_sge_1(ptr nocapture %a, i64 %N) {
1184 ; CHECK-LABEL: 'test_guard_sle_sge_1'
1185 ; CHECK-NEXT: Classifying expressions for: @test_guard_sle_sge_1
1186 ; CHECK-NEXT: %and = and i1 %c.0, %c.1
1187 ; CHECK-NEXT: --> (%c.0 umin %c.1) U: full-set S: full-set
1188 ; CHECK-NEXT: %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
1189 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,12) S: [0,12) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1190 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
1191 ; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %N) + %a) LoopDispositions: { %loop: Computable }
1192 ; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
1193 ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,13) S: [1,13) Exits: %N LoopDispositions: { %loop: Computable }
1194 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_sle_sge_1
1195 ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %N)
1196 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 11
1197 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %N)
1198 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
1201 %c.0 = icmp sle i64 %N, 12
1202 %c.1 = icmp sge i64 %N, 1
1203 %and = and i1 %c.0, %c.1
1204 br i1 %and, label %loop, label %exit
1207 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
1208 %idx = getelementptr inbounds i32, ptr %a, i64 %iv
1209 store i32 1, ptr %idx, align 4
1210 %iv.next = add nuw nsw i64 %iv, 1
1211 %exitcond = icmp eq i64 %iv.next, %N
1212 br i1 %exitcond, label %exit, label %loop
1218 define void @test_guard_sle_sge_2(ptr nocapture %a, i64 %i) {
1219 ; CHECK-LABEL: 'test_guard_sle_sge_2'
1220 ; CHECK-NEXT: Classifying expressions for: @test_guard_sle_sge_2
1221 ; CHECK-NEXT: %and = and i1 %c.0, %c.1
1222 ; CHECK-NEXT: --> (%c.0 umin %c.1) U: full-set S: full-set
1223 ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
1224 ; CHECK-NEXT: --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 17 LoopDispositions: { %loop: Computable }
1225 ; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
1226 ; CHECK-NEXT: --> {((4 * %i) + %a),+,4}<%loop> U: full-set S: full-set Exits: (68 + %a) LoopDispositions: { %loop: Computable }
1227 ; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
1228 ; CHECK-NEXT: --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 18 LoopDispositions: { %loop: Computable }
1229 ; CHECK-NEXT: Determining loop execution counts for: @test_guard_sle_sge_2
1230 ; CHECK-NEXT: Loop %loop: backedge-taken count is (17 + (-1 * %i))
1231 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 13
1232 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (17 + (-1 * %i))
1233 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
1236 %c.0 = icmp sle i64 %i, 16
1237 %c.1 = icmp sge i64 %i, 4
1238 %and = and i1 %c.0, %c.1
1239 br i1 %and, label %loop, label %exit
1242 %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
1243 %idx = getelementptr inbounds i32, ptr %a, i64 %iv
1244 store i32 1, ptr %idx, align 4
1245 %iv.next = add nuw nsw i64 %iv, 1
1246 %exitcond = icmp eq i64 %iv.next, 18
1247 br i1 %exitcond, label %exit, label %loop
1253 ; The function below uses a single condition to ensure %N > 0 && %N < 8.
1254 ; InstCombine transforms such checks with 2 conditions to a single check as in
1255 ; the test function.
1256 define void @optimized_range_check_unsigned(ptr %pred, i32 %N) {
1257 ; CHECK-LABEL: 'optimized_range_check_unsigned'
1258 ; CHECK-NEXT: Classifying expressions for: @optimized_range_check_unsigned
1259 ; CHECK-NEXT: %N.off = add i32 %N, -1
1260 ; CHECK-NEXT: --> (-1 + %N) U: full-set S: full-set
1261 ; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1262 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,7) S: [0,7) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1263 ; CHECK-NEXT: %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
1264 ; CHECK-NEXT: --> {%pred,+,2}<nuw><%loop> U: full-set S: full-set Exits: ((2 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %pred) LoopDispositions: { %loop: Computable }
1265 ; CHECK-NEXT: %iv.next = add nuw nsw i32 %iv, 1
1266 ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,8) S: [1,8) Exits: %N LoopDispositions: { %loop: Computable }
1267 ; CHECK-NEXT: Determining loop execution counts for: @optimized_range_check_unsigned
1268 ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %N)
1269 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 6
1270 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %N)
1271 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
1274 %N.off = add i32 %N, -1
1275 %cmp = icmp ult i32 %N.off, 7
1276 br i1 %cmp, label %loop, label %exit
1279 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1280 %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
1281 store i16 0, ptr %gep, align 2
1282 %iv.next = add nuw nsw i32 %iv, 1
1283 %ec = icmp eq i32 %iv.next, %N
1284 br i1 %ec, label %exit, label %loop
1290 ; Same as @optimized_range_check_unsigned, but with the icmp operands swapped.
1291 define void @optimized_range_check_unsigned_icmp_ops_swapped(ptr %pred, i32 %N) {
1292 ; CHECK-LABEL: 'optimized_range_check_unsigned_icmp_ops_swapped'
1293 ; CHECK-NEXT: Classifying expressions for: @optimized_range_check_unsigned_icmp_ops_swapped
1294 ; CHECK-NEXT: %N.off = add i32 %N, -1
1295 ; CHECK-NEXT: --> (-1 + %N) U: full-set S: full-set
1296 ; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1297 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,7) S: [0,7) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1298 ; CHECK-NEXT: %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
1299 ; CHECK-NEXT: --> {%pred,+,2}<nuw><%loop> U: full-set S: full-set Exits: ((2 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %pred) LoopDispositions: { %loop: Computable }
1300 ; CHECK-NEXT: %iv.next = add nuw nsw i32 %iv, 1
1301 ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,8) S: [1,8) Exits: %N LoopDispositions: { %loop: Computable }
1302 ; CHECK-NEXT: Determining loop execution counts for: @optimized_range_check_unsigned_icmp_ops_swapped
1303 ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %N)
1304 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 6
1305 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %N)
1306 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
1309 %N.off = add i32 %N, -1
1310 %cmp = icmp ugt i32 7, %N.off
1311 br i1 %cmp, label %loop, label %exit
1314 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1315 %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
1316 store i16 0, ptr %gep, align 2
1317 %iv.next = add nuw nsw i32 %iv, 1
1318 %ec = icmp eq i32 %iv.next, %N
1319 br i1 %ec, label %exit, label %loop
1325 ; The function below uses a single condition to ensure %N > 2 && %N < 22.
1326 ; InstCombine transforms such checks with 2 conditions to a single check as in
1327 ; the test function.
1328 define void @optimized_range_check_unsigned2(ptr %pred, i32 %N) {
1329 ; CHECK-LABEL: 'optimized_range_check_unsigned2'
1330 ; CHECK-NEXT: Classifying expressions for: @optimized_range_check_unsigned2
1331 ; CHECK-NEXT: %N.off = add i32 %N, -2
1332 ; CHECK-NEXT: --> (-2 + %N) U: full-set S: full-set
1333 ; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1334 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,21) S: [0,21) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1335 ; CHECK-NEXT: %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
1336 ; CHECK-NEXT: --> {%pred,+,2}<nuw><%loop> U: full-set S: full-set Exits: ((2 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %pred) LoopDispositions: { %loop: Computable }
1337 ; CHECK-NEXT: %iv.next = add nuw nsw i32 %iv, 1
1338 ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,22) S: [1,22) Exits: %N LoopDispositions: { %loop: Computable }
1339 ; CHECK-NEXT: Determining loop execution counts for: @optimized_range_check_unsigned2
1340 ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %N)
1341 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 20
1342 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %N)
1343 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
1346 %N.off = add i32 %N, -2
1347 %cmp = icmp ult i32 %N.off, 20
1348 br i1 %cmp, label %loop, label %exit
1351 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1352 %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
1353 store i16 0, ptr %gep, align 2
1354 %iv.next = add nuw nsw i32 %iv, 1
1355 %ec = icmp eq i32 %iv.next, %N
1356 br i1 %ec, label %exit, label %loop
1362 ; Same as @optimized_range_check_unsigned, but %N already has a range limited
1363 ; to [2,4) beforehand.
1364 define void @optimized_range_check_unsigned3(ptr %pred, i1 %c) {
1365 ; CHECK-LABEL: 'optimized_range_check_unsigned3'
1366 ; CHECK-NEXT: Classifying expressions for: @optimized_range_check_unsigned3
1367 ; CHECK-NEXT: %N = select i1 %c, i32 2, i32 3
1368 ; CHECK-NEXT: --> %N U: [2,4) S: [2,4)
1369 ; CHECK-NEXT: %N.off = add i32 %N, -1
1370 ; CHECK-NEXT: --> (-1 + %N)<nsw> U: [1,3) S: [1,3)
1371 ; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1372 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,3) S: [0,3) Exits: (-1 + %N)<nsw> LoopDispositions: { %loop: Computable }
1373 ; CHECK-NEXT: %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
1374 ; CHECK-NEXT: --> {%pred,+,2}<nuw><%loop> U: full-set S: full-set Exits: ((2 * (zext i32 (-1 + %N)<nsw> to i64))<nuw><nsw> + %pred) LoopDispositions: { %loop: Computable }
1375 ; CHECK-NEXT: %iv.next = add nuw nsw i32 %iv, 1
1376 ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,4) S: [1,4) Exits: %N LoopDispositions: { %loop: Computable }
1377 ; CHECK-NEXT: Determining loop execution counts for: @optimized_range_check_unsigned3
1378 ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %N)<nsw>
1379 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 2
1380 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %N)<nsw>
1381 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
1384 %N = select i1 %c, i32 2, i32 3
1385 %N.off = add i32 %N, -1
1386 %cmp = icmp ult i32 %N.off, 7
1387 br i1 %cmp, label %loop, label %exit
1390 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1391 %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
1392 store i16 0, ptr %gep, align 2
1393 %iv.next = add nuw nsw i32 %iv, 1
1394 %ec = icmp eq i32 %iv.next, %N
1395 br i1 %ec, label %exit, label %loop
1401 ; Similar to @optimized_range_check_unsigned, but the initial compare checks
1402 ; against unsigned max (-1), which breaks the range check idiom.
1403 define void @not_optimized_range_check_unsigned1(ptr %pred, i32 %N) {
1404 ; CHECK-LABEL: 'not_optimized_range_check_unsigned1'
1405 ; CHECK-NEXT: Classifying expressions for: @not_optimized_range_check_unsigned1
1406 ; CHECK-NEXT: %N.off = add i32 %N, -1
1407 ; CHECK-NEXT: --> (-1 + %N) U: full-set S: full-set
1408 ; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1409 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1410 ; CHECK-NEXT: %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
1411 ; CHECK-NEXT: --> {%pred,+,2}<nuw><%loop> U: full-set S: full-set Exits: ((2 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %pred) LoopDispositions: { %loop: Computable }
1412 ; CHECK-NEXT: %iv.next = add nuw nsw i32 %iv, 1
1413 ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %N LoopDispositions: { %loop: Computable }
1414 ; CHECK-NEXT: Determining loop execution counts for: @not_optimized_range_check_unsigned1
1415 ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %N)
1416 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -2
1417 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %N)
1418 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
1421 %N.off = add i32 %N, -1
1422 %cmp = icmp ult i32 %N.off, -1
1423 br i1 %cmp, label %loop, label %exit
1426 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1427 %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
1428 store i16 0, ptr %gep, align 2
1429 %iv.next = add nuw nsw i32 %iv, 1
1430 %ec = icmp eq i32 %iv.next, %N
1431 br i1 %ec, label %exit, label %loop
1437 ; Similar to @optimized_range_check_unsigned, but the initial compare checks
1438 ; against 0, which breaks the range check idiom.
1439 define void @not_optimized_range_check_unsigned2(ptr %pred, i32 %N) {
1440 ; CHECK-LABEL: 'not_optimized_range_check_unsigned2'
1441 ; CHECK-NEXT: Classifying expressions for: @not_optimized_range_check_unsigned2
1442 ; CHECK-NEXT: %N.off = add i32 %N, -1
1443 ; CHECK-NEXT: --> (-1 + %N) U: full-set S: full-set
1444 ; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1445 ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1446 ; CHECK-NEXT: %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
1447 ; CHECK-NEXT: --> {%pred,+,2}<nuw><%loop> U: full-set S: full-set Exits: ((2 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %pred) LoopDispositions: { %loop: Computable }
1448 ; CHECK-NEXT: %iv.next = add nuw nsw i32 %iv, 1
1449 ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %N LoopDispositions: { %loop: Computable }
1450 ; CHECK-NEXT: Determining loop execution counts for: @not_optimized_range_check_unsigned2
1451 ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %N)
1452 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -2
1453 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %N)
1454 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
1457 %N.off = add i32 %N, -1
1458 %cmp = icmp ult i32 %N.off, 0
1459 br i1 %cmp, label %loop, label %exit
1462 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1463 %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
1464 store i16 0, ptr %gep, align 2
1465 %iv.next = add nuw nsw i32 %iv, 1
1466 %ec = icmp eq i32 %iv.next, %N
1467 br i1 %ec, label %exit, label %loop
1473 define i32 @sle_sgt_ult_umax_to_smax(i32 %num) {
1474 ; CHECK-LABEL: 'sle_sgt_ult_umax_to_smax'
1475 ; CHECK-NEXT: Classifying expressions for: @sle_sgt_ult_umax_to_smax
1476 ; CHECK-NEXT: %iv = phi i32 [ 0, %guard.3 ], [ %iv.next, %loop ]
1477 ; CHECK-NEXT: --> {0,+,4}<nuw><nsw><%loop> U: [0,25) S: [0,25) Exits: (4 * ((-4 + %num) /u 4))<nuw> LoopDispositions: { %loop: Computable }
1478 ; CHECK-NEXT: %iv.next = add nuw i32 %iv, 4
1479 ; CHECK-NEXT: --> {4,+,4}<nuw><nsw><%loop> U: [4,29) S: [4,29) Exits: (4 + (4 * ((-4 + %num) /u 4))<nuw>) LoopDispositions: { %loop: Computable }
1480 ; CHECK-NEXT: Determining loop execution counts for: @sle_sgt_ult_umax_to_smax
1481 ; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + %num) /u 4)
1482 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 6
1483 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + %num) /u 4)
1484 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
1487 %cmp.1 = icmp sle i32 %num, 0
1488 br i1 %cmp.1, label %exit, label %guard.2
1491 %cmp.2 = icmp sgt i32 %num, 28
1492 br i1 %cmp.2, label %exit, label %guard.3
1495 %cmp.3 = icmp ult i32 %num, 4
1496 br i1 %cmp.3, label %exit, label %loop
1499 %iv = phi i32 [ 0, %guard.3 ], [ %iv.next, %loop ]
1500 %iv.next = add nuw i32 %iv, 4
1501 %ec = icmp eq i32 %iv.next, %num
1502 br i1 %ec, label %exit, label %loop
1508 ; Similar to @sle_sgt_ult_umax_to_smax but with different predicate order.
1509 define i32 @ult_sle_sgt_umax_to_smax(i32 %num) {
1510 ; CHECK-LABEL: 'ult_sle_sgt_umax_to_smax'
1511 ; CHECK-NEXT: Classifying expressions for: @ult_sle_sgt_umax_to_smax
1512 ; CHECK-NEXT: %iv = phi i32 [ 0, %guard.3 ], [ %iv.next, %loop ]
1513 ; CHECK-NEXT: --> {0,+,4}<nuw><%loop> U: [0,-3) S: [-2147483648,2147483645) Exits: (4 * ((-4 + %num) /u 4))<nuw> LoopDispositions: { %loop: Computable }
1514 ; CHECK-NEXT: %iv.next = add nuw i32 %iv, 4
1515 ; CHECK-NEXT: --> {4,+,4}<nuw><%loop> U: [4,-3) S: [-2147483648,2147483645) Exits: (4 + (4 * ((-4 + %num) /u 4))<nuw>) LoopDispositions: { %loop: Computable }
1516 ; CHECK-NEXT: Determining loop execution counts for: @ult_sle_sgt_umax_to_smax
1517 ; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + %num) /u 4)
1518 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 1073741823
1519 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + %num) /u 4)
1520 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
1523 %cmp.1 = icmp ult i32 %num, 4
1524 br i1 %cmp.1, label %exit, label %guard.2
1527 %cmp.2 = icmp sgt i32 %num, 28
1528 br i1 %cmp.2, label %exit, label %guard.3
1531 %cmp.3 = icmp sle i32 %num, 0
1532 br i1 %cmp.3, label %exit, label %loop
1535 %iv = phi i32 [ 0, %guard.3 ], [ %iv.next, %loop ]
1536 %iv.next = add nuw i32 %iv, 4
1537 %ec = icmp eq i32 %iv.next, %num
1538 br i1 %ec, label %exit, label %loop
1544 define i32 @ptr_induction_ult_1(ptr %a, ptr %b) {
1545 ; CHECK-LABEL: 'ptr_induction_ult_1'
1546 ; CHECK-NEXT: Classifying expressions for: @ptr_induction_ult_1
1547 ; CHECK-NEXT: %ptr.iv = phi ptr [ %ptr.iv.next, %loop ], [ %a, %entry ]
1548 ; CHECK-NEXT: --> {%a,+,4}<nw><%loop> U: full-set S: full-set Exits: %a LoopDispositions: { %loop: Computable }
1549 ; CHECK-NEXT: %ptr.iv.next = getelementptr i32, ptr %ptr.iv, i64 1
1550 ; CHECK-NEXT: --> {(4 + %a),+,4}<nw><%loop> U: full-set S: full-set Exits: (4 + %a) LoopDispositions: { %loop: Computable }
1551 ; CHECK-NEXT: Determining loop execution counts for: @ptr_induction_ult_1
1552 ; CHECK-NEXT: Loop %loop: backedge-taken count is i64 0
1553 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 0
1554 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is i64 0
1555 ; CHECK-NEXT: Loop %loop: Trip multiple is 1
1558 %cmp.6 = icmp ult ptr %a, %b
1559 br i1 %cmp.6, label %loop, label %exit
1562 %ptr.iv = phi ptr [ %ptr.iv.next, %loop ], [ %a, %entry ]
1563 %ptr.iv.next = getelementptr i32, ptr %ptr.iv, i64 1
1564 %exitcond = icmp eq ptr %ptr.iv, %a
1565 br i1 %exitcond, label %exit, label %loop
1572 define i32 @ptr_induction_ult_2(ptr %a, ptr %b) {
1573 ; CHECK-LABEL: 'ptr_induction_ult_2'
1574 ; CHECK-NEXT: Classifying expressions for: @ptr_induction_ult_2
1575 ; CHECK-NEXT: %ptr.iv = phi ptr [ %ptr.iv.next, %loop ], [ %a, %entry ]
1576 ; CHECK-NEXT: --> {%a,+,4}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
1577 ; CHECK-NEXT: %ptr.iv.next = getelementptr i32, ptr %ptr.iv, i64 1
1578 ; CHECK-NEXT: --> {(4 + %a),+,4}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
1579 ; CHECK-NEXT: Determining loop execution counts for: @ptr_induction_ult_2
1580 ; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.
1581 ; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.
1582 ; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.
1585 %cmp.6 = icmp ult ptr %a, %b
1586 br i1 %cmp.6, label %loop, label %exit
1589 %ptr.iv = phi ptr [ %ptr.iv.next, %loop ], [ %a, %entry ]
1590 %ptr.iv.next = getelementptr i32, ptr %ptr.iv, i64 1
1591 %exitcond = icmp eq ptr %ptr.iv, %b
1592 br i1 %exitcond, label %exit, label %loop
1598 define void @gep_addrec_nw(ptr %a) {
1599 ; CHECK-LABEL: 'gep_addrec_nw'
1600 ; CHECK-NEXT: Classifying expressions for: @gep_addrec_nw
1601 ; CHECK-NEXT: %lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %a, %entry ]
1602 ; CHECK-NEXT: --> {%a,+,4}<nw><%for.body> U: full-set S: full-set Exits: (1512 + %a) LoopDispositions: { %for.body: Computable }
1603 ; CHECK-NEXT: %lsr.iv = phi i64 [ %lsr.iv.next, %for.body ], [ 379, %entry ]
1604 ; CHECK-NEXT: --> {379,+,-1}<nsw><%for.body> U: [1,380) S: [1,380) Exits: 1 LoopDispositions: { %for.body: Computable }
1605 ; CHECK-NEXT: %lsr.iv.next = add nsw i64 %lsr.iv, -1
1606 ; CHECK-NEXT: --> {378,+,-1}<nsw><%for.body> U: [0,379) S: [0,379) Exits: 0 LoopDispositions: { %for.body: Computable }
1607 ; CHECK-NEXT: %uglygep2 = getelementptr i8, ptr %lsr.iv1, i64 4
1608 ; CHECK-NEXT: --> {(4 + %a),+,4}<nw><%for.body> U: full-set S: full-set Exits: (1516 + %a) LoopDispositions: { %for.body: Computable }
1609 ; CHECK-NEXT: Determining loop execution counts for: @gep_addrec_nw
1610 ; CHECK-NEXT: Loop %for.body: backedge-taken count is i64 378
1611 ; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i64 378
1612 ; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is i64 378
1613 ; CHECK-NEXT: Loop %for.body: Trip multiple is 379
1618 for.body: ; preds = %for.body, %entry
1619 %lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %a, %entry ]
1620 %lsr.iv = phi i64 [ %lsr.iv.next, %for.body ], [ 379, %entry ]
1621 store i32 1, ptr %lsr.iv1, align 4
1622 %lsr.iv.next = add nsw i64 %lsr.iv, -1
1623 %uglygep2 = getelementptr i8, ptr %lsr.iv1, i64 4
1624 %exitcond.not = icmp eq i64 %lsr.iv.next, 0
1625 br i1 %exitcond.not, label %for.end, label %for.body
1627 for.end: ; preds = %for.body