1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
2 ; RUN: opt -verify-loop-info -irce-print-changed-loops -passes=irce -S < %s 2>&1 | FileCheck %s
3 ; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,irce' -S < %s 2>&1 | FileCheck %s
5 ; CHECK: irce: in function test_01: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
6 ; CHECK: irce: in function test_02: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
7 ; CHECK: irce: in function test_03: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
8 ; CHECK: irce: in function test_04: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
9 ; CHECK: irce: in function test_05: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
10 ; CHECK: irce: in function test_06: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
11 ; CHECK-NOT: irce: in function test_07: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
12 ; CHECK: irce: in function test_08: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
13 ; CHECK-NOT: irce: in function test_09: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
15 ; ULT condition for increasing loop.
16 define void @test_01(ptr %arr, ptr %a_len_ptr) #0 {
17 ; CHECK-LABEL: define void @test_01
18 ; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {
20 ; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0:![0-9]+]]
21 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 0, [[EXIT_MAINLOOP_AT]]
22 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
23 ; CHECK: loop.preheader:
24 ; CHECK-NEXT: br label [[LOOP:%.*]]
26 ; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
27 ; CHECK-NEXT: [[IDX_NEXT]] = add nuw nsw i32 [[IDX]], 1
28 ; CHECK-NEXT: [[ABC:%.*]] = icmp ult i32 [[IDX]], [[EXIT_MAINLOOP_AT]]
29 ; CHECK-NEXT: br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]
31 ; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]
32 ; CHECK-NEXT: store i32 0, ptr [[ADDR]], align 4
33 ; CHECK-NEXT: [[NEXT:%.*]] = icmp ult i32 [[IDX_NEXT]], 100
34 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[IDX_NEXT]], [[EXIT_MAINLOOP_AT]]
35 ; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
36 ; CHECK: main.exit.selector:
37 ; CHECK-NEXT: [[IDX_NEXT_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT]], [[IN_BOUNDS]] ]
38 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[IDX_NEXT_LCSSA]], 100
39 ; CHECK-NEXT: br i1 [[TMP2]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
40 ; CHECK: main.pseudo.exit:
41 ; CHECK-NEXT: [[IDX_COPY:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
42 ; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
43 ; CHECK-NEXT: br label [[POSTLOOP:%.*]]
44 ; CHECK: out.of.bounds.loopexit:
45 ; CHECK-NEXT: br label [[OUT_OF_BOUNDS:%.*]]
46 ; CHECK: out.of.bounds.loopexit1:
47 ; CHECK-NEXT: br label [[OUT_OF_BOUNDS]]
48 ; CHECK: out.of.bounds:
49 ; CHECK-NEXT: ret void
50 ; CHECK: exit.loopexit:
51 ; CHECK-NEXT: br label [[EXIT]]
53 ; CHECK-NEXT: ret void
55 ; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]
56 ; CHECK: loop.postloop:
57 ; CHECK-NEXT: [[IDX_POSTLOOP:%.*]] = phi i32 [ [[IDX_COPY]], [[POSTLOOP]] ], [ [[IDX_NEXT_POSTLOOP:%.*]], [[IN_BOUNDS_POSTLOOP:%.*]] ]
58 ; CHECK-NEXT: [[IDX_NEXT_POSTLOOP]] = add nuw nsw i32 [[IDX_POSTLOOP]], 1
59 ; CHECK-NEXT: [[ABC_POSTLOOP:%.*]] = icmp ult i32 [[IDX_POSTLOOP]], [[EXIT_MAINLOOP_AT]]
60 ; CHECK-NEXT: br i1 [[ABC_POSTLOOP]], label [[IN_BOUNDS_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]
61 ; CHECK: in.bounds.postloop:
62 ; CHECK-NEXT: [[ADDR_POSTLOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_POSTLOOP]]
63 ; CHECK-NEXT: store i32 0, ptr [[ADDR_POSTLOOP]], align 4
64 ; CHECK-NEXT: [[NEXT_POSTLOOP:%.*]] = icmp ult i32 [[IDX_NEXT_POSTLOOP]], 100
65 ; CHECK-NEXT: br i1 [[NEXT_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP1:![0-9]+]], !loop_constrainer.loop.clone [[META6:![0-9]+]]
69 %len = load i32, ptr %a_len_ptr, !range !0
73 %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
74 %idx.next = add nsw nuw i32 %idx, 1
75 %abc = icmp ult i32 %idx, %len
76 br i1 %abc, label %in.bounds, label %out.of.bounds
79 %addr = getelementptr i32, ptr %arr, i32 %idx
80 store i32 0, ptr %addr
81 %next = icmp ult i32 %idx.next, 100
82 br i1 %next, label %loop, label %exit
91 ; ULT condition for decreasing loops.
92 define void @test_02(ptr %arr, ptr %a_len_ptr) #0 {
93 ; CHECK-LABEL: define void @test_02
94 ; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {
96 ; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0]]
97 ; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[LEN]], i32 1)
98 ; CHECK-NEXT: [[EXIT_PRELOOP_AT:%.*]] = add nsw i32 [[UMAX]], -1
99 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i32 100, [[EXIT_PRELOOP_AT]]
100 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]]
101 ; CHECK: loop.preloop.preheader:
102 ; CHECK-NEXT: br label [[LOOP_PRELOOP:%.*]]
104 ; CHECK-NEXT: br label [[LOOP:%.*]]
106 ; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_PRELOOP_COPY:%.*]], [[MAINLOOP:%.*]] ], [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ]
107 ; CHECK-NEXT: [[IDX_NEXT]] = add i32 [[IDX]], -1
108 ; CHECK-NEXT: [[ABC:%.*]] = icmp ult i32 [[IDX]], [[LEN]]
109 ; CHECK-NEXT: br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]
111 ; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]
112 ; CHECK-NEXT: store i32 0, ptr [[ADDR]], align 4
113 ; CHECK-NEXT: [[NEXT:%.*]] = icmp ult i32 [[IDX_NEXT]], 1
114 ; CHECK-NEXT: br i1 [[NEXT]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP]]
115 ; CHECK: out.of.bounds.loopexit:
116 ; CHECK-NEXT: br label [[OUT_OF_BOUNDS:%.*]]
117 ; CHECK: out.of.bounds.loopexit1:
118 ; CHECK-NEXT: br label [[OUT_OF_BOUNDS]]
119 ; CHECK: out.of.bounds:
120 ; CHECK-NEXT: ret void
121 ; CHECK: exit.loopexit:
122 ; CHECK-NEXT: br label [[EXIT:%.*]]
124 ; CHECK-NEXT: ret void
125 ; CHECK: loop.preloop:
126 ; CHECK-NEXT: [[IDX_PRELOOP:%.*]] = phi i32 [ [[IDX_NEXT_PRELOOP:%.*]], [[IN_BOUNDS_PRELOOP:%.*]] ], [ 100, [[LOOP_PRELOOP_PREHEADER]] ]
127 ; CHECK-NEXT: [[IDX_NEXT_PRELOOP]] = add i32 [[IDX_PRELOOP]], -1
128 ; CHECK-NEXT: [[ABC_PRELOOP:%.*]] = icmp ult i32 [[IDX_PRELOOP]], [[LEN]]
129 ; CHECK-NEXT: br i1 [[ABC_PRELOOP]], label [[IN_BOUNDS_PRELOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]
130 ; CHECK: in.bounds.preloop:
131 ; CHECK-NEXT: [[ADDR_PRELOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_PRELOOP]]
132 ; CHECK-NEXT: store i32 0, ptr [[ADDR_PRELOOP]], align 4
133 ; CHECK-NEXT: [[NEXT_PRELOOP:%.*]] = icmp ult i32 [[IDX_NEXT_PRELOOP]], 1
134 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP]], [[EXIT_PRELOOP_AT]]
135 ; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true
136 ; CHECK-NEXT: br i1 [[TMP2]], label [[PRELOOP_EXIT_SELECTOR:%.*]], label [[LOOP_PRELOOP]], !llvm.loop [[LOOP7:![0-9]+]], !loop_constrainer.loop.clone [[META6]]
137 ; CHECK: preloop.exit.selector:
138 ; CHECK-NEXT: [[IDX_NEXT_PRELOOP_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT_PRELOOP]], [[IN_BOUNDS_PRELOOP]] ]
139 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP_LCSSA]], 0
140 ; CHECK-NEXT: br i1 [[TMP3]], label [[PRELOOP_PSEUDO_EXIT]], label [[EXIT]]
141 ; CHECK: preloop.pseudo.exit:
142 ; CHECK-NEXT: [[IDX_PRELOOP_COPY]] = phi i32 [ 100, [[ENTRY:%.*]] ], [ [[IDX_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
143 ; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i32 [ 100, [[ENTRY]] ], [ [[IDX_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
144 ; CHECK-NEXT: br label [[MAINLOOP]]
148 %len = load i32, ptr %a_len_ptr, !range !0
152 %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ]
153 %idx.next = add i32 %idx, -1
154 %abc = icmp ult i32 %idx, %len
155 br i1 %abc, label %in.bounds, label %out.of.bounds
158 %addr = getelementptr i32, ptr %arr, i32 %idx
159 store i32 0, ptr %addr
160 %next = icmp ult i32 %idx.next, 1
161 br i1 %next, label %exit, label %loop
171 define void @test_03(ptr %arr, ptr %a_len_ptr) #0 {
172 ; CHECK-LABEL: define void @test_03
173 ; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {
175 ; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0]]
176 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 0, [[EXIT_MAINLOOP_AT]]
177 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
178 ; CHECK: loop.preheader:
179 ; CHECK-NEXT: br label [[LOOP:%.*]]
181 ; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
182 ; CHECK-NEXT: [[IDX_NEXT]] = add nuw nsw i32 [[IDX]], 1
183 ; CHECK-NEXT: [[ABC:%.*]] = icmp ult i32 [[IDX]], [[EXIT_MAINLOOP_AT]]
184 ; CHECK-NEXT: br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]
186 ; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]
187 ; CHECK-NEXT: store i32 0, ptr [[ADDR]], align 4
188 ; CHECK-NEXT: [[NEXT:%.*]] = icmp ult i32 [[IDX_NEXT]], 2147483647
189 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[IDX_NEXT]], [[EXIT_MAINLOOP_AT]]
190 ; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
191 ; CHECK: main.exit.selector:
192 ; CHECK-NEXT: [[IDX_NEXT_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT]], [[IN_BOUNDS]] ]
193 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[IDX_NEXT_LCSSA]], 2147483647
194 ; CHECK-NEXT: br i1 [[TMP2]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
195 ; CHECK: main.pseudo.exit:
196 ; CHECK-NEXT: [[IDX_COPY:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
197 ; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
198 ; CHECK-NEXT: br label [[POSTLOOP:%.*]]
199 ; CHECK: out.of.bounds.loopexit:
200 ; CHECK-NEXT: br label [[OUT_OF_BOUNDS:%.*]]
201 ; CHECK: out.of.bounds.loopexit1:
202 ; CHECK-NEXT: br label [[OUT_OF_BOUNDS]]
203 ; CHECK: out.of.bounds:
204 ; CHECK-NEXT: ret void
205 ; CHECK: exit.loopexit:
206 ; CHECK-NEXT: br label [[EXIT]]
208 ; CHECK-NEXT: ret void
210 ; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]
211 ; CHECK: loop.postloop:
212 ; CHECK-NEXT: [[IDX_POSTLOOP:%.*]] = phi i32 [ [[IDX_COPY]], [[POSTLOOP]] ], [ [[IDX_NEXT_POSTLOOP:%.*]], [[IN_BOUNDS_POSTLOOP:%.*]] ]
213 ; CHECK-NEXT: [[IDX_NEXT_POSTLOOP]] = add nuw nsw i32 [[IDX_POSTLOOP]], 1
214 ; CHECK-NEXT: [[ABC_POSTLOOP:%.*]] = icmp ult i32 [[IDX_POSTLOOP]], [[EXIT_MAINLOOP_AT]]
215 ; CHECK-NEXT: br i1 [[ABC_POSTLOOP]], label [[IN_BOUNDS_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]
216 ; CHECK: in.bounds.postloop:
217 ; CHECK-NEXT: [[ADDR_POSTLOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_POSTLOOP]]
218 ; CHECK-NEXT: store i32 0, ptr [[ADDR_POSTLOOP]], align 4
219 ; CHECK-NEXT: [[NEXT_POSTLOOP:%.*]] = icmp ult i32 [[IDX_NEXT_POSTLOOP]], 2147483647
220 ; CHECK-NEXT: br i1 [[NEXT_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP8:![0-9]+]], !loop_constrainer.loop.clone [[META6]]
224 %len = load i32, ptr %a_len_ptr, !range !0
228 %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
229 %idx.next = add nsw nuw i32 %idx, 1
230 %abc = icmp ult i32 %idx, %len
231 br i1 %abc, label %in.bounds, label %out.of.bounds
234 %addr = getelementptr i32, ptr %arr, i32 %idx
235 store i32 0, ptr %addr
236 %next = icmp ult i32 %idx.next, 2147483647
237 br i1 %next, label %loop, label %exit
246 ; Check SINT_MAX + 1, test is similar to test_01.
247 define void @test_04(ptr %arr, ptr %a_len_ptr) #0 {
248 ; CHECK-LABEL: define void @test_04
249 ; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {
251 ; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0]]
252 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 0, [[EXIT_MAINLOOP_AT]]
253 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
254 ; CHECK: loop.preheader:
255 ; CHECK-NEXT: br label [[LOOP:%.*]]
257 ; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
258 ; CHECK-NEXT: [[IDX_NEXT]] = add nuw nsw i32 [[IDX]], 1
259 ; CHECK-NEXT: [[ABC:%.*]] = icmp ult i32 [[IDX]], [[EXIT_MAINLOOP_AT]]
260 ; CHECK-NEXT: br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]
262 ; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]
263 ; CHECK-NEXT: store i32 0, ptr [[ADDR]], align 4
264 ; CHECK-NEXT: [[NEXT:%.*]] = icmp ult i32 [[IDX_NEXT]], -2147483648
265 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[IDX_NEXT]], [[EXIT_MAINLOOP_AT]]
266 ; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
267 ; CHECK: main.exit.selector:
268 ; CHECK-NEXT: [[IDX_NEXT_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT]], [[IN_BOUNDS]] ]
269 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[IDX_NEXT_LCSSA]], -2147483648
270 ; CHECK-NEXT: br i1 [[TMP2]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
271 ; CHECK: main.pseudo.exit:
272 ; CHECK-NEXT: [[IDX_COPY:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
273 ; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
274 ; CHECK-NEXT: br label [[POSTLOOP:%.*]]
275 ; CHECK: out.of.bounds.loopexit:
276 ; CHECK-NEXT: br label [[OUT_OF_BOUNDS:%.*]]
277 ; CHECK: out.of.bounds.loopexit1:
278 ; CHECK-NEXT: br label [[OUT_OF_BOUNDS]]
279 ; CHECK: out.of.bounds:
280 ; CHECK-NEXT: ret void
281 ; CHECK: exit.loopexit:
282 ; CHECK-NEXT: br label [[EXIT]]
284 ; CHECK-NEXT: ret void
286 ; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]
287 ; CHECK: loop.postloop:
288 ; CHECK-NEXT: [[IDX_POSTLOOP:%.*]] = phi i32 [ [[IDX_COPY]], [[POSTLOOP]] ], [ [[IDX_NEXT_POSTLOOP:%.*]], [[IN_BOUNDS_POSTLOOP:%.*]] ]
289 ; CHECK-NEXT: [[IDX_NEXT_POSTLOOP]] = add nuw nsw i32 [[IDX_POSTLOOP]], 1
290 ; CHECK-NEXT: [[ABC_POSTLOOP:%.*]] = icmp ult i32 [[IDX_POSTLOOP]], [[EXIT_MAINLOOP_AT]]
291 ; CHECK-NEXT: br i1 [[ABC_POSTLOOP]], label [[IN_BOUNDS_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]
292 ; CHECK: in.bounds.postloop:
293 ; CHECK-NEXT: [[ADDR_POSTLOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_POSTLOOP]]
294 ; CHECK-NEXT: store i32 0, ptr [[ADDR_POSTLOOP]], align 4
295 ; CHECK-NEXT: [[NEXT_POSTLOOP:%.*]] = icmp ult i32 [[IDX_NEXT_POSTLOOP]], -2147483648
296 ; CHECK-NEXT: br i1 [[NEXT_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP9:![0-9]+]], !loop_constrainer.loop.clone [[META6]]
300 %len = load i32, ptr %a_len_ptr, !range !0
304 %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
305 %idx.next = add nsw nuw i32 %idx, 1
306 %abc = icmp ult i32 %idx, %len
307 br i1 %abc, label %in.bounds, label %out.of.bounds
310 %addr = getelementptr i32, ptr %arr, i32 %idx
311 store i32 0, ptr %addr
312 %next = icmp ult i32 %idx.next, 2147483648
313 br i1 %next, label %loop, label %exit
322 ; Check SINT_MAX + 1, test is similar to test_02.
323 define void @test_05(ptr %arr, ptr %a_len_ptr) #0 {
324 ; CHECK-LABEL: define void @test_05
325 ; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {
327 ; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0]]
328 ; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[LEN]], i32 1)
329 ; CHECK-NEXT: [[EXIT_PRELOOP_AT:%.*]] = add nsw i32 [[UMAX]], -1
330 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i32 -2147483648, [[EXIT_PRELOOP_AT]]
331 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]]
332 ; CHECK: loop.preloop.preheader:
333 ; CHECK-NEXT: br label [[LOOP_PRELOOP:%.*]]
335 ; CHECK-NEXT: br label [[LOOP:%.*]]
337 ; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_PRELOOP_COPY:%.*]], [[MAINLOOP:%.*]] ], [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ]
338 ; CHECK-NEXT: [[IDX_NEXT]] = add i32 [[IDX]], -1
339 ; CHECK-NEXT: [[ABC:%.*]] = icmp ult i32 [[IDX]], [[LEN]]
340 ; CHECK-NEXT: br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]
342 ; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]
343 ; CHECK-NEXT: store i32 0, ptr [[ADDR]], align 4
344 ; CHECK-NEXT: [[NEXT:%.*]] = icmp ult i32 [[IDX_NEXT]], 1
345 ; CHECK-NEXT: br i1 [[NEXT]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP]]
346 ; CHECK: out.of.bounds.loopexit:
347 ; CHECK-NEXT: br label [[OUT_OF_BOUNDS:%.*]]
348 ; CHECK: out.of.bounds.loopexit1:
349 ; CHECK-NEXT: br label [[OUT_OF_BOUNDS]]
350 ; CHECK: out.of.bounds:
351 ; CHECK-NEXT: ret void
352 ; CHECK: exit.loopexit:
353 ; CHECK-NEXT: br label [[EXIT:%.*]]
355 ; CHECK-NEXT: ret void
356 ; CHECK: loop.preloop:
357 ; CHECK-NEXT: [[IDX_PRELOOP:%.*]] = phi i32 [ [[IDX_NEXT_PRELOOP:%.*]], [[IN_BOUNDS_PRELOOP:%.*]] ], [ -2147483648, [[LOOP_PRELOOP_PREHEADER]] ]
358 ; CHECK-NEXT: [[IDX_NEXT_PRELOOP]] = add i32 [[IDX_PRELOOP]], -1
359 ; CHECK-NEXT: [[ABC_PRELOOP:%.*]] = icmp ult i32 [[IDX_PRELOOP]], [[LEN]]
360 ; CHECK-NEXT: br i1 [[ABC_PRELOOP]], label [[IN_BOUNDS_PRELOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]
361 ; CHECK: in.bounds.preloop:
362 ; CHECK-NEXT: [[ADDR_PRELOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_PRELOOP]]
363 ; CHECK-NEXT: store i32 0, ptr [[ADDR_PRELOOP]], align 4
364 ; CHECK-NEXT: [[NEXT_PRELOOP:%.*]] = icmp ult i32 [[IDX_NEXT_PRELOOP]], 1
365 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP]], [[EXIT_PRELOOP_AT]]
366 ; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true
367 ; CHECK-NEXT: br i1 [[TMP2]], label [[PRELOOP_EXIT_SELECTOR:%.*]], label [[LOOP_PRELOOP]], !llvm.loop [[LOOP10:![0-9]+]], !loop_constrainer.loop.clone [[META6]]
368 ; CHECK: preloop.exit.selector:
369 ; CHECK-NEXT: [[IDX_NEXT_PRELOOP_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT_PRELOOP]], [[IN_BOUNDS_PRELOOP]] ]
370 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP_LCSSA]], 0
371 ; CHECK-NEXT: br i1 [[TMP3]], label [[PRELOOP_PSEUDO_EXIT]], label [[EXIT]]
372 ; CHECK: preloop.pseudo.exit:
373 ; CHECK-NEXT: [[IDX_PRELOOP_COPY]] = phi i32 [ -2147483648, [[ENTRY:%.*]] ], [ [[IDX_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
374 ; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i32 [ -2147483648, [[ENTRY]] ], [ [[IDX_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
375 ; CHECK-NEXT: br label [[MAINLOOP]]
379 %len = load i32, ptr %a_len_ptr, !range !0
383 %idx = phi i32 [ 2147483648, %entry ], [ %idx.next, %in.bounds ]
384 %idx.next = add i32 %idx, -1
385 %abc = icmp ult i32 %idx, %len
386 br i1 %abc, label %in.bounds, label %out.of.bounds
389 %addr = getelementptr i32, ptr %arr, i32 %idx
390 store i32 0, ptr %addr
391 %next = icmp ult i32 %idx.next, 1
392 br i1 %next, label %exit, label %loop
401 ; Increasing loop, UINT_MAX. Positive test.
402 define void @test_06(ptr %arr, ptr %a_len_ptr) #0 {
403 ; CHECK-LABEL: define void @test_06
404 ; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {
406 ; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0]]
407 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 0, [[EXIT_MAINLOOP_AT]]
408 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
409 ; CHECK: loop.preheader:
410 ; CHECK-NEXT: br label [[LOOP:%.*]]
412 ; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
413 ; CHECK-NEXT: [[IDX_NEXT]] = add nuw nsw i32 [[IDX]], 1
414 ; CHECK-NEXT: [[ABC:%.*]] = icmp ult i32 [[IDX]], [[EXIT_MAINLOOP_AT]]
415 ; CHECK-NEXT: br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]
417 ; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]
418 ; CHECK-NEXT: store i32 0, ptr [[ADDR]], align 4
419 ; CHECK-NEXT: [[NEXT:%.*]] = icmp ult i32 [[IDX_NEXT]], -1
420 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[IDX_NEXT]], [[EXIT_MAINLOOP_AT]]
421 ; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
422 ; CHECK: main.exit.selector:
423 ; CHECK-NEXT: [[IDX_NEXT_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT]], [[IN_BOUNDS]] ]
424 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[IDX_NEXT_LCSSA]], -1
425 ; CHECK-NEXT: br i1 [[TMP2]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
426 ; CHECK: main.pseudo.exit:
427 ; CHECK-NEXT: [[IDX_COPY:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
428 ; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
429 ; CHECK-NEXT: br label [[POSTLOOP:%.*]]
430 ; CHECK: out.of.bounds.loopexit:
431 ; CHECK-NEXT: br label [[OUT_OF_BOUNDS:%.*]]
432 ; CHECK: out.of.bounds.loopexit1:
433 ; CHECK-NEXT: br label [[OUT_OF_BOUNDS]]
434 ; CHECK: out.of.bounds:
435 ; CHECK-NEXT: ret void
436 ; CHECK: exit.loopexit:
437 ; CHECK-NEXT: br label [[EXIT]]
439 ; CHECK-NEXT: ret void
441 ; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]
442 ; CHECK: loop.postloop:
443 ; CHECK-NEXT: [[IDX_POSTLOOP:%.*]] = phi i32 [ [[IDX_COPY]], [[POSTLOOP]] ], [ [[IDX_NEXT_POSTLOOP:%.*]], [[IN_BOUNDS_POSTLOOP:%.*]] ]
444 ; CHECK-NEXT: [[IDX_NEXT_POSTLOOP]] = add nuw nsw i32 [[IDX_POSTLOOP]], 1
445 ; CHECK-NEXT: [[ABC_POSTLOOP:%.*]] = icmp ult i32 [[IDX_POSTLOOP]], [[EXIT_MAINLOOP_AT]]
446 ; CHECK-NEXT: br i1 [[ABC_POSTLOOP]], label [[IN_BOUNDS_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]
447 ; CHECK: in.bounds.postloop:
448 ; CHECK-NEXT: [[ADDR_POSTLOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_POSTLOOP]]
449 ; CHECK-NEXT: store i32 0, ptr [[ADDR_POSTLOOP]], align 4
450 ; CHECK-NEXT: [[NEXT_POSTLOOP:%.*]] = icmp ult i32 [[IDX_NEXT_POSTLOOP]], -1
451 ; CHECK-NEXT: br i1 [[NEXT_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP11:![0-9]+]], !loop_constrainer.loop.clone [[META6]]
455 %len = load i32, ptr %a_len_ptr, !range !0
459 %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
460 %idx.next = add nsw nuw i32 %idx, 1
461 %abc = icmp ult i32 %idx, %len
462 br i1 %abc, label %in.bounds, label %out.of.bounds
465 %addr = getelementptr i32, ptr %arr, i32 %idx
466 store i32 0, ptr %addr
467 %next = icmp ult i32 %idx.next, 4294967295
468 br i1 %next, label %loop, label %exit
477 ; Decreasing loop, UINT_MAX. Negative test: we cannot substract -1 from 0.
478 define void @test_07(ptr %arr, ptr %a_len_ptr) #0 {
479 ; CHECK-LABEL: define void @test_07
480 ; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {
482 ; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0]]
483 ; CHECK-NEXT: br label [[LOOP:%.*]]
485 ; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ]
486 ; CHECK-NEXT: [[IDX_NEXT]] = add nuw i32 [[IDX]], -1
487 ; CHECK-NEXT: [[ABC:%.*]] = icmp ult i32 [[IDX]], [[LEN]]
488 ; CHECK-NEXT: br i1 [[ABC]], label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS:%.*]]
490 ; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]
491 ; CHECK-NEXT: store i32 0, ptr [[ADDR]], align 4
492 ; CHECK-NEXT: [[NEXT:%.*]] = icmp ult i32 [[IDX_NEXT]], 0
493 ; CHECK-NEXT: br i1 [[NEXT]], label [[EXIT:%.*]], label [[LOOP]]
494 ; CHECK: out.of.bounds:
495 ; CHECK-NEXT: ret void
497 ; CHECK-NEXT: ret void
501 %len = load i32, ptr %a_len_ptr, !range !0
505 %idx = phi i32 [ 4294967295, %entry ], [ %idx.next, %in.bounds ]
506 %idx.next = add nuw i32 %idx, -1
507 %abc = icmp ult i32 %idx, %len
508 br i1 %abc, label %in.bounds, label %out.of.bounds
511 %addr = getelementptr i32, ptr %arr, i32 %idx
512 store i32 0, ptr %addr
513 %next = icmp ult i32 %idx.next, 0
514 br i1 %next, label %exit, label %loop
523 ; Unsigned walking through signed border is allowed.
524 ; Iteration space [0; UINT_MAX - 99), the fact that SINT_MAX is within this
525 ; range does not prevent us from performing IRCE.
527 define void @test_08(ptr %arr, ptr %a_len_ptr) #0 {
528 ; CHECK-LABEL: define void @test_08
529 ; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {
531 ; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0]]
532 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 0, [[EXIT_MAINLOOP_AT]]
533 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
534 ; CHECK: loop.preheader:
535 ; CHECK-NEXT: br label [[LOOP:%.*]]
537 ; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
538 ; CHECK-NEXT: [[IDX_NEXT]] = add i32 [[IDX]], 1
539 ; CHECK-NEXT: [[ABC:%.*]] = icmp ult i32 [[IDX]], [[EXIT_MAINLOOP_AT]]
540 ; CHECK-NEXT: br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]
542 ; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]
543 ; CHECK-NEXT: store i32 0, ptr [[ADDR]], align 4
544 ; CHECK-NEXT: [[NEXT:%.*]] = icmp ult i32 [[IDX_NEXT]], -100
545 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[IDX_NEXT]], [[EXIT_MAINLOOP_AT]]
546 ; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
547 ; CHECK: main.exit.selector:
548 ; CHECK-NEXT: [[IDX_NEXT_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT]], [[IN_BOUNDS]] ]
549 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[IDX_NEXT_LCSSA]], -100
550 ; CHECK-NEXT: br i1 [[TMP2]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
551 ; CHECK: main.pseudo.exit:
552 ; CHECK-NEXT: [[IDX_COPY:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
553 ; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
554 ; CHECK-NEXT: br label [[POSTLOOP:%.*]]
555 ; CHECK: out.of.bounds.loopexit:
556 ; CHECK-NEXT: br label [[OUT_OF_BOUNDS:%.*]]
557 ; CHECK: out.of.bounds.loopexit1:
558 ; CHECK-NEXT: br label [[OUT_OF_BOUNDS]]
559 ; CHECK: out.of.bounds:
560 ; CHECK-NEXT: ret void
561 ; CHECK: exit.loopexit:
562 ; CHECK-NEXT: br label [[EXIT]]
564 ; CHECK-NEXT: ret void
566 ; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]
567 ; CHECK: loop.postloop:
568 ; CHECK-NEXT: [[IDX_POSTLOOP:%.*]] = phi i32 [ [[IDX_COPY]], [[POSTLOOP]] ], [ [[IDX_NEXT_POSTLOOP:%.*]], [[IN_BOUNDS_POSTLOOP:%.*]] ]
569 ; CHECK-NEXT: [[IDX_NEXT_POSTLOOP]] = add i32 [[IDX_POSTLOOP]], 1
570 ; CHECK-NEXT: [[ABC_POSTLOOP:%.*]] = icmp ult i32 [[IDX_POSTLOOP]], [[EXIT_MAINLOOP_AT]]
571 ; CHECK-NEXT: br i1 [[ABC_POSTLOOP]], label [[IN_BOUNDS_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]
572 ; CHECK: in.bounds.postloop:
573 ; CHECK-NEXT: [[ADDR_POSTLOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_POSTLOOP]]
574 ; CHECK-NEXT: store i32 0, ptr [[ADDR_POSTLOOP]], align 4
575 ; CHECK-NEXT: [[NEXT_POSTLOOP:%.*]] = icmp ult i32 [[IDX_NEXT_POSTLOOP]], -100
576 ; CHECK-NEXT: br i1 [[NEXT_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP12:![0-9]+]], !loop_constrainer.loop.clone [[META6]]
580 %len = load i32, ptr %a_len_ptr, !range !0
584 %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
585 %idx.next = add i32 %idx, 1
586 %abc = icmp ult i32 %idx, %len
587 br i1 %abc, label %in.bounds, label %out.of.bounds
590 %addr = getelementptr i32, ptr %arr, i32 %idx
591 store i32 0, ptr %addr
592 %next = icmp ult i32 %idx.next, -100
593 br i1 %next, label %loop, label %exit
602 ; Walking through the border of unsigned range is not allowed
603 ; (iteration space [-100; 100)). Negative test.
605 define void @test_09(ptr %arr, ptr %a_len_ptr) #0 {
606 ; CHECK-LABEL: define void @test_09
607 ; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {
609 ; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0]]
610 ; CHECK-NEXT: br label [[LOOP:%.*]]
612 ; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ -100, [[ENTRY:%.*]] ], [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ]
613 ; CHECK-NEXT: [[IDX_NEXT]] = add i32 [[IDX]], 1
614 ; CHECK-NEXT: [[ABC:%.*]] = icmp ult i32 [[IDX]], [[LEN]]
615 ; CHECK-NEXT: br i1 [[ABC]], label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS:%.*]]
617 ; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]
618 ; CHECK-NEXT: store i32 0, ptr [[ADDR]], align 4
619 ; CHECK-NEXT: [[NEXT:%.*]] = icmp ult i32 [[IDX_NEXT]], 100
620 ; CHECK-NEXT: br i1 [[NEXT]], label [[LOOP]], label [[EXIT:%.*]]
621 ; CHECK: out.of.bounds:
622 ; CHECK-NEXT: ret void
624 ; CHECK-NEXT: ret void
628 %len = load i32, ptr %a_len_ptr, !range !0
632 %idx = phi i32 [ -100, %entry ], [ %idx.next, %in.bounds ]
633 %idx.next = add i32 %idx, 1
634 %abc = icmp ult i32 %idx, %len
635 br i1 %abc, label %in.bounds, label %out.of.bounds
638 %addr = getelementptr i32, ptr %arr, i32 %idx
639 store i32 0, ptr %addr
640 %next = icmp ult i32 %idx.next, 100
641 br i1 %next, label %loop, label %exit
650 !0 = !{i32 0, i32 50}
652 ; CHECK: [[RNG0]] = !{i32 0, i32 50}
653 ; CHECK: [[LOOP1]] = distinct !{[[LOOP1]], [[META2:![0-9]+]], [[META3:![0-9]+]], [[META4:![0-9]+]], [[META5:![0-9]+]]}
654 ; CHECK: [[META2]] = !{!"llvm.loop.unroll.disable"}
655 ; CHECK: [[META3]] = !{!"llvm.loop.vectorize.enable", i1 false}
656 ; CHECK: [[META4]] = !{!"llvm.loop.licm_versioning.disable"}
657 ; CHECK: [[META5]] = !{!"llvm.loop.distribute.enable", i1 false}
658 ; CHECK: [[META6]] = !{}
659 ; CHECK: [[LOOP7]] = distinct !{[[LOOP7]], [[META2]], [[META3]], [[META4]], [[META5]]}
660 ; CHECK: [[LOOP8]] = distinct !{[[LOOP8]], [[META2]], [[META3]], [[META4]], [[META5]]}
661 ; CHECK: [[LOOP9]] = distinct !{[[LOOP9]], [[META2]], [[META3]], [[META4]], [[META5]]}
662 ; CHECK: [[LOOP10]] = distinct !{[[LOOP10]], [[META2]], [[META3]], [[META4]], [[META5]]}
663 ; CHECK: [[LOOP11]] = distinct !{[[LOOP11]], [[META2]], [[META3]], [[META4]], [[META5]]}
664 ; CHECK: [[LOOP12]] = distinct !{[[LOOP12]], [[META2]], [[META3]], [[META4]], [[META5]]}