Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / Analysis / ScalarEvolution / max-backedge-taken-count-guard-info.ll
blobeb8e9dd09dc4fb40270b2113bb677e9d08408875
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 15
18 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (15 + (-1 * %i))
19 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (15 + (-1 * %i))
20 ; CHECK-NEXT:   Predicates:
21 ; CHECK:       Loop %loop: Trip multiple is 1
23 entry:
24   %cmp3 = icmp ult i64 %i, 16
25   br i1 %cmp3, label %loop, label %exit
27 loop:
28   %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
29   %idx = getelementptr inbounds i32, ptr %a, i64 %iv
30   store i32 1, ptr %idx, align 4
31   %iv.next = add nuw nsw i64 %iv, 1
32   %exitcond = icmp eq i64 %iv.next, 16
33   br i1 %exitcond, label %exit, label %loop
35 exit:
36   ret void
39 define void @test_guard_less_than_16_operands_swapped(ptr nocapture %a, i64 %i) {
40 ; CHECK-LABEL: 'test_guard_less_than_16_operands_swapped'
41 ; CHECK-NEXT:  Classifying expressions for: @test_guard_less_than_16_operands_swapped
42 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
43 ; CHECK-NEXT:    --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 15 LoopDispositions: { %loop: Computable }
44 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %a, i64 %iv
45 ; CHECK-NEXT:    --> {((4 * %i) + %a),+,4}<%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
46 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
47 ; CHECK-NEXT:    --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 16 LoopDispositions: { %loop: Computable }
48 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_less_than_16_operands_swapped
49 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (15 + (-1 * %i))
50 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 15
51 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (15 + (-1 * %i))
52 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (15 + (-1 * %i))
53 ; CHECK-NEXT:   Predicates:
54 ; CHECK:       Loop %loop: Trip multiple is 1
56 entry:
57   %cmp3 = icmp ugt i64 16, %i
58   br i1 %cmp3, label %loop, label %exit
60 loop:
61   %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
62   %idx = getelementptr inbounds i32, ptr %a, i64 %iv
63   store i32 1, ptr %idx, align 4
64   %iv.next = add nuw nsw i64 %iv, 1
65   %exitcond = icmp eq i64 %iv.next, 16
66   br i1 %exitcond, label %exit, label %loop
68 exit:
69   ret void
72 define void @test_guard_less_than_16_branches_flipped(ptr nocapture %a, i64 %i) {
73 ; CHECK-LABEL: 'test_guard_less_than_16_branches_flipped'
74 ; CHECK-NEXT:  Classifying expressions for: @test_guard_less_than_16_branches_flipped
75 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
76 ; CHECK-NEXT:    --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 15 LoopDispositions: { %loop: Computable }
77 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %a, i64 %iv
78 ; CHECK-NEXT:    --> {((4 * %i) + %a),+,4}<%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
79 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
80 ; CHECK-NEXT:    --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 16 LoopDispositions: { %loop: Computable }
81 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_less_than_16_branches_flipped
82 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (15 + (-1 * %i))
83 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is -1
84 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (15 + (-1 * %i))
85 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (15 + (-1 * %i))
86 ; CHECK-NEXT:   Predicates:
87 ; CHECK:       Loop %loop: Trip multiple is 1
89 entry:
90   %cmp3 = icmp ult i64 %i, 16
91   br i1 %cmp3, label %exit, label %loop
93 loop:
94   %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
95   %idx = getelementptr inbounds i32, ptr %a, i64 %iv
96   store i32 1, ptr %idx, align 4
97   %iv.next = add nuw nsw i64 %iv, 1
98   %exitcond = icmp eq i64 %iv.next, 16
99   br i1 %exitcond, label %exit, label %loop
101 exit:
102   ret void
105 define void @test_guard_uge_16_branches_flipped(ptr nocapture %a, i64 %i) {
106 ; CHECK-LABEL: 'test_guard_uge_16_branches_flipped'
107 ; CHECK-NEXT:  Classifying expressions for: @test_guard_uge_16_branches_flipped
108 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
109 ; CHECK-NEXT:    --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 15 LoopDispositions: { %loop: Computable }
110 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %a, i64 %iv
111 ; CHECK-NEXT:    --> {((4 * %i) + %a),+,4}<%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
112 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
113 ; CHECK-NEXT:    --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 16 LoopDispositions: { %loop: Computable }
114 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_uge_16_branches_flipped
115 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (15 + (-1 * %i))
116 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 15
117 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (15 + (-1 * %i))
118 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (15 + (-1 * %i))
119 ; CHECK-NEXT:   Predicates:
120 ; CHECK:       Loop %loop: Trip multiple is 1
122 entry:
123   %cmp3 = icmp uge i64 %i, 16
124   br i1 %cmp3, label %exit, label %loop
126 loop:
127   %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
128   %idx = getelementptr inbounds i32, ptr %a, i64 %iv
129   store i32 1, ptr %idx, align 4
130   %iv.next = add nuw nsw i64 %iv, 1
131   %exitcond = icmp eq i64 %iv.next, 16
132   br i1 %exitcond, label %exit, label %loop
134 exit:
135   ret void
138 define void @test_guard_eq_12(ptr nocapture %a, i64 %N) {
139 ; CHECK-LABEL: 'test_guard_eq_12'
140 ; CHECK-NEXT:  Classifying expressions for: @test_guard_eq_12
141 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
142 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: %N LoopDispositions: { %loop: Computable }
143 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %a, i64 %iv
144 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %N) + %a) LoopDispositions: { %loop: Computable }
145 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
146 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,14) S: [1,14) Exits: (1 + %N) LoopDispositions: { %loop: Computable }
147 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_eq_12
148 ; CHECK-NEXT:  Loop %loop: backedge-taken count is %N
149 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 12
150 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is %N
151 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is %N
152 ; CHECK-NEXT:   Predicates:
153 ; CHECK:       Loop %loop: Trip multiple is 13
155 entry:
156   %c.1 = icmp eq i64 %N, 12
157   br i1 %c.1, label %loop, label %exit
159 loop:
160   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
161   %idx = getelementptr inbounds i32, ptr %a, i64 %iv
162   store i32 1, ptr %idx, align 4
163   %iv.next = add nuw nsw i64 %iv, 1
164   %exitcond = icmp eq i64 %iv, %N
165   br i1 %exitcond, label %exit, label %loop
167 exit:
168   ret void
171 define void @test_guard_ule_12(ptr nocapture %a, i64 %N) {
172 ; CHECK-LABEL: 'test_guard_ule_12'
173 ; CHECK-NEXT:  Classifying expressions for: @test_guard_ule_12
174 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
175 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: %N LoopDispositions: { %loop: Computable }
176 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %a, i64 %iv
177 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %N) + %a) LoopDispositions: { %loop: Computable }
178 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
179 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,14) S: [1,14) Exits: (1 + %N) LoopDispositions: { %loop: Computable }
180 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_ule_12
181 ; CHECK-NEXT:  Loop %loop: backedge-taken count is %N
182 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 12
183 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is %N
184 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is %N
185 ; CHECK-NEXT:   Predicates:
186 ; CHECK:       Loop %loop: Trip multiple is 1
188 entry:
189   %c.1 = icmp ule i64 %N, 12
190   br i1 %c.1, label %loop, label %exit
192 loop:
193   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
194   %idx = getelementptr inbounds i32, ptr %a, i64 %iv
195   store i32 1, ptr %idx, align 4
196   %iv.next = add nuw nsw i64 %iv, 1
197   %exitcond = icmp eq i64 %iv, %N
198   br i1 %exitcond, label %exit, label %loop
200 exit:
201   ret void
204 define void @test_guard_ule_12_step2(ptr nocapture %a, i64 %N) {
205 ; CHECK-LABEL: 'test_guard_ule_12_step2'
206 ; CHECK-NEXT:  Classifying expressions for: @test_guard_ule_12_step2
207 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
208 ; CHECK-NEXT:    --> {0,+,2}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (2 * (%N /u 2))<nuw> LoopDispositions: { %loop: Computable }
209 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %a, i64 %iv
210 ; CHECK-NEXT:    --> {%a,+,8}<nuw><%loop> U: full-set S: full-set Exits: ((8 * (%N /u 2)) + %a) LoopDispositions: { %loop: Computable }
211 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 2
212 ; CHECK-NEXT:    --> {2,+,2}<nuw><nsw><%loop> U: [2,15) S: [2,15) Exits: (2 + (2 * (%N /u 2))<nuw>) LoopDispositions: { %loop: Computable }
213 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_ule_12_step2
214 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (%N /u 2)
215 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 6
216 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (%N /u 2)
217 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (%N /u 2)
218 ; CHECK-NEXT:   Predicates:
219 ; CHECK:       Loop %loop: Trip multiple is 1
221 entry:
222   %c.1 = icmp ule i64 %N, 12
223   br i1 %c.1, label %loop, label %exit
225 loop:
226   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
227   %idx = getelementptr inbounds i32, ptr %a, i64 %iv
228   store i32 1, ptr %idx, align 4
229   %iv.next = add nuw nsw i64 %iv, 2
230   %exitcond = icmp eq i64 %iv, %N
231   br i1 %exitcond, label %exit, label %loop
233 exit:
234   ret void
237 define void @test_multiple_const_guards_order1(ptr nocapture %a, i64 %i) {
238 ; CHECK-LABEL: 'test_multiple_const_guards_order1'
239 ; CHECK-NEXT:  Classifying expressions for: @test_multiple_const_guards_order1
240 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
241 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,10) S: [0,10) Exits: %i LoopDispositions: { %loop: Computable }
242 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %a, i64 %iv
243 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
244 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
245 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,11) S: [1,11) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
246 ; CHECK-NEXT:  Determining loop execution counts for: @test_multiple_const_guards_order1
247 ; CHECK-NEXT:  Loop %loop: backedge-taken count is %i
248 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 9
249 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is %i
250 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is %i
251 ; CHECK-NEXT:   Predicates:
252 ; CHECK:       Loop %loop: Trip multiple is 1
254 entry:
255   %c.1 = icmp ult i64 %i, 16
256   br i1 %c.1, label %guardbb, label %exit
258 guardbb:
259   %c.2 = icmp ult i64 %i, 10
260   br i1 %c.2, label %loop, label %exit
262 loop:
263   %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
264   %idx = getelementptr inbounds i32, ptr %a, i64 %iv
265   store i32 1, ptr %idx, align 4
266   %iv.next = add nuw nsw i64 %iv, 1
267   %exitcond = icmp eq i64 %iv, %i
268   br i1 %exitcond, label %exit, label %loop
270 exit:
271   ret void
274 define void @test_multiple_const_guards_order2(ptr nocapture %a, i64 %i) {
275 ; CHECK-LABEL: 'test_multiple_const_guards_order2'
276 ; CHECK-NEXT:  Classifying expressions for: @test_multiple_const_guards_order2
277 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
278 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,10) S: [0,10) Exits: %i LoopDispositions: { %loop: Computable }
279 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %a, i64 %iv
280 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
281 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
282 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,11) S: [1,11) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
283 ; CHECK-NEXT:  Determining loop execution counts for: @test_multiple_const_guards_order2
284 ; CHECK-NEXT:  Loop %loop: backedge-taken count is %i
285 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 9
286 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is %i
287 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is %i
288 ; CHECK-NEXT:   Predicates:
289 ; CHECK:       Loop %loop: Trip multiple is 1
291 entry:
292   %c.1 = icmp ult i64 %i, 10
293   br i1 %c.1, label %guardbb, label %exit
295 guardbb:
296   %c.2 = icmp ult i64 %i, 16
297   br i1 %c.2, label %loop, label %exit
299 loop:
300   %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
301   %idx = getelementptr inbounds i32, ptr %a, i64 %iv
302   store i32 1, ptr %idx, align 4
303   %iv.next = add nuw nsw i64 %iv, 1
304   %exitcond = icmp eq i64 %iv, %i
305   br i1 %exitcond, label %exit, label %loop
307 exit:
308   ret void
311 define void @test_multiple_var_guards_order1(ptr nocapture %a, i64 %i, i64 %N) {
312 ; CHECK-LABEL: 'test_multiple_var_guards_order1'
313 ; CHECK-NEXT:  Classifying expressions for: @test_multiple_var_guards_order1
314 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
315 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,11) S: [0,11) Exits: %i LoopDispositions: { %loop: Computable }
316 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %a, i64 %iv
317 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
318 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
319 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,12) S: [1,12) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
320 ; CHECK-NEXT:  Determining loop execution counts for: @test_multiple_var_guards_order1
321 ; CHECK-NEXT:  Loop %loop: backedge-taken count is %i
322 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 10
323 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is %i
324 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is %i
325 ; CHECK-NEXT:   Predicates:
326 ; CHECK:       Loop %loop: Trip multiple is 1
328 entry:
329   %c.1 = icmp ult i64 %N, 12
330   br i1 %c.1, label %guardbb, label %exit
332 guardbb:
333   %c.2 = icmp ult i64 %i, %N
334   br i1 %c.2, label %loop, label %exit
336 loop:
337   %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
338   %idx = getelementptr inbounds i32, ptr %a, i64 %iv
339   store i32 1, ptr %idx, align 4
340   %iv.next = add nuw nsw i64 %iv, 1
341   %exitcond = icmp eq i64 %iv, %i
342   br i1 %exitcond, label %exit, label %loop
344 exit:
345   ret void
348 define void @test_multiple_var_guards_order2(ptr nocapture %a, i64 %i, i64 %N) {
349 ; CHECK-LABEL: 'test_multiple_var_guards_order2'
350 ; CHECK-NEXT:  Classifying expressions for: @test_multiple_var_guards_order2
351 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
352 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,11) S: [0,11) Exits: %i LoopDispositions: { %loop: Computable }
353 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %a, i64 %iv
354 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
355 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
356 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,12) S: [1,12) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
357 ; CHECK-NEXT:  Determining loop execution counts for: @test_multiple_var_guards_order2
358 ; CHECK-NEXT:  Loop %loop: backedge-taken count is %i
359 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 10
360 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is %i
361 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is %i
362 ; CHECK-NEXT:   Predicates:
363 ; CHECK:       Loop %loop: Trip multiple is 1
365 entry:
366   %c.1 = icmp ult i64 %i, %N
367   br i1 %c.1, label %guardbb, label %exit
369 guardbb:
370   %c.2 = icmp ult i64 %N, 12
371   br i1 %c.2, label %loop, label %exit
373 loop:
374   %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
375   %idx = getelementptr inbounds i32, ptr %a, i64 %iv
376   store i32 1, ptr %idx, align 4
377   %iv.next = add nuw nsw i64 %iv, 1
378   %exitcond = icmp eq i64 %iv, %i
379   br i1 %exitcond, label %exit, label %loop
381 exit:
382   ret void
385 ; The guards here reference each other in a cycle.
386 define void @test_multiple_var_guards_cycle(ptr nocapture %a, i64 %i, i64 %N) {
387 ; CHECK-LABEL: 'test_multiple_var_guards_cycle'
388 ; CHECK-NEXT:  Classifying expressions for: @test_multiple_var_guards_cycle
389 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
390 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,-9223372036854775808) S: [0,-9223372036854775808) Exits: %N LoopDispositions: { %loop: Computable }
391 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %a, i64 %iv
392 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %N) + %a) LoopDispositions: { %loop: Computable }
393 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
394 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,-1) S: [1,-1) Exits: (1 + %N) LoopDispositions: { %loop: Computable }
395 ; CHECK-NEXT:  Determining loop execution counts for: @test_multiple_var_guards_cycle
396 ; CHECK-NEXT:  Loop %loop: backedge-taken count is %N
397 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is -3
398 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is %N
399 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is %N
400 ; CHECK-NEXT:   Predicates:
401 ; CHECK:       Loop %loop: Trip multiple is 1
403 entry:
404   %c.1 = icmp ult i64 %N, %i
405   br i1 %c.1, label %guardbb, label %exit
407 guardbb:
408   %c.2 = icmp ult i64 %i, %N
409   br i1 %c.2, label %loop, label %exit
411 loop:
412   %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
413   %idx = getelementptr inbounds i32, ptr %a, i64 %iv
414   store i32 1, ptr %idx, align 4
415   %iv.next = add nuw nsw i64 %iv, 1
416   %exitcond = icmp eq i64 %iv, %N
417   br i1 %exitcond, label %exit, label %loop
419 exit:
420   ret void
423 define void @test_guard_ult_ne(ptr nocapture readonly %data, i64 %count) {
424 ; CHECK-LABEL: 'test_guard_ult_ne'
425 ; CHECK-NEXT:  Classifying expressions for: @test_guard_ult_ne
426 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
427 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
428 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %data, i64 %iv
429 ; CHECK-NEXT:    --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
430 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
431 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
432 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_ult_ne
433 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
434 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 3
435 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %count)
436 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
437 ; CHECK-NEXT:   Predicates:
438 ; CHECK:       Loop %loop: Trip multiple is 1
440 entry:
441   %cmp.ult = icmp ult i64 %count, 5
442   br i1 %cmp.ult, label %guardbb, label %exit
444 guardbb:
445   %cmp.ne = icmp ne i64 %count, 0
446   br i1 %cmp.ne, label %loop, label %exit
448 loop:
449   %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
450   %idx = getelementptr inbounds i32, ptr %data, i64 %iv
451   store i32 1, ptr %idx, align 4
452   %iv.next = add nuw i64 %iv, 1
453   %exitcond.not = icmp eq i64 %iv.next, %count
454   br i1 %exitcond.not, label %exit, label %loop
456 exit:
457   ret void
460 define void @test_guard_ne_ult(ptr nocapture readonly %data, i64 %count) {
461 ; CHECK-LABEL: 'test_guard_ne_ult'
462 ; CHECK-NEXT:  Classifying expressions for: @test_guard_ne_ult
463 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
464 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
465 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %data, i64 %iv
466 ; CHECK-NEXT:    --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
467 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
468 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
469 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_ne_ult
470 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
471 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 3
472 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %count)
473 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
474 ; CHECK-NEXT:   Predicates:
475 ; CHECK:       Loop %loop: Trip multiple is 1
477 entry:
478   %cmp.ne = icmp ne i64 %count, 0
479   br i1 %cmp.ne, label %guardbb, label %exit
481 guardbb:
482   %cmp.ult = icmp ult i64 %count, 5
483   br i1 %cmp.ult, label %loop, label %exit
485 loop:
486   %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
487   %idx = getelementptr inbounds i32, ptr %data, i64 %iv
488   store i32 1, ptr %idx, align 4
489   %iv.next = add nuw i64 %iv, 1
490   %exitcond.not = icmp eq i64 %iv.next, %count
491   br i1 %exitcond.not, label %exit, label %loop
493 exit:
494   ret void
497 define void @test_guard_if_and_enter(ptr nocapture readonly %data, i64 %count) {
498 ; CHECK-LABEL: 'test_guard_if_and_enter'
499 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_and_enter
500 ; CHECK-NEXT:    %cmp.and = and i1 %cmp.ult, %cmp.ne
501 ; CHECK-NEXT:    --> (%cmp.ult umin %cmp.ne) U: full-set S: full-set
502 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
503 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
504 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %data, i64 %iv
505 ; CHECK-NEXT:    --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
506 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
507 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
508 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_and_enter
509 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
510 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 3
511 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %count)
512 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
513 ; CHECK-NEXT:   Predicates:
514 ; CHECK:       Loop %loop: Trip multiple is 1
516 entry:
517   %cmp.ult = icmp ult i64 %count, 5
518   %cmp.ne = icmp ne i64 %count, 0
519   %cmp.and = and i1 %cmp.ult, %cmp.ne
520   br i1 %cmp.and, label %loop, label %exit
522 loop:
523   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
524   %idx = getelementptr inbounds i32, ptr %data, i64 %iv
525   store i32 1, ptr %idx, align 4
526   %iv.next = add nuw i64 %iv, 1
527   %exitcond.not = icmp eq i64 %iv.next, %count
528   br i1 %exitcond.not, label %exit, label %loop
530 exit:
531   ret void
534 define void @test_guard_if_and_skip(ptr nocapture readonly %data, i64 %count) {
535 ; CHECK-LABEL: 'test_guard_if_and_skip'
536 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_and_skip
537 ; CHECK-NEXT:    %cmp.and = and i1 %cmp.ult, %cmp.ne
538 ; CHECK-NEXT:    --> (%cmp.ult umin %cmp.ne) U: full-set S: full-set
539 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
540 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
541 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %data, i64 %iv
542 ; CHECK-NEXT:    --> {%data,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
543 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
544 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %count LoopDispositions: { %loop: Computable }
545 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_and_skip
546 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
547 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is -1
548 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %count)
549 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
550 ; CHECK-NEXT:   Predicates:
551 ; CHECK:       Loop %loop: Trip multiple is 1
553 entry:
554   %cmp.ult = icmp ult i64 %count, 5
555   %cmp.ne = icmp ne i64 %count, 0
556   %cmp.and = and i1 %cmp.ult, %cmp.ne
557   br i1 %cmp.and, label %exit, label %loop
559 loop:
560   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
561   %idx = getelementptr inbounds i32, ptr %data, i64 %iv
562   store i32 1, ptr %idx, align 4
563   %iv.next = add nuw i64 %iv, 1
564   %exitcond.not = icmp eq i64 %iv.next, %count
565   br i1 %exitcond.not, label %exit, label %loop
567 exit:
568   ret void
571 define void @test_guard_if_and_and(ptr nocapture readonly %data, i64 %count, i1 %c) {
572 ; CHECK-LABEL: 'test_guard_if_and_and'
573 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_and_and
574 ; CHECK-NEXT:    %cmp.and1 = and i1 %c, %cmp.ne
575 ; CHECK-NEXT:    --> (%c umin %cmp.ne) U: full-set S: full-set
576 ; CHECK-NEXT:    %cmp.and = and i1 %cmp.ult, %cmp.and1
577 ; CHECK-NEXT:    --> (%c umin %cmp.ult umin %cmp.ne) U: full-set S: full-set
578 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
579 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
580 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %data, i64 %iv
581 ; CHECK-NEXT:    --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
582 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
583 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
584 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_and_and
585 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
586 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 3
587 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %count)
588 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
589 ; CHECK-NEXT:   Predicates:
590 ; CHECK:       Loop %loop: Trip multiple is 1
592 entry:
593   %cmp.ult = icmp ult i64 %count, 5
594   %cmp.ne = icmp ne i64 %count, 0
595   %cmp.and1 = and i1 %c, %cmp.ne
596   %cmp.and = and i1 %cmp.ult, %cmp.and1
597   br i1 %cmp.and, label %loop, label %exit
599 loop:
600   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
601   %idx = getelementptr inbounds i32, ptr %data, i64 %iv
602   store i32 1, ptr %idx, align 4
603   %iv.next = add nuw i64 %iv, 1
604   %exitcond.not = icmp eq i64 %iv.next, %count
605   br i1 %exitcond.not, label %exit, label %loop
607 exit:
608   ret void
611 define void @test_guard_if_and_or(ptr nocapture readonly %data, i64 %count, i1 %c) {
612 ; CHECK-LABEL: 'test_guard_if_and_or'
613 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_and_or
614 ; CHECK-NEXT:    %cmp.or = or i1 %c, %cmp.ne
615 ; CHECK-NEXT:    --> (%c umax %cmp.ne) U: full-set S: full-set
616 ; CHECK-NEXT:    %cmp.and = and i1 %cmp.ult, %cmp.or
617 ; CHECK-NEXT:    --> ((%c umax %cmp.ne) umin %cmp.ult) U: full-set S: full-set
618 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
619 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
620 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %data, i64 %iv
621 ; CHECK-NEXT:    --> {%data,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
622 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
623 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %count LoopDispositions: { %loop: Computable }
624 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_and_or
625 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
626 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is -1
627 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %count)
628 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
629 ; CHECK-NEXT:   Predicates:
630 ; CHECK:       Loop %loop: Trip multiple is 1
632 entry:
633   %cmp.ult = icmp ult i64 %count, 5
634   %cmp.ne = icmp ne i64 %count, 0
635   %cmp.or = or i1 %c, %cmp.ne
636   %cmp.and = and i1 %cmp.ult, %cmp.or
637   br i1 %cmp.and, label %loop, label %exit
639 loop:
640   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
641   %idx = getelementptr inbounds i32, ptr %data, i64 %iv
642   store i32 1, ptr %idx, align 4
643   %iv.next = add nuw i64 %iv, 1
644   %exitcond.not = icmp eq i64 %iv.next, %count
645   br i1 %exitcond.not, label %exit, label %loop
647 exit:
648   ret void
651 define void @test_guard_if_or_skip(ptr nocapture readonly %data, i64 %count) {
652 ; CHECK-LABEL: 'test_guard_if_or_skip'
653 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_or_skip
654 ; CHECK-NEXT:    %cmp.or = or i1 %cmp.uge, %cmp.eq
655 ; CHECK-NEXT:    --> (%cmp.uge umax %cmp.eq) U: full-set S: full-set
656 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
657 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
658 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %data, i64 %iv
659 ; CHECK-NEXT:    --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
660 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
661 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
662 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_or_skip
663 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
664 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 3
665 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %count)
666 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
667 ; CHECK-NEXT:   Predicates:
668 ; CHECK:       Loop %loop: Trip multiple is 1
670 entry:
671   %cmp.uge = icmp uge i64 %count, 5
672   %cmp.eq = icmp eq i64 %count, 0
673   %cmp.or = or i1 %cmp.uge, %cmp.eq
674   br i1 %cmp.or, label %exit, label %loop
676 loop:
677   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
678   %idx = getelementptr inbounds i32, ptr %data, i64 %iv
679   store i32 1, ptr %idx, align 4
680   %iv.next = add nuw i64 %iv, 1
681   %exitcond.not = icmp eq i64 %iv.next, %count
682   br i1 %exitcond.not, label %exit, label %loop
684 exit:
685   ret void
688 define void @test_guard_if_or_enter(ptr nocapture readonly %data, i64 %count) {
689 ; CHECK-LABEL: 'test_guard_if_or_enter'
690 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_or_enter
691 ; CHECK-NEXT:    %cmp.or = or i1 %cmp.uge, %cmp.eq
692 ; CHECK-NEXT:    --> (%cmp.uge umax %cmp.eq) U: full-set S: full-set
693 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
694 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
695 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %data, i64 %iv
696 ; CHECK-NEXT:    --> {%data,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
697 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
698 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %count LoopDispositions: { %loop: Computable }
699 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_or_enter
700 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
701 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is -1
702 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %count)
703 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
704 ; CHECK-NEXT:   Predicates:
705 ; CHECK:       Loop %loop: Trip multiple is 1
707 entry:
708   %cmp.uge = icmp uge i64 %count, 5
709   %cmp.eq = icmp eq i64 %count, 0
710   %cmp.or = or i1 %cmp.uge, %cmp.eq
711   br i1 %cmp.or, label %loop, label %exit
713 loop:
714   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
715   %idx = getelementptr inbounds i32, ptr %data, i64 %iv
716   store i32 1, ptr %idx, align 4
717   %iv.next = add nuw i64 %iv, 1
718   %exitcond.not = icmp eq i64 %iv.next, %count
719   br i1 %exitcond.not, label %exit, label %loop
721 exit:
722   ret void
725 define void @test_guard_if_or_or(ptr nocapture readonly %data, i64 %count, i1 %c) {
726 ; CHECK-LABEL: 'test_guard_if_or_or'
727 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_or_or
728 ; CHECK-NEXT:    %cmp.or1 = or i1 %c, %cmp.eq
729 ; CHECK-NEXT:    --> (%c umax %cmp.eq) U: full-set S: full-set
730 ; CHECK-NEXT:    %cmp.or = or i1 %cmp.uge, %cmp.or1
731 ; CHECK-NEXT:    --> (%c umax %cmp.uge umax %cmp.eq) U: full-set S: full-set
732 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
733 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
734 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %data, i64 %iv
735 ; CHECK-NEXT:    --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
736 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
737 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
738 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_or_or
739 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
740 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 3
741 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %count)
742 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
743 ; CHECK-NEXT:   Predicates:
744 ; CHECK:       Loop %loop: Trip multiple is 1
746 entry:
747   %cmp.uge = icmp uge i64 %count, 5
748   %cmp.eq = icmp eq i64 %count, 0
749   %cmp.or1 = or i1 %c, %cmp.eq
750   %cmp.or = or i1 %cmp.uge, %cmp.or1
751   br i1 %cmp.or, label %exit, label %loop
753 loop:
754   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
755   %idx = getelementptr inbounds i32, ptr %data, i64 %iv
756   store i32 1, ptr %idx, align 4
757   %iv.next = add nuw i64 %iv, 1
758   %exitcond.not = icmp eq i64 %iv.next, %count
759   br i1 %exitcond.not, label %exit, label %loop
761 exit:
762   ret void
765 define void @test_guard_if_or_and(ptr nocapture readonly %data, i64 %count, i1 %c) {
766 ; CHECK-LABEL: 'test_guard_if_or_and'
767 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_or_and
768 ; CHECK-NEXT:    %cmp.and = and i1 %c, %cmp.eq
769 ; CHECK-NEXT:    --> (%c umin %cmp.eq) U: full-set S: full-set
770 ; CHECK-NEXT:    %cmp.or = or i1 %cmp.uge, %cmp.and
771 ; CHECK-NEXT:    --> ((%c umin %cmp.eq) umax %cmp.uge) U: full-set S: full-set
772 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
773 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
774 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %data, i64 %iv
775 ; CHECK-NEXT:    --> {%data,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
776 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
777 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %count LoopDispositions: { %loop: Computable }
778 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_or_and
779 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
780 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is -1
781 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %count)
782 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
783 ; CHECK-NEXT:   Predicates:
784 ; CHECK:       Loop %loop: Trip multiple is 1
786 entry:
787   %cmp.uge = icmp uge i64 %count, 5
788   %cmp.eq = icmp eq i64 %count, 0
789   %cmp.and = and i1 %c, %cmp.eq
790   %cmp.or = or i1 %cmp.uge, %cmp.and
791   br i1 %cmp.or, label %exit, label %loop
793 loop:
794   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
795   %idx = getelementptr inbounds i32, ptr %data, i64 %iv
796   store i32 1, ptr %idx, align 4
797   %iv.next = add nuw i64 %iv, 1
798   %exitcond.not = icmp eq i64 %iv.next, %count
799   br i1 %exitcond.not, label %exit, label %loop
801 exit:
802   ret void
805 ; Test case for PR47247. Both the guard condition and the assume limit the
806 ; constant max backedge-taken count.
808 define void @test_guard_and_assume(ptr nocapture readonly %data, i64 %count) {
809 ; CHECK-LABEL: 'test_guard_and_assume'
810 ; CHECK-NEXT:  Classifying expressions for: @test_guard_and_assume
811 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
812 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
813 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %data, i64 %iv
814 ; CHECK-NEXT:    --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
815 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
816 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
817 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_and_assume
818 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
819 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 3
820 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %count)
821 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
822 ; CHECK-NEXT:   Predicates:
823 ; CHECK:       Loop %loop: Trip multiple is 1
825 entry:
826   %cmp = icmp ult i64 %count, 5
827   tail call void @llvm.assume(i1 %cmp)
828   %cmp18.not = icmp eq i64 %count, 0
829   br i1 %cmp18.not, label %exit, label %loop
831 loop:
832   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
833   %idx = getelementptr inbounds i32, ptr %data, i64 %iv
834   store i32 1, ptr %idx, align 4
835   %iv.next = add nuw i64 %iv, 1
836   %exitcond.not = icmp eq i64 %iv.next, %count
837   br i1 %exitcond.not, label %exit, label %loop
839 exit:
840   ret void
843 define void @test_guard_assume_and(ptr nocapture readonly %data, i64 %count) {
844 ; CHECK-LABEL: 'test_guard_assume_and'
845 ; CHECK-NEXT:  Classifying expressions for: @test_guard_assume_and
846 ; CHECK-NEXT:    %cmp.and = and i1 %cmp.ult, %cmp.ne
847 ; CHECK-NEXT:    --> (%cmp.ult umin %cmp.ne) U: full-set S: full-set
848 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
849 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
850 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %data, i64 %iv
851 ; CHECK-NEXT:    --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
852 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
853 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
854 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_assume_and
855 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
856 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 3
857 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %count)
858 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
859 ; CHECK-NEXT:   Predicates:
860 ; CHECK:       Loop %loop: Trip multiple is 1
862 entry:
863   %cmp.ult = icmp ult i64 %count, 5
864   %cmp.ne = icmp ne i64 %count, 0
865   %cmp.and = and i1 %cmp.ult, %cmp.ne
866   call void @llvm.assume(i1 %cmp.and)
867   br label %loop
869 loop:
870   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
871   %idx = getelementptr inbounds i32, ptr %data, i64 %iv
872   store i32 1, ptr %idx, align 4
873   %iv.next = add nuw i64 %iv, 1
874   %exitcond.not = icmp eq i64 %iv.next, %count
875   br i1 %exitcond.not, label %exit, label %loop
877 exit:
878   ret void
881 ; Function Attrs: nounwind willreturn
882 declare void @llvm.assume(i1 noundef)
884 define void @guard_pessimizes_analysis_step1(i1 %c, i32 %N) {
885 ; CHECK-LABEL: 'guard_pessimizes_analysis_step1'
886 ; CHECK-NEXT:  Classifying expressions for: @guard_pessimizes_analysis_step1
887 ; CHECK-NEXT:    %init = phi i32 [ 2, %entry ], [ 3, %bb1 ]
888 ; CHECK-NEXT:    --> %init U: [2,4) S: [2,4)
889 ; CHECK-NEXT:    %iv = phi i32 [ %iv.next, %loop ], [ %init, %loop.ph ]
890 ; CHECK-NEXT:    --> {%init,+,1}<nuw><nsw><%loop> U: [2,11) S: [2,11) Exits: 9 LoopDispositions: { %loop: Computable }
891 ; CHECK-NEXT:    %iv.next = add i32 %iv, 1
892 ; CHECK-NEXT:    --> {(1 + %init)<nuw><nsw>,+,1}<nuw><nsw><%loop> U: [3,12) S: [3,12) Exits: 10 LoopDispositions: { %loop: Computable }
893 ; CHECK-NEXT:  Determining loop execution counts for: @guard_pessimizes_analysis_step1
894 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (9 + (-1 * %init)<nsw>)<nsw>
895 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 7
896 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (9 + (-1 * %init)<nsw>)<nsw>
897 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (9 + (-1 * %init)<nsw>)<nsw>
898 ; CHECK-NEXT:   Predicates:
899 ; CHECK:       Loop %loop: Trip multiple is 1
901 entry:
902   br i1 %c, label %bb1, label %guard
904 bb1:
905   br label %guard
907 guard:
908   %init = phi i32 [ 2, %entry ], [ 3, %bb1 ]
909   %c.1 = icmp ult i32 %init, %N
910   br i1 %c.1, label %loop.ph, label %exit
912 loop.ph:
913   br label %loop
915 loop:
916   %iv = phi i32 [ %iv.next, %loop ], [ %init, %loop.ph ]
917   %iv.next = add i32 %iv, 1
918   %exitcond = icmp eq i32 %iv.next, 10
919   br i1 %exitcond, label %exit, label %loop
921 exit:
922   ret void
925 define void @guard_pessimizes_analysis_step2(i1 %c, i32 %N) {
926 ; CHECK-LABEL: 'guard_pessimizes_analysis_step2'
927 ; CHECK-NEXT:  Classifying expressions for: @guard_pessimizes_analysis_step2
928 ; CHECK-NEXT:    %init = phi i32 [ 2, %entry ], [ 3, %bb1 ]
929 ; CHECK-NEXT:    --> %init U: [2,4) S: [2,4)
930 ; CHECK-NEXT:    %iv = phi i32 [ %iv.next, %loop ], [ %init, %loop.ph ]
931 ; 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 }
932 ; CHECK-NEXT:    %iv.next = add nuw nsw i32 %iv, 2
933 ; 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 }
934 ; CHECK-NEXT:  Determining loop execution counts for: @guard_pessimizes_analysis_step2
935 ; CHECK-NEXT:  Loop %loop: backedge-taken count is ((8 + (-1 * %init)<nsw>)<nsw> /u 2)
936 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 3
937 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is ((8 + (-1 * %init)<nsw>)<nsw> /u 2)
938 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is ((8 + (-1 * %init)<nsw>)<nsw> /u 2)
939 ; CHECK-NEXT:   Predicates:
940 ; CHECK:       Loop %loop: Trip multiple is 1
942 entry:
943   br i1 %c, label %bb1, label %guard
945 bb1:
946   br label %guard
948 guard:
949   %init = phi i32 [ 2, %entry ], [ 3, %bb1 ]
950   %c.1 = icmp ult i32 %init, %N
951   br i1 %c.1, label %loop.ph, label %exit
953 loop.ph:
954   br label %loop
956 loop:
957   %iv = phi i32 [ %iv.next, %loop ], [ %init, %loop.ph ]
958   %iv.next = add nuw nsw i32 %iv, 2
959   %exitcond = icmp eq i32 %iv.next, 10
960   br i1 %exitcond, label %exit, label %loop
962 exit:
963   ret void
965 define void @crash(ptr %ptr) {
966 ; CHECK-LABEL: 'crash'
967 ; CHECK-NEXT:  Classifying expressions for: @crash
968 ; CHECK-NEXT:    %text.addr.5 = phi ptr [ %incdec.ptr112, %while.cond111 ], [ null, %while.body ]
969 ; CHECK-NEXT:    --> {null,+,-1}<nw><%while.cond111> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %while.cond111: Computable, %while.body: Variant }
970 ; CHECK-NEXT:    %incdec.ptr112 = getelementptr inbounds i8, ptr %text.addr.5, i64 -1
971 ; 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 }
972 ; CHECK-NEXT:    %lastout.2271 = phi ptr [ %incdec.ptr126, %while.body125 ], [ %ptr, %while.end117 ]
973 ; 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 }
974 ; CHECK-NEXT:    %incdec.ptr126 = getelementptr inbounds i8, ptr %lastout.2271, i64 1
975 ; 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 }
976 ; CHECK-NEXT:  Determining loop execution counts for: @crash
977 ; CHECK-NEXT:  Loop %while.body125: backedge-taken count is {(-2 + (-1 * (ptrtoint ptr %ptr to i64))),+,-1}<nw><%while.cond111>
978 ; CHECK-NEXT:  Loop %while.body125: constant max backedge-taken count is -2
979 ; CHECK-NEXT:  Loop %while.body125: symbolic max backedge-taken count is {(-2 + (-1 * (ptrtoint ptr %ptr to i64))),+,-1}<nw><%while.cond111>
980 ; CHECK-NEXT:  Loop %while.body125: Predicated backedge-taken count is {(-2 + (-1 * (ptrtoint ptr %ptr to i64))),+,-1}<nw><%while.cond111>
981 ; CHECK-NEXT:   Predicates:
982 ; CHECK:       Loop %while.body125: Trip multiple is 1
983 ; CHECK-NEXT:  Loop %while.cond111: Unpredictable backedge-taken count.
984 ; CHECK-NEXT:  Loop %while.cond111: Unpredictable constant max backedge-taken count.
985 ; CHECK-NEXT:  Loop %while.cond111: Unpredictable symbolic max backedge-taken count.
986 ; CHECK-NEXT:  Loop %while.cond111: Unpredictable predicated backedge-taken count.
987 ; CHECK-NEXT:  Loop %while.body: Unpredictable backedge-taken count.
988 ; CHECK-NEXT:  Loop %while.body: Unpredictable constant max backedge-taken count.
989 ; CHECK-NEXT:  Loop %while.body: Unpredictable symbolic max backedge-taken count.
990 ; CHECK-NEXT:  Loop %while.body: Unpredictable predicated backedge-taken count.
992 entry:
993   br label %while.body
995 while.body:
996   br label %while.cond111
998 while.cond111:
999   %text.addr.5 = phi ptr [ %incdec.ptr112, %while.cond111 ], [ null, %while.body ]
1000   %incdec.ptr112 = getelementptr inbounds i8, ptr %text.addr.5, i64 -1
1001   br i1 false, label %while.end117, label %while.cond111
1003 while.end117:
1004   %cmp118 = icmp ult ptr %ptr, %incdec.ptr112
1005   br i1 %cmp118, label %while.body125, label %while.cond134.preheader
1008 while.cond134.preheader:
1009   br label %while.body
1011 while.body125:
1012   %lastout.2271 = phi ptr [ %incdec.ptr126, %while.body125 ], [ %ptr, %while.end117 ]
1013   %incdec.ptr126 = getelementptr inbounds i8, ptr %lastout.2271, i64 1
1014   %exitcond.not = icmp eq ptr %incdec.ptr126, %incdec.ptr112
1015   br i1 %exitcond.not, label %while.end129, label %while.body125
1017 while.end129:                                     ; preds = %while.body125
1018   ret void
1021 define void @test_guard_uge(i32 %blockSize) {
1022 ; CHECK-LABEL: 'test_guard_uge'
1023 ; CHECK-NEXT:  Classifying expressions for: @test_guard_uge
1024 ; CHECK-NEXT:    %shr = lshr i32 %blockSize, 2
1025 ; CHECK-NEXT:    --> (%blockSize /u 4) U: [0,1073741824) S: [0,1073741824)
1026 ; CHECK-NEXT:    %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1027 ; CHECK-NEXT:    --> {(%blockSize /u 4),+,-1}<nsw><%while.body> U: [-1073741822,1073741824) S: [-1073741822,1073741824) Exits: 1 LoopDispositions: { %while.body: Computable }
1028 ; CHECK-NEXT:    %dec = add i32 %iv, -1
1029 ; CHECK-NEXT:    --> {(-1 + (%blockSize /u 4))<nsw>,+,-1}<nsw><%while.body> U: [-1073741823,1073741823) S: [-1073741823,1073741823) Exits: 0 LoopDispositions: { %while.body: Computable }
1030 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_uge
1031 ; CHECK-NEXT:  Loop %while.body: backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1032 ; CHECK-NEXT:  Loop %while.body: constant max backedge-taken count is 1073741822
1033 ; CHECK-NEXT:  Loop %while.body: symbolic max backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1034 ; CHECK-NEXT:  Loop %while.body: Predicated backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1035 ; CHECK-NEXT:   Predicates:
1036 ; CHECK:       Loop %while.body: Trip multiple is 1
1038   %shr = lshr i32 %blockSize, 2
1039   %guard = icmp uge i32 %blockSize, 4
1040   br i1 %guard, label %while.body.preheader, label %while.end
1042 while.body.preheader:
1043   br label %while.body
1045 while.body:
1046   %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1047   %dec = add i32 %iv, -1
1048   %cmp.not = icmp eq i32 %dec, 0
1049   br i1 %cmp.not, label %while.end.loopexit, label %while.body
1051 while.end.loopexit:
1052   br label %while.end
1054 while.end:
1055   ret void
1058 define void @test_guard_ugt(i32 %blockSize) {
1059 ; CHECK-LABEL: 'test_guard_ugt'
1060 ; CHECK-NEXT:  Classifying expressions for: @test_guard_ugt
1061 ; CHECK-NEXT:    %shr = lshr i32 %blockSize, 2
1062 ; CHECK-NEXT:    --> (%blockSize /u 4) U: [0,1073741824) S: [0,1073741824)
1063 ; CHECK-NEXT:    %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1064 ; CHECK-NEXT:    --> {(%blockSize /u 4),+,-1}<nsw><%while.body> U: [-1073741822,1073741824) S: [-1073741822,1073741824) Exits: 1 LoopDispositions: { %while.body: Computable }
1065 ; CHECK-NEXT:    %dec = add i32 %iv, -1
1066 ; CHECK-NEXT:    --> {(-1 + (%blockSize /u 4))<nsw>,+,-1}<nsw><%while.body> U: [-1073741823,1073741823) S: [-1073741823,1073741823) Exits: 0 LoopDispositions: { %while.body: Computable }
1067 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_ugt
1068 ; CHECK-NEXT:  Loop %while.body: backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1069 ; CHECK-NEXT:  Loop %while.body: constant max backedge-taken count is 1073741822
1070 ; CHECK-NEXT:  Loop %while.body: symbolic max backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1071 ; CHECK-NEXT:  Loop %while.body: Predicated backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1072 ; CHECK-NEXT:   Predicates:
1073 ; CHECK:       Loop %while.body: Trip multiple is 1
1075   %shr = lshr i32 %blockSize, 2
1076   %guard = icmp ugt i32 %blockSize, 3
1077   br i1 %guard, label %while.body.preheader, label %while.end
1079 while.body.preheader:
1080   br label %while.body
1082 while.body:
1083   %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1084   %dec = add i32 %iv, -1
1085   %cmp.not = icmp eq i32 %dec, 0
1086   br i1 %cmp.not, label %while.end.loopexit, label %while.body
1088 while.end.loopexit:
1089   br label %while.end
1091 while.end:
1092   ret void
1095 define void @test_guard_uge_and_ule(i32 %blockSize) {
1096 ; CHECK-LABEL: 'test_guard_uge_and_ule'
1097 ; CHECK-NEXT:  Classifying expressions for: @test_guard_uge_and_ule
1098 ; CHECK-NEXT:    %shr = lshr i32 %blockSize, 2
1099 ; CHECK-NEXT:    --> (%blockSize /u 4) U: [0,1073741824) S: [0,1073741824)
1100 ; CHECK-NEXT:    %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1101 ; CHECK-NEXT:    --> {(%blockSize /u 4),+,-1}<nsw><%while.body> U: [-255,1073741824) S: [-255,1073741824) Exits: 1 LoopDispositions: { %while.body: Computable }
1102 ; CHECK-NEXT:    %dec = add i32 %iv, -1
1103 ; CHECK-NEXT:    --> {(-1 + (%blockSize /u 4))<nsw>,+,-1}<nsw><%while.body> U: [-256,1073741823) S: [-256,1073741823) Exits: 0 LoopDispositions: { %while.body: Computable }
1104 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_uge_and_ule
1105 ; CHECK-NEXT:  Loop %while.body: backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1106 ; CHECK-NEXT:  Loop %while.body: constant max backedge-taken count is 255
1107 ; CHECK-NEXT:  Loop %while.body: symbolic max backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1108 ; CHECK-NEXT:  Loop %while.body: Predicated backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1109 ; CHECK-NEXT:   Predicates:
1110 ; CHECK:       Loop %while.body: Trip multiple is 1
1112   %shr = lshr i32 %blockSize, 2
1113   %guard1 = icmp uge i32 %blockSize, 4
1114   br i1 %guard1, label %while.guard, label %while.end
1116 while.guard:
1117   %guard2 = icmp ule i32 %blockSize, 1024
1118   br i1 %guard2, label %while.body.preheader, label %while.end
1120 while.body.preheader:
1121   br label %while.body
1123 while.body:
1124   %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1125   %dec = add i32 %iv, -1
1126   %cmp.not = icmp eq i32 %dec, 0
1127   br i1 %cmp.not, label %while.end.loopexit, label %while.body
1129 while.end.loopexit:
1130   br label %while.end
1132 while.end:
1133   ret void
1136 define void @test_guard_ugt_and_ult(i32 %blockSize) {
1137 ; CHECK-LABEL: 'test_guard_ugt_and_ult'
1138 ; CHECK-NEXT:  Classifying expressions for: @test_guard_ugt_and_ult
1139 ; CHECK-NEXT:    %shr = lshr i32 %blockSize, 2
1140 ; CHECK-NEXT:    --> (%blockSize /u 4) U: [0,1073741824) S: [0,1073741824)
1141 ; CHECK-NEXT:    %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1142 ; CHECK-NEXT:    --> {(%blockSize /u 4),+,-1}<nsw><%while.body> U: [-255,1073741824) S: [-255,1073741824) Exits: 1 LoopDispositions: { %while.body: Computable }
1143 ; CHECK-NEXT:    %dec = add i32 %iv, -1
1144 ; CHECK-NEXT:    --> {(-1 + (%blockSize /u 4))<nsw>,+,-1}<nsw><%while.body> U: [-256,1073741823) S: [-256,1073741823) Exits: 0 LoopDispositions: { %while.body: Computable }
1145 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_ugt_and_ult
1146 ; CHECK-NEXT:  Loop %while.body: backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1147 ; CHECK-NEXT:  Loop %while.body: constant max backedge-taken count is 255
1148 ; CHECK-NEXT:  Loop %while.body: symbolic max backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1149 ; CHECK-NEXT:  Loop %while.body: Predicated backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1150 ; CHECK-NEXT:   Predicates:
1151 ; CHECK:       Loop %while.body: Trip multiple is 1
1153   %shr = lshr i32 %blockSize, 2
1154   %guard1 = icmp ugt i32 %blockSize, 3
1155   br i1 %guard1, label %while.guard, label %while.end
1157 while.guard:
1158   %guard2 = icmp ult i32 %blockSize, 1025
1159   br i1 %guard2, label %while.body.preheader, label %while.end
1161 while.body.preheader:
1162   br label %while.body
1164 while.body:
1165   %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1166   %dec = add i32 %iv, -1
1167   %cmp.not = icmp eq i32 %dec, 0
1168   br i1 %cmp.not, label %while.end.loopexit, label %while.body
1170 while.end.loopexit:
1171   br label %while.end
1173 while.end:
1174   ret void
1177 define void @test_guard_slt_sgt_1(ptr nocapture %a, i64 %N) {
1178 ; CHECK-LABEL: 'test_guard_slt_sgt_1'
1179 ; CHECK-NEXT:  Classifying expressions for: @test_guard_slt_sgt_1
1180 ; CHECK-NEXT:    %and = and i1 %c.0, %c.1
1181 ; CHECK-NEXT:    --> (%c.0 umin %c.1) U: full-set S: full-set
1182 ; CHECK-NEXT:    %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
1183 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,11) S: [0,11) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1184 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %a, i64 %iv
1185 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %N) + %a) LoopDispositions: { %loop: Computable }
1186 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
1187 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,12) S: [1,12) Exits: %N LoopDispositions: { %loop: Computable }
1188 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_slt_sgt_1
1189 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %N)
1190 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 10
1191 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %N)
1192 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %N)
1193 ; CHECK-NEXT:   Predicates:
1194 ; CHECK:       Loop %loop: Trip multiple is 1
1196 entry:
1197   %c.0 = icmp slt i64 %N, 12
1198   %c.1 = icmp sgt i64 %N, 0
1199   %and = and i1 %c.0, %c.1
1200   br i1 %and, label %loop, label %exit
1202 loop:
1203   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
1204   %idx = getelementptr inbounds i32, ptr %a, i64 %iv
1205   store i32 1, ptr %idx, align 4
1206   %iv.next = add nuw nsw i64 %iv, 1
1207   %exitcond = icmp eq i64 %iv.next, %N
1208   br i1 %exitcond, label %exit, label %loop
1210 exit:
1211   ret void
1214 define void @test_guard_slt_sgt_2(ptr nocapture %a, i64 %i) {
1215 ; CHECK-LABEL: 'test_guard_slt_sgt_2'
1216 ; CHECK-NEXT:  Classifying expressions for: @test_guard_slt_sgt_2
1217 ; CHECK-NEXT:    %and = and i1 %c.0, %c.1
1218 ; CHECK-NEXT:    --> (%c.0 umin %c.1) U: full-set S: full-set
1219 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
1220 ; CHECK-NEXT:    --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 17 LoopDispositions: { %loop: Computable }
1221 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %a, i64 %iv
1222 ; CHECK-NEXT:    --> {((4 * %i) + %a),+,4}<%loop> U: full-set S: full-set Exits: (68 + %a) LoopDispositions: { %loop: Computable }
1223 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
1224 ; CHECK-NEXT:    --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 18 LoopDispositions: { %loop: Computable }
1225 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_slt_sgt_2
1226 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (17 + (-1 * %i))
1227 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 12
1228 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (17 + (-1 * %i))
1229 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (17 + (-1 * %i))
1230 ; CHECK-NEXT:   Predicates:
1231 ; CHECK:       Loop %loop: Trip multiple is 1
1233 entry:
1234   %c.0 = icmp slt i64 %i, 16
1235   %c.1 = icmp sgt i64 %i, 4
1236   %and = and i1 %c.0, %c.1
1237   br i1 %and, label %loop, label %exit
1239 loop:
1240   %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
1241   %idx = getelementptr inbounds i32, ptr %a, i64 %iv
1242   store i32 1, ptr %idx, align 4
1243   %iv.next = add nuw nsw i64 %iv, 1
1244   %exitcond = icmp eq i64 %iv.next, 18
1245   br i1 %exitcond, label %exit, label %loop
1247 exit:
1248   ret void
1251 define void @test_guard_sle_sge_1(ptr nocapture %a, i64 %N) {
1252 ; CHECK-LABEL: 'test_guard_sle_sge_1'
1253 ; CHECK-NEXT:  Classifying expressions for: @test_guard_sle_sge_1
1254 ; CHECK-NEXT:    %and = and i1 %c.0, %c.1
1255 ; CHECK-NEXT:    --> (%c.0 umin %c.1) U: full-set S: full-set
1256 ; CHECK-NEXT:    %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
1257 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,12) S: [0,12) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1258 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %a, i64 %iv
1259 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %N) + %a) LoopDispositions: { %loop: Computable }
1260 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
1261 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,13) S: [1,13) Exits: %N LoopDispositions: { %loop: Computable }
1262 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_sle_sge_1
1263 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %N)
1264 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 11
1265 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %N)
1266 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %N)
1267 ; CHECK-NEXT:   Predicates:
1268 ; CHECK:       Loop %loop: Trip multiple is 1
1270 entry:
1271   %c.0 = icmp sle i64 %N, 12
1272   %c.1 = icmp sge i64 %N, 1
1273   %and = and i1 %c.0, %c.1
1274   br i1 %and, label %loop, label %exit
1276 loop:
1277   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
1278   %idx = getelementptr inbounds i32, ptr %a, i64 %iv
1279   store i32 1, ptr %idx, align 4
1280   %iv.next = add nuw nsw i64 %iv, 1
1281   %exitcond = icmp eq i64 %iv.next, %N
1282   br i1 %exitcond, label %exit, label %loop
1284 exit:
1285   ret void
1288 define void @test_guard_sle_sge_2(ptr nocapture %a, i64 %i) {
1289 ; CHECK-LABEL: 'test_guard_sle_sge_2'
1290 ; CHECK-NEXT:  Classifying expressions for: @test_guard_sle_sge_2
1291 ; CHECK-NEXT:    %and = and i1 %c.0, %c.1
1292 ; CHECK-NEXT:    --> (%c.0 umin %c.1) U: full-set S: full-set
1293 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
1294 ; CHECK-NEXT:    --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 17 LoopDispositions: { %loop: Computable }
1295 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, ptr %a, i64 %iv
1296 ; CHECK-NEXT:    --> {((4 * %i) + %a),+,4}<%loop> U: full-set S: full-set Exits: (68 + %a) LoopDispositions: { %loop: Computable }
1297 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
1298 ; CHECK-NEXT:    --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 18 LoopDispositions: { %loop: Computable }
1299 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_sle_sge_2
1300 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (17 + (-1 * %i))
1301 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 13
1302 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (17 + (-1 * %i))
1303 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (17 + (-1 * %i))
1304 ; CHECK-NEXT:   Predicates:
1305 ; CHECK:       Loop %loop: Trip multiple is 1
1307 entry:
1308   %c.0 = icmp sle i64 %i, 16
1309   %c.1 = icmp sge i64 %i, 4
1310   %and = and i1 %c.0, %c.1
1311   br i1 %and, label %loop, label %exit
1313 loop:
1314   %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
1315   %idx = getelementptr inbounds i32, ptr %a, i64 %iv
1316   store i32 1, ptr %idx, align 4
1317   %iv.next = add nuw nsw i64 %iv, 1
1318   %exitcond = icmp eq i64 %iv.next, 18
1319   br i1 %exitcond, label %exit, label %loop
1321 exit:
1322   ret void
1325 ; The function below uses a single condition to ensure %N > 0 && %N < 8.
1326 ; InstCombine transforms such checks with 2 conditions to a single check as in
1327 ; the test function.
1328 define void @optimized_range_check_unsigned(ptr %pred, i32 %N) {
1329 ; CHECK-LABEL: 'optimized_range_check_unsigned'
1330 ; CHECK-NEXT:  Classifying expressions for: @optimized_range_check_unsigned
1331 ; CHECK-NEXT:    %N.off = add i32 %N, -1
1332 ; CHECK-NEXT:    --> (-1 + %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,7) S: [0,7) 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,8) S: [1,8) Exits: %N LoopDispositions: { %loop: Computable }
1339 ; CHECK-NEXT:  Determining loop execution counts for: @optimized_range_check_unsigned
1340 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %N)
1341 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 6
1342 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %N)
1343 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %N)
1344 ; CHECK-NEXT:   Predicates:
1345 ; CHECK:       Loop %loop: Trip multiple is 1
1347 entry:
1348   %N.off = add i32 %N, -1
1349   %cmp = icmp ult i32 %N.off, 7
1350   br i1 %cmp, label %loop, label %exit
1352 loop:
1353   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1354   %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
1355   store i16 0, ptr %gep, align 2
1356   %iv.next = add nuw nsw i32 %iv, 1
1357   %ec = icmp eq i32 %iv.next, %N
1358   br i1 %ec, label %exit, label %loop
1360 exit:
1361   ret void
1364 ; Same as @optimized_range_check_unsigned, but with the icmp operands swapped.
1365 define void @optimized_range_check_unsigned_icmp_ops_swapped(ptr %pred, i32 %N) {
1366 ; CHECK-LABEL: 'optimized_range_check_unsigned_icmp_ops_swapped'
1367 ; CHECK-NEXT:  Classifying expressions for: @optimized_range_check_unsigned_icmp_ops_swapped
1368 ; CHECK-NEXT:    %N.off = add i32 %N, -1
1369 ; CHECK-NEXT:    --> (-1 + %N) U: full-set S: full-set
1370 ; CHECK-NEXT:    %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1371 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,7) S: [0,7) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1372 ; CHECK-NEXT:    %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
1373 ; 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 }
1374 ; CHECK-NEXT:    %iv.next = add nuw nsw i32 %iv, 1
1375 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,8) S: [1,8) Exits: %N LoopDispositions: { %loop: Computable }
1376 ; CHECK-NEXT:  Determining loop execution counts for: @optimized_range_check_unsigned_icmp_ops_swapped
1377 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %N)
1378 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 6
1379 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %N)
1380 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %N)
1381 ; CHECK-NEXT:   Predicates:
1382 ; CHECK:       Loop %loop: Trip multiple is 1
1384 entry:
1385   %N.off = add i32 %N, -1
1386   %cmp = icmp ugt i32 7, %N.off
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 ; The function below uses a single condition to ensure %N > 2 && %N < 22.
1402 ; InstCombine transforms such checks with 2 conditions to a single check as in
1403 ; the test function.
1404 define void @optimized_range_check_unsigned2(ptr %pred, i32 %N) {
1405 ; CHECK-LABEL: 'optimized_range_check_unsigned2'
1406 ; CHECK-NEXT:  Classifying expressions for: @optimized_range_check_unsigned2
1407 ; CHECK-NEXT:    %N.off = add i32 %N, -2
1408 ; CHECK-NEXT:    --> (-2 + %N) U: full-set S: full-set
1409 ; CHECK-NEXT:    %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1410 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,21) S: [0,21) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1411 ; CHECK-NEXT:    %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
1412 ; 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 }
1413 ; CHECK-NEXT:    %iv.next = add nuw nsw i32 %iv, 1
1414 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,22) S: [1,22) Exits: %N LoopDispositions: { %loop: Computable }
1415 ; CHECK-NEXT:  Determining loop execution counts for: @optimized_range_check_unsigned2
1416 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %N)
1417 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 20
1418 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %N)
1419 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %N)
1420 ; CHECK-NEXT:   Predicates:
1421 ; CHECK:       Loop %loop: Trip multiple is 1
1423 entry:
1424   %N.off = add i32 %N, -2
1425   %cmp = icmp ult i32 %N.off, 20
1426   br i1 %cmp, label %loop, label %exit
1428 loop:
1429   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1430   %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
1431   store i16 0, ptr %gep, align 2
1432   %iv.next = add nuw nsw i32 %iv, 1
1433   %ec = icmp eq i32 %iv.next, %N
1434   br i1 %ec, label %exit, label %loop
1436 exit:
1437   ret void
1440 ; Same as @optimized_range_check_unsigned, but %N already has a range limited
1441 ; to [2,4) beforehand.
1442 define void @optimized_range_check_unsigned3(ptr %pred, i1 %c) {
1443 ; CHECK-LABEL: 'optimized_range_check_unsigned3'
1444 ; CHECK-NEXT:  Classifying expressions for: @optimized_range_check_unsigned3
1445 ; CHECK-NEXT:    %N = select i1 %c, i32 2, i32 3
1446 ; CHECK-NEXT:    --> %N U: [2,4) S: [2,4)
1447 ; CHECK-NEXT:    %N.off = add i32 %N, -1
1448 ; CHECK-NEXT:    --> (-1 + %N)<nsw> U: [1,3) S: [1,3)
1449 ; CHECK-NEXT:    %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1450 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,3) S: [0,3) Exits: (-1 + %N)<nsw> LoopDispositions: { %loop: Computable }
1451 ; CHECK-NEXT:    %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
1452 ; 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 }
1453 ; CHECK-NEXT:    %iv.next = add nuw nsw i32 %iv, 1
1454 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,4) S: [1,4) Exits: %N LoopDispositions: { %loop: Computable }
1455 ; CHECK-NEXT:  Determining loop execution counts for: @optimized_range_check_unsigned3
1456 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %N)<nsw>
1457 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 2
1458 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %N)<nsw>
1459 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %N)<nsw>
1460 ; CHECK-NEXT:   Predicates:
1461 ; CHECK:       Loop %loop: Trip multiple is 1
1463 entry:
1464   %N = select i1 %c, i32 2, i32 3
1465   %N.off = add i32 %N, -1
1466   %cmp = icmp ult i32 %N.off, 7
1467   br i1 %cmp, label %loop, label %exit
1469 loop:
1470   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1471   %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
1472   store i16 0, ptr %gep, align 2
1473   %iv.next = add nuw nsw i32 %iv, 1
1474   %ec = icmp eq i32 %iv.next, %N
1475   br i1 %ec, label %exit, label %loop
1477 exit:
1478   ret void
1481 ; Similar to @optimized_range_check_unsigned, but the initial compare checks
1482 ; against unsigned max (-1), which breaks the range check idiom.
1483 define void @not_optimized_range_check_unsigned1(ptr %pred, i32 %N) {
1484 ; CHECK-LABEL: 'not_optimized_range_check_unsigned1'
1485 ; CHECK-NEXT:  Classifying expressions for: @not_optimized_range_check_unsigned1
1486 ; CHECK-NEXT:    %N.off = add i32 %N, -1
1487 ; CHECK-NEXT:    --> (-1 + %N) U: full-set S: full-set
1488 ; CHECK-NEXT:    %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1489 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1490 ; CHECK-NEXT:    %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
1491 ; 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 }
1492 ; CHECK-NEXT:    %iv.next = add nuw nsw i32 %iv, 1
1493 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %N LoopDispositions: { %loop: Computable }
1494 ; CHECK-NEXT:  Determining loop execution counts for: @not_optimized_range_check_unsigned1
1495 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %N)
1496 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is -2
1497 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %N)
1498 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %N)
1499 ; CHECK-NEXT:   Predicates:
1500 ; CHECK:       Loop %loop: Trip multiple is 1
1502 entry:
1503   %N.off = add i32 %N, -1
1504   %cmp = icmp ult i32 %N.off, -1
1505   br i1 %cmp, label %loop, label %exit
1507 loop:
1508   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1509   %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
1510   store i16 0, ptr %gep, align 2
1511   %iv.next = add nuw nsw i32 %iv, 1
1512   %ec = icmp eq i32 %iv.next, %N
1513   br i1 %ec, label %exit, label %loop
1515 exit:
1516   ret void
1519 ; Similar to @optimized_range_check_unsigned, but the initial compare checks
1520 ; against 0, which breaks the range check idiom.
1521 define void @not_optimized_range_check_unsigned2(ptr %pred, i32 %N) {
1522 ; CHECK-LABEL: 'not_optimized_range_check_unsigned2'
1523 ; CHECK-NEXT:  Classifying expressions for: @not_optimized_range_check_unsigned2
1524 ; CHECK-NEXT:    %N.off = add i32 %N, -1
1525 ; CHECK-NEXT:    --> (-1 + %N) U: full-set S: full-set
1526 ; CHECK-NEXT:    %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1527 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1528 ; CHECK-NEXT:    %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
1529 ; 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 }
1530 ; CHECK-NEXT:    %iv.next = add nuw nsw i32 %iv, 1
1531 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %N LoopDispositions: { %loop: Computable }
1532 ; CHECK-NEXT:  Determining loop execution counts for: @not_optimized_range_check_unsigned2
1533 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %N)
1534 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is -2
1535 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is (-1 + %N)
1536 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %N)
1537 ; CHECK-NEXT:   Predicates:
1538 ; CHECK:       Loop %loop: Trip multiple is 1
1540 entry:
1541   %N.off = add i32 %N, -1
1542   %cmp = icmp ult i32 %N.off, 0
1543   br i1 %cmp, label %loop, label %exit
1545 loop:
1546   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1547   %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
1548   store i16 0, ptr %gep, align 2
1549   %iv.next = add nuw nsw i32 %iv, 1
1550   %ec = icmp eq i32 %iv.next, %N
1551   br i1 %ec, label %exit, label %loop
1553 exit:
1554   ret void
1557 define i32 @sle_sgt_ult_umax_to_smax(i32 %num) {
1558 ; CHECK-LABEL: 'sle_sgt_ult_umax_to_smax'
1559 ; CHECK-NEXT:  Classifying expressions for: @sle_sgt_ult_umax_to_smax
1560 ; CHECK-NEXT:    %iv = phi i32 [ 0, %guard.3 ], [ %iv.next, %loop ]
1561 ; CHECK-NEXT:    --> {0,+,4}<nuw><nsw><%loop> U: [0,25) S: [0,25) Exits: (4 * ((-4 + %num) /u 4))<nuw> LoopDispositions: { %loop: Computable }
1562 ; CHECK-NEXT:    %iv.next = add nuw i32 %iv, 4
1563 ; CHECK-NEXT:    --> {4,+,4}<nuw><nsw><%loop> U: [4,29) S: [4,29) Exits: (4 + (4 * ((-4 + %num) /u 4))<nuw>) LoopDispositions: { %loop: Computable }
1564 ; CHECK-NEXT:  Determining loop execution counts for: @sle_sgt_ult_umax_to_smax
1565 ; CHECK-NEXT:  Loop %loop: backedge-taken count is ((-4 + %num) /u 4)
1566 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 6
1567 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is ((-4 + %num) /u 4)
1568 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is ((-4 + %num) /u 4)
1569 ; CHECK-NEXT:   Predicates:
1570 ; CHECK:       Loop %loop: Trip multiple is 1
1572 guard.1:
1573   %cmp.1 = icmp sle i32 %num, 0
1574   br i1 %cmp.1, label %exit, label %guard.2
1576 guard.2:
1577   %cmp.2 = icmp sgt i32 %num, 28
1578   br i1 %cmp.2, label %exit, label %guard.3
1580 guard.3:
1581   %cmp.3 = icmp ult i32 %num, 4
1582   br i1 %cmp.3, label %exit, label %loop
1584 loop:
1585   %iv = phi i32 [ 0, %guard.3 ], [ %iv.next, %loop ]
1586   %iv.next = add nuw i32 %iv, 4
1587   %ec = icmp eq i32 %iv.next, %num
1588   br i1 %ec, label %exit, label %loop
1590 exit:
1591   ret i32 0
1594 ; Similar to @sle_sgt_ult_umax_to_smax but with different predicate order.
1595 define i32 @ult_sle_sgt_umax_to_smax(i32 %num) {
1596 ; CHECK-LABEL: 'ult_sle_sgt_umax_to_smax'
1597 ; CHECK-NEXT:  Classifying expressions for: @ult_sle_sgt_umax_to_smax
1598 ; CHECK-NEXT:    %iv = phi i32 [ 0, %guard.3 ], [ %iv.next, %loop ]
1599 ; CHECK-NEXT:    --> {0,+,4}<nuw><%loop> U: [0,-3) S: [-2147483648,2147483645) Exits: (4 * ((-4 + %num) /u 4))<nuw> LoopDispositions: { %loop: Computable }
1600 ; CHECK-NEXT:    %iv.next = add nuw i32 %iv, 4
1601 ; CHECK-NEXT:    --> {4,+,4}<nuw><%loop> U: [4,-3) S: [-2147483648,2147483645) Exits: (4 + (4 * ((-4 + %num) /u 4))<nuw>) LoopDispositions: { %loop: Computable }
1602 ; CHECK-NEXT:  Determining loop execution counts for: @ult_sle_sgt_umax_to_smax
1603 ; CHECK-NEXT:  Loop %loop: backedge-taken count is ((-4 + %num) /u 4)
1604 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 1073741823
1605 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is ((-4 + %num) /u 4)
1606 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is ((-4 + %num) /u 4)
1607 ; CHECK-NEXT:   Predicates:
1608 ; CHECK:       Loop %loop: Trip multiple is 1
1610 guard.1:
1611   %cmp.1 = icmp ult i32 %num, 4
1612   br i1 %cmp.1, label %exit, label %guard.2
1614 guard.2:
1615   %cmp.2 = icmp sgt i32 %num, 28
1616   br i1 %cmp.2, label %exit, label %guard.3
1618 guard.3:
1619   %cmp.3 = icmp sle i32 %num, 0
1620   br i1 %cmp.3, label %exit, label %loop
1622 loop:
1623   %iv = phi i32 [ 0, %guard.3 ], [ %iv.next, %loop ]
1624   %iv.next = add nuw i32 %iv, 4
1625   %ec = icmp eq i32 %iv.next, %num
1626   br i1 %ec, label %exit, label %loop
1628 exit:
1629   ret i32 0
1632 define i32 @ptr_induction_ult_1(ptr %a, ptr %b) {
1633 ; CHECK-LABEL: 'ptr_induction_ult_1'
1634 ; CHECK-NEXT:  Classifying expressions for: @ptr_induction_ult_1
1635 ; CHECK-NEXT:    %ptr.iv = phi ptr [ %ptr.iv.next, %loop ], [ %a, %entry ]
1636 ; CHECK-NEXT:    --> {%a,+,4}<nw><%loop> U: full-set S: full-set Exits: %a LoopDispositions: { %loop: Computable }
1637 ; CHECK-NEXT:    %ptr.iv.next = getelementptr i32, ptr %ptr.iv, i64 1
1638 ; CHECK-NEXT:    --> {(4 + %a),+,4}<nw><%loop> U: full-set S: full-set Exits: (4 + %a) LoopDispositions: { %loop: Computable }
1639 ; CHECK-NEXT:  Determining loop execution counts for: @ptr_induction_ult_1
1640 ; CHECK-NEXT:  Loop %loop: backedge-taken count is 0
1641 ; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is 0
1642 ; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is 0
1643 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is 0
1644 ; CHECK-NEXT:   Predicates:
1645 ; CHECK:       Loop %loop: Trip multiple is 1
1647 entry:
1648   %cmp.6 = icmp ult ptr %a, %b
1649   br i1 %cmp.6, label %loop, label %exit
1651 loop:
1652   %ptr.iv = phi ptr [ %ptr.iv.next, %loop ], [ %a, %entry ]
1653   %ptr.iv.next = getelementptr i32, ptr %ptr.iv, i64 1
1654   %exitcond = icmp eq ptr %ptr.iv, %a
1655   br i1 %exitcond, label %exit, label %loop
1657 exit:
1658   ret i32 0
1662 define i32 @ptr_induction_ult_2(ptr %a, ptr %b) {
1663 ; CHECK-LABEL: 'ptr_induction_ult_2'
1664 ; CHECK-NEXT:  Classifying expressions for: @ptr_induction_ult_2
1665 ; CHECK-NEXT:    %ptr.iv = phi ptr [ %ptr.iv.next, %loop ], [ %a, %entry ]
1666 ; CHECK-NEXT:    --> {%a,+,4}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
1667 ; CHECK-NEXT:    %ptr.iv.next = getelementptr i32, ptr %ptr.iv, i64 1
1668 ; CHECK-NEXT:    --> {(4 + %a),+,4}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
1669 ; CHECK-NEXT:  Determining loop execution counts for: @ptr_induction_ult_2
1670 ; CHECK-NEXT:  Loop %loop: Unpredictable backedge-taken count.
1671 ; CHECK-NEXT:  Loop %loop: Unpredictable constant max backedge-taken count.
1672 ; CHECK-NEXT:  Loop %loop: Unpredictable symbolic max backedge-taken count.
1673 ; CHECK-NEXT:  Loop %loop: Unpredictable predicated backedge-taken count.
1675 entry:
1676   %cmp.6 = icmp ult ptr %a, %b
1677   br i1 %cmp.6, label %loop, label %exit
1679 loop:
1680   %ptr.iv = phi ptr [ %ptr.iv.next, %loop ], [ %a, %entry ]
1681   %ptr.iv.next = getelementptr i32, ptr %ptr.iv, i64 1
1682   %exitcond = icmp eq ptr %ptr.iv, %b
1683   br i1 %exitcond, label %exit, label %loop
1685 exit:
1686   ret i32 0
1689 define void @gep_addrec_nw(ptr %a) {
1690 ; CHECK-LABEL: 'gep_addrec_nw'
1691 ; CHECK-NEXT:  Classifying expressions for: @gep_addrec_nw
1692 ; CHECK-NEXT:    %lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %a, %entry ]
1693 ; CHECK-NEXT:    --> {%a,+,4}<nw><%for.body> U: full-set S: full-set Exits: (1512 + %a) LoopDispositions: { %for.body: Computable }
1694 ; CHECK-NEXT:    %lsr.iv = phi i64 [ %lsr.iv.next, %for.body ], [ 379, %entry ]
1695 ; CHECK-NEXT:    --> {379,+,-1}<nsw><%for.body> U: [1,380) S: [1,380) Exits: 1 LoopDispositions: { %for.body: Computable }
1696 ; CHECK-NEXT:    %lsr.iv.next = add nsw i64 %lsr.iv, -1
1697 ; CHECK-NEXT:    --> {378,+,-1}<nsw><%for.body> U: [0,379) S: [0,379) Exits: 0 LoopDispositions: { %for.body: Computable }
1698 ; CHECK-NEXT:    %uglygep2 = getelementptr i8, ptr %lsr.iv1, i64 4
1699 ; CHECK-NEXT:    --> {(4 + %a),+,4}<nw><%for.body> U: full-set S: full-set Exits: (1516 + %a) LoopDispositions: { %for.body: Computable }
1700 ; CHECK-NEXT:  Determining loop execution counts for: @gep_addrec_nw
1701 ; CHECK-NEXT:  Loop %for.body: backedge-taken count is 378
1702 ; CHECK-NEXT:  Loop %for.body: constant max backedge-taken count is 378
1703 ; CHECK-NEXT:  Loop %for.body: symbolic max backedge-taken count is 378
1704 ; CHECK-NEXT:  Loop %for.body: Predicated backedge-taken count is 378
1705 ; CHECK-NEXT:   Predicates:
1706 ; CHECK:       Loop %for.body: Trip multiple is 379
1708 entry:
1709   br label %for.body
1711 for.body:                                         ; preds = %for.body, %entry
1712   %lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %a, %entry ]
1713   %lsr.iv = phi i64 [ %lsr.iv.next, %for.body ], [ 379, %entry ]
1714   store i32 1, ptr %lsr.iv1, align 4
1715   %lsr.iv.next = add nsw i64 %lsr.iv, -1
1716   %uglygep2 = getelementptr i8, ptr %lsr.iv1, i64 4
1717   %exitcond.not = icmp eq i64 %lsr.iv.next, 0
1718   br i1 %exitcond.not, label %for.end, label %for.body
1720 for.end:                                          ; preds = %for.body
1721   ret void