llvm.org GIT mirror llvm / aa5782c
[Tests] Autogen all the LoopPredication tests I'm about to make some changes to the pass which cause widespread - but uninteresting - test diffs. Prepare the tests for easy updating. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357404 91177308-0d34-0410-b5e6-96231b3b80d8 Philip Reames 5 months ago
7 changed file(s) with 2040 addition(s) and 516 deletion(s). Raw diff Collapse all Expand all
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1 ; RUN: opt -S -loop-predication < %s 2>&1 | FileCheck %s
12 ; RUN: opt -S -passes='require,loop(loop-predication)' < %s 2>&1 | FileCheck %s
23
34 declare void @llvm.experimental.guard(i1, ...)
45
56 define i32 @unsigned_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) {
6 ; CHECK-LABEL: @unsigned_loop_0_to_n_ult_check
7 ; CHECK-LABEL: @unsigned_loop_0_to_n_ult_check(
8 ; CHECK-NEXT: entry:
9 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
10 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
11 ; CHECK: loop.preheader:
12 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
13 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
14 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
15 ; CHECK-NEXT: br label [[LOOP:%.*]]
16 ; CHECK: loop:
17 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
18 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
19 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
20 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
21 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
22 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
23 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
24 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
25 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
26 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
27 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
28 ; CHECK: exit.loopexit:
29 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
30 ; CHECK-NEXT: br label [[EXIT]]
31 ; CHECK: exit:
32 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
33 ; CHECK-NEXT: ret i32 [[RESULT]]
34 ;
735 entry:
836 %tmp5 = icmp eq i32 %n, 0
937 br i1 %tmp5, label %exit, label %loop.preheader
1038
1139 loop.preheader:
12 ; CHECK: loop.preheader:
13 ; CHECK: [[limit_check:[^ ]+]] = icmp ule i32 %n, %length
14 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
15 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
16 ; CHECK-NEXT: br label %loop
17 br label %loop
18
19 loop:
20 ; CHECK: loop:
21 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
40 br label %loop
41
42 loop:
2243 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
2344 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
2445 %within.bounds = icmp ult i32 %i, %length
3960 }
4061
4162 define i32 @unsigned_loop_0_to_n_ule_latch_ult_check(i32* %array, i32 %length, i32 %n) {
42 ; CHECK-LABEL: @unsigned_loop_0_to_n_ule_latch_ult_check
63 ; CHECK-LABEL: @unsigned_loop_0_to_n_ule_latch_ult_check(
64 ; CHECK-NEXT: entry:
65 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
66 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
67 ; CHECK: loop.preheader:
68 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[N]], [[LENGTH:%.*]]
69 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
70 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
71 ; CHECK-NEXT: br label [[LOOP:%.*]]
72 ; CHECK: loop:
73 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
74 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
75 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
76 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
77 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
78 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
79 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
80 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
81 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
82 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ule i32 [[I_NEXT]], [[N]]
83 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
84 ; CHECK: exit.loopexit:
85 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
86 ; CHECK-NEXT: br label [[EXIT]]
87 ; CHECK: exit:
88 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
89 ; CHECK-NEXT: ret i32 [[RESULT]]
90 ;
4391 entry:
4492 %tmp5 = icmp eq i32 %n, 0
4593 br i1 %tmp5, label %exit, label %loop.preheader
4694
4795 loop.preheader:
48 ; CHECK: loop.preheader:
49 ; CHECK: [[limit_check:[^ ]+]] = icmp ult i32 %n, %length
50 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
51 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
52 ; CHECK-NEXT: br label %loop
53 br label %loop
54
55 loop:
56 ; CHECK: loop:
57 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
96 br label %loop
97
98 loop:
5899 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
59100 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
60101 %within.bounds = icmp ult i32 %i, %length
75116 }
76117
77118 define i32 @unsigned_loop_0_to_n_ugt_check(i32* %array, i32 %length, i32 %n) {
78 ; CHECK-LABEL: @unsigned_loop_0_to_n_ugt_check
119 ; CHECK-LABEL: @unsigned_loop_0_to_n_ugt_check(
120 ; CHECK-NEXT: entry:
121 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
122 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
123 ; CHECK: loop.preheader:
124 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
125 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
126 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
127 ; CHECK-NEXT: br label [[LOOP:%.*]]
128 ; CHECK: loop:
129 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
130 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
131 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ugt i32 [[LENGTH]], [[I]]
132 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
133 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
134 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
135 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
136 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
137 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
138 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
139 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
140 ; CHECK: exit.loopexit:
141 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
142 ; CHECK-NEXT: br label [[EXIT]]
143 ; CHECK: exit:
144 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
145 ; CHECK-NEXT: ret i32 [[RESULT]]
146 ;
79147 entry:
80148 %tmp5 = icmp eq i32 %n, 0
81149 br i1 %tmp5, label %exit, label %loop.preheader
82150
83151 loop.preheader:
84 ; CHECK: loop.preheader:
85 ; CHECK: [[limit_check:[^ ]+]] = icmp ule i32 %n, %length
86 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
87 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
88 ; CHECK-NEXT: br label %loop
89 br label %loop
90
91 loop:
92 ; CHECK: loop:
93 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
152 br label %loop
153
154 loop:
94155 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
95156 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
96157 %within.bounds = icmp ugt i32 %length, %i
111172 }
112173
113174 define i32 @signed_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) {
114 ; CHECK-LABEL: @signed_loop_0_to_n_ult_check
175 ; CHECK-LABEL: @signed_loop_0_to_n_ult_check(
176 ; CHECK-NEXT: entry:
177 ; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
178 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
179 ; CHECK: loop.preheader:
180 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]]
181 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
182 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
183 ; CHECK-NEXT: br label [[LOOP:%.*]]
184 ; CHECK: loop:
185 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
186 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
187 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
188 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
189 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
190 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
191 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
192 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
193 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
194 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
195 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
196 ; CHECK: exit.loopexit:
197 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
198 ; CHECK-NEXT: br label [[EXIT]]
199 ; CHECK: exit:
200 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
201 ; CHECK-NEXT: ret i32 [[RESULT]]
202 ;
115203 entry:
116204 %tmp5 = icmp sle i32 %n, 0
117205 br i1 %tmp5, label %exit, label %loop.preheader
118206
119207 loop.preheader:
120 ; CHECK: loop.preheader:
121 ; CHECK: [[limit_check:[^ ]+]] = icmp sle i32 %n, %length
122 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
123 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
124 ; CHECK-NEXT: br label %loop
125 br label %loop
126
127 loop:
128 ; CHECK: loop:
129 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
208 br label %loop
209
210 loop:
130211 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
131212 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
132213 %within.bounds = icmp ult i32 %i, %length
147228 }
148229
149230 define i32 @signed_loop_0_to_n_ult_check_length_range_known(i32* %array, i32* %length.ptr, i32 %n) {
150 ; CHECK-LABEL: @signed_loop_0_to_n_ult_check_length_range_known
231 ; CHECK-LABEL: @signed_loop_0_to_n_ult_check_length_range_known(
232 ; CHECK-NEXT: entry:
233 ; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
234 ; CHECK-NEXT: [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], !range !0
235 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
236 ; CHECK: loop.preheader:
237 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH]]
238 ; CHECK-NEXT: [[TMP1:%.*]] = and i1 true, [[TMP0]]
239 ; CHECK-NEXT: br label [[LOOP:%.*]]
240 ; CHECK: loop:
241 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
242 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
243 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
244 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP1]], i32 9) [ "deopt"() ]
245 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
246 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
247 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
248 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
249 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
250 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
251 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
252 ; CHECK: exit.loopexit:
253 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
254 ; CHECK-NEXT: br label [[EXIT]]
255 ; CHECK: exit:
256 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
257 ; CHECK-NEXT: ret i32 [[RESULT]]
258 ;
151259 entry:
152260 %tmp5 = icmp sle i32 %n, 0
153261 %length = load i32, i32* %length.ptr, !range !{i32 1, i32 2147483648}
154262 br i1 %tmp5, label %exit, label %loop.preheader
155263
156264 loop.preheader:
157 ; CHECK: loop.preheader:
158 ; CHECK: [[limit_check:[^ ]+]] = icmp sle i32 %n, %length
159 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 true, [[limit_check]]
160 ; CHECK-NEXT: br label %loop
161 br label %loop
162
163 loop:
164 ; CHECK: loop:
165 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
265 br label %loop
266
267 loop:
166268 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
167269 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
168270 %within.bounds = icmp ult i32 %i, %length
183285 }
184286
185287 define i32 @signed_loop_0_to_n_inverse_latch_predicate(i32* %array, i32 %length, i32 %n) {
186 ; CHECK-LABEL: @signed_loop_0_to_n_inverse_latch_predicate
288 ; CHECK-LABEL: @signed_loop_0_to_n_inverse_latch_predicate(
289 ; CHECK-NEXT: entry:
290 ; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
291 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
292 ; CHECK: loop.preheader:
293 ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]
294 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
295 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
296 ; CHECK-NEXT: br label [[LOOP:%.*]]
297 ; CHECK: loop:
298 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
299 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
300 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
301 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
302 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
303 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
304 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
305 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
306 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
307 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[I_NEXT]], [[N]]
308 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP]]
309 ; CHECK: exit.loopexit:
310 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
311 ; CHECK-NEXT: br label [[EXIT]]
312 ; CHECK: exit:
313 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
314 ; CHECK-NEXT: ret i32 [[RESULT]]
315 ;
187316 entry:
188317 %tmp5 = icmp sle i32 %n, 0
189318 br i1 %tmp5, label %exit, label %loop.preheader
190319
191320 loop.preheader:
192 ; CHECK: loop.preheader:
193 ; CHECK: [[limit_check:[^ ]+]] = icmp slt i32 %n, %length
194 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
195 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
196 ; CHECK-NEXT: br label %loop
197 br label %loop
198
199 loop:
200 ; CHECK: loop:
201 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
321 br label %loop
322
323 loop:
202324 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
203325 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
204326 %within.bounds = icmp ult i32 %i, %length
219341 }
220342
221343 define i32 @signed_loop_0_to_n_sle_latch_ult_check(i32* %array, i32 %length, i32 %n) {
222 ; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_ult_check
344 ; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_ult_check(
345 ; CHECK-NEXT: entry:
346 ; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
347 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
348 ; CHECK: loop.preheader:
349 ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]
350 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
351 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
352 ; CHECK-NEXT: br label [[LOOP:%.*]]
353 ; CHECK: loop:
354 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
355 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
356 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
357 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
358 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
359 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
360 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
361 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
362 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
363 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT]], [[N]]
364 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
365 ; CHECK: exit.loopexit:
366 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
367 ; CHECK-NEXT: br label [[EXIT]]
368 ; CHECK: exit:
369 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
370 ; CHECK-NEXT: ret i32 [[RESULT]]
371 ;
223372 entry:
224373 %tmp5 = icmp sle i32 %n, 0
225374 br i1 %tmp5, label %exit, label %loop.preheader
226375
227376 loop.preheader:
228 ; CHECK: loop.preheader:
229 ; CHECK: [[limit_check:[^ ]+]] = icmp slt i32 %n, %length
230 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
231 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
232 ; CHECK-NEXT: br label %loop
233 br label %loop
234
235 loop:
236 ; CHECK: loop:
237 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
377 br label %loop
378
379 loop:
238380 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
239381 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
240382 %within.bounds = icmp ult i32 %i, %length
255397 }
256398
257399 define i32 @signed_loop_0_to_n_preincrement_latch_check(i32* %array, i32 %length, i32 %n) {
258 ; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check
400 ; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check(
401 ; CHECK-NEXT: entry:
402 ; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
403 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
404 ; CHECK: loop.preheader:
405 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1
406 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sle i32 [[N]], [[TMP0]]
407 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]]
408 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
409 ; CHECK-NEXT: br label [[LOOP:%.*]]
410 ; CHECK: loop:
411 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
412 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
413 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
414 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
415 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
416 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
417 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
418 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
419 ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
420 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I]], [[N]]
421 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
422 ; CHECK: exit.loopexit:
423 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
424 ; CHECK-NEXT: br label [[EXIT]]
425 ; CHECK: exit:
426 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
427 ; CHECK-NEXT: ret i32 [[RESULT]]
428 ;
259429 entry:
260430 %tmp5 = icmp sle i32 %n, 0
261431 br i1 %tmp5, label %exit, label %loop.preheader
262432
263433 loop.preheader:
264 ; CHECK: loop.preheader:
265 ; CHECK: [[length_minus_1:[^ ]+]] = add i32 %length, -1
266 ; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp sle i32 %n, [[length_minus_1]]
267 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
268 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
269 ; CHECK-NEXT: br label %loop
270 br label %loop
271
272 loop:
273 ; CHECK: loop:
274 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
434 br label %loop
435
436 loop:
275437 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
276438 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
277439 %within.bounds = icmp ult i32 %i, %length
292454 }
293455
294456 define i32 @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check(i32* %array, i32 %length, i32 %n) {
295 ; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check
457 ; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check(
458 ; CHECK-NEXT: entry:
459 ; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
460 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
461 ; CHECK: loop.preheader:
462 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -2
463 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sle i32 [[N]], [[TMP0]]
464 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 1, [[LENGTH]]
465 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
466 ; CHECK-NEXT: br label [[LOOP:%.*]]
467 ; CHECK: loop:
468 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
469 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
470 ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
471 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_NEXT]], [[LENGTH]]
472 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
473 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
474 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
475 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
476 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
477 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I]], [[N]]
478 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
479 ; CHECK: exit.loopexit:
480 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
481 ; CHECK-NEXT: br label [[EXIT]]
482 ; CHECK: exit:
483 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
484 ; CHECK-NEXT: ret i32 [[RESULT]]
485 ;
296486 entry:
297487 %tmp5 = icmp sle i32 %n, 0
298488 br i1 %tmp5, label %exit, label %loop.preheader
299489
300490 loop.preheader:
301 ; CHECK: loop.preheader:
302 ; CHECK: [[length_minus_2:[^ ]+]] = add i32 %length, -2
303 ; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp sle i32 %n, [[length_minus_2]]
304 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 1, %length
305 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
306 ; CHECK-NEXT: br label %loop
307 br label %loop
308
309 loop:
310 ; CHECK: loop:
311 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
491 br label %loop
492
493 loop:
312494 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
313495 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
314496
330512 }
331513
332514 define i32 @signed_loop_0_to_n_sle_latch_offset_ult_check(i32* %array, i32 %length, i32 %n) {
333 ; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_offset_ult_check
515 ; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_offset_ult_check(
516 ; CHECK-NEXT: entry:
517 ; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
518 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
519 ; CHECK: loop.preheader:
520 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1
521 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[N]], [[TMP0]]
522 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 1, [[LENGTH]]
523 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
524 ; CHECK-NEXT: br label [[LOOP:%.*]]
525 ; CHECK: loop:
526 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
527 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
528 ; CHECK-NEXT: [[I_OFFSET:%.*]] = add i32 [[I]], 1
529 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_OFFSET]], [[LENGTH]]
530 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
531 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
532 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
533 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
534 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
535 ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
536 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT]], [[N]]
537 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
538 ; CHECK: exit.loopexit:
539 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
540 ; CHECK-NEXT: br label [[EXIT]]
541 ; CHECK: exit:
542 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
543 ; CHECK-NEXT: ret i32 [[RESULT]]
544 ;
334545 entry:
335546 %tmp5 = icmp sle i32 %n, 0
336547 br i1 %tmp5, label %exit, label %loop.preheader
337548
338549 loop.preheader:
339 ; CHECK: loop.preheader:
340 ; CHECK: [[length_minus_1:[^ ]+]] = add i32 %length, -1
341 ; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp slt i32 %n, [[length_minus_1]]
342 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 1, %length
343 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
344 ; CHECK-NEXT: br label %loop
345 br label %loop
346
347 loop:
348 ; CHECK: loop:
349 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
550 br label %loop
551
552 loop:
350553 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
351554 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
352555 %i.offset = add i32 %i, 1
368571 }
369572
370573 define i32 @signed_loop_0_to_n_offset_sle_latch_offset_ult_check(i32* %array, i32 %length, i32 %n) {
371 ; CHECK-LABEL: @signed_loop_0_to_n_offset_sle_latch_offset_ult_check
574 ; CHECK-LABEL: @signed_loop_0_to_n_offset_sle_latch_offset_ult_check(
575 ; CHECK-NEXT: entry:
576 ; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
577 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
578 ; CHECK: loop.preheader:
579 ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]
580 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 1, [[LENGTH]]
581 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
582 ; CHECK-NEXT: br label [[LOOP:%.*]]
583 ; CHECK: loop:
584 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
585 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
586 ; CHECK-NEXT: [[I_OFFSET:%.*]] = add i32 [[I]], 1
587 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_OFFSET]], [[LENGTH]]
588 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
589 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
590 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
591 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
592 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
593 ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
594 ; CHECK-NEXT: [[I_NEXT_OFFSET:%.*]] = add i32 [[I_NEXT]], 1
595 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT_OFFSET]], [[N]]
596 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
597 ; CHECK: exit.loopexit:
598 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
599 ; CHECK-NEXT: br label [[EXIT]]
600 ; CHECK: exit:
601 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
602 ; CHECK-NEXT: ret i32 [[RESULT]]
603 ;
372604 entry:
373605 %tmp5 = icmp sle i32 %n, 0
374606 br i1 %tmp5, label %exit, label %loop.preheader
375607
376608 loop.preheader:
377 ; CHECK: loop.preheader:
378 ; CHECK: [[limit_check:[^ ]+]] = icmp slt i32 %n, %length
379 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 1, %length
380 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
381 ; CHECK-NEXT: br label %loop
382 br label %loop
383
384 loop:
385 ; CHECK: loop:
386 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
609 br label %loop
610
611 loop:
387612 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
388613 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
389614 %i.offset = add i32 %i, 1
406631 }
407632
408633 define i32 @unsupported_latch_pred_loop_0_to_n(i32* %array, i32 %length, i32 %n) {
409 ; CHECK-LABEL: @unsupported_latch_pred_loop_0_to_n
634 ; CHECK-LABEL: @unsupported_latch_pred_loop_0_to_n(
635 ; CHECK-NEXT: entry:
636 ; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
637 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
638 ; CHECK: loop.preheader:
639 ; CHECK-NEXT: br label [[LOOP:%.*]]
640 ; CHECK: loop:
641 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
642 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
643 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
644 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
645 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
646 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
647 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
648 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
649 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
650 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[N]]
651 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
652 ; CHECK: exit.loopexit:
653 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
654 ; CHECK-NEXT: br label [[EXIT]]
655 ; CHECK: exit:
656 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
657 ; CHECK-NEXT: ret i32 [[RESULT]]
658 ;
410659 entry:
411660 %tmp5 = icmp sle i32 %n, 0
412661 br i1 %tmp5, label %exit, label %loop.preheader
413662
414663 loop.preheader:
415 ; CHECK: loop.preheader:
416 ; CHECK-NEXT: br label %loop
417 br label %loop
418
419 loop:
420 ; CHECK: loop:
421 ; CHECK: %within.bounds = icmp ult i32 %i, %length
422 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
664 br label %loop
665
666 loop:
423667 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
424668 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
425669 %within.bounds = icmp ult i32 %i, %length
440684 }
441685
442686 define i32 @signed_loop_0_to_n_unsupported_iv_step(i32* %array, i32 %length, i32 %n) {
443 ; CHECK-LABEL: @signed_loop_0_to_n_unsupported_iv_step
687 ; CHECK-LABEL: @signed_loop_0_to_n_unsupported_iv_step(
688 ; CHECK-NEXT: entry:
689 ; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
690 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
691 ; CHECK: loop.preheader:
692 ; CHECK-NEXT: br label [[LOOP:%.*]]
693 ; CHECK: loop:
694 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
695 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
696 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
697 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
698 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
699 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
700 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
701 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
702 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 2
703 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
704 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
705 ; CHECK: exit.loopexit:
706 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
707 ; CHECK-NEXT: br label [[EXIT]]
708 ; CHECK: exit:
709 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
710 ; CHECK-NEXT: ret i32 [[RESULT]]
711 ;
444712 entry:
445713 %tmp5 = icmp sle i32 %n, 0
446714 br i1 %tmp5, label %exit, label %loop.preheader
447715
448716 loop.preheader:
449 ; CHECK: loop.preheader:
450 ; CHECK-NEXT: br label %loop
451 br label %loop
452
453 loop:
454 ; CHECK: loop:
455 ; CHECK: %within.bounds = icmp ult i32 %i, %length
456 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
717 br label %loop
718
719 loop:
457720 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
458721 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
459722 %within.bounds = icmp ult i32 %i, %length
474737 }
475738
476739 define i32 @signed_loop_0_to_n_equal_iv_range_check(i32* %array, i32 %length, i32 %n) {
477 ; CHECK-LABEL: @signed_loop_0_to_n_equal_iv_range_check
740 ; CHECK-LABEL: @signed_loop_0_to_n_equal_iv_range_check(
741 ; CHECK-NEXT: entry:
742 ; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
743 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
744 ; CHECK: loop.preheader:
745 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]]
746 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
747 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
748 ; CHECK-NEXT: br label [[LOOP:%.*]]
749 ; CHECK: loop:
750 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
751 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
752 ; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
753 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH]]
754 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
755 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
756 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
757 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
758 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
759 ; CHECK-NEXT: [[J_NEXT]] = add nsw i32 [[J]], 1
760 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
761 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
762 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
763 ; CHECK: exit.loopexit:
764 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
765 ; CHECK-NEXT: br label [[EXIT]]
766 ; CHECK: exit:
767 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
768 ; CHECK-NEXT: ret i32 [[RESULT]]
769 ;
478770 entry:
479771 %tmp5 = icmp sle i32 %n, 0
480772 br i1 %tmp5, label %exit, label %loop.preheader
481773
482774 loop.preheader:
483 ; CHECK: loop.preheader:
484 ; CHECK: [[limit_check:[^ ]+]] = icmp sle i32 %n, %length
485 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
486 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
487 ; CHECK-NEXT: br label %loop
488 br label %loop
489
490 loop:
491 ; CHECK: loop:
492 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
775 br label %loop
776
777 loop:
493778 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
494779 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
495780 %j = phi i32 [ %j.next, %loop ], [ 0, %loop.preheader ]
513798 }
514799
515800 define i32 @signed_loop_start_to_n_offset_iv_range_check(i32* %array, i32 %start.i,
516 i32 %start.j, i32 %length,
517 i32 %n) {
518 ; CHECK-LABEL: @signed_loop_start_to_n_offset_iv_range_check
801 ; CHECK-LABEL: @signed_loop_start_to_n_offset_iv_range_check(
802 ; CHECK-NEXT: entry:
803 ; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
804 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
805 ; CHECK: loop.preheader:
806 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], [[START_I:%.*]]
807 ; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[TMP0]], [[START_J:%.*]]
808 ; CHECK-NEXT: [[TMP2:%.*]] = icmp sle i32 [[N]], [[TMP1]]
809 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i32 [[START_J]], [[LENGTH]]
810 ; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[TMP2]]
811 ; CHECK-NEXT: br label [[LOOP:%.*]]
812 ; CHECK: loop:
813 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
814 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[START_I]], [[LOOP_PREHEADER]] ]
815 ; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[LOOP]] ], [ [[START_J]], [[LOOP_PREHEADER]] ]
816 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH]]
817 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP4]], i32 9) [ "deopt"() ]
818 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
819 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
820 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
821 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
822 ; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1
823 ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
824 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
825 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
826 ; CHECK: exit.loopexit:
827 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
828 ; CHECK-NEXT: br label [[EXIT]]
829 ; CHECK: exit:
830 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
831 ; CHECK-NEXT: ret i32 [[RESULT]]
832 ;
833 i32 %start.j, i32 %length,
834 i32 %n) {
519835 entry:
520836 %tmp5 = icmp sle i32 %n, 0
521837 br i1 %tmp5, label %exit, label %loop.preheader
522838
523839 loop.preheader:
524 ; CHECK: loop.preheader:
525 ; CHECK: [[length_plus_start_i:[^ ]+]] = add i32 %length, %start.i
526 ; CHECK-NEXT: [[limit:[^ ]+]] = sub i32 [[length_plus_start_i]], %start.j
527 ; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp sle i32 %n, [[limit]]
528 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 %start.j, %length
529 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
530 ; CHECK-NEXT: br label %loop
531 br label %loop
532
533 loop:
534 ; CHECK: loop:
535 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
840 br label %loop
841
842 loop:
536843 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
537844 %i = phi i32 [ %i.next, %loop ], [ %start.i, %loop.preheader ]
538845 %j = phi i32 [ %j.next, %loop ], [ %start.j, %loop.preheader ]
556863 }
557864
558865 define i32 @signed_loop_0_to_n_different_iv_types(i32* %array, i16 %length, i32 %n) {
559 ; CHECK-LABEL: @signed_loop_0_to_n_different_iv_types
866 ; CHECK-LABEL: @signed_loop_0_to_n_different_iv_types(
867 ; CHECK-NEXT: entry:
868 ; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
869 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
870 ; CHECK: loop.preheader:
871 ; CHECK-NEXT: br label [[LOOP:%.*]]
872 ; CHECK: loop:
873 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
874 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
875 ; CHECK-NEXT: [[J:%.*]] = phi i16 [ [[J_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
876 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i16 [[J]], [[LENGTH:%.*]]
877 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
878 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
879 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
880 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
881 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
882 ; CHECK-NEXT: [[J_NEXT]] = add i16 [[J]], 1
883 ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
884 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
885 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
886 ; CHECK: exit.loopexit:
887 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
888 ; CHECK-NEXT: br label [[EXIT]]
889 ; CHECK: exit:
890 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
891 ; CHECK-NEXT: ret i32 [[RESULT]]
892 ;
560893 entry:
561894 %tmp5 = icmp sle i32 %n, 0
562895 br i1 %tmp5, label %exit, label %loop.preheader
563896
564897 loop.preheader:
565 ; CHECK: loop.preheader:
566 ; CHECK-NEXT: br label %loop
567 br label %loop
568
569 loop:
570 ; CHECK: loop:
571 ; CHECK: %within.bounds = icmp ult i16 %j, %length
572 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
898 br label %loop
899
900 loop:
573901 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
574902 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
575903 %j = phi i16 [ %j.next, %loop ], [ 0, %loop.preheader ]
593921 }
594922
595923 define i32 @signed_loop_0_to_n_different_iv_strides(i32* %array, i32 %length, i32 %n) {
596 ; CHECK-LABEL: @signed_loop_0_to_n_different_iv_strides
924 ; CHECK-LABEL: @signed_loop_0_to_n_different_iv_strides(
925 ; CHECK-NEXT: entry:
926 ; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
927 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
928 ; CHECK: loop.preheader:
929 ; CHECK-NEXT: br label [[LOOP:%.*]]
930 ; CHECK: loop:
931 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
932 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
933 ; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
934 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH:%.*]]
935 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
936 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
937 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
938 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
939 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
940 ; CHECK-NEXT: [[J_NEXT]] = add nsw i32 [[J]], 2
941 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
942 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
943 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
944 ; CHECK: exit.loopexit:
945 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
946 ; CHECK-NEXT: br label [[EXIT]]
947 ; CHECK: exit:
948 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
949 ; CHECK-NEXT: ret i32 [[RESULT]]
950 ;
597951 entry:
598952 %tmp5 = icmp sle i32 %n, 0
599953 br i1 %tmp5, label %exit, label %loop.preheader
600954
601955 loop.preheader:
602 ; CHECK: loop.preheader:
603 ; CHECK-NEXT: br label %loop
604 br label %loop
605
606 loop:
607 ; CHECK: loop:
608 ; CHECK: %within.bounds = icmp ult i32 %j, %length
609 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
956 br label %loop
957
958 loop:
610959 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
611960 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
612961 %j = phi i32 [ %j.next, %loop ], [ 0, %loop.preheader ]
630979 }
631980
632981 define i32 @two_range_checks(i32* %array.1, i32 %length.1,
633 i32* %array.2, i32 %length.2, i32 %n) {
634 ; CHECK-LABEL: @two_range_checks
982 ; CHECK-LABEL: @two_range_checks(
983 ; CHECK-NEXT: entry:
984 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
985 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
986 ; CHECK: loop.preheader:
987 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]
988 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_2]]
989 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
990 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]
991 ; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_1]]
992 ; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]]
993 ; CHECK-NEXT: br label [[LOOP:%.*]]
994 ; CHECK: loop:
995 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
996 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
997 ; CHECK-NEXT: [[WITHIN_BOUNDS_1:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]]
998 ; CHECK-NEXT: [[WITHIN_BOUNDS_2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]]
999 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = and i1 [[WITHIN_BOUNDS_1]], [[WITHIN_BOUNDS_2]]
1000 ; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP2]], [[TMP5]]
1001 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP6]], i32 9) [ "deopt"() ]
1002 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1003 ; CHECK-NEXT: [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]]
1004 ; CHECK-NEXT: [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4
1005 ; CHECK-NEXT: [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
1006 ; CHECK-NEXT: [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]]
1007 ; CHECK-NEXT: [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4
1008 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
1009 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
1010 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1011 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1012 ; CHECK: exit.loopexit:
1013 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1014 ; CHECK-NEXT: br label [[EXIT]]
1015 ; CHECK: exit:
1016 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1017 ; CHECK-NEXT: ret i32 [[RESULT]]
1018 ;
1019 i32* %array.2, i32 %length.2, i32 %n) {
6351020 entry:
6361021 %tmp5 = icmp eq i32 %n, 0
6371022 br i1 %tmp5, label %exit, label %loop.preheader
6381023
6391024 loop.preheader:
640 ; CHECK: loop.preheader:
641 ; CHECK: [[limit_check_1:[^ ]+]] = icmp ule i32 %n, %length.{{1|2}}
642 ; CHECK-NEXT: [[first_iteration_check_1:[^ ]+]] = icmp ult i32 0, %length.{{1|2}}
643 ; CHECK-NEXT: [[wide_cond_1:[^ ]+]] = and i1 [[first_iteration_check_1]], [[limit_check_1]]
644 ; CHECK-NEXT: [[limit_check_2:[^ ]+]] = icmp ule i32 %n, %length.{{1|2}}
645 ; CHECK-NEXT: [[first_iteration_check_2:[^ ]+]] = icmp ult i32 0, %length.{{1|2}}
646 ; CHECK-NEXT: [[wide_cond_2:[^ ]+]] = and i1 [[first_iteration_check_2]], [[limit_check_2]]
647 ; CHECK-NEXT: br label %loop
648 br label %loop
649
650 loop:
651 ; CHECK: loop:
652 ; CHECK: [[wide_cond:[^ ]+]] = and i1 [[wide_cond_1]], [[wide_cond_2]]
653 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
1025 br label %loop
1026
1027 loop:
6541028 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
6551029 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
6561030 %within.bounds.1 = icmp ult i32 %i, %length.1
6771051 }
6781052
6791053 define i32 @three_range_checks(i32* %array.1, i32 %length.1,
680 i32* %array.2, i32 %length.2,
681 i32* %array.3, i32 %length.3, i32 %n) {
682 ; CHECK-LABEL: @three_range_checks
1054 ; CHECK-LABEL: @three_range_checks(
1055 ; CHECK-NEXT: entry:
1056 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1057 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1058 ; CHECK: loop.preheader:
1059 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_3:%.*]]
1060 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_3]]
1061 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
1062 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]
1063 ; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_2]]
1064 ; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]]
1065 ; CHECK-NEXT: [[TMP6:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]
1066 ; CHECK-NEXT: [[TMP7:%.*]] = icmp ult i32 0, [[LENGTH_1]]
1067 ; CHECK-NEXT: [[TMP8:%.*]] = and i1 [[TMP7]], [[TMP6]]
1068 ; CHECK-NEXT: br label [[LOOP:%.*]]
1069 ; CHECK: loop:
1070 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1071 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1072 ; CHECK-NEXT: [[WITHIN_BOUNDS_1:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]]
1073 ; CHECK-NEXT: [[WITHIN_BOUNDS_2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]]
1074 ; CHECK-NEXT: [[WITHIN_BOUNDS_3:%.*]] = icmp ult i32 [[I]], [[LENGTH_3]]
1075 ; CHECK-NEXT: [[WITHIN_BOUNDS_1_AND_2:%.*]] = and i1 [[WITHIN_BOUNDS_1]], [[WITHIN_BOUNDS_2]]
1076 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = and i1 [[WITHIN_BOUNDS_1_AND_2]], [[WITHIN_BOUNDS_3]]
1077 ; CHECK-NEXT: [[TMP9:%.*]] = and i1 [[TMP2]], [[TMP5]]
1078 ; CHECK-NEXT: [[TMP10:%.*]] = and i1 [[TMP9]], [[TMP8]]
1079 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP10]], i32 9) [ "deopt"() ]
1080 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1081 ; CHECK-NEXT: [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]]
1082 ; CHECK-NEXT: [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4
1083 ; CHECK-NEXT: [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
1084 ; CHECK-NEXT: [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]]
1085 ; CHECK-NEXT: [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4
1086 ; CHECK-NEXT: [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
1087 ; CHECK-NEXT: [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_3:%.*]], i64 [[I_I64]]
1088 ; CHECK-NEXT: [[ARRAY_3_I:%.*]] = load i32, i32* [[ARRAY_3_I_PTR]], align 4
1089 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]]
1090 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
1091 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1092 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1093 ; CHECK: exit.loopexit:
1094 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1095 ; CHECK-NEXT: br label [[EXIT]]
1096 ; CHECK: exit:
1097 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1098 ; CHECK-NEXT: ret i32 [[RESULT]]
1099 ;
1100 i32* %array.2, i32 %length.2,
1101 i32* %array.3, i32 %length.3, i32 %n) {
6831102 entry:
6841103 %tmp5 = icmp eq i32 %n, 0
6851104 br i1 %tmp5, label %exit, label %loop.preheader
6861105
6871106 loop.preheader:
688 ; CHECK: loop.preheader:
689 ; CHECK: [[limit_check_1:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
690 ; CHECK-NEXT: [[first_iteration_check_1:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
691 ; CHECK-NEXT: [[wide_cond_1:[^ ]+]] = and i1 [[first_iteration_check_1]], [[limit_check_1]]
692 ; CHECK-NEXT: [[limit_check_2:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
693 ; CHECK-NEXT: [[first_iteration_check_2:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
694 ; CHECK-NEXT: [[wide_cond_2:[^ ]+]] = and i1 [[first_iteration_check_2]], [[limit_check_2]]
695 ; CHECK-NEXT: [[limit_check_3:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
696 ; CHECK-NEXT: [[first_iteration_check_3:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
697 ; CHECK-NEXT: [[wide_cond_3:[^ ]+]] = and i1 [[first_iteration_check_3]], [[limit_check_3]]
698 ; CHECK-NEXT: br label %loop
699 br label %loop
700
701 loop:
702 ; CHECK: loop:
703 ; CHECK: [[wide_cond_and:[^ ]+]] = and i1 [[wide_cond_1]], [[wide_cond_2]]
704 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[wide_cond_and]], [[wide_cond_3]]
705 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
1107 br label %loop
1108
1109 loop:
7061110 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
7071111 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
7081112 %within.bounds.1 = icmp ult i32 %i, %length.1
7351139 }
7361140
7371141 define i32 @three_guards(i32* %array.1, i32 %length.1,
738 i32* %array.2, i32 %length.2,
739 i32* %array.3, i32 %length.3, i32 %n) {
740 ; CHECK-LABEL: @three_guards
1142 ; CHECK-LABEL: @three_guards(
1143 ; CHECK-NEXT: entry:
1144 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1145 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1146 ; CHECK: loop.preheader:
1147 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]
1148 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_1]]
1149 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
1150 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]
1151 ; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_2]]
1152 ; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]]
1153 ; CHECK-NEXT: [[TMP6:%.*]] = icmp ule i32 [[N]], [[LENGTH_3:%.*]]
1154 ; CHECK-NEXT: [[TMP7:%.*]] = icmp ult i32 0, [[LENGTH_3]]
1155 ; CHECK-NEXT: [[TMP8:%.*]] = and i1 [[TMP7]], [[TMP6]]
1156 ; CHECK-NEXT: br label [[LOOP:%.*]]
1157 ; CHECK: loop:
1158 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1159 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1160 ; CHECK-NEXT: [[WITHIN_BOUNDS_1:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]]
1161 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
1162 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1163 ; CHECK-NEXT: [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]]
1164 ; CHECK-NEXT: [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4
1165 ; CHECK-NEXT: [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
1166 ; CHECK-NEXT: [[WITHIN_BOUNDS_2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]]
1167 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP5]], i32 9) [ "deopt"() ]
1168 ; CHECK-NEXT: [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]]
1169 ; CHECK-NEXT: [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4
1170 ; CHECK-NEXT: [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
1171 ; CHECK-NEXT: [[WITHIN_BOUNDS_3:%.*]] = icmp ult i32 [[I]], [[LENGTH_3]]
1172 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP8]], i32 9) [ "deopt"() ]
1173 ; CHECK-NEXT: [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_3:%.*]], i64 [[I_I64]]
1174 ; CHECK-NEXT: [[ARRAY_3_I:%.*]] = load i32, i32* [[ARRAY_3_I_PTR]], align 4
1175 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]]
1176 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
1177 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1178 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1179 ; CHECK: exit.loopexit:
1180 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1181 ; CHECK-NEXT: br label [[EXIT]]
1182 ; CHECK: exit:
1183 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1184 ; CHECK-NEXT: ret i32 [[RESULT]]
1185 ;
1186 i32* %array.2, i32 %length.2,
1187 i32* %array.3, i32 %length.3, i32 %n) {
7411188 entry:
7421189 %tmp5 = icmp eq i32 %n, 0
7431190 br i1 %tmp5, label %exit, label %loop.preheader
7441191
7451192 loop.preheader:
746 ; CHECK: loop.preheader:
747 ; CHECK: [[limit_check_1:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
748 ; CHECK-NEXT: [[first_iteration_check_1:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
749 ; CHECK-NEXT: [[wide_cond_1:[^ ]+]] = and i1 [[first_iteration_check_1]], [[limit_check_1]]
750 ; CHECK-NEXT: [[limit_check_2:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
751 ; CHECK-NEXT: [[first_iteration_check_2:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
752 ; CHECK-NEXT: [[wide_cond_2:[^ ]+]] = and i1 [[first_iteration_check_2]], [[limit_check_2]]
753 ; CHECK-NEXT: [[limit_check_3:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
754 ; CHECK-NEXT: [[first_iteration_check_3:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
755 ; CHECK-NEXT: [[wide_cond_3:[^ ]+]] = and i1 [[first_iteration_check_3]], [[limit_check_3]]
756 ; CHECK-NEXT: br label %loop
757 br label %loop
758
759 loop:
760 ; CHECK: loop:
761 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond_1]], i32 9) [ "deopt"() ]
762 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond_2]], i32 9) [ "deopt"() ]
763 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond_3]], i32 9) [ "deopt"() ]
1193 br label %loop
1194
1195 loop:
7641196
7651197 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
7661198 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
7971229 }
7981230
7991231 define i32 @unsigned_loop_0_to_n_unrelated_condition(i32* %array, i32 %length, i32 %n, i32 %x) {
800 ; CHECK-LABEL: @unsigned_loop_0_to_n_unrelated_condition
1232 ; CHECK-LABEL: @unsigned_loop_0_to_n_unrelated_condition(
1233 ; CHECK-NEXT: entry:
1234 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1235 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1236 ; CHECK: loop.preheader:
1237 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
1238 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
1239 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
1240 ; CHECK-NEXT: br label [[LOOP:%.*]]
1241 ; CHECK: loop:
1242 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1243 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1244 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
1245 ; CHECK-NEXT: [[UNRELATED_COND:%.*]] = icmp ult i32 [[X:%.*]], [[LENGTH]]
1246 ; CHECK-NEXT: [[GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[UNRELATED_COND]]
1247 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[UNRELATED_COND]], [[TMP2]]
1248 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
1249 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1250 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1251 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1252 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1253 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
1254 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1255 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1256 ; CHECK: exit.loopexit:
1257 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1258 ; CHECK-NEXT: br label [[EXIT]]
1259 ; CHECK: exit:
1260 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1261 ; CHECK-NEXT: ret i32 [[RESULT]]
1262 ;
8011263 entry:
8021264 %tmp5 = icmp eq i32 %n, 0
8031265 br i1 %tmp5, label %exit, label %loop.preheader
8041266
8051267 loop.preheader:
806 ; CHECK: loop.preheader:
807 ; CHECK: [[limit_check:[^ ]+]] = icmp ule i32 %n, %length
808 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
809 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
810 ; CHECK-NEXT: br label %loop
811 br label %loop
812
813 loop:
814 ; CHECK: loop:
815 ; CHECK: %unrelated.cond = icmp ult i32 %x, %length
816 ; CHECK: [[guard_cond:[^ ]+]] = and i1 %unrelated.cond, [[wide_cond]]
817 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[guard_cond]], i32 9) [ "deopt"() ]
1268 br label %loop
1269
1270 loop:
8181271 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
8191272 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
8201273 %within.bounds = icmp ult i32 %i, %length
8381291
8391292 ; Don't change the guard condition if there were no widened subconditions
8401293 define i32 @test_no_widened_conditions(i32* %array, i32 %length, i32 %n, i32 %x1, i32 %x2, i32 %x3) {
841 ; CHECK-LABEL: @test_no_widened_conditions
1294 ; CHECK-LABEL: @test_no_widened_conditions(
1295 ; CHECK-NEXT: entry:
1296 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1297 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1298 ; CHECK: loop.preheader:
1299 ; CHECK-NEXT: br label [[LOOP:%.*]]
1300 ; CHECK: loop:
1301 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1302 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1303 ; CHECK-NEXT: [[UNRELATED_COND_1:%.*]] = icmp eq i32 [[X1:%.*]], [[I]]
1304 ; CHECK-NEXT: [[UNRELATED_COND_2:%.*]] = icmp eq i32 [[X2:%.*]], [[I]]
1305 ; CHECK-NEXT: [[UNRELATED_COND_3:%.*]] = icmp eq i32 [[X3:%.*]], [[I]]
1306 ; CHECK-NEXT: [[UNRELATED_COND_AND_1:%.*]] = and i1 [[UNRELATED_COND_1]], [[UNRELATED_COND_2]]
1307 ; CHECK-NEXT: [[GUARD_COND:%.*]] = and i1 [[UNRELATED_COND_AND_1]], [[UNRELATED_COND_3]]
1308 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[GUARD_COND]], i32 9) [ "deopt"() ]
1309 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1310 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1311 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1312 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1313 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
1314 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1315 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1316 ; CHECK: exit.loopexit:
1317 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1318 ; CHECK-NEXT: br label [[EXIT]]
1319 ; CHECK: exit:
1320 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1321 ; CHECK-NEXT: ret i32 [[RESULT]]
1322 ;
8421323 entry:
8431324 %tmp5 = icmp eq i32 %n, 0
8441325 br i1 %tmp5, label %exit, label %loop.preheader
8451326
8461327 loop.preheader:
847 ; CHECK: loop.preheader:
848 ; CHECK-NEXT: br label %loop
849 br label %loop
850
851 loop:
852 ; CHECK: loop:
853 ; CHECK: %unrelated.cond.1 = icmp eq i32 %x1, %i
854 ; CHECK-NEXT: %unrelated.cond.2 = icmp eq i32 %x2, %i
855 ; CHECK-NEXT: %unrelated.cond.3 = icmp eq i32 %x3, %i
856 ; CHECK-NEXT: %unrelated.cond.and.1 = and i1 %unrelated.cond.1, %unrelated.cond.2
857 ; CHECK-NEXT: %guard.cond = and i1 %unrelated.cond.and.1, %unrelated.cond.3
858 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ]
1328 br label %loop
1329
1330 loop:
8591331 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
8601332 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
8611333 %unrelated.cond.1 = icmp eq i32 %x1, %i
8811353 }
8821354
8831355 define i32 @signed_loop_start_to_n_loop_variant_bound(i32* %array, i32 %x, i32 %start, i32 %n) {
884 ; CHECK-LABEL: @signed_loop_start_to_n_loop_variant_bound
1356 ; CHECK-LABEL: @signed_loop_start_to_n_loop_variant_bound(
1357 ; CHECK-NEXT: entry:
1358 ; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
1359 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1360 ; CHECK: loop.preheader:
1361 ; CHECK-NEXT: br label [[LOOP:%.*]]
1362 ; CHECK: loop:
1363 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1364 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ]
1365 ; CHECK-NEXT: [[BOUND:%.*]] = add i32 [[I]], [[X:%.*]]
1366 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[BOUND]]
1367 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
1368 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1369 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1370 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1371 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1372 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
1373 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1374 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1375 ; CHECK: exit.loopexit:
1376 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1377 ; CHECK-NEXT: br label [[EXIT]]
1378 ; CHECK: exit:
1379 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1380 ; CHECK-NEXT: ret i32 [[RESULT]]
1381 ;
8851382 entry:
8861383 %tmp5 = icmp sle i32 %n, 0
8871384 br i1 %tmp5, label %exit, label %loop.preheader
8881385
8891386 loop.preheader:
890 ; CHECK: loop.preheader:
891 ; CHECK-NEXT: br label %loop
892 br label %loop
893
894 loop:
895 ; CHECK: loop:
896 ; CHECK: %bound = add i32 %i, %x
897 ; CHECK-NEXT: %within.bounds = icmp ult i32 %i, %bound
898 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1387 br label %loop
1388
1389 loop:
8991390 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
9001391 %i = phi i32 [ %i.next, %loop ], [ %start, %loop.preheader ]
9011392 %bound = add i32 %i, %x
9171408 }
9181409
9191410 define i32 @signed_loop_start_to_n_non_monotonic_predicate(i32* %array, i32 %x, i32 %start, i32 %n) {
920 ; CHECK-LABEL: @signed_loop_start_to_n_non_monotonic_predicate
1411 ; CHECK-LABEL: @signed_loop_start_to_n_non_monotonic_predicate(
1412 ; CHECK-NEXT: entry:
1413 ; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
1414 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1415 ; CHECK: loop.preheader:
1416 ; CHECK-NEXT: br label [[LOOP:%.*]]
1417 ; CHECK: loop:
1418 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1419 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ]
1420 ; CHECK-NEXT: [[GUARD_COND:%.*]] = icmp eq i32 [[I]], [[X:%.*]]
1421 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[GUARD_COND]], i32 9) [ "deopt"() ]
1422 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1423 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1424 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1425 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1426 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
1427 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1428 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1429 ; CHECK: exit.loopexit:
1430 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1431 ; CHECK-NEXT: br label [[EXIT]]
1432 ; CHECK: exit:
1433 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1434 ; CHECK-NEXT: ret i32 [[RESULT]]
1435 ;
9211436 entry:
9221437 %tmp5 = icmp sle i32 %n, 0
9231438 br i1 %tmp5, label %exit, label %loop.preheader
9241439
9251440 loop.preheader:
926 ; CHECK: loop.preheader:
927 ; CHECK-NEXT: br label %loop
928 br label %loop
929
930 loop:
931 ; CHECK: loop:
932 ; CHECK: %guard.cond = icmp eq i32 %i, %x
933 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ]
1441 br label %loop
1442
1443 loop:
9341444 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
9351445 %i = phi i32 [ %i.next, %loop ], [ %start, %loop.preheader ]
9361446 %guard.cond = icmp eq i32 %i, %x
9511461 }
9521462
9531463 define i32 @unsigned_loop_0_to_n_hoist_length(i32* %array, i16 %length.i16, i32 %n) {
954 ; CHECK-LABEL: @unsigned_loop_0_to_n_hoist_length
1464 ; CHECK-LABEL: @unsigned_loop_0_to_n_hoist_length(
1465 ; CHECK-NEXT: entry:
1466 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1467 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1468 ; CHECK: loop.preheader:
1469 ; CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[LENGTH_I16:%.*]] to i32
1470 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]]
1471 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 0, [[TMP0]]
1472 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
1473 ; CHECK-NEXT: br label [[LOOP:%.*]]
1474 ; CHECK: loop:
1475 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1476 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1477 ; CHECK-NEXT: [[LENGTH:%.*]] = zext i16 [[LENGTH_I16]] to i32
1478 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
1479 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
1480 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1481 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1482 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1483 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1484 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
1485 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1486 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1487 ; CHECK: exit.loopexit:
1488 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1489 ; CHECK-NEXT: br label [[EXIT]]
1490 ; CHECK: exit:
1491 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1492 ; CHECK-NEXT: ret i32 [[RESULT]]
1493 ;
9551494 entry:
9561495 %tmp5 = icmp eq i32 %n, 0
9571496 br i1 %tmp5, label %exit, label %loop.preheader
9581497
9591498 loop.preheader:
960 ; CHECK: loop.preheader:
961 ; CHECK: [[length:[^ ]+]] = zext i16 %length.i16 to i32
962 ; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp ule i32 %n, [[length]]
963 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, [[length]]
964 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
965 ; CHECK-NEXT: br label %loop
966 br label %loop
967
968 loop:
969 ; CHECK: loop:
970 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
1499 br label %loop
1500
1501 loop:
9711502 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
9721503 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
9731504 %length = zext i16 %length.i16 to i32
9891520 }
9901521
9911522 define i32 @unsigned_loop_0_to_n_cant_hoist_length(i32* %array, i32 %length, i32 %divider, i32 %n) {
992 ; CHECK-LABEL: @unsigned_loop_0_to_n_cant_hoist_length
1523 ; CHECK-LABEL: @unsigned_loop_0_to_n_cant_hoist_length(
1524 ; CHECK-NEXT: entry:
1525 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1526 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1527 ; CHECK: loop.preheader:
1528 ; CHECK-NEXT: br label [[LOOP:%.*]]
1529 ; CHECK: loop:
1530 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1531 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1532 ; CHECK-NEXT: [[LENGTH_UDIV:%.*]] = udiv i32 [[LENGTH:%.*]], [[DIVIDER:%.*]]
1533 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH_UDIV]]
1534 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
1535 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1536 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1537 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1538 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1539 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
1540 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1541 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1542 ; CHECK: exit.loopexit:
1543 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1544 ; CHECK-NEXT: br label [[EXIT]]
1545 ; CHECK: exit:
1546 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1547 ; CHECK-NEXT: ret i32 [[RESULT]]
1548 ;
9931549 entry:
9941550 %tmp5 = icmp eq i32 %n, 0
9951551 br i1 %tmp5, label %exit, label %loop.preheader
9961552
9971553 loop.preheader:
998 ; CHECK: loop.preheader:
999 ; CHECK-NEXT: br label %loop
1000 br label %loop
1001
1002 loop:
1003 ; CHECK: loop:
1004 ; CHECK-NEXT: %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1005 ; CHECK-NEXT: %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1006 ; CHECK-NEXT: %length.udiv = udiv i32 %length, %divider
1007 ; CHECK-NEXT: %within.bounds = icmp ult i32 %i, %length.udiv
1008 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1554 br label %loop
1555
1556 loop:
10091557 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
10101558 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
10111559 %length.udiv = udiv i32 %length, %divider
2121 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
2222 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
2323 ; CHECK-NEXT: br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
24 ; CHECK: deopt:
25 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
26 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
27 ; CHECK: guarded:
28 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
29 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
30 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
31 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
32 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
33 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
34 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
35 ; CHECK: exit.loopexit:
36 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
37 ; CHECK-NEXT: br label [[EXIT]]
38 ; CHECK: exit:
39 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
40 ; CHECK-NEXT: ret i32 [[RESULT]]
2441 ;
2542 entry:
2643 %tmp5 = icmp eq i32 %n, 0
7390 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
7491 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
7592 ; CHECK-NEXT: br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
93 ; CHECK: deopt:
94 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
95 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
96 ; CHECK: guarded:
97 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
98 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
99 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
100 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
101 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
102 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ule i32 [[I_NEXT]], [[N]]
103 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
104 ; CHECK: exit.loopexit:
105 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
106 ; CHECK-NEXT: br label [[EXIT]]
107 ; CHECK: exit:
108 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
109 ; CHECK-NEXT: ret i32 [[RESULT]]
76110 ;
77111 entry:
78112 %tmp5 = icmp eq i32 %n, 0
125159 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
126160 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
127161 ; CHECK-NEXT: br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
162 ; CHECK: deopt:
163 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
164 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
165 ; CHECK: guarded:
166 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
167 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
168 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
169 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
170 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
171 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
172 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
173 ; CHECK: exit.loopexit:
174 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
175 ; CHECK-NEXT: br label [[EXIT]]
176 ; CHECK: exit:
177 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
178 ; CHECK-NEXT: ret i32 [[RESULT]]
128179 ;
129180 entry:
130181 %tmp5 = icmp eq i32 %n, 0
177228 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
178229 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
179230 ; CHECK-NEXT: br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
180
181 ;
231 ; CHECK: deopt:
232 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
233 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
234 ; CHECK: guarded:
235 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
236 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
237 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
238 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
239 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
240 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
241 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
242 ; CHECK: exit.loopexit:
243 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
244 ; CHECK-NEXT: br label [[EXIT]]
245 ; CHECK: exit:
246 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
247 ; CHECK-NEXT: ret i32 [[RESULT]]
248 ;
249
182250 entry:
183251 %tmp5 = icmp sle i32 %n, 0
184252 br i1 %tmp5, label %exit, label %loop.preheader
230298 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
231299 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]]
232300 ; CHECK-NEXT: br i1 [[TMP2]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
301 ; CHECK: deopt:
302 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
303 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
304 ; CHECK: guarded:
305 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
306 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
307 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
308 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
309 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
310 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
311 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
312 ; CHECK: exit.loopexit:
313 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
314 ; CHECK-NEXT: br label [[EXIT]]
315 ; CHECK: exit:
316 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
317 ; CHECK-NEXT: ret i32 [[RESULT]]
233318 ;
234319 entry:
235320 %tmp5 = icmp sle i32 %n, 0
283368 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
284369 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
285370 ; CHECK-NEXT: br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
371 ; CHECK: deopt:
372 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
373 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
374 ; CHECK: guarded:
375 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
376 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
377 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
378 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
379 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
380 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[I_NEXT]], [[N]]
381 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP]]
382 ; CHECK: exit.loopexit:
383 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
384 ; CHECK-NEXT: br label [[EXIT]]
385 ; CHECK: exit:
386 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
387 ; CHECK-NEXT: ret i32 [[RESULT]]
286388 ;
287389 entry:
288390 %tmp5 = icmp sle i32 %n, 0
335437 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
336438 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
337439 ; CHECK-NEXT: br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
440 ; CHECK: deopt:
441 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
442 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
443 ; CHECK: guarded:
444 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
445 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
446 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
447 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
448 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
449 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT]], [[N]]
450 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
451 ; CHECK: exit.loopexit:
452 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
453 ; CHECK-NEXT: br label [[EXIT]]
454 ; CHECK: exit:
455 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
456 ; CHECK-NEXT: ret i32 [[RESULT]]
338457 ;
339458 entry:
340459 %tmp5 = icmp sle i32 %n, 0
388507 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
389508 ; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
390509 ; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
510 ; CHECK: deopt:
511 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
512 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
513 ; CHECK: guarded:
514 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
515 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
516 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
517 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
518 ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
519 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I]], [[N]]
520 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
521 ; CHECK: exit.loopexit:
522 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
523 ; CHECK-NEXT: br label [[EXIT]]
524 ; CHECK: exit:
525 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
526 ; CHECK-NEXT: ret i32 [[RESULT]]
391527 ;
392528 entry:
393529 %tmp5 = icmp sle i32 %n, 0
442578 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
443579 ; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
444580 ; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
581 ; CHECK: deopt:
582 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
583 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
584 ; CHECK: guarded:
585 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
586 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
587 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
588 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
589 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I]], [[N]]
590 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
591 ; CHECK: exit.loopexit:
592 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
593 ; CHECK-NEXT: br label [[EXIT]]
594 ; CHECK: exit:
595 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
596 ; CHECK-NEXT: ret i32 [[RESULT]]
445597 ;
446598 entry:
447599 %tmp5 = icmp sle i32 %n, 0
496648 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
497649 ; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
498650 ; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
651 ; CHECK: deopt:
652 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
653 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
654 ; CHECK: guarded:
655 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
656 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
657 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
658 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
659 ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
660 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT]], [[N]]
661 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
662 ; CHECK: exit.loopexit:
663 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
664 ; CHECK-NEXT: br label [[EXIT]]
665 ; CHECK: exit:
666 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
667 ; CHECK-NEXT: ret i32 [[RESULT]]
499668 ;
500669 entry:
501670 %tmp5 = icmp sle i32 %n, 0
550719 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
551720 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
552721 ; CHECK-NEXT: br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
722 ; CHECK: deopt:
723 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
724 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
725 ; CHECK: guarded:
726 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
727 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
728 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
729 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
730 ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
731 ; CHECK-NEXT: [[I_NEXT_OFFSET:%.*]] = add i32 [[I_NEXT]], 1
732 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT_OFFSET]], [[N]]
733 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
734 ; CHECK: exit.loopexit:
735 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
736 ; CHECK-NEXT: br label [[EXIT]]
737 ; CHECK: exit:
738 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
739 ; CHECK-NEXT: ret i32 [[RESULT]]
553740 ;
554741 entry:
555742 %tmp5 = icmp sle i32 %n, 0
600787 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
601788 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
602789 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
790 ; CHECK: deopt:
791 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
792 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
793 ; CHECK: guarded:
794 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
795 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
796 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
797 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
798 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
799 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[N]]
800 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
801 ; CHECK: exit.loopexit:
802 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
803 ; CHECK-NEXT: br label [[EXIT]]
804 ; CHECK: exit:
805 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
806 ; CHECK-NEXT: ret i32 [[RESULT]]
603807 ;
604808 entry:
605809 %tmp5 = icmp sle i32 %n, 0
648852 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
649853 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
650854 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
855 ; CHECK: deopt:
856 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
857 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
858 ; CHECK: guarded:
859 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
860 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
861 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
862 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
863 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 2
864 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
865 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
866 ; CHECK: exit.loopexit:
867 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
868 ; CHECK-NEXT: br label [[EXIT]]
869 ; CHECK: exit:
870 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
871 ; CHECK-NEXT: ret i32 [[RESULT]]
651872 ;
652873 entry:
653874 %tmp5 = icmp sle i32 %n, 0
701922 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
702923 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
703924 ; CHECK-NEXT: br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
925 ; CHECK: deopt:
926 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
927 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
928 ; CHECK: guarded:
929 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
930 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
931 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
932 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
933 ; CHECK-NEXT: [[J_NEXT]] = add nsw i32 [[J]], 1
934 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
935 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
936 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
937 ; CHECK: exit.loopexit:
938 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
939 ; CHECK-NEXT: br label [[EXIT]]
940 ; CHECK: exit:
941 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
942 ; CHECK-NEXT: ret i32 [[RESULT]]
704943 ;
705944 entry:
706945 %tmp5 = icmp sle i32 %n, 0
758997 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
759998 ; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[WIDENABLE_COND]]
760999 ; CHECK-NEXT: br i1 [[TMP5]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1000 ; CHECK: deopt:
1001 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1002 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
1003 ; CHECK: guarded:
1004 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1005 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1006 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1007 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1008 ; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1
1009 ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
1010 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1011 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1012 ; CHECK: exit.loopexit:
1013 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1014 ; CHECK-NEXT: br label [[EXIT]]
1015 ; CHECK: exit:
1016 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1017 ; CHECK-NEXT: ret i32 [[RESULT]]
7611018 ;
7621019 entry:
7631020 %tmp5 = icmp sle i32 %n, 0
8091066 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
8101067 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
8111068 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1069 ; CHECK: deopt:
1070 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1071 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
1072 ; CHECK: guarded:
1073 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1074 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1075 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1076 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1077 ; CHECK-NEXT: [[J_NEXT]] = add i16 [[J]], 1
1078 ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
1079 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1080 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1081 ; CHECK: exit.loopexit:
1082 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1083 ; CHECK-NEXT: br label [[EXIT]]
1084 ; CHECK: exit:
1085 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1086 ; CHECK-NEXT: ret i32 [[RESULT]]
8121087 ;
8131088 entry:
8141089 %tmp5 = icmp sle i32 %n, 0
8601135 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
8611136 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
8621137 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1138 ; CHECK: deopt:
1139 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1140 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
1141 ; CHECK: guarded:
1142 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1143 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1144 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1145 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1146 ; CHECK-NEXT: [[J_NEXT]] = add nsw i32 [[J]], 2
1147 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
1148 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1149 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1150 ; CHECK: exit.loopexit:
1151 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1152 ; CHECK-NEXT: br label [[EXIT]]
1153 ; CHECK: exit:
1154 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1155 ; CHECK-NEXT: ret i32 [[RESULT]]
8631156 ;
8641157 entry:
8651158 %tmp5 = icmp sle i32 %n, 0
9201213 ; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP2]], [[TMP5]]
9211214 ; CHECK-NEXT: [[TMP7:%.*]] = and i1 [[TMP6]], [[WIDENABLE_COND]]
9221215 ; CHECK-NEXT: br i1 [[TMP7]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1216 ; CHECK: deopt:
1217 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1218 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
1219 ; CHECK: guarded:
1220 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1221 ; CHECK-NEXT: [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]]
1222 ; CHECK-NEXT: [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4
1223 ; CHECK-NEXT: [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
1224 ; CHECK-NEXT: [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]]
1225 ; CHECK-NEXT: [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4
1226 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
1227 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
1228 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1229 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1230 ; CHECK: exit.loopexit:
1231 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1232 ; CHECK-NEXT: br label [[EXIT]]
1233 ; CHECK: exit:
1234 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1235 ; CHECK-NEXT: ret i32 [[RESULT]]
9231236 ;
9241237 entry:
9251238 %tmp5 = icmp eq i32 %n, 0
9891302 ; CHECK-NEXT: [[TMP10:%.*]] = and i1 [[TMP9]], [[TMP8]]
9901303 ; CHECK-NEXT: [[TMP11:%.*]] = and i1 [[TMP10]], [[WIDENABLE_COND]]
9911304 ; CHECK-NEXT: br i1 [[TMP11]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1305 ; CHECK: deopt:
1306 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1307 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
1308 ; CHECK: guarded:
1309 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1310 ; CHECK-NEXT: [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]]
1311 ; CHECK-NEXT: [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4
1312 ; CHECK-NEXT: [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
1313 ; CHECK-NEXT: [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]]
1314 ; CHECK-NEXT: [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4
1315 ; CHECK-NEXT: [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
1316 ; CHECK-NEXT: [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_3:%.*]], i64 [[I_I64]]
1317 ; CHECK-NEXT: [[ARRAY_3_I:%.*]] = load i32, i32* [[ARRAY_3_I_PTR]], align 4
1318 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]]
1319 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
1320 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1321 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1322 ; CHECK: exit.loopexit:
1323 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1324 ; CHECK-NEXT: br label [[EXIT]]
1325 ; CHECK: exit:
1326 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1327 ; CHECK-NEXT: ret i32 [[RESULT]]
9921328 ;
9931329 entry:
9941330 %tmp5 = icmp eq i32 %n, 0
11791515 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[UNRELATED_COND]], [[TMP2]]
11801516 ; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
11811517 ; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1518 ; CHECK: deopt:
1519 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1520 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
1521 ; CHECK: guarded:
1522 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1523 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1524 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1525 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1526 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
1527 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1528 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1529 ; CHECK: exit.loopexit:
1530 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1531 ; CHECK-NEXT: br label [[EXIT]]
1532 ; CHECK: exit:
1533 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1534 ; CHECK-NEXT: ret i32 [[RESULT]]
11821535 ;
11831536 entry:
11841537 %tmp5 = icmp eq i32 %n, 0
12331586 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
12341587 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[GUARD_COND]], [[WIDENABLE_COND]]
12351588 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1589 ; CHECK: deopt:
1590 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1591 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
1592 ; CHECK: guarded:
1593 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1594 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1595 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1596 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1597 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
1598 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1599 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1600 ; CHECK: exit.loopexit:
1601 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1602 ; CHECK-NEXT: br label [[EXIT]]
1603 ; CHECK: exit:
1604 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1605 ; CHECK-NEXT: ret i32 [[RESULT]]
12361606 ;
12371607 entry:
12381608 %tmp5 = icmp eq i32 %n, 0
12861656 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
12871657 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
12881658 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1659 ; CHECK: deopt:
1660 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1661 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
1662 ; CHECK: guarded:
1663 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1664 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1665 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1666 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1667 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
1668 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1669 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1670 ; CHECK: exit.loopexit:
1671 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1672 ; CHECK-NEXT: br label [[EXIT]]
1673 ; CHECK: exit:
1674 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1675 ; CHECK-NEXT: ret i32 [[RESULT]]
12891676 ;
12901677 entry:
12911678 %tmp5 = icmp sle i32 %n, 0
13351722 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
13361723 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[GUARD_COND]], [[WIDENABLE_COND]]
13371724 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1725 ; CHECK: deopt:
1726 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1727 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
1728 ; CHECK: guarded:
1729 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1730 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1731 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1732 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1733 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
1734 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1735 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1736 ; CHECK: exit.loopexit:
1737 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1738 ; CHECK-NEXT: br label [[EXIT]]
1739 ; CHECK: exit:
1740 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1741 ; CHECK-NEXT: ret i32 [[RESULT]]
13381742 ;
13391743 entry:
13401744 %tmp5 = icmp sle i32 %n, 0
13891793 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
13901794 ; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
13911795 ; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1796 ; CHECK: deopt:
1797 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1798 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
1799 ; CHECK: guarded:
1800 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1801 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1802 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1803 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1804 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
1805 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1806 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1807 ; CHECK: exit.loopexit:
1808 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1809 ; CHECK-NEXT: br label [[EXIT]]
1810 ; CHECK: exit:
1811 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1812 ; CHECK-NEXT: ret i32 [[RESULT]]
13921813 ;
13931814 entry:
13941815 %tmp5 = icmp eq i32 %n, 0
14391860 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
14401861 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
14411862 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1863 ; CHECK: deopt:
1864 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1865 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
1866 ; CHECK: guarded:
1867 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1868 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1869 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1870 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1871 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
1872 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1873 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1874 ; CHECK: exit.loopexit:
1875 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1876 ; CHECK-NEXT: br label [[EXIT]]
1877 ; CHECK: exit:
1878 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1879 ; CHECK-NEXT: ret i32 [[RESULT]]
14421880 ;
14431881 entry:
14441882 %tmp5 = icmp eq i32 %n, 0
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1 ; RUN: opt -S -loop-predication < %s 2>&1 | FileCheck %s
12 ; RUN: opt -S -passes='require,loop(loop-predication)' < %s 2>&1 | FileCheck %s
23
34 declare void @llvm.experimental.guard(i1, ...)
45
56 define i32 @signed_loop_0_to_n_nested_0_to_l_inner_index_check(i32* %array, i32 %length, i32 %n, i32 %l) {
6 ; CHECK-LABEL: @signed_loop_0_to_n_nested_0_to_l_inner_index_check
7 ; CHECK-LABEL: @signed_loop_0_to_n_nested_0_to_l_inner_index_check(
8 ; CHECK-NEXT: entry:
9 ; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
10 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[OUTER_LOOP_PREHEADER:%.*]]
11 ; CHECK: outer.loop.preheader:
12 ; CHECK-NEXT: br label [[OUTER_LOOP:%.*]]
13 ; CHECK: outer.loop:
14 ; CHECK-NEXT: [[OUTER_LOOP_ACC:%.*]] = phi i32 [ [[OUTER_LOOP_ACC_NEXT:%.*]], [[OUTER_LOOP_INC:%.*]] ], [ 0, [[OUTER_LOOP_PREHEADER]] ]
15 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[OUTER_LOOP_INC]] ], [ 0, [[OUTER_LOOP_PREHEADER]] ]
16 ; CHECK-NEXT: [[TMP6:%.*]] = icmp sle i32 [[L:%.*]], 0
17 ; CHECK-NEXT: br i1 [[TMP6]], label [[OUTER_LOOP_INC]], label [[INNER_LOOP_PREHEADER:%.*]]
18 ; CHECK: inner.loop.preheader:
19 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[L]], [[LENGTH:%.*]]
20 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
21 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
22 ; CHECK-NEXT: br label [[INNER_LOOP:%.*]]
23 ; CHECK: inner.loop:
24 ; CHECK-NEXT: [[INNER_LOOP_ACC:%.*]] = phi i32 [ [[INNER_LOOP_ACC_NEXT:%.*]], [[INNER_LOOP]] ], [ [[OUTER_LOOP_ACC]], [[INNER_LOOP_PREHEADER]] ]
25 ; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[INNER_LOOP]] ], [ 0, [[INNER_LOOP_PREHEADER]] ]
26 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH]]
27 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
28 ; CHECK-NEXT: [[J_I64:%.*]] = zext i32 [[J]] to i64
29 ; CHECK-NEXT: [[ARRAY_J_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[J_I64]]
30 ; CHECK-NEXT: [[ARRAY_J:%.*]] = load i32, i32* [[ARRAY_J_PTR]], align 4
31 ; CHECK-NEXT: [[INNER_LOOP_ACC_NEXT]] = add i32 [[INNER_LOOP_ACC]], [[ARRAY_J]]
32 ; CHECK-NEXT: [[J_NEXT]] = add nsw i32 [[J]], 1
33 ; CHECK-NEXT: [[INNER_CONTINUE:%.*]] = icmp slt i32 [[J_NEXT]], [[L]]
34 ; CHECK-NEXT: br i1 [[INNER_CONTINUE]], label [[INNER_LOOP]], label [[OUTER_LOOP_INC_LOOPEXIT:%.*]]
35 ; CHECK: outer.loop.inc.loopexit:
36 ; CHECK-NEXT: [[INNER_LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[INNER_LOOP_ACC_NEXT]], [[INNER_LOOP]] ]
37 ; CHECK-NEXT: br label [[OUTER_LOOP_INC]]
38 ; CHECK: outer.loop.inc:
39 ; CHECK-NEXT: [[OUTER_LOOP_ACC_NEXT]] = phi i32 [ [[OUTER_LOOP_ACC]], [[OUTER_LOOP]] ], [ [[INNER_LOOP_ACC_NEXT_LCSSA]], [[OUTER_LOOP_INC_LOOPEXIT]] ]
40 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
41 ; CHECK-NEXT: [[OUTER_CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
42 ; CHECK-NEXT: br i1 [[OUTER_CONTINUE]], label [[OUTER_LOOP]], label [[EXIT_LOOPEXIT:%.*]]
43 ; CHECK: exit.loopexit:
44 ; CHECK-NEXT: [[OUTER_LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[OUTER_LOOP_ACC_NEXT]], [[OUTER_LOOP_INC]] ]
45 ; CHECK-NEXT: br label [[EXIT]]
46 ; CHECK: exit:
47 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[OUTER_LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
48 ; CHECK-NEXT: ret i32 [[RESULT]]
49 ;
750 entry:
851 %tmp5 = icmp sle i32 %n, 0
952 br i1 %tmp5, label %exit, label %outer.loop.preheader
1659 %i = phi i32 [ %i.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
1760 %tmp6 = icmp sle i32 %l, 0
1861 br i1 %tmp6, label %outer.loop.inc, label %inner.loop.preheader
19
62
2063 inner.loop.preheader:
21 ; CHECK: inner.loop.preheader:
22 ; CHECK: [[limit_check:[^ ]+]] = icmp sle i32 %l, %length
23 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
24 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
25 ; CHECK-NEXT: br label %inner.loop
2664 br label %inner.loop
2765
2866 inner.loop:
29 ; CHECK: inner.loop:
30 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
3167 %inner.loop.acc = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %inner.loop.preheader ]
3268 %j = phi i32 [ %j.next, %inner.loop ], [ 0, %inner.loop.preheader ]
3369
3470 %within.bounds = icmp ult i32 %j, %length
3571 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
36
72
3773 %j.i64 = zext i32 %j to i64
3874 %array.j.ptr = getelementptr inbounds i32, i32* %array, i64 %j.i64
3975 %array.j = load i32, i32* %array.j.ptr, align 4
5591 }
5692
5793 define i32 @signed_loop_0_to_n_nested_0_to_l_outer_index_check(i32* %array, i32 %length, i32 %n, i32 %l) {
58 ; CHECK-LABEL: @signed_loop_0_to_n_nested_0_to_l_outer_index_check
94 ; CHECK-LABEL: @signed_loop_0_to_n_nested_0_to_l_outer_index_check(
95 ; CHECK-NEXT: entry:
96 ; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
97 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[OUTER_LOOP_PREHEADER:%.*]]
98 ; CHECK: outer.loop.preheader:
99 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]]
100 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
101 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
102 ; CHECK-NEXT: br label [[OUTER_LOOP:%.*]]
103 ; CHECK: outer.loop:
104 ; CHECK-NEXT: [[OUTER_LOOP_ACC:%.*]] = phi i32 [ [[OUTER_LOOP_ACC_NEXT:%.*]], [[OUTER_LOOP_INC:%.*]] ], [ 0, [[OUTER_LOOP_PREHEADER]] ]
105 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[OUTER_LOOP_INC]] ], [ 0, [[OUTER_LOOP_PREHEADER]] ]
106 ; CHECK-NEXT: [[TMP6:%.*]] = icmp sle i32 [[L:%.*]], 0
107 ; CHECK-NEXT: br i1 [[TMP6]], label [[OUTER_LOOP_INC]], label [[INNER_LOOP_PREHEADER:%.*]]
108 ; CHECK: inner.loop.preheader:
109 ; CHECK-NEXT: br label [[INNER_LOOP:%.*]]
110 ; CHECK: inner.loop:
111 ; CHECK-NEXT: [[INNER_LOOP_ACC:%.*]] = phi i32 [ [[INNER_LOOP_ACC_NEXT:%.*]], [[INNER_LOOP]] ], [ [[OUTER_LOOP_ACC]], [[INNER_LOOP_PREHEADER]] ]
112 ; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[INNER_LOOP]] ], [ 0, [[INNER_LOOP_PREHEADER]] ]
113 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
114 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
115 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
116 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
117 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
118 ; CHECK-NEXT: [[INNER_LOOP_ACC_NEXT]] = add i32 [[INNER_LOOP_ACC]], [[ARRAY_I]]
119 ; CHECK-NEXT: [[J_NEXT]] = add nsw i32 [[J]], 1
120 ; CHECK-NEXT: [[INNER_CONTINUE:%.*]] = icmp slt i32 [[J_NEXT]], [[L]]
121 ; CHECK-NEXT: br i1 [[INNER_CONTINUE]], label [[INNER_LOOP]], label [[OUTER_LOOP_INC_LOOPEXIT:%.*]]
122 ; CHECK: outer.loop.inc.loopexit:
123 ; CHECK-NEXT: [[INNER_LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[INNER_LOOP_ACC_NEXT]], [[INNER_LOOP]] ]
124 ; CHECK-NEXT: br label [[OUTER_LOOP_INC]]
125 ; CHECK: outer.loop.inc:
126 ; CHECK-NEXT: [[OUTER_LOOP_ACC_NEXT]] = phi i32 [ [[OUTER_LOOP_ACC]], [[OUTER_LOOP]] ], [ [[INNER_LOOP_ACC_NEXT_LCSSA]], [[OUTER_LOOP_INC_LOOPEXIT]] ]
127 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
128 ; CHECK-NEXT: [[OUTER_CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
129 ; CHECK-NEXT: br i1 [[OUTER_CONTINUE]], label [[OUTER_LOOP]], label [[EXIT_LOOPEXIT:%.*]]
130 ; CHECK: exit.loopexit:
131 ; CHECK-NEXT: [[OUTER_LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[OUTER_LOOP_ACC_NEXT]], [[OUTER_LOOP_INC]] ]
132 ; CHECK-NEXT: br label [[EXIT]]
133 ; CHECK: exit:
134 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[OUTER_LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
135 ; CHECK-NEXT: ret i32 [[RESULT]]
136 ;
59137 entry:
60138 %tmp5 = icmp sle i32 %n, 0
61139 br i1 %tmp5, label %exit, label %outer.loop.preheader
62140
63141 outer.loop.preheader:
64 ; CHECK: outer.loop.preheader:
65 ; CHECK: [[limit_check:[^ ]+]] = icmp sle i32 %n, %length
66 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
67 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
68 ; CHECK-NEXT: br label %outer.loop
69142 br label %outer.loop
70143
71144 outer.loop:
73146 %i = phi i32 [ %i.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
74147 %tmp6 = icmp sle i32 %l, 0
75148 br i1 %tmp6, label %outer.loop.inc, label %inner.loop.preheader
76
149
77150 inner.loop.preheader:
78151 br label %inner.loop
79152
80153 inner.loop:
81 ; CHECK: inner.loop:
82 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
83154
84155 %inner.loop.acc = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %inner.loop.preheader ]
85156 %j = phi i32 [ %j.next, %inner.loop ], [ 0, %inner.loop.preheader ]
86157
87158 %within.bounds = icmp ult i32 %i, %length
88159 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
89
160
90161 %i.i64 = zext i32 %i to i64
91162 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
92163 %array.i = load i32, i32* %array.i.ptr, align 4
108179 }
109180
110181 define i32 @signed_loop_0_to_n_nested_i_to_l_inner_index_check(i32* %array, i32 %length, i32 %n, i32 %l) {
111 ; CHECK-LABEL: @signed_loop_0_to_n_nested_i_to_l_inner_index_check
182 ; CHECK-LABEL: @signed_loop_0_to_n_nested_i_to_l_inner_index_check(
183 ; CHECK-NEXT: entry:
184 ; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
185 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[OUTER_LOOP_PREHEADER:%.*]]
186 ; CHECK: outer.loop.preheader:
187 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]]
188 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
189 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
190 ; CHECK-NEXT: br label [[OUTER_LOOP:%.*]]
191 ; CHECK: outer.loop:
192 ; CHECK-NEXT: [[OUTER_LOOP_ACC:%.*]] = phi i32 [ [[OUTER_LOOP_ACC_NEXT:%.*]], [[OUTER_LOOP_INC:%.*]] ], [ 0, [[OUTER_LOOP_PREHEADER]] ]
193 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[OUTER_LOOP_INC]] ], [ 0, [[OUTER_LOOP_PREHEADER]] ]
194 ; CHECK-NEXT: [[TMP6:%.*]] = icmp sle i32 [[L:%.*]], 0
195 ; CHECK-NEXT: br i1 [[TMP6]], label [[OUTER_LOOP_INC]], label [[INNER_LOOP_PREHEADER:%.*]]
196 ; CHECK: inner.loop.preheader:
197 ; CHECK-NEXT: [[TMP3:%.*]] = icmp sle i32 [[L]], [[LENGTH]]
198 ; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
199 ; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]]
200 ; CHECK-NEXT: br label [[INNER_LOOP:%.*]]
201 ; CHECK: inner.loop:
202 ; CHECK-NEXT: [[INNER_LOOP_ACC:%.*]] = phi i32 [ [[INNER_LOOP_ACC_NEXT:%.*]], [[INNER_LOOP]] ], [ [[OUTER_LOOP_ACC]], [[INNER_LOOP_PREHEADER]] ]
203 ; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[INNER_LOOP]] ], [ [[I]], [[INNER_LOOP_PREHEADER]] ]
204 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH]]
205 ; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP3]], [[TMP2]]
206 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP6]], i32 9) [ "deopt"() ]
207 ; CHECK-NEXT: [[J_I64:%.*]] = zext i32 [[J]] to i64
208 ; CHECK-NEXT: [[ARRAY_J_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[J_I64]]
209 ; CHECK-NEXT: [[ARRAY_J:%.*]] = load i32, i32* [[ARRAY_J_PTR]], align 4
210 ; CHECK-NEXT: [[INNER_LOOP_ACC_NEXT]] = add i32 [[INNER_LOOP_ACC]], [[ARRAY_J]]
211 ; CHECK-NEXT: [[J_NEXT]] = add nsw i32 [[J]], 1
212 ; CHECK-NEXT: [[INNER_CONTINUE:%.*]] = icmp slt i32 [[J_NEXT]], [[L]]
213 ; CHECK-NEXT: br i1 [[INNER_CONTINUE]], label [[INNER_LOOP]], label [[OUTER_LOOP_INC_LOOPEXIT:%.*]]
214 ; CHECK: outer.loop.inc.loopexit:
215 ; CHECK-NEXT: [[INNER_LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[INNER_LOOP_ACC_NEXT]], [[INNER_LOOP]] ]
216 ; CHECK-NEXT: br label [[OUTER_LOOP_INC]]
217 ; CHECK: outer.loop.inc:
218 ; CHECK-NEXT: [[OUTER_LOOP_ACC_NEXT]] = phi i32 [ [[OUTER_LOOP_ACC]], [[OUTER_LOOP]] ], [ [[INNER_LOOP_ACC_NEXT_LCSSA]], [[OUTER_LOOP_INC_LOOPEXIT]] ]
219 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
220 ; CHECK-NEXT: [[OUTER_CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
221 ; CHECK-NEXT: br i1 [[OUTER_CONTINUE]], label [[OUTER_LOOP]], label [[EXIT_LOOPEXIT:%.*]]
222 ; CHECK: exit.loopexit:
223 ; CHECK-NEXT: [[OUTER_LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[OUTER_LOOP_ACC_NEXT]], [[OUTER_LOOP_INC]] ]
224 ; CHECK-NEXT: br label [[EXIT]]
225 ; CHECK: exit:
226 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[OUTER_LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
227 ; CHECK-NEXT: ret i32 [[RESULT]]
228 ;
112229 entry:
113230 %tmp5 = icmp sle i32 %n, 0
114231 br i1 %tmp5, label %exit, label %outer.loop.preheader
115232
116233 outer.loop.preheader:
117 ; CHECK: outer.loop.preheader:
118 ; CHECK-NEXT: [[limit_check_outer:[^ ]+]] = icmp sle i32 %n, %length
119 ; CHECK-NEXT: [[first_iteration_check_outer:[^ ]+]] = icmp ult i32 0, %length
120 ; CHECK-NEXT: [[wide_cond_outer:[^ ]+]] = and i1 [[first_iteration_check_outer]], [[limit_check_outer]]
121 ; CHECK-NEXT: br label %outer.loop
122234 br label %outer.loop
123235
124236 outer.loop:
125 ; CHECK: outer.loop:
126237 %outer.loop.acc = phi i32 [ %outer.loop.acc.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
127238 %i = phi i32 [ %i.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
128239 %tmp6 = icmp sle i32 %l, 0
129240 br i1 %tmp6, label %outer.loop.inc, label %inner.loop.preheader
130
241
131242 inner.loop.preheader:
132 ; CHECK: inner.loop.preheader:
133 ; CHECK: [[limit_check_inner:[^ ]+]] = icmp sle i32 %l, %length
134 ; CHECK: br label %inner.loop
135243 br label %inner.loop
136244
137245 inner.loop:
138 ; CHECK: inner.loop:
139 ; CHECK: [[wide_cond:[^ ]+]] = and i1 [[limit_check_inner]], [[wide_cond_outer]]
140 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
141246 %inner.loop.acc = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %inner.loop.preheader ]
142247 %j = phi i32 [ %j.next, %inner.loop ], [ %i, %inner.loop.preheader ]
143248
144249 %within.bounds = icmp ult i32 %j, %length
145250 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
146
251
147252 %j.i64 = zext i32 %j to i64
148253 %array.j.ptr = getelementptr inbounds i32, i32* %array, i64 %j.i64
149254 %array.j = load i32, i32* %array.j.ptr, align 4
165270 }
166271
167272 define i32 @cant_expand_guard_check_start(i32* %array, i32 %length, i32 %n, i32 %l, i32 %maybezero) {
168 ; CHECK-LABEL: @cant_expand_guard_check_start
273 ; CHECK-LABEL: @cant_expand_guard_check_start(
274 ; CHECK-NEXT: entry:
275 ; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
276 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[OUTER_LOOP_PREHEADER:%.*]]
277 ; CHECK: outer.loop.preheader:
278 ; CHECK-NEXT: br label [[OUTER_LOOP:%.*]]
279 ; CHECK: outer.loop:
280 ; CHECK-NEXT: [[OUTER_LOOP_ACC:%.*]] = phi i32 [ [[OUTER_LOOP_ACC_NEXT:%.*]], [[OUTER_LOOP_INC:%.*]] ], [ 0, [[OUTER_LOOP_PREHEADER]] ]
281 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[OUTER_LOOP_INC]] ], [ 0, [[OUTER_LOOP_PREHEADER]] ]
282 ; CHECK-NEXT: [[TMP6:%.*]] = icmp sle i32 [[L:%.*]], 0
283 ; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[I]], [[MAYBEZERO:%.*]]
284 ; CHECK-NEXT: br i1 [[TMP6]], label [[OUTER_LOOP_INC]], label [[INNER_LOOP_PREHEADER:%.*]]
285 ; CHECK: inner.loop.preheader:
286 ; CHECK-NEXT: br label [[INNER_LOOP:%.*]]
287 ; CHECK: inner.loop:
288 ; CHECK-NEXT: [[INNER_LOOP_ACC:%.*]] = phi i32 [ [[INNER_LOOP_ACC_NEXT:%.*]], [[INNER_LOOP]] ], [ [[OUTER_LOOP_ACC]], [[INNER_LOOP_PREHEADER]] ]
289 ; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[INNER_LOOP]] ], [ [[DIV]], [[INNER_LOOP_PREHEADER]] ]
290 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH:%.*]]
291 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
292 ; CHECK-NEXT: [[J_I64:%.*]] = zext i32 [[J]] to i64
293 ; CHECK-NEXT: [[ARRAY_J_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[J_I64]]
294 ; CHECK-NEXT: [[ARRAY_J:%.*]] = load i32, i32* [[ARRAY_J_PTR]], align 4
295 ; CHECK-NEXT: [[INNER_LOOP_ACC_NEXT]] = add i32 [[INNER_LOOP_ACC]], [[ARRAY_J]]
296 ; CHECK-NEXT: [[J_NEXT]] = add nsw i32 [[J]], 1
297 ; CHECK-NEXT: [[INNER_CONTINUE:%.*]] = icmp slt i32 [[J_NEXT]], [[L]]
298 ; CHECK-NEXT: br i1 [[INNER_CONTINUE]], label [[INNER_LOOP]], label [[OUTER_LOOP_INC_LOOPEXIT:%.*]]
299 ; CHECK: outer.loop.inc.loopexit:
300 ; CHECK-NEXT: [[INNER_LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[INNER_LOOP_ACC_NEXT]], [[INNER_LOOP]] ]
301 ; CHECK-NEXT: br label [[OUTER_LOOP_INC]]
302 ; CHECK: outer.loop.inc:
303 ; CHECK-NEXT: [[OUTER_LOOP_ACC_NEXT]] = phi i32 [ [[OUTER_LOOP_ACC]], [[OUTER_LOOP]] ], [ [[INNER_LOOP_ACC_NEXT_LCSSA]], [[OUTER_LOOP_INC_LOOPEXIT]] ]
304 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
305 ; CHECK-NEXT: [[OUTER_CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
306 ; CHECK-NEXT: br i1 [[OUTER_CONTINUE]], label [[OUTER_LOOP]], label [[EXIT_LOOPEXIT:%.*]]
307 ; CHECK: exit.loopexit:
308 ; CHECK-NEXT: [[OUTER_LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[OUTER_LOOP_ACC_NEXT]], [[OUTER_LOOP_INC]] ]
309 ; CHECK-NEXT: br label [[EXIT]]
310 ; CHECK: exit:
311 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[OUTER_LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
312 ; CHECK-NEXT: ret i32 [[RESULT]]
313 ;
169314 entry:
170315 %tmp5 = icmp sle i32 %n, 0
171316 br i1 %tmp5, label %exit, label %outer.loop.preheader
179324 %tmp6 = icmp sle i32 %l, 0
180325 %div = udiv i32 %i, %maybezero
181326 br i1 %tmp6, label %outer.loop.inc, label %inner.loop.preheader
182
327
183328 inner.loop.preheader:
184 ; CHECK: inner.loop.preheader:
185 ; CHECK: br label %inner.loop
186329 br label %inner.loop
187330
188331 inner.loop:
189 ; CHECK: inner.loop:
190 ; CHECK: %within.bounds = icmp ult i32 %j, %length
191 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
192332 %inner.loop.acc = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %inner.loop.preheader ]
193333 %j = phi i32 [ %j.next, %inner.loop ], [ %div, %inner.loop.preheader ]
194334
195335 %within.bounds = icmp ult i32 %j, %length
196336 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
197
337
198338 %j.i64 = zext i32 %j to i64
199339 %array.j.ptr = getelementptr inbounds i32, i32* %array, i64 %j.i64
200340 %array.j = load i32, i32* %array.j.ptr, align 4
213353 exit:
214354 %result = phi i32 [ 0, %entry ], [ %outer.loop.acc.next, %outer.loop.inc ]
215355 ret i32 %result
216 }
356 }
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1 ; RUN: opt -S -loop-predication -loop-predication-skip-profitability-checks=false < %s 2>&1 | FileCheck %s
12 ; RUN: opt -S -loop-predication-skip-profitability-checks=false -passes='require,require,loop(loop-predication)' < %s 2>&1 | FileCheck %s
23
67 ; LatchExitProbability: 0x04000000 / 0x80000000 = 3.12%
78 ; ExitingBlockProbability: 0x7ffa572a / 0x80000000 = 99.98%
89 define i64 @donot_predicate(i64* nocapture readonly %arg, i32 %length, i64* nocapture readonly %arg2, i64* nocapture readonly %n_addr, i64 %i) {
9 ; CHECK-LABEL: donot_predicate(
10 ; CHECK-LABEL: @donot_predicate(
11 ; CHECK-NEXT: entry:
12 ; CHECK-NEXT: [[LENGTH_EXT:%.*]] = zext i32 [[LENGTH:%.*]] to i64
13 ; CHECK-NEXT: [[N_PRE:%.*]] = load i64, i64* [[N_ADDR:%.*]], align 4
14 ; CHECK-NEXT: br label [[HEADER:%.*]]
15 ; CHECK: Header:
16 ; CHECK-NEXT: [[RESULT_IN3:%.*]] = phi i64* [ [[ARG2:%.*]], [[ENTRY:%.*]] ], [ [[ARG:%.*]], [[LATCH:%.*]] ]
17 ; CHECK-NEXT: [[J2:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[J_NEXT:%.*]], [[LATCH]] ]
18 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i64 [[J2]], [[LENGTH_EXT]]
19 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
20 ; CHECK-NEXT: [[INNERCMP:%.*]] = icmp eq i64 [[J2]], [[N_PRE]]
21 ; CHECK-NEXT: [[J_NEXT]] = add nuw nsw i64 [[J2]], 1
22 ; CHECK-NEXT: br i1 [[INNERCMP]], label [[LATCH]], label [[EXIT:%.*]], !prof !0
23 ; CHECK: Latch:
24 ; CHECK-NEXT: [[SPECULATE_TRIP_COUNT:%.*]] = icmp ult i64 [[J_NEXT]], 1048576
25 ; CHECK-NEXT: br i1 [[SPECULATE_TRIP_COUNT]], label [[HEADER]], label [[DEOPT:%.*]]
26 ; CHECK: deopt:
27 ; CHECK-NEXT: [[COUNTED_SPECULATION_FAILED:%.*]] = call i64 (...) @llvm.experimental.deoptimize.i64(i64 30) [ "deopt"(i32 0) ]
28 ; CHECK-NEXT: ret i64 [[COUNTED_SPECULATION_FAILED]]
29 ; CHECK: exit:
30 ; CHECK-NEXT: [[RESULT_IN3_LCSSA:%.*]] = phi i64* [ [[RESULT_IN3]], [[HEADER]] ]
31 ; CHECK-NEXT: [[RESULT_LE:%.*]] = load i64, i64* [[RESULT_IN3_LCSSA]], align 8
32 ; CHECK-NEXT: ret i64 [[RESULT_LE]]
33 ;
1034 entry:
1135 %length.ext = zext i32 %length to i64
1236 %n.pre = load i64, i64* %n_addr, align 4
1337 br label %Header
1438
15 ; CHECK-LABEL: Header:
16 ; CHECK: %within.bounds = icmp ult i64 %j2, %length.ext
17 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9)
1839 Header: ; preds = %entry, %Latch
1940 %result.in3 = phi i64* [ %arg2, %entry ], [ %arg, %Latch ]
2041 %j2 = phi i64 [ 0, %entry ], [ %j.next, %Latch ]
4263 ; predicate loop since there's no profile information and BPI concluded all
4364 ; exiting blocks have same probability of exiting from loop.
4465 define i64 @predicate(i64* nocapture readonly %arg, i32 %length, i64* nocapture readonly %arg2, i64* nocapture readonly %n_addr, i64 %i) {
45 ; CHECK-LABEL: predicate(
46 ; CHECK-LABEL: entry:
47 ; CHECK: [[limit_check:[^ ]+]] = icmp ule i64 1048576, %length.ext
48 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i64 0, %length.ext
49 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
66 ; CHECK-LABEL: @predicate(
67 ; CHECK-NEXT: entry:
68 ; CHECK-NEXT: [[LENGTH_EXT:%.*]] = zext i32 [[LENGTH:%.*]] to i64
69 ; CHECK-NEXT: [[N_PRE:%.*]] = load i64, i64* [[N_ADDR:%.*]], align 4
70 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i64 1048576, [[LENGTH_EXT]]
71 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i64 0, [[LENGTH_EXT]]
72 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
73 ; CHECK-NEXT: br label [[HEADER:%.*]]
74 ; CHECK: Header:
75 ; CHECK-NEXT: [[RESULT_IN3:%.*]] = phi i64* [ [[ARG2:%.*]], [[ENTRY:%.*]] ], [ [[ARG:%.*]], [[LATCH:%.*]] ]
76 ; CHECK-NEXT: [[J2:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[J_NEXT:%.*]], [[LATCH]] ]
77 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i64 [[J2]], [[LENGTH_EXT]]
78 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
79 ; CHECK-NEXT: [[INNERCMP:%.*]] = icmp eq i64 [[J2]], [[N_PRE]]
80 ; CHECK-NEXT: [[J_NEXT]] = add nuw nsw i64 [[J2]], 1
81 ; CHECK-NEXT: br i1 [[INNERCMP]], label [[LATCH]], label [[EXIT:%.*]]
82 ; CHECK: Latch:
83 ; CHECK-NEXT: [[SPECULATE_TRIP_COUNT:%.*]] = icmp ult i64 [[J_NEXT]], 1048576
84 ; CHECK-NEXT: br i1 [[SPECULATE_TRIP_COUNT]], label [[HEADER]], label [[EXITLATCH:%.*]]
85 ; CHECK: exitLatch:
86 ; CHECK-NEXT: ret i64 1
87 ; CHECK: exit:
88 ; CHECK-NEXT: [[RESULT_IN3_LCSSA:%.*]] = phi i64* [ [[RESULT_IN3]], [[HEADER]] ]
89 ; CHECK-NEXT: [[RESULT_LE:%.*]] = load i64, i64* [[RESULT_IN3_LCSSA]], align 8
90 ; CHECK-NEXT: ret i64 [[RESULT_LE]]
91 ;
5092 entry:
5193 %length.ext = zext i32 %length to i64
5294 %n.pre = load i64, i64* %n_addr, align 4
5395 br label %Header
5496
55 ; CHECK-LABEL: Header:
56 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
5797 Header: ; preds = %entry, %Latch
5898 %result.in3 = phi i64* [ %arg2, %entry ], [ %arg, %Latch ]
5999 %j2 = phi i64 [ 0, %entry ], [ %j.next, %Latch ]
81121 ; LatchExitProbability: 0x000020e1 / 0x80000000 = 0.00%
82122 ; ExitingBlockProbability: 0x7ffcbb86 / 0x80000000 = 99.99%
83123 define i64 @donot_predicate_prof(i64* nocapture readonly %arg, i32 %length, i64* nocapture readonly %arg2, i64* nocapture readonly %n_addr, i64 %i) {
84 ; CHECK-LABEL: donot_predicate_prof(
85 ; CHECK-LABEL: entry:
124 ; CHECK-LABEL: @donot_predicate_prof(
125 ; CHECK-NEXT: entry:
126 ; CHECK-NEXT: [[LENGTH_EXT:%.*]] = zext i32 [[LENGTH:%.*]] to i64
127 ; CHECK-NEXT: [[N_PRE:%.*]] = load i64, i64* [[N_ADDR:%.*]], align 4
128 ; CHECK-NEXT: br label [[HEADER:%.*]]
129 ; CHECK: Header:
130 ; CHECK-NEXT: [[RESULT_IN3:%.*]] = phi i64* [ [[ARG2:%.*]], [[ENTRY:%.*]] ], [ [[ARG:%.*]], [[LATCH:%.*]] ]
131 ; CHECK-NEXT: [[J2:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[J_NEXT:%.*]], [[LATCH]] ]
132 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i64 [[J2]], [[LENGTH_EXT]]
133 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
134 ; CHECK-NEXT: [[INNERCMP:%.*]] = icmp eq i64 [[J2]], [[N_PRE]]
135 ; CHECK-NEXT: [[J_NEXT]] = add nuw nsw i64 [[J2]], 1
136 ; CHECK-NEXT: br i1 [[INNERCMP]], label [[LATCH]], label [[EXIT:%.*]], !prof !1
137 ; CHECK: Latch:
138 ; CHECK-NEXT: [[SPECULATE_TRIP_COUNT:%.*]] = icmp ult i64 [[J_NEXT]], 1048576
139 ; CHECK-NEXT: br i1 [[SPECULATE_TRIP_COUNT]], label [[HEADER]], label [[EXITLATCH:%.*]], !prof !2
140 ; CHECK: exitLatch:
141 ; CHECK-NEXT: ret i64 1
142 ; CHECK: exit:
143 ; CHECK-NEXT: [[RESULT_IN3_LCSSA:%.*]] = phi i64* [ [[RESULT_IN3]], [[HEADER]] ]
144 ; CHECK-NEXT: [[RESULT_LE:%.*]] = load i64, i64* [[RESULT_IN3_LCSSA]], align 8
145 ; CHECK-NEXT: ret i64 [[RESULT_LE]]
146 ;
86147 entry:
87148 %length.ext = zext i32 %length to i64
88149 %n.pre = load i64, i64* %n_addr, align 4
89150 br label %Header
90151
91 ; CHECK-LABEL: Header:
92 ; CHECK: %within.bounds = icmp ult i64 %j2, %length.ext
93 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9)
94152 Header: ; preds = %entry, %Latch
95153 %result.in3 = phi i64* [ %arg2, %entry ], [ %arg, %Latch ]
96154 %j2 = phi i64 [ 0, %entry ], [ %j.next, %Latch ]
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1 ; RUN: opt -S -loop-predication -loop-predication-enable-count-down-loop=true < %s 2>&1 | FileCheck %s
12 ; RUN: opt -S -passes='require,loop(loop-predication)' -loop-predication-enable-count-down-loop=true < %s 2>&1 | FileCheck %s
23
45
56 define i32 @signed_reverse_loop_n_to_lower_limit(i32* %array, i32 %length, i32 %n, i32 %lowerlimit) {
67 ; CHECK-LABEL: @signed_reverse_loop_n_to_lower_limit(
7 entry:
8 %tmp5 = icmp eq i32 %n, 0
9 br i1 %tmp5, label %exit, label %loop.preheader
10
11 ; CHECK: loop.preheader:
12 ; CHECK-NEXT: [[range_start:%.*]] = add i32 %n, -1
13 ; CHECK-NEXT: [[first_iteration_check:%.*]] = icmp ult i32 [[range_start]], %length
14 ; CHECK-NEXT: [[no_wrap_check:%.*]] = icmp sge i32 %lowerlimit, 1
15 ; CHECK-NEXT: [[wide_cond:%.*]] = and i1 [[first_iteration_check]], [[no_wrap_check]]
16 loop.preheader:
17 br label %loop
18
19 ; CHECK: loop:
20 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
8 ; CHECK-NEXT: entry:
9 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
10 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
11 ; CHECK: loop.preheader:
12 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1
13 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], [[LENGTH:%.*]]
14 ; CHECK-NEXT: [[TMP2:%.*]] = icmp sge i32 [[LOWERLIMIT:%.*]], 1
15 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]]
16 ; CHECK-NEXT: br label [[LOOP:%.*]]
17 ; CHECK: loop:
18 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
19 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[N]], [[LOOP_PREHEADER]] ]
20 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], -1
21 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_NEXT]], [[LENGTH]]
22 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
23 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I_NEXT]] to i64
24 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
25 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
26 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
27 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[I]], [[LOWERLIMIT]]
28 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
29 ; CHECK: exit.loopexit:
30 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
31 ; CHECK-NEXT: br label [[EXIT]]
32 ; CHECK: exit:
33 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
34 ; CHECK-NEXT: ret i32 [[RESULT]]
35 ;
36 entry:
37 %tmp5 = icmp eq i32 %n, 0
38 br i1 %tmp5, label %exit, label %loop.preheader
39
40 loop.preheader:
41 br label %loop
42
2143 loop:
2244 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
2345 %i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ]
3860
3961 define i32 @unsigned_reverse_loop_n_to_lower_limit(i32* %array, i32 %length, i32 %n, i32 %lowerlimit) {
4062 ; CHECK-LABEL: @unsigned_reverse_loop_n_to_lower_limit(
41 entry:
42 %tmp5 = icmp eq i32 %n, 0
43 br i1 %tmp5, label %exit, label %loop.preheader
44
45 ; CHECK: loop.preheader:
46 ; CHECK-NEXT: [[range_start:%.*]] = add i32 %n, -1
47 ; CHECK-NEXT: [[first_iteration_check:%.*]] = icmp ult i32 [[range_start]], %length
48 ; CHECK-NEXT: [[no_wrap_check:%.*]] = icmp uge i32 %lowerlimit, 1
49 ; CHECK-NEXT: [[wide_cond:%.*]] = and i1 [[first_iteration_check]], [[no_wrap_check]]
50 loop.preheader:
51 br label %loop
52
53 ; CHECK: loop:
54 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
63 ; CHECK-NEXT: entry:
64 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
65 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
66 ; CHECK: loop.preheader:
67 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1
68 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], [[LENGTH:%.*]]
69 ; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i32 [[LOWERLIMIT:%.*]], 1
70 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]]
71 ; CHECK-NEXT: br label [[LOOP:%.*]]
72 ; CHECK: loop:
73 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
74 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[N]], [[LOOP_PREHEADER]] ]
75 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], -1
76 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_NEXT]], [[LENGTH]]
77 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
78 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I_NEXT]] to i64
79 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
80 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
81 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
82 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ugt i32 [[I]], [[LOWERLIMIT]]
83 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
84 ; CHECK: exit.loopexit:
85 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
86 ; CHECK-NEXT: br label [[EXIT]]
87 ; CHECK: exit:
88 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
89 ; CHECK-NEXT: ret i32 [[RESULT]]
90 ;
91 entry:
92 %tmp5 = icmp eq i32 %n, 0
93 br i1 %tmp5, label %exit, label %loop.preheader
94
95 loop.preheader:
96 br label %loop
97
5598 loop:
5699 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
57100 %i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ]
75118 ; deoptimize early on.
76119 define i32 @unsigned_reverse_loop_n_to_0(i32* %array, i32 %length, i32 %n, i32 %lowerlimit) {
77120 ; CHECK-LABEL: @unsigned_reverse_loop_n_to_0(
78 entry:
79 %tmp5 = icmp eq i32 %n, 0
80 br i1 %tmp5, label %exit, label %loop.preheader
81
82 ; CHECK: loop.preheader:
83 ; CHECK-NEXT: [[range_start:%.*]] = add i32 %n, -1
84 ; CHECK-NEXT: [[first_iteration_check:%.*]] = icmp ult i32 [[range_start]], %length
85 ; CHECK-NEXT: [[wide_cond:%.*]] = and i1 [[first_iteration_check]], false
86 loop.preheader:
87 br label %loop
88
89 ; CHECK: loop:
90 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
121 ; CHECK-NEXT: entry:
122 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
123 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
124 ; CHECK: loop.preheader:
125 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1
126 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], [[LENGTH:%.*]]
127 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], false
128 ; CHECK-NEXT: br label [[LOOP:%.*]]
129 ; CHECK: loop:
130 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
131 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[N]], [[LOOP_PREHEADER]] ]
132 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], -1
133 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_NEXT]], [[LENGTH]]
134 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
135 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I_NEXT]] to i64
136 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
137 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
138 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
139 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ugt i32 [[I]], 0
140 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
141 ; CHECK: exit.loopexit:
142 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
143 ; CHECK-NEXT: br label [[EXIT]]
144 ; CHECK: exit:
145 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
146 ; CHECK-NEXT: ret i32 [[RESULT]]
147 ;
148 entry:
149 %tmp5 = icmp eq i32 %n, 0
150 br i1 %tmp5, label %exit, label %loop.preheader
151
152 loop.preheader:
153 br label %loop
154
91155 loop:
92156 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
93157 %i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ]
109173 ; do not loop predicate when the range has step -1 and latch has step 1.
110174 define i32 @reverse_loop_range_step_increment(i32 %n, i32* %array, i32 %length) {
111175 ; CHECK-LABEL: @reverse_loop_range_step_increment(
112 entry:
113 %tmp5 = icmp eq i32 %n, 0
114 br i1 %tmp5, label %exit, label %loop.preheader
115
116 loop.preheader:
117 br label %loop
118
119 ; CHECK: loop:
120 ; CHECK: llvm.experimental.guard(i1 %within.bounds, i32 9)
176 ; CHECK-NEXT: entry:
177 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
178 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
179 ; CHECK: loop.preheader:
180 ; CHECK-NEXT: br label [[LOOP:%.*]]
181 ; CHECK: loop:
182 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
183 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[N]], [[LOOP_PREHEADER]] ]
184 ; CHECK-NEXT: [[IRC:%.*]] = phi i32 [ [[I_INC:%.*]], [[LOOP]] ], [ 1, [[LOOP_PREHEADER]] ]
185 ; CHECK-NEXT: [[I_INC]] = add nuw nsw i32 [[IRC]], 1
186 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[IRC]], [[LENGTH:%.*]]
187 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
188 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[IRC]] to i64
189 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
190 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
191 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], -1
192 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
193 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ugt i32 [[I]], 65534
194 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
195 ; CHECK: exit.loopexit:
196 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
197 ; CHECK-NEXT: br label [[EXIT]]
198 ; CHECK: exit:
199 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
200 ; CHECK-NEXT: ret i32 [[RESULT]]
201 ;
202 entry:
203 %tmp5 = icmp eq i32 %n, 0
204 br i1 %tmp5, label %exit, label %loop.preheader
205
206 loop.preheader:
207 br label %loop
208
121209 loop:
122210 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
123211 %i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ]
140228
141229 define i32 @signed_reverse_loop_n_to_lower_limit_equal(i32* %array, i32 %length, i32 %n, i32 %lowerlimit) {
142230 ; CHECK-LABEL: @signed_reverse_loop_n_to_lower_limit_equal(
143 entry:
144 %tmp5 = icmp eq i32 %n, 0
145 br i1 %tmp5, label %exit, label %loop.preheader
146
147 ; CHECK: loop.preheader:
148 ; CHECK-NEXT: [[range_start:%.*]] = add i32 %n, -1
149 ; CHECK-NEXT: [[first_iteration_check:%.*]] = icmp ult i32 [[range_start]], %length
150 ; CHECK-NEXT: [[no_wrap_check:%.*]] = icmp sgt i32 %lowerlimit, 1
151 ; CHECK-NEXT: [[wide_cond:%.*]] = and i1 [[first_iteration_check]], [[no_wrap_check]]
152 loop.preheader:
153 br label %loop
154
155 ; CHECK: loop:
156 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
231 ; CHECK-NEXT: entry:
232 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
233 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
234 ; CHECK: loop.preheader:
235 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1
236 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], [[LENGTH:%.*]]
237 ; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[LOWERLIMIT:%.*]], 1
238 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]]
239 ; CHECK-NEXT: br label [[LOOP:%.*]]
240 ; CHECK: loop:
241 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
242 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[N]], [[LOOP_PREHEADER]] ]
243 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], -1
244 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_NEXT]], [[LENGTH]]
245 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
246 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I_NEXT]] to i64
247 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
248 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
249 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
250 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sge i32 [[I]], [[LOWERLIMIT]]
251 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
252 ; CHECK: exit.loopexit:
253 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
254 ; CHECK-NEXT: br label [[EXIT]]
255 ; CHECK: exit:
256 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
257 ; CHECK-NEXT: ret i32 [[RESULT]]
258 ;
259 entry:
260 %tmp5 = icmp eq i32 %n, 0
261 br i1 %tmp5, label %exit, label %loop.preheader
262
263 loop.preheader:
264 br label %loop
265
157266 loop:
158267 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
159268 %i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ]
174283
175284 define i32 @unsigned_reverse_loop_n_to_lower_limit_equal(i32* %array, i32 %length, i32 %n, i32 %lowerlimit) {
176285 ; CHECK-LABEL: @unsigned_reverse_loop_n_to_lower_limit_equal(
177 entry:
178 %tmp5 = icmp eq i32 %n, 0
179 br i1 %tmp5, label %exit, label %loop.preheader
180
181 ; CHECK: loop.preheader:
182 ; CHECK-NEXT: [[range_start:%.*]] = add i32 %n, -1
183 ; CHECK-NEXT: [[first_iteration_check:%.*]] = icmp ult i32 [[range_start]], %length
184 ; CHECK-NEXT: [[no_wrap_check:%.*]] = icmp ugt i32 %lowerlimit, 1
185 ; CHECK-NEXT: [[wide_cond:%.*]] = and i1 [[first_iteration_check]], [[no_wrap_check]]
186 loop.preheader:
187 br label %loop
188
189 ; CHECK: loop:
190 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
286 ; CHECK-NEXT: entry:
287 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
288 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
289 ; CHECK: loop.preheader:
290 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1
291 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], [[LENGTH:%.*]]
292 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i32 [[LOWERLIMIT:%.*]], 1
293 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]]
294 ; CHECK-NEXT: br label [[LOOP:%.*]]
295 ; CHECK: loop:
296 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
297 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[N]], [[LOOP_PREHEADER]] ]
298 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], -1
299 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_NEXT]], [[LENGTH]]
300 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
301 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I_NEXT]] to i64
302 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
303 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
304 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
305 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp uge i32 [[I]], [[LOWERLIMIT]]
306 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
307 ; CHECK: exit.loopexit:
308 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
309 ; CHECK-NEXT: br label [[EXIT]]
310 ; CHECK: exit:
311 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
312 ; CHECK-NEXT: ret i32 [[RESULT]]
313 ;
314 entry:
315 %tmp5 = icmp eq i32 %n, 0
316 br i1 %tmp5, label %exit, label %loop.preheader
317
318 loop.preheader:
319 br label %loop
320
191321 loop:
192322 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
193323 %i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ]
211341 ; deoptimize early on.
212342 define i32 @unsigned_reverse_loop_n_to_1(i32* %array, i32 %length, i32 %n, i32 %lowerlimit) {
213343 ; CHECK-LABEL: @unsigned_reverse_loop_n_to_1(
214 entry:
215 %tmp5 = icmp eq i32 %n, 0
216 br i1 %tmp5, label %exit, label %loop.preheader
217
218 ; CHECK: loop.preheader:
219 ; CHECK-NEXT: [[range_start:%.*]] = add i32 %n, -1
220 ; CHECK-NEXT: [[first_iteration_check:%.*]] = icmp ult i32 [[range_start]], %length
221 ; CHECK-NEXT: [[wide_cond:%.*]] = and i1 [[first_iteration_check]], false
222 loop.preheader:
223 br label %loop
224
225 ; CHECK: loop:
226 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
344 ; CHECK-NEXT: entry:
345 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
346 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
347 ; CHECK: loop.preheader:
348 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1
349 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], [[LENGTH:%.*]]
350 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], false
351 ; CHECK-NEXT: br label [[LOOP:%.*]]
352 ; CHECK: loop:
353 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
354 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[N]], [[LOOP_PREHEADER]] ]
355 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], -1
356 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_NEXT]], [[LENGTH]]
357 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
358 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I_NEXT]] to i64
359 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
360 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
361 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
362 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp uge i32 [[I]], 1
363 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
364 ; CHECK: exit.loopexit:
365 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
366 ; CHECK-NEXT: br label [[EXIT]]
367 ; CHECK: exit:
368 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
369 ; CHECK-NEXT: ret i32 [[RESULT]]
370 ;
371 entry:
372 %tmp5 = icmp eq i32 %n, 0
373 br i1 %tmp5, label %exit, label %loop.preheader
374
375 loop.preheader:
376 br label %loop
377
227378 loop:
228379 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
229380 %i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ]
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1 ; RUN: opt -S -loop-predication < %s 2>&1 | FileCheck %s
12 ; RUN: opt -S -passes='require,loop(loop-predication)' < %s 2>&1 | FileCheck %s
23
34 declare void @llvm.experimental.guard(i1, ...)
45
56 define i32 @test_visited(i32* %array, i32 %length, i32 %n, i32 %x) {
6 ; CHECK-LABEL: @test_visited
7 ; CHECK-LABEL: @test_visited(
8 ; CHECK-NEXT: entry:
9 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
10 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
11 ; CHECK: loop.preheader:
12 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
13 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
14 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
15 ; CHECK-NEXT: br label [[LOOP:%.*]]
16 ; CHECK: loop:
17 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
18 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
19 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
20 ; CHECK-NEXT: [[UNRELATED_COND:%.*]] = icmp eq i32 [[X:%.*]], [[I]]
21 ; CHECK-NEXT: [[GUARD_COND_2:%.*]] = and i1 [[WITHIN_BOUNDS]], [[UNRELATED_COND]]
22 ; CHECK-NEXT: [[GUARD_COND_3:%.*]] = and i1 [[GUARD_COND_2]], [[UNRELATED_COND]]
23 ; CHECK-NEXT: [[GUARD_COND_4:%.*]] = and i1 [[GUARD_COND_3]], [[GUARD_COND_2]]
24 ; CHECK-NEXT: [[GUARD_COND_5:%.*]] = and i1 [[GUARD_COND_4]], [[GUARD_COND_3]]
25 ; CHECK-NEXT: [[GUARD_COND_6:%.*]] = and i1 [[GUARD_COND_5]], [[GUARD_COND_4]]
26 ; CHECK-NEXT: [[GUARD_COND_7:%.*]] = and i1 [[GUARD_COND_6]], [[GUARD_COND_5]]
27 ; CHECK-NEXT: [[GUARD_COND_8:%.*]] = and i1 [[GUARD_COND_7]], [[GUARD_COND_6]]
28 ; CHECK-NEXT: [[GUARD_COND_9:%.*]] = and i1 [[GUARD_COND_8]], [[GUARD_COND_7]]
29 ; CHECK-NEXT: [[GUARD_COND_10:%.*]] = and i1 [[GUARD_COND_9]], [[GUARD_COND_8]]
30 ; CHECK-NEXT: [[GUARD_COND_11:%.*]] = and i1 [[GUARD_COND_10]], [[GUARD_COND_9]]
31 ; CHECK-NEXT: [[GUARD_COND_12:%.*]] = and i1 [[GUARD_COND_11]], [[GUARD_COND_10]]
32 ; CHECK-NEXT: [[GUARD_COND_13:%.*]] = and i1 [[GUARD_COND_12]], [[GUARD_COND_11]]
33 ; CHECK-NEXT: [[GUARD_COND_14:%.*]] = and i1 [[GUARD_COND_13]], [[GUARD_COND_12]]
34 ; CHECK-NEXT: [[GUARD_COND_15:%.*]] = and i1 [[GUARD_COND_14]], [[GUARD_COND_13]]
35 ; CHECK-NEXT: [[GUARD_COND_16:%.*]] = and i1 [[GUARD_COND_15]], [[GUARD_COND_14]]
36 ; CHECK-NEXT: [[GUARD_COND_17:%.*]] = and i1 [[GUARD_COND_16]], [[GUARD_COND_15]]
37 ; CHECK-NEXT: [[GUARD_COND_18:%.*]] = and i1 [[GUARD_COND_17]], [[GUARD_COND_16]]
38 ; CHECK-NEXT: [[GUARD_COND_19:%.*]] = and i1 [[GUARD_COND_18]], [[GUARD_COND_17]]
39 ; CHECK-NEXT: [[GUARD_COND_20:%.*]] = and i1 [[GUARD_COND_19]], [[GUARD_COND_18]]
40 ; CHECK-NEXT: [[GUARD_COND_21:%.*]] = and i1 [[GUARD_COND_20]], [[GUARD_COND_19]]
41 ; CHECK-NEXT: [[GUARD_COND_22:%.*]] = and i1 [[GUARD_COND_21]], [[GUARD_COND_20]]
42 ; CHECK-NEXT: [[GUARD_COND_23:%.*]] = and i1 [[GUARD_COND_22]], [[GUARD_COND_21]]
43 ; CHECK-NEXT: [[GUARD_COND_24:%.*]] = and i1 [[GUARD_COND_23]], [[GUARD_COND_22]]
44 ; CHECK-NEXT: [[GUARD_COND_25:%.*]] = and i1 [[GUARD_COND_24]], [[GUARD_COND_23]]
45 ; CHECK-NEXT: [[GUARD_COND_26:%.*]] = and i1 [[GUARD_COND_25]], [[GUARD_COND_24]]
46 ; CHECK-NEXT: [[GUARD_COND_27:%.*]] = and i1 [[GUARD_COND_26]], [[GUARD_COND_25]]
47 ; CHECK-NEXT: [[GUARD_COND_28:%.*]] = and i1 [[GUARD_COND_27]], [[GUARD_COND_26]]
48 ; CHECK-NEXT: [[GUARD_COND_29:%.*]] = and i1 [[GUARD_COND_28]], [[GUARD_COND_27]]
49 ; CHECK-NEXT: [[GUARD_COND_30:%.*]] = and i1 [[GUARD_COND_29]], [[GUARD_COND_28]]
50 ; CHECK-NEXT: [[GUARD_COND_31:%.*]] = and i1 [[GUARD_COND_30]], [[GUARD_COND_29]]
51 ; CHECK-NEXT: [[GUARD_COND_32:%.*]] = and i1 [[GUARD_COND_31]], [[GUARD_COND_30]]
52 ; CHECK-NEXT: [[GUARD_COND_33:%.*]] = and i1 [[GUARD_COND_32]], [[GUARD_COND_31]]
53 ; CHECK-NEXT: [[GUARD_COND_34:%.*]] = and i1 [[GUARD_COND_33]], [[GUARD_COND_32]]
54 ; CHECK-NEXT: [[GUARD_COND_35:%.*]] = and i1 [[GUARD_COND_34]], [[GUARD_COND_33]]
55 ; CHECK-NEXT: [[GUARD_COND_36:%.*]] = and i1 [[GUARD_COND_35]], [[GUARD_COND_34]]
56 ; CHECK-NEXT: [[GUARD_COND_37:%.*]] = and i1 [[GUARD_COND_36]], [[GUARD_COND_35]]
57 ; CHECK-NEXT: [[GUARD_COND_38:%.*]] = and i1 [[GUARD_COND_37]], [[GUARD_COND_36]]
58 ; CHECK-NEXT: [[GUARD_COND_39:%.*]] = and i1 [[GUARD_COND_38]], [[GUARD_COND_37]]
59 ; CHECK-NEXT: [[GUARD_COND_40:%.*]] = and i1 [[GUARD_COND_39]], [[GUARD_COND_38]]
60 ; CHECK-NEXT: [[GUARD_COND_41:%.*]] = and i1 [[GUARD_COND_40]], [[GUARD_COND_39]]
61 ; CHECK-NEXT: [[GUARD_COND_42:%.*]] = and i1 [[GUARD_COND_41]], [[GUARD_COND_40]]
62 ; CHECK-NEXT: [[GUARD_COND_43:%.*]] = and i1 [[GUARD_COND_42]], [[GUARD_COND_41]]
63 ; CHECK-NEXT: [[GUARD_COND_44:%.*]] = and i1 [[GUARD_COND_43]], [[GUARD_COND_42]]
64 ; CHECK-NEXT: [[GUARD_COND_45:%.*]] = and i1 [[GUARD_COND_44]], [[GUARD_COND_43]]
65 ; CHECK-NEXT: [[GUARD_COND_46:%.*]] = and i1 [[GUARD_COND_45]], [[GUARD_COND_44]]
66 ; CHECK-NEXT: [[GUARD_COND_47:%.*]] = and i1 [[GUARD_COND_46]], [[GUARD_COND_45]]
67 ; CHECK-NEXT: [[GUARD_COND_48:%.*]] = and i1 [[GUARD_COND_47]], [[GUARD_COND_46]]
68 ; CHECK-NEXT: [[GUARD_COND_49:%.*]] = and i1 [[GUARD_COND_48]], [[GUARD_COND_47]]
69 ; CHECK-NEXT: [[GUARD_COND_50:%.*]] = and i1 [[GUARD_COND_49]], [[GUARD_COND_48]]
70 ; CHECK-NEXT: [[GUARD_COND_51:%.*]] = and i1 [[GUARD_COND_50]], [[GUARD_COND_49]]
71 ; CHECK-NEXT: [[GUARD_COND_52:%.*]] = and i1 [[GUARD_COND_51]], [[GUARD_COND_50]]
72 ; CHECK-NEXT: [[GUARD_COND_53:%.*]] = and i1 [[GUARD_COND_52]], [[GUARD_COND_51]]
73 ; CHECK-NEXT: [[GUARD_COND_54:%.*]] = and i1 [[GUARD_COND_53]], [[GUARD_COND_52]]
74 ; CHECK-NEXT: [[GUARD_COND_55:%.*]] = and i1 [[GUARD_COND_54]], [[GUARD_COND_53]]
75 ; CHECK-NEXT: [[GUARD_COND_56:%.*]] = and i1 [[GUARD_COND_55]], [[GUARD_COND_54]]
76 ; CHECK-NEXT: [[GUARD_COND_57:%.*]] = and i1 [[GUARD_COND_56]], [[GUARD_COND_55]]
77 ; CHECK-NEXT: [[GUARD_COND_58:%.*]] = and i1 [[GUARD_COND_57]], [[GUARD_COND_56]]
78 ; CHECK-NEXT: [[GUARD_COND_59:%.*]] = and i1 [[GUARD_COND_58]], [[GUARD_COND_57]]
79 ; CHECK-NEXT: [[GUARD_COND_60:%.*]] = and i1 [[GUARD_COND_59]], [[GUARD_COND_58]]
80 ; CHECK-NEXT: [[GUARD_COND_61:%.*]] = and i1 [[GUARD_COND_60]], [[GUARD_COND_59]]
81 ; CHECK-NEXT: [[GUARD_COND_62:%.*]] = and i1 [[GUARD_COND_61]], [[GUARD_COND_60]]
82 ; CHECK-NEXT: [[GUARD_COND_63:%.*]] = and i1 [[GUARD_COND_62]], [[GUARD_COND_61]]
83 ; CHECK-NEXT: [[GUARD_COND_64:%.*]] = and i1 [[GUARD_COND_63]], [[GUARD_COND_62]]
84 ; CHECK-NEXT: [[GUARD_COND_65:%.*]] = and i1 [[GUARD_COND_64]], [[GUARD_COND_63]]
85 ; CHECK-NEXT: [[GUARD_COND_66:%.*]] = and i1 [[GUARD_COND_65]], [[GUARD_COND_64]]
86 ; CHECK-NEXT: [[GUARD_COND_67:%.*]] = and i1 [[GUARD_COND_66]], [[GUARD_COND_65]]
87 ; CHECK-NEXT: [[GUARD_COND_68:%.*]] = and i1 [[GUARD_COND_67]], [[GUARD_COND_66]]
88 ; CHECK-NEXT: [[GUARD_COND_69:%.*]] = and i1 [[GUARD_COND_68]], [[GUARD_COND_67]]
89 ; CHECK-NEXT: [[GUARD_COND_70:%.*]] = and i1 [[GUARD_COND_69]], [[GUARD_COND_68]]
90 ; CHECK-NEXT: [[GUARD_COND_71:%.*]] = and i1 [[GUARD_COND_70]], [[GUARD_COND_69]]
91 ; CHECK-NEXT: [[GUARD_COND_72:%.*]] = and i1 [[GUARD_COND_71]], [[GUARD_COND_70]]
92 ; CHECK-NEXT: [[GUARD_COND_73:%.*]] = and i1 [[GUARD_COND_72]], [[GUARD_COND_71]]
93 ; CHECK-NEXT: [[GUARD_COND_74:%.*]] = and i1 [[GUARD_COND_73]], [[GUARD_COND_72]]
94 ; CHECK-NEXT: [[GUARD_COND_75:%.*]] = and i1 [[GUARD_COND_74]], [[GUARD_COND_73]]
95 ; CHECK-NEXT: [[GUARD_COND_76:%.*]] = and i1 [[GUARD_COND_75]], [[GUARD_COND_74]]
96 ; CHECK-NEXT: [[GUARD_COND_77:%.*]] = and i1 [[GUARD_COND_76]], [[GUARD_COND_75]]
97 ; CHECK-NEXT: [[GUARD_COND_78:%.*]] = and i1 [[GUARD_COND_77]], [[GUARD_COND_76]]
98 ; CHECK-NEXT: [[GUARD_COND_79:%.*]] = and i1 [[GUARD_COND_78]], [[GUARD_COND_77]]
99 ; CHECK-NEXT: [[GUARD_COND_80:%.*]] = and i1 [[GUARD_COND_79]], [[GUARD_COND_78]]
100 ; CHECK-NEXT: [[GUARD_COND_81:%.*]] = and i1 [[GUARD_COND_80]], [[GUARD_COND_79]]
101 ; CHECK-NEXT: [[GUARD_COND_82:%.*]] = and i1 [[GUARD_COND_81]], [[GUARD_COND_80]]
102 ; CHECK-NEXT: [[GUARD_COND_83:%.*]] = and i1 [[GUARD_COND_82]], [[GUARD_COND_81]]
103 ; CHECK-NEXT: [[GUARD_COND_84:%.*]] = and i1 [[GUARD_COND_83]], [[GUARD_COND_82]]
104 ; CHECK-NEXT: [[GUARD_COND_85:%.*]] = and i1 [[GUARD_COND_84]], [[GUARD_COND_83]]
105 ; CHECK-NEXT: [[GUARD_COND_86:%.*]] = and i1 [[GUARD_COND_85]], [[GUARD_COND_84]]
106 ; CHECK-NEXT: [[GUARD_COND_87:%.*]] = and i1 [[GUARD_COND_86]], [[GUARD_COND_85]]
107 ; CHECK-NEXT: [[GUARD_COND_88:%.*]] = and i1 [[GUARD_COND_87]], [[GUARD_COND_86]]
108 ; CHECK-NEXT: [[GUARD_COND_89:%.*]] = and i1 [[GUARD_COND_88]], [[GUARD_COND_87]]
109 ; CHECK-NEXT: [[GUARD_COND_90:%.*]] = and i1 [[GUARD_COND_89]], [[GUARD_COND_88]]
110 ; CHECK-NEXT: [[GUARD_COND_91:%.*]] = and i1 [[GUARD_COND_90]], [[GUARD_COND_89]]
111 ; CHECK-NEXT: [[GUARD_COND_92:%.*]] = and i1 [[GUARD_COND_91]], [[GUARD_COND_90]]
112 ; CHECK-NEXT: [[GUARD_COND_93:%.*]] = and i1 [[GUARD_COND_92]], [[GUARD_COND_91]]
113 ; CHECK-NEXT: [[GUARD_COND_94:%.*]] = and i1 [[GUARD_COND_93]], [[GUARD_COND_92]]
114 ; CHECK-NEXT: [[GUARD_COND_95:%.*]] = and i1 [[GUARD_COND_94]], [[GUARD_COND_93]]
115 ; CHECK-NEXT: [[GUARD_COND_96:%.*]] = and i1 [[GUARD_COND_95]], [[GUARD_COND_94]]
116 ; CHECK-NEXT: [[GUARD_COND_97:%.*]] = and i1 [[GUARD_COND_96]], [[GUARD_COND_95]]
117 ; CHECK-NEXT: [[GUARD_COND_98:%.*]] = and i1 [[GUARD_COND_97]], [[GUARD_COND_96]]
118 ; CHECK-NEXT: [[GUARD_COND_99:%.*]] = and i1 [[GUARD_COND_98]], [[GUARD_COND_97]]
119 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[UNRELATED_COND]], [[TMP2]]
120 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
121 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
122 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
123 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
124 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
125 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
126 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
127 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
128 ; CHECK: exit.loopexit:
129 ; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
130 ; CHECK-NEXT: br label [[EXIT]]
131 ; CHECK: exit:
132 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
133 ; CHECK-NEXT: ret i32 [[RESULT]]
134 ;
7135 entry:
8136 %tmp5 = icmp eq i32 %n, 0
9137 br i1 %tmp5, label %exit, label %loop.preheader
10138
11139 loop.preheader:
12 ; CHECK: loop.preheader:
13 ; CHECK: [[limit_check:[^ ]+]] = icmp ule i32 %n, %length
14 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
15 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
16 ; CHECK-NEXT: br label %loop
17140 br label %loop
18141
19142 loop:
20 ; CHECK: loop:
21 ; CHECK: %unrelated.cond = icmp eq i32 %x, %i
22 ; CHECK: [[guard_cond:[^ ]+]] = and i1 %unrelated.cond, [[wide_cond]]
23 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[guard_cond]], i32 9) [ "deopt"() ]
24143 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
25144 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
26145 %within.bounds = icmp ult i32 %i, %length
137256 exit:
138257 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
139258 ret i32 %result
140 }
259 }
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1 ; RUN: opt -S -loop-predication -loop-predication-enable-iv-truncation=true < %s 2>&1 | FileCheck %s
12 declare void @llvm.experimental.guard(i1, ...)
23
67 ; Consider range check of type i16 and i32, while IV is of type i64
78 ; We can loop predicate this because the IV range is within i16 and within i32.
89 define i64 @iv_wider_type_rc_two_narrow_types(i32 %offA, i16 %offB, i8* %arrA, i8* %arrB) {
9 ; CHECK-LABEL: iv_wider_type_rc_two_narrow_types
10 ; CHECK-LABEL: @iv_wider_type_rc_two_narrow_types(
11 ; CHECK-NEXT: entry:
12 ; CHECK-NEXT: [[LENGTHA:%.*]] = call i32 @length(i8* [[ARRA:%.*]])
13 ; CHECK-NEXT: [[LENGTHB:%.*]] = call i16 @short_length(i8* [[ARRB:%.*]])
14 ; CHECK-NEXT: [[TMP0:%.*]] = sub i16 [[LENGTHB]], [[OFFB:%.*]]
15 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i16 16, [[TMP0]]
16 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i16 [[OFFB]], [[LENGTHB]]
17 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
18 ; CHECK-NEXT: [[TMP4:%.*]] = sub i32 [[LENGTHA]], [[OFFA:%.*]]
19 ; CHECK-NEXT: [[TMP5:%.*]] = icmp ule i32 16, [[TMP4]]
20 ; CHECK-NEXT: [[TMP6:%.*]] = icmp ult i32 [[OFFA]], [[LENGTHA]]
21 ; CHECK-NEXT: [[TMP7:%.*]] = and i1 [[TMP6]], [[TMP5]]
22 ; CHECK-NEXT: br label [[LOOP:%.*]]
23 ; CHECK: loop:
24 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
25 ; CHECK-NEXT: [[IV_TRUNC_32:%.*]] = trunc i64 [[IV]] to i32
26 ; CHECK-NEXT: [[IV_TRUNC_16:%.*]] = trunc i64 [[IV]] to i16
27 ; CHECK-NEXT: [[INDEXA:%.*]] = add i32 [[IV_TRUNC_32]], [[OFFA]]
28 ; CHECK-NEXT: [[INDEXB:%.*]] = add i16 [[IV_TRUNC_16]], [[OFFB]]
29 ; CHECK-NEXT: [[RCA:%.*]] = icmp ult i32 [[INDEXA]], [[LENGTHA]]
30 ; CHECK-NEXT: [[RCB:%.*]] = icmp ult i16 [[INDEXB]], [[LENGTHB]]
31 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[RCA]], [[RCB]]
32 ; CHECK-NEXT: [[TMP8:%.*]] = and i1 [[TMP3]], [[TMP7]]
33 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP8]], i32 9) [ "deopt"() ]
34 ; CHECK-NEXT: [[INDEXA_EXT:%.*]] = zext i32 [[INDEXA]] to i64
35 ; CHECK-NEXT: [[ADDRA:%.*]] = getelementptr inbounds i8, i8* [[ARRA]], i64 [[INDEXA_EXT]]
36 ; CHECK-NEXT: [[ELTA:%.*]] = load i8, i8* [[ADDRA]]
37 ; CHECK-NEXT: [[INDEXB_EXT:%.*]] = zext i16 [[INDEXB]] to i64
38 ; CHECK-NEXT: [[ADDRB:%.*]] = getelementptr inbounds i8, i8* [[ARRB]], i64 [[INDEXB_EXT]]
39 ; CHECK-NEXT: store i8 [[ELTA]], i8* [[ADDRB]]
40 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
41 ; CHECK-NEXT: [[LATCH_CHECK:%.*]] = icmp ult i64 [[IV_NEXT]], 16
42 ; CHECK-NEXT: br i1 [[LATCH_CHECK]], label [[LOOP]], label [[EXIT:%.*]]
43 ; CHECK: exit:
44 ; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], [[LOOP]] ]
45 ; CHECK-NEXT: ret i64 [[IV_LCSSA]]
46 ;
1047 entry:
11 ; CHECK-LABEL: entry:
12 ; CHECK: [[idxB:[^ ]+]] = sub i16 %lengthB, %offB
13 ; CHECK-NEXT: [[limit_checkB:[^ ]+]] = icmp ule i16 16, [[idxB]]
14 ; CHECK-NEXT: [[first_iteration_checkB:[^ ]+]] = icmp ult i16 %offB, %lengthB
15 ; CHECK-NEXT: [[WideChkB:[^ ]+]] = and i1 [[first_iteration_checkB]], [[limit_checkB]]
16 ; CHECK-NEXT: [[idxA:[^ ]+]] = sub i32 %lengthA, %offA
17 ; CHECK-NEXT: [[limit_checkA:[^ ]+]] = icmp ule i32 16, [[idxA]]
18 ; CHECK-NEXT: [[first_iteration_checkA:[^ ]+]] = icmp ult i32 %offA, %lengthA
19 ; CHECK-NEXT: [[WideChkA:[^ ]+]] = and i1 [[first_iteration_checkA]], [[limit_checkA]]
2048 %lengthA = call i32 @length(i8* %arrA)
2149 %lengthB = call i16 @short_length(i8* %arrB)
22 br label %loop
50 br label %loop
2351
2452 loop:
25 ; CHECK-LABEL: loop:
26 ; CHECK: [[invariant_check:[^ ]+]] = and i1 [[WideChkB]], [[WideChkA]]
27 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[invariant_check]], i32 9)
2853 %iv = phi i64 [0, %entry ], [ %iv.next, %loop ]
2954 %iv.trunc.32 = trunc i64 %iv to i32
3055 %iv.trunc.16 = trunc i64 %iv to i16
4570 br i1 %latch.check, label %loop, label %exit
4671
4772 exit:
48 ret i64 %iv
73 ret i64 %iv
4974 }
5075
5176
5277 ; Consider an IV of type long and an array access into int array.
5378 ; IV is of type i64 while the range check operands are of type i32 and i64.
5479 define i64 @iv_rc_different_types(i32 %offA, i32 %offB, i8* %arrA, i8* %arrB, i64 %max)
80 ; CHECK-LABEL: @iv_rc_different_types(
81 ; CHECK-NEXT: entry:
82 ; CHECK-NEXT: [[LENGTHA:%.*]] = call i32 @length(i8* [[ARRA:%.*]])
83 ; CHECK-NEXT: [[LENGTHB:%.*]] = call i32 @length(i8* [[ARRB:%.*]])
84 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTHB]], -1
85 ; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[TMP0]], [[OFFB:%.*]]
86 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ule i32 15, [[TMP1]]
87 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i32 [[OFFB]], [[LENGTHB]]
88 ; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[TMP2]]
89 ; CHECK-NEXT: [[TMP5:%.*]] = add i64 [[MAX:%.*]], -1
90 ; CHECK-NEXT: [[TMP6:%.*]] = icmp ule i64 15, [[TMP5]]
91 ; CHECK-NEXT: [[TMP7:%.*]] = icmp ult i64 0, [[MAX]]
92 ; CHECK-NEXT: [[TMP8:%.*]] = and i1 [[TMP7]], [[TMP6]]
93 ; CHECK-NEXT: [[TMP9:%.*]] = add i32 [[LENGTHA]], -1
94 ; CHECK-NEXT: [[TMP10:%.*]] = sub i32 [[TMP9]], [[OFFA:%.*]]
95 ; CHECK-NEXT: [[TMP11:%.*]] = icmp ule i32 15, [[TMP10]]
96 ; CHECK-NEXT: [[TMP12:%.*]] = icmp ult i32 [[OFFA]], [[LENGTHA]]
97 ; CHECK-NEXT: [[TMP13:%.*]] = and i1 [[TMP12]], [[TMP11]]
98 ; CHECK-NEXT: br label [[LOOP:%.*]]
99 ; CHECK: loop:
100 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
101 ; CHECK-NEXT: [[IV_TRUNC:%.*]] = trunc i64 [[IV]] to i32
102 ; CHECK-NEXT: [[INDEXA:%.*]] = add i32 [[IV_TRUNC]], [[OFFA]]
103 ; CHECK-NEXT: [[INDEXB:%.*]] = add i32 [[IV_TRUNC]], [[OFFB]]
104 ; CHECK-NEXT: [[RCA:%.*]] = icmp ult i32 [[INDEXA]], [[LENGTHA]]
105 ; CHECK-NEXT: [[RCIV:%.*]] = icmp ult i64 [[IV]], [[MAX]]
106 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[RCA]], [[RCIV]]
107 ; CHECK-NEXT: [[RCB:%.*]] = icmp ult i32 [[INDEXB]], [[LENGTHB]]
108 ; CHECK-NEXT: [[WIDE_CHK_FINAL:%.*]] = and i1 [[WIDE_CHK]], [[RCB]]
109 ; CHECK-NEXT: [[TMP14:%.*]] = and i1 [[TMP4]], [[TMP8]]
110 ; CHECK-NEXT: [[TMP15:%.*]] = and i1 [[TMP14]], [[TMP13]]
111 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP15]], i32 9) [ "deopt"() ]
112 ; CHECK-NEXT: [[INDEXA_EXT:%.*]] = zext i32 [[INDEXA]] to i64
113 ; CHECK-NEXT: [[ADDRA:%.*]] = getelementptr inbounds i8, i8* [[ARRA]], i64 [[INDEXA_EXT]]
114 ; CHECK-NEXT: [[ELTA:%.*]] = load i8, i8* [[ADDRA]]
115 ; CHECK-NEXT: [[INDEXB_EXT:%.*]] = zext i32 [[INDEXB]] to i64
116 ; CHECK-NEXT: [[ADDRB:%.*]] = getelementptr inbounds i8, i8* [[ARRB]], i64 [[INDEXB_EXT]]
117 ; CHECK-NEXT: [[ELTB:%.*]] = load i8, i8* [[ADDRB]]
118 ; CHECK-NEXT: [[RESULT:%.*]] = xor i8 [[ELTA]], [[ELTB]]
119 ; CHECK-NEXT: store i8 [[RESULT]], i8* [[ADDRA]]
120 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
121 ; CHECK-NEXT: [[LATCH_CHECK:%.*]] = icmp ult i64 [[IV]], 15
122 ; CHECK-NEXT: br i1 [[LATCH_CHECK]], label [[LOOP]], label [[EXIT:%.*]]
123 ; CHECK: exit:
124 ; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], [[LOOP]] ]
125 ; CHECK-NEXT: ret i64 [[IV_LCSSA]]
126 ;
55127 {
56 ; CHECK-LABEL: iv_rc_different_types
57128 entry:
58 ; CHECK-LABEL: entry:
59 ; CHECK: [[lenB:[^ ]+]] = add i32 %lengthB, -1
60 ; CHECK-NEXT: [[idxB:[^ ]+]] = sub i32 [[lenB]], %offB
61 ; CHECK-NEXT: [[limit_checkB:[^ ]+]] = icmp ule i32 15, [[idxB]]
62 ; CHECK-NEXT: [[first_iteration_checkB:[^ ]+]] = icmp ult i32 %offB, %lengthB
63 ; CHECK-NEXT: [[WideChkB:[^ ]+]] = and i1 [[first_iteration_checkB]], [[limit_checkB]]
64 ; CHECK-NEXT: [[maxMinusOne:[^ ]+]] = add i64 %max, -1
65 ; CHECK-NEXT: [[limit_checkMax:[^ ]+]] = icmp ule i64 15, [[maxMinusOne]]
66 ; CHECK-NEXT: [[first_iteration_checkMax:[^ ]+]] = icmp ult i64 0, %max
67 ; CHECK-NEXT: [[WideChkMax:[^ ]+]] = and i1 [[first_iteration_checkMax]], [[limit_checkMax]]
68 ; CHECK-NEXT: [[lenA:[^ ]+]] = add i32 %lengthA, -1
69 ; CHECK-NEXT: [[idxA:[^ ]+]] = sub i32 [[lenA]], %offA
70 ; CHECK-NEXT: [[limit_checkA:[^ ]+]] = icmp ule i32 15, [[idxA]]
71 ; CHECK-NEXT: [[first_iteration_checkA:[^ ]+]] = icmp ult i32 %offA, %lengthA
72 ; CHECK-NEXT: [[WideChkA:[^ ]+]] = and i1 [[first_iteration_checkA]], [[limit_checkA]]
73129 %lengthA = call i32 @length(i8* %arrA)
74130 %lengthB = call i32 @length(i8* %arrB)
75131 br label %loop
76132
77133 loop:
78 ; CHECK-LABEL: loop:
79 ; CHECK: [[BandMax:[^ ]+]] = and i1 [[WideChkB]], [[WideChkMax]]
80 ; CHECK: [[ABandMax:[^ ]+]] = and i1 [[BandMax]], [[WideChkA]]
81 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[ABandMax]], i32 9)
82134 %iv = phi i64 [0, %entry ], [ %iv.next, %loop ]
83135 %iv.trunc = trunc i64 %iv to i32
84136 %indexA = add i32 %iv.trunc, %offA
109161 ; for (i64 i= 5; i>= 2; i++)
110162 ; this loop wraps around after reaching 2^64.
111163 define i64 @iv_rc_different_type(i32 %offA, i8* %arrA) {
112 ; CHECK-LABEL: iv_rc_different_type
164 ; CHECK-LABEL: @iv_rc_different_type(
165 ; CHECK-NEXT: entry:
166 ; CHECK-NEXT: [[LENGTHA:%.*]] = call i32 @length(i8* [[ARRA:%.*]])
167 ; CHECK-NEXT: br label [[LOOP:%.*]]
168 ; CHECK: loop:
169 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 5, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
170 ; CHECK-NEXT: [[IV_TRUNC_32:%.*]] = trunc i64 [[IV]] to i32
171 ; CHECK-NEXT: [[INDEXA:%.*]] = add i32 [[IV_TRUNC_32]], [[OFFA:%.*]]
172 ; CHECK-NEXT: [[RCA:%.*]] = icmp ult i32 [[INDEXA]], [[LENGTHA]]
173 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[RCA]], i32 9) [ "deopt"() ]
174 ; CHECK-NEXT: [[INDEXA_EXT:%.*]] = zext i32 [[INDEXA]] to i64
175 ; CHECK-NEXT: [[ADDRA:%.*]] = getelementptr inbounds i8, i8* [[ARRA]], i64 [[INDEXA_EXT]]
176 ; CHECK-NEXT: [[ELTA:%.*]] = load i8, i8* [[ADDRA]]
177 ; CHECK-NEXT: [[RES:%.*]] = add i8 [[ELTA]], 2
178 ; CHECK-NEXT: store i8 [[ELTA]], i8* [[ADDRA]]
179 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
180 ; CHECK-NEXT: [[LATCH_CHECK:%.*]] = icmp sge i64 [[IV_NEXT]], 2
181 ; CHECK-NEXT: br i1 [[LATCH_CHECK]], label [[LOOP]], label [[EXIT:%.*]]
182 ; CHECK: exit:
183 ; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], [[LOOP]] ]
184 ; CHECK-NEXT: ret i64 [[IV_LCSSA]]
185 ;
113186 entry:
114187 %lengthA = call i32 @length(i8* %arrA)
115188 br label %loop
116189
117190 loop:
118 ; CHECK-LABEL: loop:
119 ; CHECK: %rcA = icmp ult i32 %indexA, %lengthA
120 ; CHECK-NEXT: call v