[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Analysis / ScalarEvolution / max-backedge-taken-count-guard-info.ll
blob9e7957a3736e5a055011a2f18693bb4f1b3c5977
1 ; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
2 ; RUN: opt -analyze -scalar-evolution %s -enable-new-pm=0 | FileCheck %s
3 ; RUN: opt -passes='print<scalar-evolution>' -disable-output %s 2>&1 | FileCheck %s
5 ; Test case for PR40961. The loop guard limit the max backedge-taken count.
7 define void @test_guard_less_than_16(i32* nocapture %a, i64 %i) {
8 ; CHECK-LABEL: 'test_guard_less_than_16'
9 ; CHECK-NEXT:  Classifying expressions for: @test_guard_less_than_16
10 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
11 ; CHECK-NEXT:    --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 15 LoopDispositions: { %loop: Computable }
12 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
13 ; CHECK-NEXT:    --> {((4 * %i) + %a),+,4}<nw><%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
14 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
15 ; CHECK-NEXT:    --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 16 LoopDispositions: { %loop: Computable }
16 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_less_than_16
17 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (15 + (-1 * %i))
18 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 15
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, i32* %a, i64 %iv
30   store i32 1, i32* %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(i32* 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, i32* %a, i64 %iv
45 ; CHECK-NEXT:    --> {((4 * %i) + %a),+,4}<nw><%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: max backedge-taken count is 15
51 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (15 + (-1 * %i))
52 ; CHECK-NEXT:   Predicates:
53 ; CHECK:       Loop %loop: Trip multiple is 1
55 entry:
56   %cmp3 = icmp ugt i64 16, %i
57   br i1 %cmp3, label %loop, label %exit
59 loop:
60   %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
61   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
62   store i32 1, i32* %idx, align 4
63   %iv.next = add nuw nsw i64 %iv, 1
64   %exitcond = icmp eq i64 %iv.next, 16
65   br i1 %exitcond, label %exit, label %loop
67 exit:
68   ret void
71 define void @test_guard_less_than_16_branches_flipped(i32* nocapture %a, i64 %i) {
72 ; CHECK-LABEL: 'test_guard_less_than_16_branches_flipped'
73 ; CHECK-NEXT:  Classifying expressions for: @test_guard_less_than_16_branches_flipped
74 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
75 ; CHECK-NEXT:    --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 15 LoopDispositions: { %loop: Computable }
76 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
77 ; CHECK-NEXT:    --> {((4 * %i) + %a),+,4}<nw><%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
78 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
79 ; CHECK-NEXT:    --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 16 LoopDispositions: { %loop: Computable }
80 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_less_than_16_branches_flipped
81 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (15 + (-1 * %i))
82 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is -1
83 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (15 + (-1 * %i))
84 ; CHECK-NEXT:   Predicates:
85 ; CHECK:       Loop %loop: Trip multiple is 1
87 entry:
88   %cmp3 = icmp ult i64 %i, 16
89   br i1 %cmp3, label %exit, label %loop
91 loop:
92   %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
93   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
94   store i32 1, i32* %idx, align 4
95   %iv.next = add nuw nsw i64 %iv, 1
96   %exitcond = icmp eq i64 %iv.next, 16
97   br i1 %exitcond, label %exit, label %loop
99 exit:
100   ret void
103 define void @test_guard_uge_16_branches_flipped(i32* nocapture %a, i64 %i) {
104 ; CHECK-LABEL: 'test_guard_uge_16_branches_flipped'
105 ; CHECK-NEXT:  Classifying expressions for: @test_guard_uge_16_branches_flipped
106 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
107 ; CHECK-NEXT:    --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 15 LoopDispositions: { %loop: Computable }
108 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
109 ; CHECK-NEXT:    --> {((4 * %i) + %a),+,4}<nw><%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
110 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
111 ; CHECK-NEXT:    --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 16 LoopDispositions: { %loop: Computable }
112 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_uge_16_branches_flipped
113 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (15 + (-1 * %i))
114 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 15
115 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (15 + (-1 * %i))
116 ; CHECK-NEXT:   Predicates:
117 ; CHECK:       Loop %loop: Trip multiple is 1
119 entry:
120   %cmp3 = icmp uge i64 %i, 16
121   br i1 %cmp3, label %exit, label %loop
123 loop:
124   %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
125   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
126   store i32 1, i32* %idx, align 4
127   %iv.next = add nuw nsw i64 %iv, 1
128   %exitcond = icmp eq i64 %iv.next, 16
129   br i1 %exitcond, label %exit, label %loop
131 exit:
132   ret void
135 define void @test_guard_eq_12(i32* nocapture %a, i64 %N) {
136 ; CHECK-LABEL: 'test_guard_eq_12'
137 ; CHECK-NEXT:  Classifying expressions for: @test_guard_eq_12
138 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
139 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: %N LoopDispositions: { %loop: Computable }
140 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
141 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %N) + %a) LoopDispositions: { %loop: Computable }
142 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
143 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,14) S: [1,14) Exits: (1 + %N) LoopDispositions: { %loop: Computable }
144 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_eq_12
145 ; CHECK-NEXT:  Loop %loop: backedge-taken count is %N
146 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 12
147 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is %N
148 ; CHECK-NEXT:   Predicates:
149 ; CHECK:       Loop %loop: Trip multiple is 1
151 entry:
152   %c.1 = icmp eq i64 %N, 12
153   br i1 %c.1, label %loop, label %exit
155 loop:
156   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
157   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
158   store i32 1, i32* %idx, align 4
159   %iv.next = add nuw nsw i64 %iv, 1
160   %exitcond = icmp eq i64 %iv, %N
161   br i1 %exitcond, label %exit, label %loop
163 exit:
164   ret void
167 define void @test_guard_ule_12(i32* nocapture %a, i64 %N) {
168 ; CHECK-LABEL: 'test_guard_ule_12'
169 ; CHECK-NEXT:  Classifying expressions for: @test_guard_ule_12
170 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
171 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: %N LoopDispositions: { %loop: Computable }
172 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
173 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %N) + %a) LoopDispositions: { %loop: Computable }
174 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
175 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,14) S: [1,14) Exits: (1 + %N) LoopDispositions: { %loop: Computable }
176 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_ule_12
177 ; CHECK-NEXT:  Loop %loop: backedge-taken count is %N
178 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 12
179 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is %N
180 ; CHECK-NEXT:   Predicates:
181 ; CHECK:       Loop %loop: Trip multiple is 1
183 entry:
184   %c.1 = icmp ule i64 %N, 12
185   br i1 %c.1, label %loop, label %exit
187 loop:
188   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
189   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
190   store i32 1, i32* %idx, align 4
191   %iv.next = add nuw nsw i64 %iv, 1
192   %exitcond = icmp eq i64 %iv, %N
193   br i1 %exitcond, label %exit, label %loop
195 exit:
196   ret void
199 define void @test_guard_ule_12_step2(i32* nocapture %a, i64 %N) {
200 ; CHECK-LABEL: 'test_guard_ule_12_step2'
201 ; CHECK-NEXT:  Classifying expressions for: @test_guard_ule_12_step2
202 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
203 ; CHECK-NEXT:    --> {0,+,2}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (2 * (%N /u 2))<nuw> LoopDispositions: { %loop: Computable }
204 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
205 ; CHECK-NEXT:    --> {%a,+,8}<nuw><%loop> U: full-set S: full-set Exits: ((8 * (%N /u 2)) + %a) LoopDispositions: { %loop: Computable }
206 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 2
207 ; CHECK-NEXT:    --> {2,+,2}<nuw><nsw><%loop> U: [2,15) S: [2,15) Exits: (2 + (2 * (%N /u 2))<nuw>) LoopDispositions: { %loop: Computable }
208 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_ule_12_step2
209 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (%N /u 2)
210 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 6
211 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (%N /u 2)
212 ; CHECK-NEXT:   Predicates:
213 ; CHECK:       Loop %loop: Trip multiple is 1
215 entry:
216   %c.1 = icmp ule i64 %N, 12
217   br i1 %c.1, label %loop, label %exit
219 loop:
220   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
221   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
222   store i32 1, i32* %idx, align 4
223   %iv.next = add nuw nsw i64 %iv, 2
224   %exitcond = icmp eq i64 %iv, %N
225   br i1 %exitcond, label %exit, label %loop
227 exit:
228   ret void
231 define void @test_multiple_const_guards_order1(i32* nocapture %a, i64 %i) {
232 ; CHECK-LABEL: 'test_multiple_const_guards_order1'
233 ; CHECK-NEXT:  Classifying expressions for: @test_multiple_const_guards_order1
234 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
235 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,10) S: [0,10) Exits: %i LoopDispositions: { %loop: Computable }
236 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
237 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
238 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
239 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,11) S: [1,11) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
240 ; CHECK-NEXT:  Determining loop execution counts for: @test_multiple_const_guards_order1
241 ; CHECK-NEXT:  Loop %loop: backedge-taken count is %i
242 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 9
243 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is %i
244 ; CHECK-NEXT:   Predicates:
245 ; CHECK:       Loop %loop: Trip multiple is 1
247 entry:
248   %c.1 = icmp ult i64 %i, 16
249   br i1 %c.1, label %guardbb, label %exit
251 guardbb:
252   %c.2 = icmp ult i64 %i, 10
253   br i1 %c.2, label %loop, label %exit
255 loop:
256   %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
257   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
258   store i32 1, i32* %idx, align 4
259   %iv.next = add nuw nsw i64 %iv, 1
260   %exitcond = icmp eq i64 %iv, %i
261   br i1 %exitcond, label %exit, label %loop
263 exit:
264   ret void
267 define void @test_multiple_const_guards_order2(i32* nocapture %a, i64 %i) {
268 ; CHECK-LABEL: 'test_multiple_const_guards_order2'
269 ; CHECK-NEXT:  Classifying expressions for: @test_multiple_const_guards_order2
270 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
271 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,10) S: [0,10) Exits: %i LoopDispositions: { %loop: Computable }
272 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
273 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
274 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
275 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,11) S: [1,11) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
276 ; CHECK-NEXT:  Determining loop execution counts for: @test_multiple_const_guards_order2
277 ; CHECK-NEXT:  Loop %loop: backedge-taken count is %i
278 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 9
279 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is %i
280 ; CHECK-NEXT:   Predicates:
281 ; CHECK:       Loop %loop: Trip multiple is 1
283 entry:
284   %c.1 = icmp ult i64 %i, 10
285   br i1 %c.1, label %guardbb, label %exit
287 guardbb:
288   %c.2 = icmp ult i64 %i, 16
289   br i1 %c.2, label %loop, label %exit
291 loop:
292   %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
293   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
294   store i32 1, i32* %idx, align 4
295   %iv.next = add nuw nsw i64 %iv, 1
296   %exitcond = icmp eq i64 %iv, %i
297   br i1 %exitcond, label %exit, label %loop
299 exit:
300   ret void
303 ; TODO: Currently we miss getting the tightest max backedge-taken count (11).
304 define void @test_multiple_var_guards_order1(i32* nocapture %a, i64 %i, i64 %N) {
305 ; CHECK-LABEL: 'test_multiple_var_guards_order1'
306 ; CHECK-NEXT:  Classifying expressions for: @test_multiple_var_guards_order1
307 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
308 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,-9223372036854775808) S: [0,-9223372036854775808) Exits: %i LoopDispositions: { %loop: Computable }
309 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
310 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
311 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
312 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
313 ; CHECK-NEXT:  Determining loop execution counts for: @test_multiple_var_guards_order1
314 ; CHECK-NEXT:  Loop %loop: backedge-taken count is %i
315 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is -1
316 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is %i
317 ; CHECK-NEXT:   Predicates:
318 ; CHECK:       Loop %loop: Trip multiple is 1
320 entry:
321   %c.1 = icmp ult i64 %N, 12
322   br i1 %c.1, label %guardbb, label %exit
324 guardbb:
325   %c.2 = icmp ult i64 %i, %N
326   br i1 %c.2, label %loop, label %exit
328 loop:
329   %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
330   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
331   store i32 1, i32* %idx, align 4
332   %iv.next = add nuw nsw i64 %iv, 1
333   %exitcond = icmp eq i64 %iv, %i
334   br i1 %exitcond, label %exit, label %loop
336 exit:
337   ret void
340 ; TODO: Currently we miss getting the tightest max backedge-taken count (11).
341 define void @test_multiple_var_guards_order2(i32* nocapture %a, i64 %i, i64 %N) {
342 ; CHECK-LABEL: 'test_multiple_var_guards_order2'
343 ; CHECK-NEXT:  Classifying expressions for: @test_multiple_var_guards_order2
344 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
345 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,-9223372036854775808) S: [0,-9223372036854775808) Exits: %i LoopDispositions: { %loop: Computable }
346 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
347 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
348 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
349 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
350 ; CHECK-NEXT:  Determining loop execution counts for: @test_multiple_var_guards_order2
351 ; CHECK-NEXT:  Loop %loop: backedge-taken count is %i
352 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is -1
353 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is %i
354 ; CHECK-NEXT:   Predicates:
355 ; CHECK:       Loop %loop: Trip multiple is 1
357 entry:
358   %c.1 = icmp ult i64 %i, %N
359   br i1 %c.1, label %guardbb, label %exit
361 guardbb:
362   %c.2 = icmp ult i64 %N, 12
363   br i1 %c.2, label %loop, label %exit
365 loop:
366   %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
367   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
368   store i32 1, i32* %idx, align 4
369   %iv.next = add nuw nsw i64 %iv, 1
370   %exitcond = icmp eq i64 %iv, %i
371   br i1 %exitcond, label %exit, label %loop
373 exit:
374   ret void
377 ; The guards here reference each other in a cycle.
378 define void @test_multiple_var_guards_cycle(i32* nocapture %a, i64 %i, i64 %N) {
379 ; CHECK-LABEL: 'test_multiple_var_guards_cycle'
380 ; CHECK-NEXT:  Classifying expressions for: @test_multiple_var_guards_cycle
381 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
382 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,-9223372036854775808) S: [0,-9223372036854775808) Exits: %N LoopDispositions: { %loop: Computable }
383 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
384 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %N) + %a) LoopDispositions: { %loop: Computable }
385 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
386 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: (1 + %N) LoopDispositions: { %loop: Computable }
387 ; CHECK-NEXT:  Determining loop execution counts for: @test_multiple_var_guards_cycle
388 ; CHECK-NEXT:  Loop %loop: backedge-taken count is %N
389 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is -1
390 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is %N
391 ; CHECK-NEXT:   Predicates:
392 ; CHECK:       Loop %loop: Trip multiple is 1
394 entry:
395   %c.1 = icmp ult i64 %N, %i
396   br i1 %c.1, label %guardbb, label %exit
398 guardbb:
399   %c.2 = icmp ult i64 %i, %N
400   br i1 %c.2, label %loop, label %exit
402 loop:
403   %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
404   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
405   store i32 1, i32* %idx, align 4
406   %iv.next = add nuw nsw i64 %iv, 1
407   %exitcond = icmp eq i64 %iv, %N
408   br i1 %exitcond, label %exit, label %loop
410 exit:
411   ret void
414 define void @test_guard_ult_ne(i32* nocapture readonly %data, i64 %count) {
415 ; CHECK-LABEL: 'test_guard_ult_ne'
416 ; CHECK-NEXT:  Classifying expressions for: @test_guard_ult_ne
417 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
418 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
419 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %data, i64 %iv
420 ; CHECK-NEXT:    --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
421 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
422 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
423 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_ult_ne
424 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
425 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 3
426 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
427 ; CHECK-NEXT:   Predicates:
428 ; CHECK:       Loop %loop: Trip multiple is 1
430 entry:
431   %cmp.ult = icmp ult i64 %count, 5
432   br i1 %cmp.ult, label %guardbb, label %exit
434 guardbb:
435   %cmp.ne = icmp ne i64 %count, 0
436   br i1 %cmp.ne, label %loop, label %exit
438 loop:
439   %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
440   %idx = getelementptr inbounds i32, i32* %data, i64 %iv
441   store i32 1, i32* %idx, align 4
442   %iv.next = add nuw i64 %iv, 1
443   %exitcond.not = icmp eq i64 %iv.next, %count
444   br i1 %exitcond.not, label %exit, label %loop
446 exit:
447   ret void
450 define void @test_guard_ne_ult(i32* nocapture readonly %data, i64 %count) {
451 ; CHECK-LABEL: 'test_guard_ne_ult'
452 ; CHECK-NEXT:  Classifying expressions for: @test_guard_ne_ult
453 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
454 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
455 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %data, i64 %iv
456 ; CHECK-NEXT:    --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
457 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
458 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
459 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_ne_ult
460 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
461 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 3
462 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
463 ; CHECK-NEXT:   Predicates:
464 ; CHECK:       Loop %loop: Trip multiple is 1
466 entry:
467   %cmp.ne = icmp ne i64 %count, 0
468   br i1 %cmp.ne, label %guardbb, label %exit
470 guardbb:
471   %cmp.ult = icmp ult i64 %count, 5
472   br i1 %cmp.ult, label %loop, label %exit
474 loop:
475   %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
476   %idx = getelementptr inbounds i32, i32* %data, i64 %iv
477   store i32 1, i32* %idx, align 4
478   %iv.next = add nuw i64 %iv, 1
479   %exitcond.not = icmp eq i64 %iv.next, %count
480   br i1 %exitcond.not, label %exit, label %loop
482 exit:
483   ret void
486 define void @test_guard_if_and_enter(i32* nocapture readonly %data, i64 %count) {
487 ; CHECK-LABEL: 'test_guard_if_and_enter'
488 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_and_enter
489 ; CHECK-NEXT:    %cmp.and = and i1 %cmp.ult, %cmp.ne
490 ; CHECK-NEXT:    --> %cmp.and U: full-set S: full-set
491 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
492 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
493 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %data, i64 %iv
494 ; CHECK-NEXT:    --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
495 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
496 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
497 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_and_enter
498 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
499 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 3
500 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
501 ; CHECK-NEXT:   Predicates:
502 ; CHECK:       Loop %loop: Trip multiple is 1
504 entry:
505   %cmp.ult = icmp ult i64 %count, 5
506   %cmp.ne = icmp ne i64 %count, 0
507   %cmp.and = and i1 %cmp.ult, %cmp.ne
508   br i1 %cmp.and, label %loop, label %exit
510 loop:
511   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
512   %idx = getelementptr inbounds i32, i32* %data, i64 %iv
513   store i32 1, i32* %idx, align 4
514   %iv.next = add nuw i64 %iv, 1
515   %exitcond.not = icmp eq i64 %iv.next, %count
516   br i1 %exitcond.not, label %exit, label %loop
518 exit:
519   ret void
522 define void @test_guard_if_and_skip(i32* nocapture readonly %data, i64 %count) {
523 ; CHECK-LABEL: 'test_guard_if_and_skip'
524 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_and_skip
525 ; CHECK-NEXT:    %cmp.and = and i1 %cmp.ult, %cmp.ne
526 ; CHECK-NEXT:    --> %cmp.and U: full-set S: full-set
527 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
528 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
529 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %data, i64 %iv
530 ; CHECK-NEXT:    --> {%data,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
531 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
532 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %count LoopDispositions: { %loop: Computable }
533 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_and_skip
534 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
535 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is -1
536 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
537 ; CHECK-NEXT:   Predicates:
538 ; CHECK:       Loop %loop: Trip multiple is 1
540 entry:
541   %cmp.ult = icmp ult i64 %count, 5
542   %cmp.ne = icmp ne i64 %count, 0
543   %cmp.and = and i1 %cmp.ult, %cmp.ne
544   br i1 %cmp.and, label %exit, label %loop
546 loop:
547   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
548   %idx = getelementptr inbounds i32, i32* %data, i64 %iv
549   store i32 1, i32* %idx, align 4
550   %iv.next = add nuw i64 %iv, 1
551   %exitcond.not = icmp eq i64 %iv.next, %count
552   br i1 %exitcond.not, label %exit, label %loop
554 exit:
555   ret void
558 define void @test_guard_if_and_and(i32* nocapture readonly %data, i64 %count, i1 %c) {
559 ; CHECK-LABEL: 'test_guard_if_and_and'
560 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_and_and
561 ; CHECK-NEXT:    %cmp.and1 = and i1 %c, %cmp.ne
562 ; CHECK-NEXT:    --> %cmp.and1 U: full-set S: full-set
563 ; CHECK-NEXT:    %cmp.and = and i1 %cmp.ult, %cmp.and1
564 ; CHECK-NEXT:    --> %cmp.and U: full-set S: full-set
565 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
566 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
567 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %data, i64 %iv
568 ; CHECK-NEXT:    --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
569 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
570 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
571 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_and_and
572 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
573 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 3
574 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
575 ; CHECK-NEXT:   Predicates:
576 ; CHECK:       Loop %loop: Trip multiple is 1
578 entry:
579   %cmp.ult = icmp ult i64 %count, 5
580   %cmp.ne = icmp ne i64 %count, 0
581   %cmp.and1 = and i1 %c, %cmp.ne
582   %cmp.and = and i1 %cmp.ult, %cmp.and1
583   br i1 %cmp.and, label %loop, label %exit
585 loop:
586   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
587   %idx = getelementptr inbounds i32, i32* %data, i64 %iv
588   store i32 1, i32* %idx, align 4
589   %iv.next = add nuw i64 %iv, 1
590   %exitcond.not = icmp eq i64 %iv.next, %count
591   br i1 %exitcond.not, label %exit, label %loop
593 exit:
594   ret void
597 define void @test_guard_if_and_or(i32* nocapture readonly %data, i64 %count, i1 %c) {
598 ; CHECK-LABEL: 'test_guard_if_and_or'
599 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_and_or
600 ; CHECK-NEXT:    %cmp.or = or i1 %c, %cmp.ne
601 ; CHECK-NEXT:    --> %cmp.or U: full-set S: full-set
602 ; CHECK-NEXT:    %cmp.and = and i1 %cmp.ult, %cmp.or
603 ; CHECK-NEXT:    --> %cmp.and U: full-set S: full-set
604 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
605 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
606 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %data, i64 %iv
607 ; CHECK-NEXT:    --> {%data,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
608 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
609 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %count LoopDispositions: { %loop: Computable }
610 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_and_or
611 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
612 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is -1
613 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
614 ; CHECK-NEXT:   Predicates:
615 ; CHECK:       Loop %loop: Trip multiple is 1
617 entry:
618   %cmp.ult = icmp ult i64 %count, 5
619   %cmp.ne = icmp ne i64 %count, 0
620   %cmp.or = or i1 %c, %cmp.ne
621   %cmp.and = and i1 %cmp.ult, %cmp.or
622   br i1 %cmp.and, label %loop, label %exit
624 loop:
625   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
626   %idx = getelementptr inbounds i32, i32* %data, i64 %iv
627   store i32 1, i32* %idx, align 4
628   %iv.next = add nuw i64 %iv, 1
629   %exitcond.not = icmp eq i64 %iv.next, %count
630   br i1 %exitcond.not, label %exit, label %loop
632 exit:
633   ret void
636 define void @test_guard_if_or_skip(i32* nocapture readonly %data, i64 %count) {
637 ; CHECK-LABEL: 'test_guard_if_or_skip'
638 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_or_skip
639 ; CHECK-NEXT:    %cmp.or = or i1 %cmp.uge, %cmp.eq
640 ; CHECK-NEXT:    --> %cmp.or U: full-set S: full-set
641 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
642 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
643 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %data, i64 %iv
644 ; CHECK-NEXT:    --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
645 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
646 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
647 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_or_skip
648 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
649 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 3
650 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
651 ; CHECK-NEXT:   Predicates:
652 ; CHECK:       Loop %loop: Trip multiple is 1
654 entry:
655   %cmp.uge = icmp uge i64 %count, 5
656   %cmp.eq = icmp eq i64 %count, 0
657   %cmp.or = or i1 %cmp.uge, %cmp.eq
658   br i1 %cmp.or, label %exit, label %loop
660 loop:
661   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
662   %idx = getelementptr inbounds i32, i32* %data, i64 %iv
663   store i32 1, i32* %idx, align 4
664   %iv.next = add nuw i64 %iv, 1
665   %exitcond.not = icmp eq i64 %iv.next, %count
666   br i1 %exitcond.not, label %exit, label %loop
668 exit:
669   ret void
672 define void @test_guard_if_or_enter(i32* nocapture readonly %data, i64 %count) {
673 ; CHECK-LABEL: 'test_guard_if_or_enter'
674 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_or_enter
675 ; CHECK-NEXT:    %cmp.or = or i1 %cmp.uge, %cmp.eq
676 ; CHECK-NEXT:    --> %cmp.or U: full-set S: full-set
677 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
678 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
679 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %data, i64 %iv
680 ; CHECK-NEXT:    --> {%data,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
681 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
682 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %count LoopDispositions: { %loop: Computable }
683 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_or_enter
684 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
685 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is -1
686 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
687 ; CHECK-NEXT:   Predicates:
688 ; CHECK:       Loop %loop: Trip multiple is 1
690 entry:
691   %cmp.uge = icmp uge i64 %count, 5
692   %cmp.eq = icmp eq i64 %count, 0
693   %cmp.or = or i1 %cmp.uge, %cmp.eq
694   br i1 %cmp.or, label %loop, label %exit
696 loop:
697   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
698   %idx = getelementptr inbounds i32, i32* %data, i64 %iv
699   store i32 1, i32* %idx, align 4
700   %iv.next = add nuw i64 %iv, 1
701   %exitcond.not = icmp eq i64 %iv.next, %count
702   br i1 %exitcond.not, label %exit, label %loop
704 exit:
705   ret void
708 define void @test_guard_if_or_or(i32* nocapture readonly %data, i64 %count, i1 %c) {
709 ; CHECK-LABEL: 'test_guard_if_or_or'
710 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_or_or
711 ; CHECK-NEXT:    %cmp.or1 = or i1 %c, %cmp.eq
712 ; CHECK-NEXT:    --> %cmp.or1 U: full-set S: full-set
713 ; CHECK-NEXT:    %cmp.or = or i1 %cmp.uge, %cmp.or1
714 ; CHECK-NEXT:    --> %cmp.or U: full-set S: full-set
715 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
716 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
717 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %data, i64 %iv
718 ; CHECK-NEXT:    --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
719 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
720 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
721 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_or_or
722 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
723 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 3
724 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
725 ; CHECK-NEXT:   Predicates:
726 ; CHECK:       Loop %loop: Trip multiple is 1
728 entry:
729   %cmp.uge = icmp uge i64 %count, 5
730   %cmp.eq = icmp eq i64 %count, 0
731   %cmp.or1 = or i1 %c, %cmp.eq
732   %cmp.or = or i1 %cmp.uge, %cmp.or1
733   br i1 %cmp.or, label %exit, label %loop
735 loop:
736   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
737   %idx = getelementptr inbounds i32, i32* %data, i64 %iv
738   store i32 1, i32* %idx, align 4
739   %iv.next = add nuw i64 %iv, 1
740   %exitcond.not = icmp eq i64 %iv.next, %count
741   br i1 %exitcond.not, label %exit, label %loop
743 exit:
744   ret void
747 define void @test_guard_if_or_and(i32* nocapture readonly %data, i64 %count, i1 %c) {
748 ; CHECK-LABEL: 'test_guard_if_or_and'
749 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_or_and
750 ; CHECK-NEXT:    %cmp.and = and i1 %c, %cmp.eq
751 ; CHECK-NEXT:    --> %cmp.and U: full-set S: full-set
752 ; CHECK-NEXT:    %cmp.or = or i1 %cmp.uge, %cmp.and
753 ; CHECK-NEXT:    --> %cmp.or U: full-set S: full-set
754 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
755 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
756 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %data, i64 %iv
757 ; CHECK-NEXT:    --> {%data,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
758 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
759 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %count LoopDispositions: { %loop: Computable }
760 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_or_and
761 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
762 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is -1
763 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
764 ; CHECK-NEXT:   Predicates:
765 ; CHECK:       Loop %loop: Trip multiple is 1
767 entry:
768   %cmp.uge = icmp uge i64 %count, 5
769   %cmp.eq = icmp eq i64 %count, 0
770   %cmp.and = and i1 %c, %cmp.eq
771   %cmp.or = or i1 %cmp.uge, %cmp.and
772   br i1 %cmp.or, label %exit, label %loop
774 loop:
775   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
776   %idx = getelementptr inbounds i32, i32* %data, i64 %iv
777   store i32 1, i32* %idx, align 4
778   %iv.next = add nuw i64 %iv, 1
779   %exitcond.not = icmp eq i64 %iv.next, %count
780   br i1 %exitcond.not, label %exit, label %loop
782 exit:
783   ret void
786 ; Test case for PR47247. Both the guard condition and the assume limit the
787 ; max backedge-taken count.
789 define void @test_guard_and_assume(i32* nocapture readonly %data, i64 %count) {
790 ; CHECK-LABEL: 'test_guard_and_assume'
791 ; CHECK-NEXT:  Classifying expressions for: @test_guard_and_assume
792 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
793 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
794 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %data, i64 %iv
795 ; CHECK-NEXT:    --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
796 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
797 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
798 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_and_assume
799 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
800 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 3
801 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
802 ; CHECK-NEXT:   Predicates:
803 ; CHECK:       Loop %loop: Trip multiple is 1
805 entry:
806   %cmp = icmp ult i64 %count, 5
807   tail call void @llvm.assume(i1 %cmp)
808   %cmp18.not = icmp eq i64 %count, 0
809   br i1 %cmp18.not, label %exit, label %loop
811 loop:
812   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
813   %idx = getelementptr inbounds i32, i32* %data, i64 %iv
814   store i32 1, i32* %idx, align 4
815   %iv.next = add nuw i64 %iv, 1
816   %exitcond.not = icmp eq i64 %iv.next, %count
817   br i1 %exitcond.not, label %exit, label %loop
819 exit:
820   ret void
823 ; Function Attrs: nounwind willreturn
824 declare void @llvm.assume(i1 noundef)
826 define void @guard_pessimizes_analysis_step1(i1 %c, i32 %N) {
827 ; CHECK-LABEL: 'guard_pessimizes_analysis_step1'
828 ; CHECK-NEXT:  Classifying expressions for: @guard_pessimizes_analysis_step1
829 ; CHECK-NEXT:    %init = phi i32 [ 2, %entry ], [ 3, %bb1 ]
830 ; CHECK-NEXT:    --> %init U: [2,4) S: [2,4)
831 ; CHECK-NEXT:    %iv = phi i32 [ %iv.next, %loop ], [ %init, %loop.ph ]
832 ; CHECK-NEXT:    --> {%init,+,1}<%loop> U: [2,11) S: [2,11) Exits: 9 LoopDispositions: { %loop: Computable }
833 ; CHECK-NEXT:    %iv.next = add i32 %iv, 1
834 ; CHECK-NEXT:    --> {(1 + %init)<nuw><nsw>,+,1}<%loop> U: [3,12) S: [3,12) Exits: 10 LoopDispositions: { %loop: Computable }
835 ; CHECK-NEXT:  Determining loop execution counts for: @guard_pessimizes_analysis_step1
836 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (9 + (-1 * %init)<nsw>)<nsw>
837 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 7
838 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (9 + (-1 * %init)<nsw>)<nsw>
839 ; CHECK-NEXT:   Predicates:
840 ; CHECK:       Loop %loop: Trip multiple is 1
842 entry:
843   br i1 %c, label %bb1, label %guard
845 bb1:
846   br label %guard
848 guard:
849   %init = phi i32 [ 2, %entry ], [ 3, %bb1 ]
850   %c.1 = icmp ult i32 %init, %N
851   br i1 %c.1, label %loop.ph, label %exit
853 loop.ph:
854   br label %loop
856 loop:
857   %iv = phi i32 [ %iv.next, %loop ], [ %init, %loop.ph ]
858   %iv.next = add i32 %iv, 1
859   %exitcond = icmp eq i32 %iv.next, 10
860   br i1 %exitcond, label %exit, label %loop
862 exit:
863   ret void
866 define void @guard_pessimizes_analysis_step2(i1 %c, i32 %N) {
867 ; CHECK-LABEL: 'guard_pessimizes_analysis_step2'
868 ; CHECK-NEXT:  Classifying expressions for: @guard_pessimizes_analysis_step2
869 ; CHECK-NEXT:    %init = phi i32 [ 2, %entry ], [ 3, %bb1 ]
870 ; CHECK-NEXT:    --> %init U: [2,4) S: [2,4)
871 ; CHECK-NEXT:    %iv = phi i32 [ %iv.next, %loop ], [ %init, %loop.ph ]
872 ; 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 }
873 ; CHECK-NEXT:    %iv.next = add nuw nsw i32 %iv, 2
874 ; 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 }
875 ; CHECK-NEXT:  Determining loop execution counts for: @guard_pessimizes_analysis_step2
876 ; CHECK-NEXT:  Loop %loop: backedge-taken count is ((8 + (-1 * %init)<nsw>)<nsw> /u 2)
877 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 3
878 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is ((8 + (-1 * %init)<nsw>)<nsw> /u 2)
879 ; CHECK-NEXT:   Predicates:
880 ; CHECK:       Loop %loop: Trip multiple is 1
882 entry:
883   br i1 %c, label %bb1, label %guard
885 bb1:
886   br label %guard
888 guard:
889   %init = phi i32 [ 2, %entry ], [ 3, %bb1 ]
890   %c.1 = icmp ult i32 %init, %N
891   br i1 %c.1, label %loop.ph, label %exit
893 loop.ph:
894   br label %loop
896 loop:
897   %iv = phi i32 [ %iv.next, %loop ], [ %init, %loop.ph ]
898   %iv.next = add nuw nsw i32 %iv, 2
899   %exitcond = icmp eq i32 %iv.next, 10
900   br i1 %exitcond, label %exit, label %loop
902 exit:
903   ret void
905 define void @crash(i8* %ptr) {
906 ; CHECK-LABEL: 'crash'
907 ; CHECK-NEXT:  Classifying expressions for: @crash
908 ; CHECK-NEXT:    %text.addr.5 = phi i8* [ %incdec.ptr112, %while.cond111 ], [ null, %while.body ]
909 ; CHECK-NEXT:    --> {null,+,-1}<nw><%while.cond111> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %while.cond111: Computable, %while.body: Variant }
910 ; CHECK-NEXT:    %incdec.ptr112 = getelementptr inbounds i8, i8* %text.addr.5, i64 -1
911 ; 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 }
912 ; CHECK-NEXT:    %lastout.2271 = phi i8* [ %incdec.ptr126, %while.body125 ], [ %ptr, %while.end117 ]
913 ; CHECK-NEXT:    --> {%ptr,+,1}<nuw><%while.body125> U: full-set S: full-set Exits: {(-2 + (-1 * (ptrtoint i8* %ptr to i64)) + %ptr),+,-1}<nw><%while.cond111> LoopDispositions: { %while.body125: Computable }
914 ; CHECK-NEXT:    %incdec.ptr126 = getelementptr inbounds i8, i8* %lastout.2271, i64 1
915 ; CHECK-NEXT:    --> {(1 + %ptr)<nuw>,+,1}<nuw><%while.body125> U: [1,0) S: [1,0) Exits: {(-1 + (-1 * (ptrtoint i8* %ptr to i64)) + %ptr),+,-1}<nw><%while.cond111> LoopDispositions: { %while.body125: Computable }
916 ; CHECK-NEXT:  Determining loop execution counts for: @crash
917 ; CHECK-NEXT:  Loop %while.body125: backedge-taken count is {(-2 + (-1 * (ptrtoint i8* %ptr to i64))),+,-1}<nw><%while.cond111>
918 ; CHECK-NEXT:  Loop %while.body125: max backedge-taken count is -2
919 ; CHECK-NEXT:  Loop %while.body125: Predicated backedge-taken count is {(-2 + (-1 * (ptrtoint i8* %ptr to i64))),+,-1}<nw><%while.cond111>
920 ; CHECK-NEXT:   Predicates:
921 ; CHECK:       Loop %while.body125: Trip multiple is 1
922 ; CHECK-NEXT:  Loop %while.cond111: Unpredictable backedge-taken count.
923 ; CHECK-NEXT:  Loop %while.cond111: Unpredictable max backedge-taken count.
924 ; CHECK-NEXT:  Loop %while.cond111: Unpredictable predicated backedge-taken count.
925 ; CHECK-NEXT:  Loop %while.body: Unpredictable backedge-taken count.
926 ; CHECK-NEXT:  Loop %while.body: Unpredictable max backedge-taken count.
927 ; CHECK-NEXT:  Loop %while.body: Unpredictable predicated backedge-taken count.
929 entry:
930   br label %while.body
932 while.body:
933   br label %while.cond111
935 while.cond111:
936   %text.addr.5 = phi i8* [ %incdec.ptr112, %while.cond111 ], [ null, %while.body ]
937   %incdec.ptr112 = getelementptr inbounds i8, i8* %text.addr.5, i64 -1
938   br i1 false, label %while.end117, label %while.cond111
940 while.end117:
941   %cmp118 = icmp ult i8* %ptr, %incdec.ptr112
942   br i1 %cmp118, label %while.body125, label %while.cond134.preheader
945 while.cond134.preheader:
946   br label %while.body
948 while.body125:
949   %lastout.2271 = phi i8* [ %incdec.ptr126, %while.body125 ], [ %ptr, %while.end117 ]
950   %incdec.ptr126 = getelementptr inbounds i8, i8* %lastout.2271, i64 1
951   %exitcond.not = icmp eq i8* %incdec.ptr126, %incdec.ptr112
952   br i1 %exitcond.not, label %while.end129, label %while.body125
954 while.end129:                                     ; preds = %while.body125
955   ret void
958 define void @test_guard_uge(i32 %blockSize) {
959 ; CHECK-LABEL: 'test_guard_uge'
960 ; CHECK-NEXT:  Classifying expressions for: @test_guard_uge
961 ; CHECK-NEXT:    %shr = lshr i32 %blockSize, 2
962 ; CHECK-NEXT:    --> (%blockSize /u 4) U: [0,1073741824) S: [0,1073741824)
963 ; CHECK-NEXT:    %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
964 ; CHECK-NEXT:    --> {(%blockSize /u 4),+,-1}<%while.body> U: [-1073741822,1073741824) S: [-1073741822,1073741824) Exits: 1 LoopDispositions: { %while.body: Computable }
965 ; CHECK-NEXT:    %dec = add i32 %iv, -1
966 ; CHECK-NEXT:    --> {(-1 + (%blockSize /u 4))<nsw>,+,-1}<%while.body> U: [-1073741823,1073741823) S: [-1073741823,1073741823) Exits: 0 LoopDispositions: { %while.body: Computable }
967 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_uge
968 ; CHECK-NEXT:  Loop %while.body: backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
969 ; CHECK-NEXT:  Loop %while.body: max backedge-taken count is 1073741822
970 ; CHECK-NEXT:  Loop %while.body: Predicated backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
971 ; CHECK-NEXT:   Predicates:
972 ; CHECK:       Loop %while.body: Trip multiple is 1
974   %shr = lshr i32 %blockSize, 2
975   %guard = icmp uge i32 %blockSize, 4
976   br i1 %guard, label %while.body.preheader, label %while.end
978 while.body.preheader:
979   br label %while.body
981 while.body:
982   %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
983   %dec = add i32 %iv, -1
984   %cmp.not = icmp eq i32 %dec, 0
985   br i1 %cmp.not, label %while.end.loopexit, label %while.body
987 while.end.loopexit:
988   br label %while.end
990 while.end:
991   ret void
994 define void @test_guard_ugt(i32 %blockSize) {
995 ; CHECK-LABEL: 'test_guard_ugt'
996 ; CHECK-NEXT:  Classifying expressions for: @test_guard_ugt
997 ; CHECK-NEXT:    %shr = lshr i32 %blockSize, 2
998 ; CHECK-NEXT:    --> (%blockSize /u 4) U: [0,1073741824) S: [0,1073741824)
999 ; CHECK-NEXT:    %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1000 ; CHECK-NEXT:    --> {(%blockSize /u 4),+,-1}<%while.body> U: [-1073741822,1073741824) S: [-1073741822,1073741824) Exits: 1 LoopDispositions: { %while.body: Computable }
1001 ; CHECK-NEXT:    %dec = add i32 %iv, -1
1002 ; CHECK-NEXT:    --> {(-1 + (%blockSize /u 4))<nsw>,+,-1}<%while.body> U: [-1073741823,1073741823) S: [-1073741823,1073741823) Exits: 0 LoopDispositions: { %while.body: Computable }
1003 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_ugt
1004 ; CHECK-NEXT:  Loop %while.body: backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1005 ; CHECK-NEXT:  Loop %while.body: max backedge-taken count is 1073741822
1006 ; CHECK-NEXT:  Loop %while.body: Predicated backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1007 ; CHECK-NEXT:   Predicates:
1008 ; CHECK:       Loop %while.body: Trip multiple is 1
1010   %shr = lshr i32 %blockSize, 2
1011   %guard = icmp ugt i32 %blockSize, 3
1012   br i1 %guard, label %while.body.preheader, label %while.end
1014 while.body.preheader:
1015   br label %while.body
1017 while.body:
1018   %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1019   %dec = add i32 %iv, -1
1020   %cmp.not = icmp eq i32 %dec, 0
1021   br i1 %cmp.not, label %while.end.loopexit, label %while.body
1023 while.end.loopexit:
1024   br label %while.end
1026 while.end:
1027   ret void
1030 define void @test_guard_uge_and_ule(i32 %blockSize) {
1031 ; CHECK-LABEL: 'test_guard_uge_and_ule'
1032 ; CHECK-NEXT:  Classifying expressions for: @test_guard_uge_and_ule
1033 ; CHECK-NEXT:    %shr = lshr i32 %blockSize, 2
1034 ; CHECK-NEXT:    --> (%blockSize /u 4) U: [0,1073741824) S: [0,1073741824)
1035 ; CHECK-NEXT:    %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1036 ; CHECK-NEXT:    --> {(%blockSize /u 4),+,-1}<%while.body> U: [-255,1073741824) S: [-255,1073741824) Exits: 1 LoopDispositions: { %while.body: Computable }
1037 ; CHECK-NEXT:    %dec = add i32 %iv, -1
1038 ; CHECK-NEXT:    --> {(-1 + (%blockSize /u 4))<nsw>,+,-1}<%while.body> U: [-256,1073741823) S: [-256,1073741823) Exits: 0 LoopDispositions: { %while.body: Computable }
1039 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_uge_and_ule
1040 ; CHECK-NEXT:  Loop %while.body: backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1041 ; CHECK-NEXT:  Loop %while.body: max backedge-taken count is 255
1042 ; CHECK-NEXT:  Loop %while.body: Predicated backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1043 ; CHECK-NEXT:   Predicates:
1044 ; CHECK:       Loop %while.body: Trip multiple is 1
1046   %shr = lshr i32 %blockSize, 2
1047   %guard1 = icmp uge i32 %blockSize, 4
1048   br i1 %guard1, label %while.guard, label %while.end
1050 while.guard:
1051   %guard2 = icmp ule i32 %blockSize, 1024
1052   br i1 %guard2, label %while.body.preheader, label %while.end
1054 while.body.preheader:
1055   br label %while.body
1057 while.body:
1058   %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1059   %dec = add i32 %iv, -1
1060   %cmp.not = icmp eq i32 %dec, 0
1061   br i1 %cmp.not, label %while.end.loopexit, label %while.body
1063 while.end.loopexit:
1064   br label %while.end
1066 while.end:
1067   ret void
1070 define void @test_guard_ugt_and_ult(i32 %blockSize) {
1071 ; CHECK-LABEL: 'test_guard_ugt_and_ult'
1072 ; CHECK-NEXT:  Classifying expressions for: @test_guard_ugt_and_ult
1073 ; CHECK-NEXT:    %shr = lshr i32 %blockSize, 2
1074 ; CHECK-NEXT:    --> (%blockSize /u 4) U: [0,1073741824) S: [0,1073741824)
1075 ; CHECK-NEXT:    %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1076 ; CHECK-NEXT:    --> {(%blockSize /u 4),+,-1}<%while.body> U: [-255,1073741824) S: [-255,1073741824) Exits: 1 LoopDispositions: { %while.body: Computable }
1077 ; CHECK-NEXT:    %dec = add i32 %iv, -1
1078 ; CHECK-NEXT:    --> {(-1 + (%blockSize /u 4))<nsw>,+,-1}<%while.body> U: [-256,1073741823) S: [-256,1073741823) Exits: 0 LoopDispositions: { %while.body: Computable }
1079 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_ugt_and_ult
1080 ; CHECK-NEXT:  Loop %while.body: backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1081 ; CHECK-NEXT:  Loop %while.body: max backedge-taken count is 255
1082 ; CHECK-NEXT:  Loop %while.body: Predicated backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1083 ; CHECK-NEXT:   Predicates:
1084 ; CHECK:       Loop %while.body: Trip multiple is 1
1086   %shr = lshr i32 %blockSize, 2
1087   %guard1 = icmp ugt i32 %blockSize, 3
1088   br i1 %guard1, label %while.guard, label %while.end
1090 while.guard:
1091   %guard2 = icmp ult i32 %blockSize, 1025
1092   br i1 %guard2, label %while.body.preheader, label %while.end
1094 while.body.preheader:
1095   br label %while.body
1097 while.body:
1098   %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1099   %dec = add i32 %iv, -1
1100   %cmp.not = icmp eq i32 %dec, 0
1101   br i1 %cmp.not, label %while.end.loopexit, label %while.body
1103 while.end.loopexit:
1104   br label %while.end
1106 while.end:
1107   ret void
1110 define void @test_guard_slt_sgt_1(i32* nocapture %a, i64 %N) {
1111 ; CHECK-LABEL: 'test_guard_slt_sgt_1'
1112 ; CHECK-NEXT:  Classifying expressions for: @test_guard_slt_sgt_1
1113 ; CHECK-NEXT:    %and = and i1 %c.0, %c.1
1114 ; CHECK-NEXT:    --> %and U: full-set S: full-set
1115 ; CHECK-NEXT:    %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
1116 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,11) S: [0,11) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1117 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
1118 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %N) + %a) LoopDispositions: { %loop: Computable }
1119 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
1120 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,12) S: [1,12) Exits: %N LoopDispositions: { %loop: Computable }
1121 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_slt_sgt_1
1122 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %N)
1123 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 10
1124 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %N)
1125 ; CHECK-NEXT:   Predicates:
1126 ; CHECK:       Loop %loop: Trip multiple is 1
1128 entry:
1129   %c.0 = icmp slt i64 %N, 12
1130   %c.1 = icmp sgt i64 %N, 0
1131   %and = and i1 %c.0, %c.1
1132   br i1 %and, label %loop, label %exit
1134 loop:
1135   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
1136   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
1137   store i32 1, i32* %idx, align 4
1138   %iv.next = add nuw nsw i64 %iv, 1
1139   %exitcond = icmp eq i64 %iv.next, %N
1140   br i1 %exitcond, label %exit, label %loop
1142 exit:
1143   ret void
1146 define void @test_guard_slt_sgt_2(i32* nocapture %a, i64 %i) {
1147 ; CHECK-LABEL: 'test_guard_slt_sgt_2'
1148 ; CHECK-NEXT:  Classifying expressions for: @test_guard_slt_sgt_2
1149 ; CHECK-NEXT:    %and = and i1 %c.0, %c.1
1150 ; CHECK-NEXT:    --> %and U: full-set S: full-set
1151 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
1152 ; CHECK-NEXT:    --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 17 LoopDispositions: { %loop: Computable }
1153 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
1154 ; CHECK-NEXT:    --> {((4 * %i) + %a),+,4}<nw><%loop> U: full-set S: full-set Exits: (68 + %a) LoopDispositions: { %loop: Computable }
1155 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
1156 ; CHECK-NEXT:    --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 18 LoopDispositions: { %loop: Computable }
1157 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_slt_sgt_2
1158 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (17 + (-1 * %i))
1159 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 12
1160 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (17 + (-1 * %i))
1161 ; CHECK-NEXT:   Predicates:
1162 ; CHECK:       Loop %loop: Trip multiple is 1
1164 entry:
1165   %c.0 = icmp slt i64 %i, 16
1166   %c.1 = icmp sgt i64 %i, 4
1167   %and = and i1 %c.0, %c.1
1168   br i1 %and, label %loop, label %exit
1170 loop:
1171   %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
1172   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
1173   store i32 1, i32* %idx, align 4
1174   %iv.next = add nuw nsw i64 %iv, 1
1175   %exitcond = icmp eq i64 %iv.next, 18
1176   br i1 %exitcond, label %exit, label %loop
1178 exit:
1179   ret void
1182 define void @test_guard_sle_sge_1(i32* nocapture %a, i64 %N) {
1183 ; CHECK-LABEL: 'test_guard_sle_sge_1'
1184 ; CHECK-NEXT:  Classifying expressions for: @test_guard_sle_sge_1
1185 ; CHECK-NEXT:    %and = and i1 %c.0, %c.1
1186 ; CHECK-NEXT:    --> %and U: full-set S: full-set
1187 ; CHECK-NEXT:    %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
1188 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,12) S: [0,12) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1189 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
1190 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %N) + %a) LoopDispositions: { %loop: Computable }
1191 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
1192 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,13) S: [1,13) Exits: %N LoopDispositions: { %loop: Computable }
1193 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_sle_sge_1
1194 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %N)
1195 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 11
1196 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %N)
1197 ; CHECK-NEXT:   Predicates:
1198 ; CHECK:       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, i32* %a, i64 %iv
1209   store i32 1, i32* %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(i32* 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:    --> %and 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, i32* %a, i64 %iv
1226 ; CHECK-NEXT:    --> {((4 * %i) + %a),+,4}<nw><%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: max backedge-taken count is 13
1232 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (17 + (-1 * %i))
1233 ; CHECK-NEXT:   Predicates:
1234 ; CHECK:       Loop %loop: Trip multiple is 1
1236 entry:
1237   %c.0 = icmp sle i64 %i, 16
1238   %c.1 = icmp sge i64 %i, 4
1239   %and = and i1 %c.0, %c.1
1240   br i1 %and, label %loop, label %exit
1242 loop:
1243   %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
1244   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
1245   store i32 1, i32* %idx, align 4
1246   %iv.next = add nuw nsw i64 %iv, 1
1247   %exitcond = icmp eq i64 %iv.next, 18
1248   br i1 %exitcond, label %exit, label %loop
1250 exit:
1251   ret void
1254 ; The function below uses a single condition to ensure %N > 0 && %N < 8.
1255 ; InstCombine transforms such checks with 2 conditions to a single check as in
1256 ; the test function.
1257 define void @optimized_range_check_unsigned(i16* %pred, i32 %N) {
1258 ; CHECK-LABEL: 'optimized_range_check_unsigned'
1259 ; CHECK-NEXT:  Classifying expressions for: @optimized_range_check_unsigned
1260 ; CHECK-NEXT:    %N.off = add i32 %N, -1
1261 ; CHECK-NEXT:    --> (-1 + %N) U: full-set S: full-set
1262 ; CHECK-NEXT:    %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1263 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,7) S: [0,7) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1264 ; CHECK-NEXT:    %gep = getelementptr inbounds i16, i16* %pred, i32 %iv
1265 ; 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 }
1266 ; CHECK-NEXT:    %iv.next = add nuw nsw i32 %iv, 1
1267 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,8) S: [1,8) Exits: %N LoopDispositions: { %loop: Computable }
1268 ; CHECK-NEXT:  Determining loop execution counts for: @optimized_range_check_unsigned
1269 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %N)
1270 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 6
1271 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %N)
1272 ; CHECK-NEXT:   Predicates:
1273 ; CHECK:       Loop %loop: Trip multiple is 1
1275 entry:
1276   %N.off = add i32 %N, -1
1277   %cmp = icmp ult i32 %N.off, 7
1278   br i1 %cmp, label %loop, label %exit
1280 loop:
1281   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1282   %gep = getelementptr inbounds i16, i16* %pred, i32 %iv
1283   store i16 0, i16* %gep, align 2
1284   %iv.next = add nuw nsw i32 %iv, 1
1285   %ec = icmp eq i32 %iv.next, %N
1286   br i1 %ec, label %exit, label %loop
1288 exit:
1289   ret void
1292 ; The function below uses a single condition to ensure %N > 2 && %N < 22.
1293 ; InstCombine transforms such checks with 2 conditions to a single check as in
1294 ; the test function.
1295 define void @optimized_range_check_unsigned2(i16* %pred, i32 %N) {
1296 ; CHECK-LABEL: 'optimized_range_check_unsigned2'
1297 ; CHECK-NEXT:  Classifying expressions for: @optimized_range_check_unsigned2
1298 ; CHECK-NEXT:    %N.off = add i32 %N, -2
1299 ; CHECK-NEXT:    --> (-2 + %N) U: full-set S: full-set
1300 ; CHECK-NEXT:    %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1301 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,21) S: [0,21) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1302 ; CHECK-NEXT:    %gep = getelementptr inbounds i16, i16* %pred, i32 %iv
1303 ; 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 }
1304 ; CHECK-NEXT:    %iv.next = add nuw nsw i32 %iv, 1
1305 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,22) S: [1,22) Exits: %N LoopDispositions: { %loop: Computable }
1306 ; CHECK-NEXT:  Determining loop execution counts for: @optimized_range_check_unsigned2
1307 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %N)
1308 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 20
1309 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %N)
1310 ; CHECK-NEXT:   Predicates:
1311 ; CHECK:       Loop %loop: Trip multiple is 1
1313 entry:
1314   %N.off = add i32 %N, -2
1315   %cmp = icmp ult i32 %N.off, 20
1316   br i1 %cmp, label %loop, label %exit
1318 loop:
1319   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1320   %gep = getelementptr inbounds i16, i16* %pred, i32 %iv
1321   store i16 0, i16* %gep, align 2
1322   %iv.next = add nuw nsw i32 %iv, 1
1323   %ec = icmp eq i32 %iv.next, %N
1324   br i1 %ec, label %exit, label %loop
1326 exit:
1327   ret void
1330 ; Similar to @optimized_range_check_unsigned, but the initial compare checks
1331 ; against unsigned max (-1), which breaks the range check idiom.
1332 define void @not_optimized_range_check_unsigned1(i16* %pred, i32 %N) {
1333 ; CHECK-LABEL: 'not_optimized_range_check_unsigned1'
1334 ; CHECK-NEXT:  Classifying expressions for: @not_optimized_range_check_unsigned1
1335 ; CHECK-NEXT:    %N.off = add i32 %N, -1
1336 ; CHECK-NEXT:    --> (-1 + %N) U: full-set S: full-set
1337 ; CHECK-NEXT:    %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1338 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1339 ; CHECK-NEXT:    %gep = getelementptr inbounds i16, i16* %pred, i32 %iv
1340 ; 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 }
1341 ; CHECK-NEXT:    %iv.next = add nuw nsw i32 %iv, 1
1342 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %N LoopDispositions: { %loop: Computable }
1343 ; CHECK-NEXT:  Determining loop execution counts for: @not_optimized_range_check_unsigned1
1344 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %N)
1345 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is -2
1346 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %N)
1347 ; CHECK-NEXT:   Predicates:
1348 ; CHECK:       Loop %loop: Trip multiple is 1
1350 entry:
1351   %N.off = add i32 %N, -1
1352   %cmp = icmp ult i32 %N.off, -1
1353   br i1 %cmp, label %loop, label %exit
1355 loop:
1356   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1357   %gep = getelementptr inbounds i16, i16* %pred, i32 %iv
1358   store i16 0, i16* %gep, align 2
1359   %iv.next = add nuw nsw i32 %iv, 1
1360   %ec = icmp eq i32 %iv.next, %N
1361   br i1 %ec, label %exit, label %loop
1363 exit:
1364   ret void
1367 ; Similar to @optimized_range_check_unsigned, but the initial compare checks
1368 ; against 0, which breaks the range check idiom.
1369 define void @not_optimized_range_check_unsigned2(i16* %pred, i32 %N) {
1370 ; CHECK-LABEL: 'not_optimized_range_check_unsigned2'
1371 ; CHECK-NEXT:  Classifying expressions for: @not_optimized_range_check_unsigned2
1372 ; CHECK-NEXT:    %N.off = add i32 %N, -1
1373 ; CHECK-NEXT:    --> (-1 + %N) U: full-set S: full-set
1374 ; CHECK-NEXT:    %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1375 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1376 ; CHECK-NEXT:    %gep = getelementptr inbounds i16, i16* %pred, i32 %iv
1377 ; 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 }
1378 ; CHECK-NEXT:    %iv.next = add nuw nsw i32 %iv, 1
1379 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %N LoopDispositions: { %loop: Computable }
1380 ; CHECK-NEXT:  Determining loop execution counts for: @not_optimized_range_check_unsigned2
1381 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %N)
1382 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is -2
1383 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %N)
1384 ; CHECK-NEXT:   Predicates:
1385 ; CHECK:       Loop %loop: Trip multiple is 1
1387 entry:
1388   %N.off = add i32 %N, -1
1389   %cmp = icmp ult i32 %N.off, 0
1390   br i1 %cmp, label %loop, label %exit
1392 loop:
1393   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1394   %gep = getelementptr inbounds i16, i16* %pred, i32 %iv
1395   store i16 0, i16* %gep, align 2
1396   %iv.next = add nuw nsw i32 %iv, 1
1397   %ec = icmp eq i32 %iv.next, %N
1398   br i1 %ec, label %exit, label %loop
1400 exit:
1401   ret void