[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / test / Analysis / ScalarEvolution / max-backedge-taken-count-guard-info.ll
blob1a9dba0511cd2b83b9d6f888d0b8c97baa9e85b5
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 max backedge-taken count.
6 define void @test_guard_less_than_16(i32* 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, i32* %a, i64 %iv
12 ; CHECK-NEXT:    --> {((4 * %i) + %a),+,4}<nw><%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: max backedge-taken count is 15
18 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (15 + (-1 * %i))
19 ; CHECK-NEXT:   Predicates:
20 ; CHECK:       Loop %loop: Trip multiple is 1
22 entry:
23   %cmp3 = icmp ult i64 %i, 16
24   br i1 %cmp3, label %loop, label %exit
26 loop:
27   %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
28   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
29   store i32 1, i32* %idx, align 4
30   %iv.next = add nuw nsw i64 %iv, 1
31   %exitcond = icmp eq i64 %iv.next, 16
32   br i1 %exitcond, label %exit, label %loop
34 exit:
35   ret void
38 define void @test_guard_less_than_16_operands_swapped(i32* nocapture %a, i64 %i) {
39 ; CHECK-LABEL: 'test_guard_less_than_16_operands_swapped'
40 ; CHECK-NEXT:  Classifying expressions for: @test_guard_less_than_16_operands_swapped
41 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
42 ; CHECK-NEXT:    --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 15 LoopDispositions: { %loop: Computable }
43 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
44 ; CHECK-NEXT:    --> {((4 * %i) + %a),+,4}<nw><%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
45 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
46 ; CHECK-NEXT:    --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 16 LoopDispositions: { %loop: Computable }
47 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_less_than_16_operands_swapped
48 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (15 + (-1 * %i))
49 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 15
50 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (15 + (-1 * %i))
51 ; CHECK-NEXT:   Predicates:
52 ; CHECK:       Loop %loop: Trip multiple is 1
54 entry:
55   %cmp3 = icmp ugt i64 16, %i
56   br i1 %cmp3, label %loop, label %exit
58 loop:
59   %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
60   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
61   store i32 1, i32* %idx, align 4
62   %iv.next = add nuw nsw i64 %iv, 1
63   %exitcond = icmp eq i64 %iv.next, 16
64   br i1 %exitcond, label %exit, label %loop
66 exit:
67   ret void
70 define void @test_guard_less_than_16_branches_flipped(i32* nocapture %a, i64 %i) {
71 ; CHECK-LABEL: 'test_guard_less_than_16_branches_flipped'
72 ; CHECK-NEXT:  Classifying expressions for: @test_guard_less_than_16_branches_flipped
73 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
74 ; CHECK-NEXT:    --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 15 LoopDispositions: { %loop: Computable }
75 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
76 ; CHECK-NEXT:    --> {((4 * %i) + %a),+,4}<nw><%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
77 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
78 ; CHECK-NEXT:    --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 16 LoopDispositions: { %loop: Computable }
79 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_less_than_16_branches_flipped
80 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (15 + (-1 * %i))
81 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is -1
82 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (15 + (-1 * %i))
83 ; CHECK-NEXT:   Predicates:
84 ; CHECK:       Loop %loop: Trip multiple is 1
86 entry:
87   %cmp3 = icmp ult i64 %i, 16
88   br i1 %cmp3, label %exit, label %loop
90 loop:
91   %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
92   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
93   store i32 1, i32* %idx, align 4
94   %iv.next = add nuw nsw i64 %iv, 1
95   %exitcond = icmp eq i64 %iv.next, 16
96   br i1 %exitcond, label %exit, label %loop
98 exit:
99   ret void
102 define void @test_guard_uge_16_branches_flipped(i32* nocapture %a, i64 %i) {
103 ; CHECK-LABEL: 'test_guard_uge_16_branches_flipped'
104 ; CHECK-NEXT:  Classifying expressions for: @test_guard_uge_16_branches_flipped
105 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
106 ; CHECK-NEXT:    --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 15 LoopDispositions: { %loop: Computable }
107 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
108 ; CHECK-NEXT:    --> {((4 * %i) + %a),+,4}<nw><%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
109 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
110 ; CHECK-NEXT:    --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 16 LoopDispositions: { %loop: Computable }
111 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_uge_16_branches_flipped
112 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (15 + (-1 * %i))
113 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 15
114 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (15 + (-1 * %i))
115 ; CHECK-NEXT:   Predicates:
116 ; CHECK:       Loop %loop: Trip multiple is 1
118 entry:
119   %cmp3 = icmp uge i64 %i, 16
120   br i1 %cmp3, label %exit, label %loop
122 loop:
123   %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
124   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
125   store i32 1, i32* %idx, align 4
126   %iv.next = add nuw nsw i64 %iv, 1
127   %exitcond = icmp eq i64 %iv.next, 16
128   br i1 %exitcond, label %exit, label %loop
130 exit:
131   ret void
134 define void @test_guard_eq_12(i32* nocapture %a, i64 %N) {
135 ; CHECK-LABEL: 'test_guard_eq_12'
136 ; CHECK-NEXT:  Classifying expressions for: @test_guard_eq_12
137 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
138 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: %N LoopDispositions: { %loop: Computable }
139 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
140 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %N) + %a) LoopDispositions: { %loop: Computable }
141 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
142 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,14) S: [1,14) Exits: (1 + %N) LoopDispositions: { %loop: Computable }
143 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_eq_12
144 ; CHECK-NEXT:  Loop %loop: backedge-taken count is %N
145 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 12
146 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is %N
147 ; CHECK-NEXT:   Predicates:
148 ; CHECK:       Loop %loop: Trip multiple is 1
150 entry:
151   %c.1 = icmp eq i64 %N, 12
152   br i1 %c.1, label %loop, label %exit
154 loop:
155   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
156   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
157   store i32 1, i32* %idx, align 4
158   %iv.next = add nuw nsw i64 %iv, 1
159   %exitcond = icmp eq i64 %iv, %N
160   br i1 %exitcond, label %exit, label %loop
162 exit:
163   ret void
166 define void @test_guard_ule_12(i32* nocapture %a, i64 %N) {
167 ; CHECK-LABEL: 'test_guard_ule_12'
168 ; CHECK-NEXT:  Classifying expressions for: @test_guard_ule_12
169 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
170 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: %N LoopDispositions: { %loop: Computable }
171 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
172 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %N) + %a) LoopDispositions: { %loop: Computable }
173 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
174 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,14) S: [1,14) Exits: (1 + %N) LoopDispositions: { %loop: Computable }
175 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_ule_12
176 ; CHECK-NEXT:  Loop %loop: backedge-taken count is %N
177 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 12
178 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is %N
179 ; CHECK-NEXT:   Predicates:
180 ; CHECK:       Loop %loop: Trip multiple is 1
182 entry:
183   %c.1 = icmp ule i64 %N, 12
184   br i1 %c.1, label %loop, label %exit
186 loop:
187   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
188   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
189   store i32 1, i32* %idx, align 4
190   %iv.next = add nuw nsw i64 %iv, 1
191   %exitcond = icmp eq i64 %iv, %N
192   br i1 %exitcond, label %exit, label %loop
194 exit:
195   ret void
198 define void @test_guard_ule_12_step2(i32* nocapture %a, i64 %N) {
199 ; CHECK-LABEL: 'test_guard_ule_12_step2'
200 ; CHECK-NEXT:  Classifying expressions for: @test_guard_ule_12_step2
201 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
202 ; CHECK-NEXT:    --> {0,+,2}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (2 * (%N /u 2))<nuw> LoopDispositions: { %loop: Computable }
203 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
204 ; CHECK-NEXT:    --> {%a,+,8}<nuw><%loop> U: full-set S: full-set Exits: ((8 * (%N /u 2)) + %a) LoopDispositions: { %loop: Computable }
205 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 2
206 ; CHECK-NEXT:    --> {2,+,2}<nuw><nsw><%loop> U: [2,15) S: [2,15) Exits: (2 + (2 * (%N /u 2))<nuw>) LoopDispositions: { %loop: Computable }
207 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_ule_12_step2
208 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (%N /u 2)
209 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 6
210 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (%N /u 2)
211 ; CHECK-NEXT:   Predicates:
212 ; CHECK:       Loop %loop: Trip multiple is 1
214 entry:
215   %c.1 = icmp ule i64 %N, 12
216   br i1 %c.1, label %loop, label %exit
218 loop:
219   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
220   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
221   store i32 1, i32* %idx, align 4
222   %iv.next = add nuw nsw i64 %iv, 2
223   %exitcond = icmp eq i64 %iv, %N
224   br i1 %exitcond, label %exit, label %loop
226 exit:
227   ret void
230 define void @test_multiple_const_guards_order1(i32* nocapture %a, i64 %i) {
231 ; CHECK-LABEL: 'test_multiple_const_guards_order1'
232 ; CHECK-NEXT:  Classifying expressions for: @test_multiple_const_guards_order1
233 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
234 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,10) S: [0,10) Exits: %i LoopDispositions: { %loop: Computable }
235 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
236 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
237 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
238 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,11) S: [1,11) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
239 ; CHECK-NEXT:  Determining loop execution counts for: @test_multiple_const_guards_order1
240 ; CHECK-NEXT:  Loop %loop: backedge-taken count is %i
241 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 9
242 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is %i
243 ; CHECK-NEXT:   Predicates:
244 ; CHECK:       Loop %loop: Trip multiple is 1
246 entry:
247   %c.1 = icmp ult i64 %i, 16
248   br i1 %c.1, label %guardbb, label %exit
250 guardbb:
251   %c.2 = icmp ult i64 %i, 10
252   br i1 %c.2, label %loop, label %exit
254 loop:
255   %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
256   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
257   store i32 1, i32* %idx, align 4
258   %iv.next = add nuw nsw i64 %iv, 1
259   %exitcond = icmp eq i64 %iv, %i
260   br i1 %exitcond, label %exit, label %loop
262 exit:
263   ret void
266 define void @test_multiple_const_guards_order2(i32* nocapture %a, i64 %i) {
267 ; CHECK-LABEL: 'test_multiple_const_guards_order2'
268 ; CHECK-NEXT:  Classifying expressions for: @test_multiple_const_guards_order2
269 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
270 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,10) S: [0,10) Exits: %i LoopDispositions: { %loop: Computable }
271 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
272 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
273 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
274 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,11) S: [1,11) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
275 ; CHECK-NEXT:  Determining loop execution counts for: @test_multiple_const_guards_order2
276 ; CHECK-NEXT:  Loop %loop: backedge-taken count is %i
277 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 9
278 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is %i
279 ; CHECK-NEXT:   Predicates:
280 ; CHECK:       Loop %loop: Trip multiple is 1
282 entry:
283   %c.1 = icmp ult i64 %i, 10
284   br i1 %c.1, label %guardbb, label %exit
286 guardbb:
287   %c.2 = icmp ult i64 %i, 16
288   br i1 %c.2, label %loop, label %exit
290 loop:
291   %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
292   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
293   store i32 1, i32* %idx, align 4
294   %iv.next = add nuw nsw i64 %iv, 1
295   %exitcond = icmp eq i64 %iv, %i
296   br i1 %exitcond, label %exit, label %loop
298 exit:
299   ret void
302 ; TODO: Currently we miss getting the tightest max backedge-taken count (11).
303 define void @test_multiple_var_guards_order1(i32* nocapture %a, i64 %i, i64 %N) {
304 ; CHECK-LABEL: 'test_multiple_var_guards_order1'
305 ; CHECK-NEXT:  Classifying expressions for: @test_multiple_var_guards_order1
306 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
307 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,-9223372036854775808) S: [0,-9223372036854775808) Exits: %i LoopDispositions: { %loop: Computable }
308 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
309 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
310 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
311 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
312 ; CHECK-NEXT:  Determining loop execution counts for: @test_multiple_var_guards_order1
313 ; CHECK-NEXT:  Loop %loop: backedge-taken count is %i
314 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is -1
315 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is %i
316 ; CHECK-NEXT:   Predicates:
317 ; CHECK:       Loop %loop: Trip multiple is 1
319 entry:
320   %c.1 = icmp ult i64 %N, 12
321   br i1 %c.1, label %guardbb, label %exit
323 guardbb:
324   %c.2 = icmp ult i64 %i, %N
325   br i1 %c.2, label %loop, label %exit
327 loop:
328   %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
329   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
330   store i32 1, i32* %idx, align 4
331   %iv.next = add nuw nsw i64 %iv, 1
332   %exitcond = icmp eq i64 %iv, %i
333   br i1 %exitcond, label %exit, label %loop
335 exit:
336   ret void
339 ; TODO: Currently we miss getting the tightest max backedge-taken count (11).
340 define void @test_multiple_var_guards_order2(i32* nocapture %a, i64 %i, i64 %N) {
341 ; CHECK-LABEL: 'test_multiple_var_guards_order2'
342 ; CHECK-NEXT:  Classifying expressions for: @test_multiple_var_guards_order2
343 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
344 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,-9223372036854775808) S: [0,-9223372036854775808) Exits: %i LoopDispositions: { %loop: Computable }
345 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
346 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
347 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
348 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
349 ; CHECK-NEXT:  Determining loop execution counts for: @test_multiple_var_guards_order2
350 ; CHECK-NEXT:  Loop %loop: backedge-taken count is %i
351 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is -1
352 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is %i
353 ; CHECK-NEXT:   Predicates:
354 ; CHECK:       Loop %loop: Trip multiple is 1
356 entry:
357   %c.1 = icmp ult i64 %i, %N
358   br i1 %c.1, label %guardbb, label %exit
360 guardbb:
361   %c.2 = icmp ult i64 %N, 12
362   br i1 %c.2, label %loop, label %exit
364 loop:
365   %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
366   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
367   store i32 1, i32* %idx, align 4
368   %iv.next = add nuw nsw i64 %iv, 1
369   %exitcond = icmp eq i64 %iv, %i
370   br i1 %exitcond, label %exit, label %loop
372 exit:
373   ret void
376 ; The guards here reference each other in a cycle.
377 define void @test_multiple_var_guards_cycle(i32* nocapture %a, i64 %i, i64 %N) {
378 ; CHECK-LABEL: 'test_multiple_var_guards_cycle'
379 ; CHECK-NEXT:  Classifying expressions for: @test_multiple_var_guards_cycle
380 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
381 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,-9223372036854775808) S: [0,-9223372036854775808) Exits: %N LoopDispositions: { %loop: Computable }
382 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
383 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %N) + %a) LoopDispositions: { %loop: Computable }
384 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
385 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: (1 + %N) LoopDispositions: { %loop: Computable }
386 ; CHECK-NEXT:  Determining loop execution counts for: @test_multiple_var_guards_cycle
387 ; CHECK-NEXT:  Loop %loop: backedge-taken count is %N
388 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is -1
389 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is %N
390 ; CHECK-NEXT:   Predicates:
391 ; CHECK:       Loop %loop: Trip multiple is 1
393 entry:
394   %c.1 = icmp ult i64 %N, %i
395   br i1 %c.1, label %guardbb, label %exit
397 guardbb:
398   %c.2 = icmp ult i64 %i, %N
399   br i1 %c.2, label %loop, label %exit
401 loop:
402   %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
403   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
404   store i32 1, i32* %idx, align 4
405   %iv.next = add nuw nsw i64 %iv, 1
406   %exitcond = icmp eq i64 %iv, %N
407   br i1 %exitcond, label %exit, label %loop
409 exit:
410   ret void
413 define void @test_guard_ult_ne(i32* nocapture readonly %data, i64 %count) {
414 ; CHECK-LABEL: 'test_guard_ult_ne'
415 ; CHECK-NEXT:  Classifying expressions for: @test_guard_ult_ne
416 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
417 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
418 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %data, i64 %iv
419 ; CHECK-NEXT:    --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
420 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
421 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
422 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_ult_ne
423 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
424 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 3
425 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
426 ; CHECK-NEXT:   Predicates:
427 ; CHECK:       Loop %loop: Trip multiple is 1
429 entry:
430   %cmp.ult = icmp ult i64 %count, 5
431   br i1 %cmp.ult, label %guardbb, label %exit
433 guardbb:
434   %cmp.ne = icmp ne i64 %count, 0
435   br i1 %cmp.ne, label %loop, label %exit
437 loop:
438   %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
439   %idx = getelementptr inbounds i32, i32* %data, i64 %iv
440   store i32 1, i32* %idx, align 4
441   %iv.next = add nuw i64 %iv, 1
442   %exitcond.not = icmp eq i64 %iv.next, %count
443   br i1 %exitcond.not, label %exit, label %loop
445 exit:
446   ret void
449 define void @test_guard_ne_ult(i32* nocapture readonly %data, i64 %count) {
450 ; CHECK-LABEL: 'test_guard_ne_ult'
451 ; CHECK-NEXT:  Classifying expressions for: @test_guard_ne_ult
452 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
453 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
454 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %data, i64 %iv
455 ; CHECK-NEXT:    --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
456 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
457 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
458 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_ne_ult
459 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
460 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 3
461 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
462 ; CHECK-NEXT:   Predicates:
463 ; CHECK:       Loop %loop: Trip multiple is 1
465 entry:
466   %cmp.ne = icmp ne i64 %count, 0
467   br i1 %cmp.ne, label %guardbb, label %exit
469 guardbb:
470   %cmp.ult = icmp ult i64 %count, 5
471   br i1 %cmp.ult, label %loop, label %exit
473 loop:
474   %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
475   %idx = getelementptr inbounds i32, i32* %data, i64 %iv
476   store i32 1, i32* %idx, align 4
477   %iv.next = add nuw i64 %iv, 1
478   %exitcond.not = icmp eq i64 %iv.next, %count
479   br i1 %exitcond.not, label %exit, label %loop
481 exit:
482   ret void
485 define void @test_guard_if_and_enter(i32* nocapture readonly %data, i64 %count) {
486 ; CHECK-LABEL: 'test_guard_if_and_enter'
487 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_and_enter
488 ; CHECK-NEXT:    %cmp.and = and i1 %cmp.ult, %cmp.ne
489 ; CHECK-NEXT:    --> %cmp.and U: full-set S: full-set
490 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
491 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
492 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %data, i64 %iv
493 ; CHECK-NEXT:    --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
494 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
495 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
496 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_and_enter
497 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
498 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 3
499 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
500 ; CHECK-NEXT:   Predicates:
501 ; CHECK:       Loop %loop: Trip multiple is 1
503 entry:
504   %cmp.ult = icmp ult i64 %count, 5
505   %cmp.ne = icmp ne i64 %count, 0
506   %cmp.and = and i1 %cmp.ult, %cmp.ne
507   br i1 %cmp.and, label %loop, label %exit
509 loop:
510   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
511   %idx = getelementptr inbounds i32, i32* %data, i64 %iv
512   store i32 1, i32* %idx, align 4
513   %iv.next = add nuw i64 %iv, 1
514   %exitcond.not = icmp eq i64 %iv.next, %count
515   br i1 %exitcond.not, label %exit, label %loop
517 exit:
518   ret void
521 define void @test_guard_if_and_skip(i32* nocapture readonly %data, i64 %count) {
522 ; CHECK-LABEL: 'test_guard_if_and_skip'
523 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_and_skip
524 ; CHECK-NEXT:    %cmp.and = and i1 %cmp.ult, %cmp.ne
525 ; CHECK-NEXT:    --> %cmp.and U: full-set S: full-set
526 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
527 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
528 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %data, i64 %iv
529 ; CHECK-NEXT:    --> {%data,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
530 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
531 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %count LoopDispositions: { %loop: Computable }
532 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_and_skip
533 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
534 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is -1
535 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
536 ; CHECK-NEXT:   Predicates:
537 ; CHECK:       Loop %loop: Trip multiple is 1
539 entry:
540   %cmp.ult = icmp ult i64 %count, 5
541   %cmp.ne = icmp ne i64 %count, 0
542   %cmp.and = and i1 %cmp.ult, %cmp.ne
543   br i1 %cmp.and, label %exit, label %loop
545 loop:
546   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
547   %idx = getelementptr inbounds i32, i32* %data, i64 %iv
548   store i32 1, i32* %idx, align 4
549   %iv.next = add nuw i64 %iv, 1
550   %exitcond.not = icmp eq i64 %iv.next, %count
551   br i1 %exitcond.not, label %exit, label %loop
553 exit:
554   ret void
557 define void @test_guard_if_and_and(i32* nocapture readonly %data, i64 %count, i1 %c) {
558 ; CHECK-LABEL: 'test_guard_if_and_and'
559 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_and_and
560 ; CHECK-NEXT:    %cmp.and1 = and i1 %c, %cmp.ne
561 ; CHECK-NEXT:    --> %cmp.and1 U: full-set S: full-set
562 ; CHECK-NEXT:    %cmp.and = and i1 %cmp.ult, %cmp.and1
563 ; CHECK-NEXT:    --> %cmp.and U: full-set S: full-set
564 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
565 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
566 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %data, i64 %iv
567 ; CHECK-NEXT:    --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
568 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
569 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
570 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_and_and
571 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
572 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 3
573 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
574 ; CHECK-NEXT:   Predicates:
575 ; CHECK:       Loop %loop: Trip multiple is 1
577 entry:
578   %cmp.ult = icmp ult i64 %count, 5
579   %cmp.ne = icmp ne i64 %count, 0
580   %cmp.and1 = and i1 %c, %cmp.ne
581   %cmp.and = and i1 %cmp.ult, %cmp.and1
582   br i1 %cmp.and, label %loop, label %exit
584 loop:
585   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
586   %idx = getelementptr inbounds i32, i32* %data, i64 %iv
587   store i32 1, i32* %idx, align 4
588   %iv.next = add nuw i64 %iv, 1
589   %exitcond.not = icmp eq i64 %iv.next, %count
590   br i1 %exitcond.not, label %exit, label %loop
592 exit:
593   ret void
596 define void @test_guard_if_and_or(i32* nocapture readonly %data, i64 %count, i1 %c) {
597 ; CHECK-LABEL: 'test_guard_if_and_or'
598 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_and_or
599 ; CHECK-NEXT:    %cmp.or = or i1 %c, %cmp.ne
600 ; CHECK-NEXT:    --> %cmp.or U: full-set S: full-set
601 ; CHECK-NEXT:    %cmp.and = and i1 %cmp.ult, %cmp.or
602 ; CHECK-NEXT:    --> %cmp.and U: full-set S: full-set
603 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
604 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
605 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %data, i64 %iv
606 ; CHECK-NEXT:    --> {%data,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
607 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
608 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %count LoopDispositions: { %loop: Computable }
609 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_and_or
610 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
611 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is -1
612 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
613 ; CHECK-NEXT:   Predicates:
614 ; CHECK:       Loop %loop: Trip multiple is 1
616 entry:
617   %cmp.ult = icmp ult i64 %count, 5
618   %cmp.ne = icmp ne i64 %count, 0
619   %cmp.or = or i1 %c, %cmp.ne
620   %cmp.and = and i1 %cmp.ult, %cmp.or
621   br i1 %cmp.and, label %loop, label %exit
623 loop:
624   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
625   %idx = getelementptr inbounds i32, i32* %data, i64 %iv
626   store i32 1, i32* %idx, align 4
627   %iv.next = add nuw i64 %iv, 1
628   %exitcond.not = icmp eq i64 %iv.next, %count
629   br i1 %exitcond.not, label %exit, label %loop
631 exit:
632   ret void
635 define void @test_guard_if_or_skip(i32* nocapture readonly %data, i64 %count) {
636 ; CHECK-LABEL: 'test_guard_if_or_skip'
637 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_or_skip
638 ; CHECK-NEXT:    %cmp.or = or i1 %cmp.uge, %cmp.eq
639 ; CHECK-NEXT:    --> %cmp.or U: full-set S: full-set
640 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
641 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
642 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %data, i64 %iv
643 ; CHECK-NEXT:    --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
644 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
645 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
646 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_or_skip
647 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
648 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 3
649 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
650 ; CHECK-NEXT:   Predicates:
651 ; CHECK:       Loop %loop: Trip multiple is 1
653 entry:
654   %cmp.uge = icmp uge i64 %count, 5
655   %cmp.eq = icmp eq i64 %count, 0
656   %cmp.or = or i1 %cmp.uge, %cmp.eq
657   br i1 %cmp.or, label %exit, label %loop
659 loop:
660   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
661   %idx = getelementptr inbounds i32, i32* %data, i64 %iv
662   store i32 1, i32* %idx, align 4
663   %iv.next = add nuw i64 %iv, 1
664   %exitcond.not = icmp eq i64 %iv.next, %count
665   br i1 %exitcond.not, label %exit, label %loop
667 exit:
668   ret void
671 define void @test_guard_if_or_enter(i32* nocapture readonly %data, i64 %count) {
672 ; CHECK-LABEL: 'test_guard_if_or_enter'
673 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_or_enter
674 ; CHECK-NEXT:    %cmp.or = or i1 %cmp.uge, %cmp.eq
675 ; CHECK-NEXT:    --> %cmp.or U: full-set S: full-set
676 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
677 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
678 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %data, i64 %iv
679 ; CHECK-NEXT:    --> {%data,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
680 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
681 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %count LoopDispositions: { %loop: Computable }
682 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_or_enter
683 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
684 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is -1
685 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
686 ; CHECK-NEXT:   Predicates:
687 ; CHECK:       Loop %loop: Trip multiple is 1
689 entry:
690   %cmp.uge = icmp uge i64 %count, 5
691   %cmp.eq = icmp eq i64 %count, 0
692   %cmp.or = or i1 %cmp.uge, %cmp.eq
693   br i1 %cmp.or, label %loop, label %exit
695 loop:
696   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
697   %idx = getelementptr inbounds i32, i32* %data, i64 %iv
698   store i32 1, i32* %idx, align 4
699   %iv.next = add nuw i64 %iv, 1
700   %exitcond.not = icmp eq i64 %iv.next, %count
701   br i1 %exitcond.not, label %exit, label %loop
703 exit:
704   ret void
707 define void @test_guard_if_or_or(i32* nocapture readonly %data, i64 %count, i1 %c) {
708 ; CHECK-LABEL: 'test_guard_if_or_or'
709 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_or_or
710 ; CHECK-NEXT:    %cmp.or1 = or i1 %c, %cmp.eq
711 ; CHECK-NEXT:    --> %cmp.or1 U: full-set S: full-set
712 ; CHECK-NEXT:    %cmp.or = or i1 %cmp.uge, %cmp.or1
713 ; CHECK-NEXT:    --> %cmp.or U: full-set S: full-set
714 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
715 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
716 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %data, i64 %iv
717 ; CHECK-NEXT:    --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
718 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
719 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
720 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_or_or
721 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
722 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 3
723 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
724 ; CHECK-NEXT:   Predicates:
725 ; CHECK:       Loop %loop: Trip multiple is 1
727 entry:
728   %cmp.uge = icmp uge i64 %count, 5
729   %cmp.eq = icmp eq i64 %count, 0
730   %cmp.or1 = or i1 %c, %cmp.eq
731   %cmp.or = or i1 %cmp.uge, %cmp.or1
732   br i1 %cmp.or, label %exit, label %loop
734 loop:
735   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
736   %idx = getelementptr inbounds i32, i32* %data, i64 %iv
737   store i32 1, i32* %idx, align 4
738   %iv.next = add nuw i64 %iv, 1
739   %exitcond.not = icmp eq i64 %iv.next, %count
740   br i1 %exitcond.not, label %exit, label %loop
742 exit:
743   ret void
746 define void @test_guard_if_or_and(i32* nocapture readonly %data, i64 %count, i1 %c) {
747 ; CHECK-LABEL: 'test_guard_if_or_and'
748 ; CHECK-NEXT:  Classifying expressions for: @test_guard_if_or_and
749 ; CHECK-NEXT:    %cmp.and = and i1 %c, %cmp.eq
750 ; CHECK-NEXT:    --> %cmp.and U: full-set S: full-set
751 ; CHECK-NEXT:    %cmp.or = or i1 %cmp.uge, %cmp.and
752 ; CHECK-NEXT:    --> %cmp.or U: full-set S: full-set
753 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
754 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
755 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %data, i64 %iv
756 ; CHECK-NEXT:    --> {%data,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
757 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
758 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %count LoopDispositions: { %loop: Computable }
759 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_if_or_and
760 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
761 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is -1
762 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
763 ; CHECK-NEXT:   Predicates:
764 ; CHECK:       Loop %loop: Trip multiple is 1
766 entry:
767   %cmp.uge = icmp uge i64 %count, 5
768   %cmp.eq = icmp eq i64 %count, 0
769   %cmp.and = and i1 %c, %cmp.eq
770   %cmp.or = or i1 %cmp.uge, %cmp.and
771   br i1 %cmp.or, label %exit, label %loop
773 loop:
774   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
775   %idx = getelementptr inbounds i32, i32* %data, i64 %iv
776   store i32 1, i32* %idx, align 4
777   %iv.next = add nuw i64 %iv, 1
778   %exitcond.not = icmp eq i64 %iv.next, %count
779   br i1 %exitcond.not, label %exit, label %loop
781 exit:
782   ret void
785 ; Test case for PR47247. Both the guard condition and the assume limit the
786 ; max backedge-taken count.
788 define void @test_guard_and_assume(i32* nocapture readonly %data, i64 %count) {
789 ; CHECK-LABEL: 'test_guard_and_assume'
790 ; CHECK-NEXT:  Classifying expressions for: @test_guard_and_assume
791 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
792 ; CHECK-NEXT:    --> {0,+,1}<nuw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
793 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %data, i64 %iv
794 ; CHECK-NEXT:    --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
795 ; CHECK-NEXT:    %iv.next = add nuw i64 %iv, 1
796 ; CHECK-NEXT:    --> {1,+,1}<nuw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
797 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_and_assume
798 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %count)
799 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 3
800 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %count)
801 ; CHECK-NEXT:   Predicates:
802 ; CHECK:       Loop %loop: Trip multiple is 1
804 entry:
805   %cmp = icmp ult i64 %count, 5
806   tail call void @llvm.assume(i1 %cmp)
807   %cmp18.not = icmp eq i64 %count, 0
808   br i1 %cmp18.not, label %exit, label %loop
810 loop:
811   %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
812   %idx = getelementptr inbounds i32, i32* %data, i64 %iv
813   store i32 1, i32* %idx, align 4
814   %iv.next = add nuw i64 %iv, 1
815   %exitcond.not = icmp eq i64 %iv.next, %count
816   br i1 %exitcond.not, label %exit, label %loop
818 exit:
819   ret void
822 ; Function Attrs: nounwind willreturn
823 declare void @llvm.assume(i1 noundef)
825 define void @guard_pessimizes_analysis_step1(i1 %c, i32 %N) {
826 ; CHECK-LABEL: 'guard_pessimizes_analysis_step1'
827 ; CHECK-NEXT:  Classifying expressions for: @guard_pessimizes_analysis_step1
828 ; CHECK-NEXT:    %init = phi i32 [ 2, %entry ], [ 3, %bb1 ]
829 ; CHECK-NEXT:    --> %init U: [2,4) S: [2,4)
830 ; CHECK-NEXT:    %iv = phi i32 [ %iv.next, %loop ], [ %init, %loop.ph ]
831 ; CHECK-NEXT:    --> {%init,+,1}<%loop> U: [2,11) S: [2,11) Exits: 9 LoopDispositions: { %loop: Computable }
832 ; CHECK-NEXT:    %iv.next = add i32 %iv, 1
833 ; CHECK-NEXT:    --> {(1 + %init)<nuw><nsw>,+,1}<%loop> U: [3,12) S: [3,12) Exits: 10 LoopDispositions: { %loop: Computable }
834 ; CHECK-NEXT:  Determining loop execution counts for: @guard_pessimizes_analysis_step1
835 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (9 + (-1 * %init)<nsw>)<nsw>
836 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 7
837 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (9 + (-1 * %init)<nsw>)<nsw>
838 ; CHECK-NEXT:   Predicates:
839 ; CHECK:       Loop %loop: Trip multiple is 1
841 entry:
842   br i1 %c, label %bb1, label %guard
844 bb1:
845   br label %guard
847 guard:
848   %init = phi i32 [ 2, %entry ], [ 3, %bb1 ]
849   %c.1 = icmp ult i32 %init, %N
850   br i1 %c.1, label %loop.ph, label %exit
852 loop.ph:
853   br label %loop
855 loop:
856   %iv = phi i32 [ %iv.next, %loop ], [ %init, %loop.ph ]
857   %iv.next = add i32 %iv, 1
858   %exitcond = icmp eq i32 %iv.next, 10
859   br i1 %exitcond, label %exit, label %loop
861 exit:
862   ret void
865 define void @guard_pessimizes_analysis_step2(i1 %c, i32 %N) {
866 ; CHECK-LABEL: 'guard_pessimizes_analysis_step2'
867 ; CHECK-NEXT:  Classifying expressions for: @guard_pessimizes_analysis_step2
868 ; CHECK-NEXT:    %init = phi i32 [ 2, %entry ], [ 3, %bb1 ]
869 ; CHECK-NEXT:    --> %init U: [2,4) S: [2,4)
870 ; CHECK-NEXT:    %iv = phi i32 [ %iv.next, %loop ], [ %init, %loop.ph ]
871 ; 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 }
872 ; CHECK-NEXT:    %iv.next = add nuw nsw i32 %iv, 2
873 ; 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 }
874 ; CHECK-NEXT:  Determining loop execution counts for: @guard_pessimizes_analysis_step2
875 ; CHECK-NEXT:  Loop %loop: backedge-taken count is ((8 + (-1 * %init)<nsw>)<nsw> /u 2)
876 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 3
877 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is ((8 + (-1 * %init)<nsw>)<nsw> /u 2)
878 ; CHECK-NEXT:   Predicates:
879 ; CHECK:       Loop %loop: Trip multiple is 1
881 entry:
882   br i1 %c, label %bb1, label %guard
884 bb1:
885   br label %guard
887 guard:
888   %init = phi i32 [ 2, %entry ], [ 3, %bb1 ]
889   %c.1 = icmp ult i32 %init, %N
890   br i1 %c.1, label %loop.ph, label %exit
892 loop.ph:
893   br label %loop
895 loop:
896   %iv = phi i32 [ %iv.next, %loop ], [ %init, %loop.ph ]
897   %iv.next = add nuw nsw i32 %iv, 2
898   %exitcond = icmp eq i32 %iv.next, 10
899   br i1 %exitcond, label %exit, label %loop
901 exit:
902   ret void
904 define void @crash(i8* %ptr) {
905 ; CHECK-LABEL: 'crash'
906 ; CHECK-NEXT:  Classifying expressions for: @crash
907 ; CHECK-NEXT:    %text.addr.5 = phi i8* [ %incdec.ptr112, %while.cond111 ], [ null, %while.body ]
908 ; CHECK-NEXT:    --> {null,+,-1}<nw><%while.cond111> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %while.cond111: Computable, %while.body: Variant }
909 ; CHECK-NEXT:    %incdec.ptr112 = getelementptr inbounds i8, i8* %text.addr.5, i64 -1
910 ; 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 }
911 ; CHECK-NEXT:    %lastout.2271 = phi i8* [ %incdec.ptr126, %while.body125 ], [ %ptr, %while.end117 ]
912 ; 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 }
913 ; CHECK-NEXT:    %incdec.ptr126 = getelementptr inbounds i8, i8* %lastout.2271, i64 1
914 ; CHECK-NEXT:    --> {(1 + %ptr),+,1}<nuw><%while.body125> U: full-set S: full-set Exits: {(-1 + (-1 * (ptrtoint i8* %ptr to i64)) + %ptr),+,-1}<nw><%while.cond111> LoopDispositions: { %while.body125: Computable }
915 ; CHECK-NEXT:  Determining loop execution counts for: @crash
916 ; CHECK-NEXT:  Loop %while.body125: backedge-taken count is {(-2 + (-1 * (ptrtoint i8* %ptr to i64))),+,-1}<nw><%while.cond111>
917 ; CHECK-NEXT:  Loop %while.body125: max backedge-taken count is -2
918 ; CHECK-NEXT:  Loop %while.body125: Predicated backedge-taken count is {(-2 + (-1 * (ptrtoint i8* %ptr to i64))),+,-1}<nw><%while.cond111>
919 ; CHECK-NEXT:   Predicates:
920 ; CHECK:       Loop %while.body125: Trip multiple is 1
921 ; CHECK-NEXT:  Loop %while.cond111: Unpredictable backedge-taken count.
922 ; CHECK-NEXT:  Loop %while.cond111: Unpredictable max backedge-taken count.
923 ; CHECK-NEXT:  Loop %while.cond111: Unpredictable predicated backedge-taken count.
924 ; CHECK-NEXT:  Loop %while.body: Unpredictable backedge-taken count.
925 ; CHECK-NEXT:  Loop %while.body: Unpredictable max backedge-taken count.
926 ; CHECK-NEXT:  Loop %while.body: Unpredictable predicated backedge-taken count.
928 entry:
929   br label %while.body
931 while.body:
932   br label %while.cond111
934 while.cond111:
935   %text.addr.5 = phi i8* [ %incdec.ptr112, %while.cond111 ], [ null, %while.body ]
936   %incdec.ptr112 = getelementptr inbounds i8, i8* %text.addr.5, i64 -1
937   br i1 false, label %while.end117, label %while.cond111
939 while.end117:
940   %cmp118 = icmp ult i8* %ptr, %incdec.ptr112
941   br i1 %cmp118, label %while.body125, label %while.cond134.preheader
944 while.cond134.preheader:
945   br label %while.body
947 while.body125:
948   %lastout.2271 = phi i8* [ %incdec.ptr126, %while.body125 ], [ %ptr, %while.end117 ]
949   %incdec.ptr126 = getelementptr inbounds i8, i8* %lastout.2271, i64 1
950   %exitcond.not = icmp eq i8* %incdec.ptr126, %incdec.ptr112
951   br i1 %exitcond.not, label %while.end129, label %while.body125
953 while.end129:                                     ; preds = %while.body125
954   ret void
957 define void @test_guard_uge(i32 %blockSize) {
958 ; CHECK-LABEL: 'test_guard_uge'
959 ; CHECK-NEXT:  Classifying expressions for: @test_guard_uge
960 ; CHECK-NEXT:    %shr = lshr i32 %blockSize, 2
961 ; CHECK-NEXT:    --> (%blockSize /u 4) U: [0,1073741824) S: [0,1073741824)
962 ; CHECK-NEXT:    %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
963 ; CHECK-NEXT:    --> {(%blockSize /u 4),+,-1}<%while.body> U: [-1073741822,1073741824) S: [-1073741822,1073741824) Exits: 1 LoopDispositions: { %while.body: Computable }
964 ; CHECK-NEXT:    %dec = add i32 %iv, -1
965 ; CHECK-NEXT:    --> {(-1 + (%blockSize /u 4))<nsw>,+,-1}<%while.body> U: [-1073741823,1073741823) S: [-1073741823,1073741823) Exits: 0 LoopDispositions: { %while.body: Computable }
966 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_uge
967 ; CHECK-NEXT:  Loop %while.body: backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
968 ; CHECK-NEXT:  Loop %while.body: max backedge-taken count is 1073741822
969 ; CHECK-NEXT:  Loop %while.body: Predicated backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
970 ; CHECK-NEXT:   Predicates:
971 ; CHECK:       Loop %while.body: Trip multiple is 1
973   %shr = lshr i32 %blockSize, 2
974   %guard = icmp uge i32 %blockSize, 4
975   br i1 %guard, label %while.body.preheader, label %while.end
977 while.body.preheader:
978   br label %while.body
980 while.body:
981   %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
982   %dec = add i32 %iv, -1
983   %cmp.not = icmp eq i32 %dec, 0
984   br i1 %cmp.not, label %while.end.loopexit, label %while.body
986 while.end.loopexit:
987   br label %while.end
989 while.end:
990   ret void
993 define void @test_guard_ugt(i32 %blockSize) {
994 ; CHECK-LABEL: 'test_guard_ugt'
995 ; CHECK-NEXT:  Classifying expressions for: @test_guard_ugt
996 ; CHECK-NEXT:    %shr = lshr i32 %blockSize, 2
997 ; CHECK-NEXT:    --> (%blockSize /u 4) U: [0,1073741824) S: [0,1073741824)
998 ; CHECK-NEXT:    %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
999 ; CHECK-NEXT:    --> {(%blockSize /u 4),+,-1}<%while.body> U: [-1073741822,1073741824) S: [-1073741822,1073741824) Exits: 1 LoopDispositions: { %while.body: Computable }
1000 ; CHECK-NEXT:    %dec = add i32 %iv, -1
1001 ; CHECK-NEXT:    --> {(-1 + (%blockSize /u 4))<nsw>,+,-1}<%while.body> U: [-1073741823,1073741823) S: [-1073741823,1073741823) Exits: 0 LoopDispositions: { %while.body: Computable }
1002 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_ugt
1003 ; CHECK-NEXT:  Loop %while.body: backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1004 ; CHECK-NEXT:  Loop %while.body: max backedge-taken count is 1073741822
1005 ; CHECK-NEXT:  Loop %while.body: Predicated backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1006 ; CHECK-NEXT:   Predicates:
1007 ; CHECK:       Loop %while.body: Trip multiple is 1
1009   %shr = lshr i32 %blockSize, 2
1010   %guard = icmp ugt i32 %blockSize, 3
1011   br i1 %guard, label %while.body.preheader, label %while.end
1013 while.body.preheader:
1014   br label %while.body
1016 while.body:
1017   %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1018   %dec = add i32 %iv, -1
1019   %cmp.not = icmp eq i32 %dec, 0
1020   br i1 %cmp.not, label %while.end.loopexit, label %while.body
1022 while.end.loopexit:
1023   br label %while.end
1025 while.end:
1026   ret void
1029 define void @test_guard_uge_and_ule(i32 %blockSize) {
1030 ; CHECK-LABEL: 'test_guard_uge_and_ule'
1031 ; CHECK-NEXT:  Classifying expressions for: @test_guard_uge_and_ule
1032 ; CHECK-NEXT:    %shr = lshr i32 %blockSize, 2
1033 ; CHECK-NEXT:    --> (%blockSize /u 4) U: [0,1073741824) S: [0,1073741824)
1034 ; CHECK-NEXT:    %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1035 ; CHECK-NEXT:    --> {(%blockSize /u 4),+,-1}<%while.body> U: [-255,1073741824) S: [-255,1073741824) Exits: 1 LoopDispositions: { %while.body: Computable }
1036 ; CHECK-NEXT:    %dec = add i32 %iv, -1
1037 ; CHECK-NEXT:    --> {(-1 + (%blockSize /u 4))<nsw>,+,-1}<%while.body> U: [-256,1073741823) S: [-256,1073741823) Exits: 0 LoopDispositions: { %while.body: Computable }
1038 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_uge_and_ule
1039 ; CHECK-NEXT:  Loop %while.body: backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1040 ; CHECK-NEXT:  Loop %while.body: max backedge-taken count is 255
1041 ; CHECK-NEXT:  Loop %while.body: Predicated backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1042 ; CHECK-NEXT:   Predicates:
1043 ; CHECK:       Loop %while.body: Trip multiple is 1
1045   %shr = lshr i32 %blockSize, 2
1046   %guard1 = icmp uge i32 %blockSize, 4
1047   br i1 %guard1, label %while.guard, label %while.end
1049 while.guard:
1050   %guard2 = icmp ule i32 %blockSize, 1024
1051   br i1 %guard2, label %while.body.preheader, label %while.end
1053 while.body.preheader:
1054   br label %while.body
1056 while.body:
1057   %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1058   %dec = add i32 %iv, -1
1059   %cmp.not = icmp eq i32 %dec, 0
1060   br i1 %cmp.not, label %while.end.loopexit, label %while.body
1062 while.end.loopexit:
1063   br label %while.end
1065 while.end:
1066   ret void
1069 define void @test_guard_ugt_and_ult(i32 %blockSize) {
1070 ; CHECK-LABEL: 'test_guard_ugt_and_ult'
1071 ; CHECK-NEXT:  Classifying expressions for: @test_guard_ugt_and_ult
1072 ; CHECK-NEXT:    %shr = lshr i32 %blockSize, 2
1073 ; CHECK-NEXT:    --> (%blockSize /u 4) U: [0,1073741824) S: [0,1073741824)
1074 ; CHECK-NEXT:    %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1075 ; CHECK-NEXT:    --> {(%blockSize /u 4),+,-1}<%while.body> U: [-255,1073741824) S: [-255,1073741824) Exits: 1 LoopDispositions: { %while.body: Computable }
1076 ; CHECK-NEXT:    %dec = add i32 %iv, -1
1077 ; CHECK-NEXT:    --> {(-1 + (%blockSize /u 4))<nsw>,+,-1}<%while.body> U: [-256,1073741823) S: [-256,1073741823) Exits: 0 LoopDispositions: { %while.body: Computable }
1078 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_ugt_and_ult
1079 ; CHECK-NEXT:  Loop %while.body: backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1080 ; CHECK-NEXT:  Loop %while.body: max backedge-taken count is 255
1081 ; CHECK-NEXT:  Loop %while.body: Predicated backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
1082 ; CHECK-NEXT:   Predicates:
1083 ; CHECK:       Loop %while.body: Trip multiple is 1
1085   %shr = lshr i32 %blockSize, 2
1086   %guard1 = icmp ugt i32 %blockSize, 3
1087   br i1 %guard1, label %while.guard, label %while.end
1089 while.guard:
1090   %guard2 = icmp ult i32 %blockSize, 1025
1091   br i1 %guard2, label %while.body.preheader, label %while.end
1093 while.body.preheader:
1094   br label %while.body
1096 while.body:
1097   %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
1098   %dec = add i32 %iv, -1
1099   %cmp.not = icmp eq i32 %dec, 0
1100   br i1 %cmp.not, label %while.end.loopexit, label %while.body
1102 while.end.loopexit:
1103   br label %while.end
1105 while.end:
1106   ret void
1109 define void @test_guard_slt_sgt_1(i32* nocapture %a, i64 %N) {
1110 ; CHECK-LABEL: 'test_guard_slt_sgt_1'
1111 ; CHECK-NEXT:  Classifying expressions for: @test_guard_slt_sgt_1
1112 ; CHECK-NEXT:    %and = and i1 %c.0, %c.1
1113 ; CHECK-NEXT:    --> %and U: full-set S: full-set
1114 ; CHECK-NEXT:    %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
1115 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,11) S: [0,11) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1116 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
1117 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %N) + %a) LoopDispositions: { %loop: Computable }
1118 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
1119 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,12) S: [1,12) Exits: %N LoopDispositions: { %loop: Computable }
1120 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_slt_sgt_1
1121 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %N)
1122 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 10
1123 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %N)
1124 ; CHECK-NEXT:   Predicates:
1125 ; CHECK:       Loop %loop: Trip multiple is 1
1127 entry:
1128   %c.0 = icmp slt i64 %N, 12
1129   %c.1 = icmp sgt i64 %N, 0
1130   %and = and i1 %c.0, %c.1
1131   br i1 %and, label %loop, label %exit
1133 loop:
1134   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
1135   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
1136   store i32 1, i32* %idx, align 4
1137   %iv.next = add nuw nsw i64 %iv, 1
1138   %exitcond = icmp eq i64 %iv.next, %N
1139   br i1 %exitcond, label %exit, label %loop
1141 exit:
1142   ret void
1145 define void @test_guard_slt_sgt_2(i32* nocapture %a, i64 %i) {
1146 ; CHECK-LABEL: 'test_guard_slt_sgt_2'
1147 ; CHECK-NEXT:  Classifying expressions for: @test_guard_slt_sgt_2
1148 ; CHECK-NEXT:    %and = and i1 %c.0, %c.1
1149 ; CHECK-NEXT:    --> %and U: full-set S: full-set
1150 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
1151 ; CHECK-NEXT:    --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 17 LoopDispositions: { %loop: Computable }
1152 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
1153 ; CHECK-NEXT:    --> {((4 * %i) + %a),+,4}<nw><%loop> U: full-set S: full-set Exits: (68 + %a) LoopDispositions: { %loop: Computable }
1154 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
1155 ; CHECK-NEXT:    --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 18 LoopDispositions: { %loop: Computable }
1156 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_slt_sgt_2
1157 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (17 + (-1 * %i))
1158 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 12
1159 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (17 + (-1 * %i))
1160 ; CHECK-NEXT:   Predicates:
1161 ; CHECK:       Loop %loop: Trip multiple is 1
1163 entry:
1164   %c.0 = icmp slt i64 %i, 16
1165   %c.1 = icmp sgt i64 %i, 4
1166   %and = and i1 %c.0, %c.1
1167   br i1 %and, label %loop, label %exit
1169 loop:
1170   %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
1171   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
1172   store i32 1, i32* %idx, align 4
1173   %iv.next = add nuw nsw i64 %iv, 1
1174   %exitcond = icmp eq i64 %iv.next, 18
1175   br i1 %exitcond, label %exit, label %loop
1177 exit:
1178   ret void
1181 define void @test_guard_sle_sge_1(i32* nocapture %a, i64 %N) {
1182 ; CHECK-LABEL: 'test_guard_sle_sge_1'
1183 ; CHECK-NEXT:  Classifying expressions for: @test_guard_sle_sge_1
1184 ; CHECK-NEXT:    %and = and i1 %c.0, %c.1
1185 ; CHECK-NEXT:    --> %and U: full-set S: full-set
1186 ; CHECK-NEXT:    %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
1187 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,12) S: [0,12) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1188 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
1189 ; CHECK-NEXT:    --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %N) + %a) LoopDispositions: { %loop: Computable }
1190 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
1191 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,13) S: [1,13) Exits: %N LoopDispositions: { %loop: Computable }
1192 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_sle_sge_1
1193 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %N)
1194 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 11
1195 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %N)
1196 ; CHECK-NEXT:   Predicates:
1197 ; CHECK:       Loop %loop: Trip multiple is 1
1199 entry:
1200   %c.0 = icmp sle i64 %N, 12
1201   %c.1 = icmp sge i64 %N, 1
1202   %and = and i1 %c.0, %c.1
1203   br i1 %and, label %loop, label %exit
1205 loop:
1206   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
1207   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
1208   store i32 1, i32* %idx, align 4
1209   %iv.next = add nuw nsw i64 %iv, 1
1210   %exitcond = icmp eq i64 %iv.next, %N
1211   br i1 %exitcond, label %exit, label %loop
1213 exit:
1214   ret void
1217 define void @test_guard_sle_sge_2(i32* nocapture %a, i64 %i) {
1218 ; CHECK-LABEL: 'test_guard_sle_sge_2'
1219 ; CHECK-NEXT:  Classifying expressions for: @test_guard_sle_sge_2
1220 ; CHECK-NEXT:    %and = and i1 %c.0, %c.1
1221 ; CHECK-NEXT:    --> %and U: full-set S: full-set
1222 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
1223 ; CHECK-NEXT:    --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 17 LoopDispositions: { %loop: Computable }
1224 ; CHECK-NEXT:    %idx = getelementptr inbounds i32, i32* %a, i64 %iv
1225 ; CHECK-NEXT:    --> {((4 * %i) + %a),+,4}<nw><%loop> U: full-set S: full-set Exits: (68 + %a) LoopDispositions: { %loop: Computable }
1226 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
1227 ; CHECK-NEXT:    --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 18 LoopDispositions: { %loop: Computable }
1228 ; CHECK-NEXT:  Determining loop execution counts for: @test_guard_sle_sge_2
1229 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (17 + (-1 * %i))
1230 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 13
1231 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (17 + (-1 * %i))
1232 ; CHECK-NEXT:   Predicates:
1233 ; CHECK:       Loop %loop: Trip multiple is 1
1235 entry:
1236   %c.0 = icmp sle i64 %i, 16
1237   %c.1 = icmp sge i64 %i, 4
1238   %and = and i1 %c.0, %c.1
1239   br i1 %and, label %loop, label %exit
1241 loop:
1242   %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
1243   %idx = getelementptr inbounds i32, i32* %a, i64 %iv
1244   store i32 1, i32* %idx, align 4
1245   %iv.next = add nuw nsw i64 %iv, 1
1246   %exitcond = icmp eq i64 %iv.next, 18
1247   br i1 %exitcond, label %exit, label %loop
1249 exit:
1250   ret void
1253 ; The function below uses a single condition to ensure %N > 0 && %N < 8.
1254 ; InstCombine transforms such checks with 2 conditions to a single check as in
1255 ; the test function.
1256 define void @optimized_range_check_unsigned(i16* %pred, i32 %N) {
1257 ; CHECK-LABEL: 'optimized_range_check_unsigned'
1258 ; CHECK-NEXT:  Classifying expressions for: @optimized_range_check_unsigned
1259 ; CHECK-NEXT:    %N.off = add i32 %N, -1
1260 ; CHECK-NEXT:    --> (-1 + %N) U: full-set S: full-set
1261 ; CHECK-NEXT:    %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1262 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,7) S: [0,7) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1263 ; CHECK-NEXT:    %gep = getelementptr inbounds i16, i16* %pred, i32 %iv
1264 ; CHECK-NEXT:    --> {%pred,+,2}<nuw><%loop> U: full-set S: full-set Exits: ((2 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %pred) LoopDispositions: { %loop: Computable }
1265 ; CHECK-NEXT:    %iv.next = add nuw nsw i32 %iv, 1
1266 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,8) S: [1,8) Exits: %N LoopDispositions: { %loop: Computable }
1267 ; CHECK-NEXT:  Determining loop execution counts for: @optimized_range_check_unsigned
1268 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %N)
1269 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 6
1270 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %N)
1271 ; CHECK-NEXT:   Predicates:
1272 ; CHECK:       Loop %loop: Trip multiple is 1
1274 entry:
1275   %N.off = add i32 %N, -1
1276   %cmp = icmp ult i32 %N.off, 7
1277   br i1 %cmp, label %loop, label %exit
1279 loop:
1280   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1281   %gep = getelementptr inbounds i16, i16* %pred, i32 %iv
1282   store i16 0, i16* %gep, align 2
1283   %iv.next = add nuw nsw i32 %iv, 1
1284   %ec = icmp eq i32 %iv.next, %N
1285   br i1 %ec, label %exit, label %loop
1287 exit:
1288   ret void
1291 ; Same as @optimized_range_check_unsigned, but with the icmp operands swapped.
1292 define void @optimized_range_check_unsigned_icmp_ops_swapped(i16* %pred, i32 %N) {
1293 ; CHECK-LABEL: 'optimized_range_check_unsigned_icmp_ops_swapped'
1294 ; CHECK-NEXT:  Classifying expressions for: @optimized_range_check_unsigned_icmp_ops_swapped
1295 ; CHECK-NEXT:    %N.off = add i32 %N, -1
1296 ; CHECK-NEXT:    --> (-1 + %N) U: full-set S: full-set
1297 ; CHECK-NEXT:    %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1298 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,7) S: [0,7) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1299 ; CHECK-NEXT:    %gep = getelementptr inbounds i16, i16* %pred, i32 %iv
1300 ; 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 }
1301 ; CHECK-NEXT:    %iv.next = add nuw nsw i32 %iv, 1
1302 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,8) S: [1,8) Exits: %N LoopDispositions: { %loop: Computable }
1303 ; CHECK-NEXT:  Determining loop execution counts for: @optimized_range_check_unsigned_icmp_ops_swapped
1304 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %N)
1305 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 6
1306 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %N)
1307 ; CHECK-NEXT:   Predicates:
1308 ; CHECK:       Loop %loop: Trip multiple is 1
1310 entry:
1311   %N.off = add i32 %N, -1
1312   %cmp = icmp ugt i32 7, %N.off
1313   br i1 %cmp, label %loop, label %exit
1315 loop:
1316   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1317   %gep = getelementptr inbounds i16, i16* %pred, i32 %iv
1318   store i16 0, i16* %gep, align 2
1319   %iv.next = add nuw nsw i32 %iv, 1
1320   %ec = icmp eq i32 %iv.next, %N
1321   br i1 %ec, label %exit, label %loop
1323 exit:
1324   ret void
1327 ; The function below uses a single condition to ensure %N > 2 && %N < 22.
1328 ; InstCombine transforms such checks with 2 conditions to a single check as in
1329 ; the test function.
1330 define void @optimized_range_check_unsigned2(i16* %pred, i32 %N) {
1331 ; CHECK-LABEL: 'optimized_range_check_unsigned2'
1332 ; CHECK-NEXT:  Classifying expressions for: @optimized_range_check_unsigned2
1333 ; CHECK-NEXT:    %N.off = add i32 %N, -2
1334 ; CHECK-NEXT:    --> (-2 + %N) U: full-set S: full-set
1335 ; CHECK-NEXT:    %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1336 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,21) S: [0,21) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1337 ; CHECK-NEXT:    %gep = getelementptr inbounds i16, i16* %pred, i32 %iv
1338 ; 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 }
1339 ; CHECK-NEXT:    %iv.next = add nuw nsw i32 %iv, 1
1340 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,22) S: [1,22) Exits: %N LoopDispositions: { %loop: Computable }
1341 ; CHECK-NEXT:  Determining loop execution counts for: @optimized_range_check_unsigned2
1342 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %N)
1343 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 20
1344 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %N)
1345 ; CHECK-NEXT:   Predicates:
1346 ; CHECK:       Loop %loop: Trip multiple is 1
1348 entry:
1349   %N.off = add i32 %N, -2
1350   %cmp = icmp ult i32 %N.off, 20
1351   br i1 %cmp, label %loop, label %exit
1353 loop:
1354   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1355   %gep = getelementptr inbounds i16, i16* %pred, i32 %iv
1356   store i16 0, i16* %gep, align 2
1357   %iv.next = add nuw nsw i32 %iv, 1
1358   %ec = icmp eq i32 %iv.next, %N
1359   br i1 %ec, label %exit, label %loop
1361 exit:
1362   ret void
1365 ; Same as @optimized_range_check_unsigned, but %N already has a range limited
1366 ; to [2,4) beforehand.
1367 define void @optimized_range_check_unsigned3(i16* %pred, i1 %c) {
1368 ; CHECK-LABEL: 'optimized_range_check_unsigned3'
1369 ; CHECK-NEXT:  Classifying expressions for: @optimized_range_check_unsigned3
1370 ; CHECK-NEXT:    %N = select i1 %c, i32 2, i32 3
1371 ; CHECK-NEXT:    --> %N U: [2,4) S: [2,4)
1372 ; CHECK-NEXT:    %N.off = add i32 %N, -1
1373 ; CHECK-NEXT:    --> (-1 + %N)<nsw> U: [1,3) S: [1,3)
1374 ; CHECK-NEXT:    %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1375 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,3) S: [0,3) Exits: (-1 + %N)<nsw> 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)<nsw> 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,4) S: [1,4) Exits: %N LoopDispositions: { %loop: Computable }
1380 ; CHECK-NEXT:  Determining loop execution counts for: @optimized_range_check_unsigned3
1381 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %N)<nsw>
1382 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 2
1383 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %N)<nsw>
1384 ; CHECK-NEXT:   Predicates:
1385 ; CHECK:       Loop %loop: Trip multiple is 1
1387 entry:
1388   %N = select i1 %c, i32 2, i32 3
1389   %N.off = add i32 %N, -1
1390   %cmp = icmp ult i32 %N.off, 7
1391   br i1 %cmp, label %loop, label %exit
1393 loop:
1394   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1395   %gep = getelementptr inbounds i16, i16* %pred, i32 %iv
1396   store i16 0, i16* %gep, align 2
1397   %iv.next = add nuw nsw i32 %iv, 1
1398   %ec = icmp eq i32 %iv.next, %N
1399   br i1 %ec, label %exit, label %loop
1401 exit:
1402   ret void
1405 ; Similar to @optimized_range_check_unsigned, but the initial compare checks
1406 ; against unsigned max (-1), which breaks the range check idiom.
1407 define void @not_optimized_range_check_unsigned1(i16* %pred, i32 %N) {
1408 ; CHECK-LABEL: 'not_optimized_range_check_unsigned1'
1409 ; CHECK-NEXT:  Classifying expressions for: @not_optimized_range_check_unsigned1
1410 ; CHECK-NEXT:    %N.off = add i32 %N, -1
1411 ; CHECK-NEXT:    --> (-1 + %N) U: full-set S: full-set
1412 ; CHECK-NEXT:    %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1413 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1414 ; CHECK-NEXT:    %gep = getelementptr inbounds i16, i16* %pred, i32 %iv
1415 ; 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 }
1416 ; CHECK-NEXT:    %iv.next = add nuw nsw i32 %iv, 1
1417 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %N LoopDispositions: { %loop: Computable }
1418 ; CHECK-NEXT:  Determining loop execution counts for: @not_optimized_range_check_unsigned1
1419 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %N)
1420 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is -2
1421 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %N)
1422 ; CHECK-NEXT:   Predicates:
1423 ; CHECK:       Loop %loop: Trip multiple is 1
1425 entry:
1426   %N.off = add i32 %N, -1
1427   %cmp = icmp ult i32 %N.off, -1
1428   br i1 %cmp, label %loop, label %exit
1430 loop:
1431   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1432   %gep = getelementptr inbounds i16, i16* %pred, i32 %iv
1433   store i16 0, i16* %gep, align 2
1434   %iv.next = add nuw nsw i32 %iv, 1
1435   %ec = icmp eq i32 %iv.next, %N
1436   br i1 %ec, label %exit, label %loop
1438 exit:
1439   ret void
1442 ; Similar to @optimized_range_check_unsigned, but the initial compare checks
1443 ; against 0, which breaks the range check idiom.
1444 define void @not_optimized_range_check_unsigned2(i16* %pred, i32 %N) {
1445 ; CHECK-LABEL: 'not_optimized_range_check_unsigned2'
1446 ; CHECK-NEXT:  Classifying expressions for: @not_optimized_range_check_unsigned2
1447 ; CHECK-NEXT:    %N.off = add i32 %N, -1
1448 ; CHECK-NEXT:    --> (-1 + %N) U: full-set S: full-set
1449 ; CHECK-NEXT:    %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1450 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
1451 ; CHECK-NEXT:    %gep = getelementptr inbounds i16, i16* %pred, i32 %iv
1452 ; 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 }
1453 ; CHECK-NEXT:    %iv.next = add nuw nsw i32 %iv, 1
1454 ; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %N LoopDispositions: { %loop: Computable }
1455 ; CHECK-NEXT:  Determining loop execution counts for: @not_optimized_range_check_unsigned2
1456 ; CHECK-NEXT:  Loop %loop: backedge-taken count is (-1 + %N)
1457 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is -2
1458 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is (-1 + %N)
1459 ; CHECK-NEXT:   Predicates:
1460 ; CHECK:       Loop %loop: Trip multiple is 1
1462 entry:
1463   %N.off = add i32 %N, -1
1464   %cmp = icmp ult i32 %N.off, 0
1465   br i1 %cmp, label %loop, label %exit
1467 loop:
1468   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1469   %gep = getelementptr inbounds i16, i16* %pred, i32 %iv
1470   store i16 0, i16* %gep, align 2
1471   %iv.next = add nuw nsw i32 %iv, 1
1472   %ec = icmp eq i32 %iv.next, %N
1473   br i1 %ec, label %exit, label %loop
1475 exit:
1476   ret void
1479 define i32 @sle_sgt_ult_umax_to_smax(i32 %num) {
1480 ; CHECK-LABEL: 'sle_sgt_ult_umax_to_smax'
1481 ; CHECK-NEXT:  Classifying expressions for: @sle_sgt_ult_umax_to_smax
1482 ; CHECK-NEXT:    %iv = phi i32 [ 0, %guard.3 ], [ %iv.next, %loop ]
1483 ; CHECK-NEXT:    --> {0,+,4}<nuw><%loop> U: [0,25) S: [0,25) Exits: (4 * ((-4 + %num) /u 4))<nuw> LoopDispositions: { %loop: Computable }
1484 ; CHECK-NEXT:    %iv.next = add nuw i32 %iv, 4
1485 ; CHECK-NEXT:    --> {4,+,4}<nuw><%loop> U: [4,29) S: [4,29) Exits: (4 + (4 * ((-4 + %num) /u 4))<nuw>) LoopDispositions: { %loop: Computable }
1486 ; CHECK-NEXT:  Determining loop execution counts for: @sle_sgt_ult_umax_to_smax
1487 ; CHECK-NEXT:  Loop %loop: backedge-taken count is ((-4 + %num) /u 4)
1488 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 6
1489 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is ((-4 + %num) /u 4)
1490 ; CHECK-NEXT:   Predicates:
1491 ; CHECK:       Loop %loop: Trip multiple is 1
1493 guard.1:
1494   %cmp.1 = icmp sle i32 %num, 0
1495   br i1 %cmp.1, label %exit, label %guard.2
1497 guard.2:
1498   %cmp.2 = icmp sgt i32 %num, 28
1499   br i1 %cmp.2, label %exit, label %guard.3
1501 guard.3:
1502   %cmp.3 = icmp ult i32 %num, 4
1503   br i1 %cmp.3, label %exit, label %loop
1505 loop:
1506   %iv = phi i32 [ 0, %guard.3 ], [ %iv.next, %loop ]
1507   %iv.next = add nuw i32 %iv, 4
1508   %ec = icmp eq i32 %iv.next, %num
1509   br i1 %ec, label %exit, label %loop
1511 exit:
1512   ret i32 0
1515 ; Similar to @sle_sgt_ult_umax_to_smax but with different predicate order.
1516 define i32 @ult_sle_sgt_umax_to_smax(i32 %num) {
1517 ; CHECK-LABEL: 'ult_sle_sgt_umax_to_smax'
1518 ; CHECK-NEXT:  Classifying expressions for: @ult_sle_sgt_umax_to_smax
1519 ; CHECK-NEXT:    %iv = phi i32 [ 0, %guard.3 ], [ %iv.next, %loop ]
1520 ; CHECK-NEXT:    --> {0,+,4}<nuw><%loop> U: [0,-3) S: [-2147483648,2147483645) Exits: (4 * ((-4 + %num) /u 4))<nuw> LoopDispositions: { %loop: Computable }
1521 ; CHECK-NEXT:    %iv.next = add nuw i32 %iv, 4
1522 ; CHECK-NEXT:    --> {4,+,4}<nuw><%loop> U: [4,-3) S: [-2147483648,2147483645) Exits: (4 + (4 * ((-4 + %num) /u 4))<nuw>) LoopDispositions: { %loop: Computable }
1523 ; CHECK-NEXT:  Determining loop execution counts for: @ult_sle_sgt_umax_to_smax
1524 ; CHECK-NEXT:  Loop %loop: backedge-taken count is ((-4 + %num) /u 4)
1525 ; CHECK-NEXT:  Loop %loop: max backedge-taken count is 1073741823
1526 ; CHECK-NEXT:  Loop %loop: Predicated backedge-taken count is ((-4 + %num) /u 4)
1527 ; CHECK-NEXT:   Predicates:
1528 ; CHECK:       Loop %loop: Trip multiple is 1
1530 guard.1:
1531   %cmp.1 = icmp ult i32 %num, 4
1532   br i1 %cmp.1, label %exit, label %guard.2
1534 guard.2:
1535   %cmp.2 = icmp sgt i32 %num, 28
1536   br i1 %cmp.2, label %exit, label %guard.3
1538 guard.3:
1539   %cmp.3 = icmp sle i32 %num, 0
1540   br i1 %cmp.3, label %exit, label %loop
1542 loop:
1543   %iv = phi i32 [ 0, %guard.3 ], [ %iv.next, %loop ]
1544   %iv.next = add nuw i32 %iv, 4
1545   %ec = icmp eq i32 %iv.next, %num
1546   br i1 %ec, label %exit, label %loop
1548 exit:
1549   ret i32 0