Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Analysis / ScalarEvolution / max-backedge-taken-count-guard-info.ll
blob413bd21554c98dc1018a67c0a76929b0a99d195f
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
21 entry:
22   %cmp3 = icmp ult i64 %i, 16
23   br i1 %cmp3, label %loop, label %exit
25 loop:
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
33 exit:
34   ret void
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
52 entry:
53   %cmp3 = icmp ugt i64 16, %i
54   br i1 %cmp3, label %loop, label %exit
56 loop:
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
64 exit:
65   ret void
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
83 entry:
84   %cmp3 = icmp ult i64 %i, 16
85   br i1 %cmp3, label %exit, label %loop
87 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
95 exit:
96   ret void
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
114 entry:
115   %cmp3 = icmp uge i64 %i, 16
116   br i1 %cmp3, label %exit, label %loop
118 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
126 exit:
127   ret void
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
145 entry:
146   %c.1 = icmp eq i64 %N, 12
147   br i1 %c.1, label %loop, label %exit
149 loop:
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
157 exit:
158   ret void
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
176 entry:
177   %c.1 = icmp ule i64 %N, 12
178   br i1 %c.1, label %loop, label %exit
180 loop:
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
188 exit:
189   ret void
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
207 entry:
208   %c.1 = icmp ule i64 %N, 12
209   br i1 %c.1, label %loop, label %exit
211 loop:
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
219 exit:
220   ret void
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
238 entry:
239   %c.1 = icmp ult i64 %i, 16
240   br i1 %c.1, label %guardbb, label %exit
242 guardbb:
243   %c.2 = icmp ult i64 %i, 10
244   br i1 %c.2, label %loop, label %exit
246 loop:
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
254 exit:
255   ret void
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
273 entry:
274   %c.1 = icmp ult i64 %i, 10
275   br i1 %c.1, label %guardbb, label %exit
277 guardbb:
278   %c.2 = icmp ult i64 %i, 16
279   br i1 %c.2, label %loop, label %exit
281 loop:
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
289 exit:
290   ret void
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
308 entry:
309   %c.1 = icmp ult i64 %N, 12
310   br i1 %c.1, label %guardbb, label %exit
312 guardbb:
313   %c.2 = icmp ult i64 %i, %N
314   br i1 %c.2, label %loop, label %exit
316 loop:
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
324 exit:
325   ret void
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
343 entry:
344   %c.1 = icmp ult i64 %i, %N
345   br i1 %c.1, label %guardbb, label %exit
347 guardbb:
348   %c.2 = icmp ult i64 %N, 12
349   br i1 %c.2, label %loop, label %exit
351 loop:
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
359 exit:
360   ret void
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
379 entry:
380   %c.1 = icmp ult i64 %N, %i
381   br i1 %c.1, label %guardbb, label %exit
383 guardbb:
384   %c.2 = icmp ult i64 %i, %N
385   br i1 %c.2, label %loop, label %exit
387 loop:
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
395 exit:
396   ret void
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
414 entry:
415   %cmp.ult = icmp ult i64 %count, 5
416   br i1 %cmp.ult, label %guardbb, label %exit
418 guardbb:
419   %cmp.ne = icmp ne i64 %count, 0
420   br i1 %cmp.ne, label %loop, label %exit
422 loop:
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
430 exit:
431   ret void
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
449 entry:
450   %cmp.ne = icmp ne i64 %count, 0
451   br i1 %cmp.ne, label %guardbb, label %exit
453 guardbb:
454   %cmp.ult = icmp ult i64 %count, 5
455   br i1 %cmp.ult, label %loop, label %exit
457 loop:
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
465 exit:
466   ret void
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
486 entry:
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
492 loop:
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
500 exit:
501   ret void
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
521 entry:
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
527 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
535 exit:
536   ret void
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
558 entry:
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
565 loop:
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
573 exit:
574   ret void
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
596 entry:
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
603 loop:
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
611 exit:
612   ret void
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
632 entry:
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
638 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
646 exit:
647   ret void
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
667 entry:
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
673 loop:
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
681 exit:
682   ret void
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
704 entry:
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
711 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
719 exit:
720   ret void
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
742 entry:
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
749 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
757 exit:
758   ret void
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
779 entry:
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
785 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
793 exit:
794   ret void
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
814 entry:
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)
819   br label %loop
821 loop:
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
829 exit:
830   ret void
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
851 entry:
852   br i1 %c, label %bb1, label %guard
854 bb1:
855   br label %guard
857 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
862 loop.ph:
863   br label %loop
865 loop:
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
871 exit:
872   ret void
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
890 entry:
891   br i1 %c, label %bb1, label %guard
893 bb1:
894   br label %guard
896 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
901 loop.ph:
902   br label %loop
904 loop:
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
910 exit:
911   ret void
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.
936 entry:
937   br label %while.body
939 while.body:
940   br label %while.cond111
942 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
947 while.end117:
948   %cmp118 = icmp ult ptr %ptr, %incdec.ptr112
949   br i1 %cmp118, label %while.body125, label %while.cond134.preheader
952 while.cond134.preheader:
953   br label %while.body
955 while.body125:
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
962   ret void
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:
985   br label %while.body
987 while.body:
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
993 while.end.loopexit:
994   br label %while.end
996 while.end:
997   ret void
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
1022 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
1028 while.end.loopexit:
1029   br label %while.end
1031 while.end:
1032   ret void
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
1054 while.guard:
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
1061 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
1067 while.end.loopexit:
1068   br label %while.end
1070 while.end:
1071   ret void
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
1093 while.guard:
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
1100 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
1106 while.end.loopexit:
1107   br label %while.end
1109 while.end:
1110   ret void
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
1130 entry:
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
1136 loop:
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
1144 exit:
1145   ret void
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
1165 entry:
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
1171 loop:
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
1179 exit:
1180   ret void
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
1200 entry:
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
1206 loop:
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
1214 exit:
1215   ret void
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
1235 entry:
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
1241 loop:
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
1249 exit:
1250   ret void
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
1273 entry:
1274   %N.off = add i32 %N, -1
1275   %cmp = icmp ult i32 %N.off, 7
1276   br i1 %cmp, label %loop, label %exit
1278 loop:
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
1286 exit:
1287   ret void
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
1308 entry:
1309   %N.off = add i32 %N, -1
1310   %cmp = icmp ugt i32 7, %N.off
1311   br i1 %cmp, label %loop, label %exit
1313 loop:
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
1321 exit:
1322   ret void
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
1345 entry:
1346   %N.off = add i32 %N, -2
1347   %cmp = icmp ult i32 %N.off, 20
1348   br i1 %cmp, label %loop, label %exit
1350 loop:
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
1358 exit:
1359   ret void
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
1383 entry:
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
1389 loop:
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
1397 exit:
1398   ret void
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
1420 entry:
1421   %N.off = add i32 %N, -1
1422   %cmp = icmp ult i32 %N.off, -1
1423   br i1 %cmp, label %loop, label %exit
1425 loop:
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
1433 exit:
1434   ret void
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
1456 entry:
1457   %N.off = add i32 %N, -1
1458   %cmp = icmp ult i32 %N.off, 0
1459   br i1 %cmp, label %loop, label %exit
1461 loop:
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
1469 exit:
1470   ret void
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
1486 guard.1:
1487   %cmp.1 = icmp sle i32 %num, 0
1488   br i1 %cmp.1, label %exit, label %guard.2
1490 guard.2:
1491   %cmp.2 = icmp sgt i32 %num, 28
1492   br i1 %cmp.2, label %exit, label %guard.3
1494 guard.3:
1495   %cmp.3 = icmp ult i32 %num, 4
1496   br i1 %cmp.3, label %exit, label %loop
1498 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
1504 exit:
1505   ret i32 0
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
1522 guard.1:
1523   %cmp.1 = icmp ult i32 %num, 4
1524   br i1 %cmp.1, label %exit, label %guard.2
1526 guard.2:
1527   %cmp.2 = icmp sgt i32 %num, 28
1528   br i1 %cmp.2, label %exit, label %guard.3
1530 guard.3:
1531   %cmp.3 = icmp sle i32 %num, 0
1532   br i1 %cmp.3, label %exit, label %loop
1534 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
1540 exit:
1541   ret i32 0
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
1557 entry:
1558   %cmp.6 = icmp ult ptr %a, %b
1559   br i1 %cmp.6, label %loop, label %exit
1561 loop:
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
1567 exit:
1568   ret i32 0
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.
1584 entry:
1585   %cmp.6 = icmp ult ptr %a, %b
1586   br i1 %cmp.6, label %loop, label %exit
1588 loop:
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
1594 exit:
1595   ret i32 0
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
1615 entry:
1616   br label %for.body
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
1628   ret void