1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -loop-predication -S | FileCheck %s
4 declare void @prevent_merging()
6 ; Base case - with side effects in loop
7 define i32 @test1(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
10 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
11 ; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
12 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1
13 ; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])
14 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
15 ; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]]
16 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]
17 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
18 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
20 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
21 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
22 ; CHECK: loop.preheader:
23 ; CHECK-NEXT: br label [[LOOP:%.*]]
25 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
26 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
27 ; CHECK-NEXT: call void @unknown()
28 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
29 ; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
31 ; CHECK-NEXT: call void @unknown()
32 ; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
33 ; CHECK-NEXT: ret i32 [[DEOPTRET2]]
35 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
36 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
37 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
38 ; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4
39 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
40 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
41 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
42 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
44 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
45 ; CHECK-NEXT: ret i32 [[RESULT]]
48 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
49 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
50 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
53 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
60 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
61 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
63 %within.bounds = icmp ult i32 %i, %length
64 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
68 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
72 %i.i64 = zext i32 %i to i64
73 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
74 %array.i = load i32, i32* %array.i.ptr, align 4
75 store i32 0, i32* %array.i.ptr
76 %loop.acc.next = add i32 %loop.acc, %array.i
77 %i.next = add nuw i32 %i, 1
78 %continue = icmp ult i32 %i.next, %n
79 br i1 %continue, label %loop, label %exit
82 %result = phi i32 [ %loop.acc.next, %guarded ]
88 define i32 @test_non_canonical(i32* %array, i32 %length, i1 %cond_0) {
89 ; CHECK-LABEL: @test_non_canonical(
91 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
92 ; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[LENGTH:%.*]], i32 1)
93 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1
94 ; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH]], i32 [[TMP0]])
95 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
96 ; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]]
97 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]
98 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
99 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
101 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
102 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
103 ; CHECK: loop.preheader:
104 ; CHECK-NEXT: br label [[LOOP:%.*]]
106 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
107 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
108 ; CHECK-NEXT: call void @unknown()
109 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
110 ; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
112 ; CHECK-NEXT: call void @unknown()
113 ; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
114 ; CHECK-NEXT: ret i32 [[DEOPTRET2]]
116 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
117 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
118 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
119 ; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4
120 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
121 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
122 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[LENGTH]]
123 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
125 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
126 ; CHECK-NEXT: ret i32 [[RESULT]]
129 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
130 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
131 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
134 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
141 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
142 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
144 %within.bounds = icmp ult i32 %i, %length
145 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
149 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
153 %i.i64 = zext i32 %i to i64
154 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
155 %array.i = load i32, i32* %array.i.ptr, align 4
156 store i32 0, i32* %array.i.ptr
157 %loop.acc.next = add i32 %loop.acc, %array.i
158 %i.next = add nuw i32 %i, 1
159 %continue = icmp ult i32 %i.next, %length
160 br i1 %continue, label %loop, label %exit
163 %result = phi i32 [ %loop.acc.next, %guarded ]
168 define i32 @test_two_range_checks(i32* %array, i32 %length.1, i32 %length.2, i32 %n, i1 %cond_0) {
169 ; CHECK-LABEL: @test_two_range_checks(
171 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
172 ; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH_2:%.*]], i32 [[LENGTH_1:%.*]])
173 ; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
174 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1
175 ; CHECK-NEXT: [[UMIN1:%.*]] = call i32 @llvm.umin.i32(i32 [[UMIN]], i32 [[TMP0]])
176 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH_1]], [[UMIN1]]
177 ; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]]
178 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]
179 ; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i32 [[LENGTH_2]], [[UMIN1]]
180 ; CHECK-NEXT: [[TMP5:%.*]] = freeze i1 [[TMP4]]
181 ; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP3]]
182 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP6]], [[WIDENABLE_COND]]
183 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
185 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
186 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
187 ; CHECK: loop.preheader:
188 ; CHECK-NEXT: br label [[LOOP:%.*]]
190 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
191 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]
192 ; CHECK-NEXT: call void @unknown()
193 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]]
194 ; CHECK-NEXT: br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof !0
196 ; CHECK-NEXT: call void @unknown()
197 ; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
198 ; CHECK-NEXT: ret i32 [[DEOPTRET2]]
200 ; CHECK-NEXT: [[WITHIN_BOUNDS2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]]
201 ; CHECK-NEXT: br i1 true, label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0
203 ; CHECK-NEXT: call void @unknown()
204 ; CHECK-NEXT: [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
205 ; CHECK-NEXT: ret i32 [[DEOPTRET3]]
207 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
208 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
209 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
210 ; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4
211 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
212 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
213 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
214 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
216 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
217 ; CHECK-NEXT: ret i32 [[RESULT]]
220 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
221 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
222 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
225 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
232 %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]
233 %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
235 %within.bounds = icmp ult i32 %i, %length.1
236 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
240 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
244 %within.bounds2 = icmp ult i32 %i, %length.2
245 br i1 %within.bounds2, label %guarded2, label %deopt3, !prof !0
249 %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
253 %i.i64 = zext i32 %i to i64
254 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
255 %array.i = load i32, i32* %array.i.ptr, align 4
256 store i32 0, i32* %array.i.ptr
257 %loop.acc.next = add i32 %loop.acc, %array.i
258 %i.next = add nuw i32 %i, 1
259 %continue = icmp ult i32 %i.next, %n
260 br i1 %continue, label %loop, label %exit
263 %result = phi i32 [ %loop.acc.next, %guarded2 ]
267 @G = external global i32
269 define i32 @test_unanalyzeable_exit(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
270 ; CHECK-LABEL: @test_unanalyzeable_exit(
272 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
273 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
274 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
276 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
277 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
278 ; CHECK: loop.preheader:
279 ; CHECK-NEXT: br label [[LOOP:%.*]]
281 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
282 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]
283 ; CHECK-NEXT: call void @unknown()
284 ; CHECK-NEXT: [[VOL:%.*]] = load volatile i32, i32* @G, align 4
285 ; CHECK-NEXT: [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0
286 ; CHECK-NEXT: br i1 [[UNKNOWN]], label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0
288 ; CHECK-NEXT: call void @unknown()
289 ; CHECK-NEXT: [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
290 ; CHECK-NEXT: ret i32 [[DEOPTRET3]]
292 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
293 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
294 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
295 ; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4
296 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
297 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
298 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N:%.*]]
299 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
301 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
302 ; CHECK-NEXT: ret i32 [[RESULT]]
305 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
306 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
307 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
310 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
317 %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]
318 %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
320 %vol = load volatile i32, i32* @G
321 %unknown = icmp eq i32 %vol, 0
322 br i1 %unknown, label %guarded2, label %deopt3, !prof !0
326 %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
330 %i.i64 = zext i32 %i to i64
331 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
332 %array.i = load i32, i32* %array.i.ptr, align 4
333 store i32 0, i32* %array.i.ptr
334 %loop.acc.next = add i32 %loop.acc, %array.i
335 %i.next = add nuw i32 %i, 1
336 %continue = icmp ult i32 %i.next, %n
337 br i1 %continue, label %loop, label %exit
340 %result = phi i32 [ %loop.acc.next, %guarded2 ]
344 define i32 @test_unanalyzeable_exit2(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
345 ; CHECK-LABEL: @test_unanalyzeable_exit2(
347 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
348 ; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
349 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1
350 ; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])
351 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
352 ; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]]
353 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]
354 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
355 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
357 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
358 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
359 ; CHECK: loop.preheader:
360 ; CHECK-NEXT: br label [[LOOP:%.*]]
362 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
363 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]
364 ; CHECK-NEXT: call void @unknown()
365 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
366 ; CHECK-NEXT: br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof !0
368 ; CHECK-NEXT: call void @unknown()
369 ; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
370 ; CHECK-NEXT: ret i32 [[DEOPTRET2]]
372 ; CHECK-NEXT: [[VOL:%.*]] = load volatile i32, i32* @G, align 4
373 ; CHECK-NEXT: [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0
374 ; CHECK-NEXT: br i1 [[UNKNOWN]], label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0
376 ; CHECK-NEXT: call void @unknown()
377 ; CHECK-NEXT: [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
378 ; CHECK-NEXT: ret i32 [[DEOPTRET3]]
380 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
381 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
382 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
383 ; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4
384 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
385 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
386 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
387 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
389 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
390 ; CHECK-NEXT: ret i32 [[RESULT]]
393 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
394 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
395 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
398 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
405 %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]
406 %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
408 %within.bounds = icmp ult i32 %i, %length
409 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
413 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
417 %vol = load volatile i32, i32* @G
418 %unknown = icmp eq i32 %vol, 0
419 br i1 %unknown, label %guarded2, label %deopt3, !prof !0
423 %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
427 %i.i64 = zext i32 %i to i64
428 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
429 %array.i = load i32, i32* %array.i.ptr, align 4
430 store i32 0, i32* %array.i.ptr
431 %loop.acc.next = add i32 %loop.acc, %array.i
432 %i.next = add nuw i32 %i, 1
433 %continue = icmp ult i32 %i.next, %n
434 br i1 %continue, label %loop, label %exit
437 %result = phi i32 [ %loop.acc.next, %guarded2 ]
442 define i32 @test_unanalyzeable_latch(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
443 ; CHECK-LABEL: @test_unanalyzeable_latch(
445 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
446 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
447 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
449 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
450 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
451 ; CHECK: loop.preheader:
452 ; CHECK-NEXT: br label [[LOOP:%.*]]
454 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
455 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
456 ; CHECK-NEXT: call void @unknown()
457 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
458 ; CHECK-NEXT: br i1 [[WITHIN_BOUNDS]], label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
460 ; CHECK-NEXT: call void @unknown()
461 ; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
462 ; CHECK-NEXT: ret i32 [[DEOPTRET2]]
464 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
465 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
466 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
467 ; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4
468 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
469 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
470 ; CHECK-NEXT: [[VOL:%.*]] = load volatile i32, i32* @G, align 4
471 ; CHECK-NEXT: [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0
472 ; CHECK-NEXT: br i1 [[UNKNOWN]], label [[LOOP]], label [[EXIT:%.*]]
474 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
475 ; CHECK-NEXT: ret i32 [[RESULT]]
478 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
479 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
480 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
483 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
490 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
491 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
493 %within.bounds = icmp ult i32 %i, %length
494 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
498 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
502 %i.i64 = zext i32 %i to i64
503 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
504 %array.i = load i32, i32* %array.i.ptr, align 4
505 store i32 0, i32* %array.i.ptr
506 %loop.acc.next = add i32 %loop.acc, %array.i
507 %i.next = add nuw i32 %i, 1
508 %vol = load volatile i32, i32* @G
509 %unknown = icmp eq i32 %vol, 0
510 br i1 %unknown, label %loop, label %exit
513 %result = phi i32 [ %loop.acc.next, %guarded ]
518 define i32 @provably_taken(i32* %array, i1 %cond_0) {
519 ; CHECK-LABEL: @provably_taken(
521 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
522 ; CHECK-NEXT: [[TMP0:%.*]] = freeze i1 false
523 ; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[TMP0]], [[COND_0:%.*]]
524 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]]
525 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
527 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
528 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
529 ; CHECK: loop.preheader:
530 ; CHECK-NEXT: br label [[LOOP:%.*]]
532 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
533 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
534 ; CHECK-NEXT: call void @unknown()
535 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], 198
536 ; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
538 ; CHECK-NEXT: call void @unknown()
539 ; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
540 ; CHECK-NEXT: ret i32 [[DEOPTRET2]]
542 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
543 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
544 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
545 ; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4
546 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
547 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
548 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], 200
549 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
551 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
552 ; CHECK-NEXT: ret i32 [[RESULT]]
555 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
556 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
557 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
560 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
567 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
568 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
570 %within.bounds = icmp ult i32 %i, 198
571 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
575 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
579 %i.i64 = zext i32 %i to i64
580 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
581 %array.i = load i32, i32* %array.i.ptr, align 4
582 store i32 0, i32* %array.i.ptr
583 %loop.acc.next = add i32 %loop.acc, %array.i
584 %i.next = add nuw i32 %i, 1
585 %continue = icmp ult i32 %i.next, 200
586 br i1 %continue, label %loop, label %exit
589 %result = phi i32 [ %loop.acc.next, %guarded ]
593 define i32 @provably_not_taken(i32* %array, i1 %cond_0) {
594 ; CHECK-LABEL: @provably_not_taken(
596 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
597 ; CHECK-NEXT: [[TMP0:%.*]] = freeze i1 true
598 ; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[TMP0]], [[COND_0:%.*]]
599 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]]
600 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
602 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
603 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
604 ; CHECK: loop.preheader:
605 ; CHECK-NEXT: br label [[LOOP:%.*]]
607 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
608 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
609 ; CHECK-NEXT: call void @unknown()
610 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], 205
611 ; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
613 ; CHECK-NEXT: call void @unknown()
614 ; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
615 ; CHECK-NEXT: ret i32 [[DEOPTRET2]]
617 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
618 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
619 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
620 ; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4
621 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
622 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
623 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], 200
624 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
626 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
627 ; CHECK-NEXT: ret i32 [[RESULT]]
630 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
631 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
632 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
635 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
642 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
643 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
645 %within.bounds = icmp ult i32 %i, 205
646 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
650 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
654 %i.i64 = zext i32 %i to i64
655 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
656 %array.i = load i32, i32* %array.i.ptr, align 4
657 store i32 0, i32* %array.i.ptr
658 %loop.acc.next = add i32 %loop.acc, %array.i
659 %i.next = add nuw i32 %i, 1
660 %continue = icmp ult i32 %i.next, 200
661 br i1 %continue, label %loop, label %exit
664 %result = phi i32 [ %loop.acc.next, %guarded ]
669 ;; Unswitch likes to produce some ugly exit blocks without simplifications
670 ;; being applied. Make sure we can handle that form.
671 define i32 @unswitch_exit_form(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
672 ; CHECK-LABEL: @unswitch_exit_form(
674 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
675 ; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
676 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1
677 ; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])
678 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
679 ; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]]
680 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]
681 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
682 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
683 ; CHECK: deopt.loopexit:
684 ; CHECK-NEXT: br label [[DEOPT]]
686 ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[DEOPT_LOOPEXIT:%.*]] ]
687 ; CHECK-NEXT: call void @unknown()
688 ; CHECK-NEXT: br label [[ACTUAL_DEOPT:%.*]]
689 ; CHECK: actual_deopt:
690 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[PHI]]) ]
691 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
692 ; CHECK: loop.preheader:
693 ; CHECK-NEXT: br label [[LOOP:%.*]]
695 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
696 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
697 ; CHECK-NEXT: call void @unknown()
698 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
699 ; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT_LOOPEXIT]], !prof !0
701 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
702 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
703 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
704 ; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4
705 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
706 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
707 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
708 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
710 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
711 ; CHECK-NEXT: ret i32 [[RESULT]]
714 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
715 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
716 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
719 ;; This is written to look like an unsimplified loop exit after unswitch
720 ;; (i.e. phis, merge, and branch to actual block)
721 %phi = phi i32 [0, %entry], [1, %loop]
722 call void @unknown() ;; it's okay to skip possible throws
723 br label %actual_deopt
726 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %phi) ]
733 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
734 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
736 %within.bounds = icmp ult i32 %i, %length
737 br i1 %within.bounds, label %guarded, label %deopt, !prof !0
740 %i.i64 = zext i32 %i to i64
741 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
742 %array.i = load i32, i32* %array.i.ptr, align 4
743 store i32 0, i32* %array.i.ptr
744 %loop.acc.next = add i32 %loop.acc, %array.i
745 %i.next = add nuw i32 %i, 1
746 %continue = icmp ult i32 %i.next, %n
747 br i1 %continue, label %loop, label %exit
750 %result = phi i32 [ %loop.acc.next, %guarded ]
754 define i32 @swapped_wb(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
755 ; CHECK-LABEL: @swapped_wb(
757 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
758 ; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
759 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1
760 ; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])
761 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
762 ; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]]
763 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]
764 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP3]]
765 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
767 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
768 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
769 ; CHECK: loop.preheader:
770 ; CHECK-NEXT: br label [[LOOP:%.*]]
772 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
773 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
774 ; CHECK-NEXT: call void @unknown()
775 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
776 ; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
778 ; CHECK-NEXT: call void @unknown()
779 ; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
780 ; CHECK-NEXT: ret i32 [[DEOPTRET2]]
782 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
783 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
784 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
785 ; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4
786 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
787 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
788 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
789 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
791 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
792 ; CHECK-NEXT: ret i32 [[RESULT]]
795 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
796 %exiplicit_guard_cond = and i1 %widenable_cond, %cond_0
797 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
800 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
807 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
808 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
810 %within.bounds = icmp ult i32 %i, %length
811 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
815 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
819 %i.i64 = zext i32 %i to i64
820 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
821 %array.i = load i32, i32* %array.i.ptr, align 4
822 store i32 0, i32* %array.i.ptr
823 %loop.acc.next = add i32 %loop.acc, %array.i
824 %i.next = add nuw i32 %i, 1
825 %continue = icmp ult i32 %i.next, %n
826 br i1 %continue, label %loop, label %exit
829 %result = phi i32 [ %loop.acc.next, %guarded ]
833 define i32 @trivial_wb(i32* %array, i32 %length, i32 %n) {
834 ; CHECK-LABEL: @trivial_wb(
836 ; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
837 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1
838 ; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])
839 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
840 ; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]]
841 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
842 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
843 ; CHECK-NEXT: br i1 [[TMP3]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
845 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
846 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
847 ; CHECK: loop.preheader:
848 ; CHECK-NEXT: br label [[LOOP:%.*]]
850 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
851 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
852 ; CHECK-NEXT: call void @unknown()
853 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
854 ; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
856 ; CHECK-NEXT: call void @unknown()
857 ; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
858 ; CHECK-NEXT: ret i32 [[DEOPTRET2]]
860 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
861 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
862 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
863 ; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4
864 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
865 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
866 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
867 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
869 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
870 ; CHECK-NEXT: ret i32 [[RESULT]]
873 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
874 br i1 %widenable_cond, label %loop.preheader, label %deopt, !prof !0
877 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
884 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
885 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
887 %within.bounds = icmp ult i32 %i, %length
888 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
892 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
896 %i.i64 = zext i32 %i to i64
897 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
898 %array.i = load i32, i32* %array.i.ptr, align 4
899 store i32 0, i32* %array.i.ptr
900 %loop.acc.next = add i32 %loop.acc, %array.i
901 %i.next = add nuw i32 %i, 1
902 %continue = icmp ult i32 %i.next, %n
903 br i1 %continue, label %loop, label %exit
906 %result = phi i32 [ %loop.acc.next, %guarded ]
910 ; TODO: Non-latch exits can still be predicated
911 ; This is currently prevented by an overly restrictive profitability check.
912 define i32 @todo_unconditional_latch(i32* %array, i32 %length, i1 %cond_0) {
913 ; CHECK-LABEL: @todo_unconditional_latch(
915 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
916 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
917 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
919 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
920 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
921 ; CHECK: loop.preheader:
922 ; CHECK-NEXT: br label [[LOOP:%.*]]
924 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
925 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
926 ; CHECK-NEXT: call void @unknown()
927 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
928 ; CHECK-NEXT: br i1 [[WITHIN_BOUNDS]], label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
930 ; CHECK-NEXT: call void @unknown()
931 ; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
932 ; CHECK-NEXT: ret i32 [[DEOPTRET2]]
934 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
935 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
936 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
937 ; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4
938 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
939 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
940 ; CHECK-NEXT: br label [[LOOP]]
943 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
944 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
945 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
948 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
955 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
956 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
958 %within.bounds = icmp ult i32 %i, %length
959 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
963 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
967 %i.i64 = zext i32 %i to i64
968 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
969 %array.i = load i32, i32* %array.i.ptr, align 4
970 store i32 0, i32* %array.i.ptr
971 %loop.acc.next = add i32 %loop.acc, %array.i
972 %i.next = add nuw i32 %i, 1
977 ; If we have a stray widenable branch in the loop, we should still be able to
978 ; run. This can happen when unswitching's cost model avoids unswitching some
980 define i32 @wb_in_loop(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
981 ; CHECK-LABEL: @wb_in_loop(
983 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
984 ; CHECK-NEXT: [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition()
985 ; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
986 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1
987 ; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])
988 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
989 ; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]]
990 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]
991 ; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
992 ; CHECK-NEXT: [[TMP5:%.*]] = freeze i1 [[TMP4]]
993 ; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP3]]
994 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP6]], [[WIDENABLE_COND]]
995 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
997 ; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
998 ; CHECK-NEXT: ret i32 [[DEOPTRET]]
999 ; CHECK: loop.preheader:
1000 ; CHECK-NEXT: br label [[LOOP:%.*]]
1002 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1003 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]
1004 ; CHECK-NEXT: call void @unknown()
1005 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
1006 ; CHECK-NEXT: br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof !0
1008 ; CHECK-NEXT: call void @unknown()
1009 ; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1010 ; CHECK-NEXT: ret i32 [[DEOPTRET2]]
1012 ; CHECK-NEXT: call void @unknown()
1013 ; CHECK-NEXT: [[WITHIN_BOUNDS2:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
1014 ; CHECK-NEXT: [[WB_COND:%.*]] = and i1 [[WITHIN_BOUNDS2]], true
1015 ; CHECK-NEXT: br i1 true, label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0
1017 ; CHECK-NEXT: call void @unknown()
1018 ; CHECK-NEXT: [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1019 ; CHECK-NEXT: ret i32 [[DEOPTRET3]]
1021 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1022 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1023 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1024 ; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4
1025 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1026 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
1027 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1028 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
1030 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
1031 ; CHECK-NEXT: ret i32 [[RESULT]]
1034 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1035 %wc2 = call i1 @llvm.experimental.widenable.condition()
1036 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
1037 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
1040 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1047 %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]
1048 %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
1049 call void @unknown()
1050 %within.bounds = icmp ult i32 %i, %length
1051 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
1054 call void @unknown()
1055 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1059 call void @unknown()
1060 %within.bounds2 = icmp ult i32 %i, %length
1061 %wb_cond = and i1 %within.bounds2, %wc2
1062 br i1 %wb_cond, label %guarded2, label %deopt3, !prof !0
1065 call void @unknown()
1066 %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1070 %i.i64 = zext i32 %i to i64
1071 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1072 %array.i = load i32, i32* %array.i.ptr, align 4
1073 store i32 0, i32* %array.i.ptr
1074 %loop.acc.next = add i32 %loop.acc, %array.i
1075 %i.next = add nuw i32 %i, 1
1076 %continue = icmp ult i32 %i.next, %n
1077 br i1 %continue, label %loop, label %exit
1080 %result = phi i32 [ %loop.acc.next, %guarded2 ]
1086 declare void @unknown()
1088 declare i1 @llvm.experimental.widenable.condition()
1089 declare i32 @llvm.experimental.deoptimize.i32(...)
1091 !0 = !{!"branch_weights", i32 1048576, i32 1}
1092 !1 = !{i32 1, i32 -2147483648}
1093 !2 = !{i32 0, i32 50}