1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -loop-predication -S | FileCheck %s
3
4declare void @prevent_merging()
5
6; Base case - with side effects in loop
7define i32 @test1(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
8; CHECK-LABEL: @test1(
9; CHECK-NEXT:  entry:
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
19; CHECK:       deopt:
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:%.*]]
24; CHECK:       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
30; CHECK:       deopt2:
31; CHECK-NEXT:    call void @unknown()
32; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
33; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
34; CHECK:       guarded:
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:%.*]]
43; CHECK:       exit:
44; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
45; CHECK-NEXT:    ret i32 [[RESULT]]
46;
47entry:
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
51
52deopt:
53  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
54  ret i32 %deoptret
55
56loop.preheader:
57  br label %loop
58
59loop:
60  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
61  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
62  call void @unknown()
63  %within.bounds = icmp ult i32 %i, %length
64  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
65
66deopt2:
67  call void @unknown()
68  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
69  ret i32 %deoptret2
70
71guarded:
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
80
81exit:
82  %result = phi i32 [ %loop.acc.next, %guarded ]
83  ret i32 %result
84}
85
86
87
88define i32 @test_non_canonical(i32* %array, i32 %length, i1 %cond_0) {
89; CHECK-LABEL: @test_non_canonical(
90; CHECK-NEXT:  entry:
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
100; CHECK:       deopt:
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:%.*]]
105; CHECK:       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
111; CHECK:       deopt2:
112; CHECK-NEXT:    call void @unknown()
113; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
114; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
115; CHECK:       guarded:
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:%.*]]
124; CHECK:       exit:
125; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
126; CHECK-NEXT:    ret i32 [[RESULT]]
127;
128entry:
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
132
133deopt:
134  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
135  ret i32 %deoptret
136
137loop.preheader:
138  br label %loop
139
140loop:
141  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
142  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
143  call void @unknown()
144  %within.bounds = icmp ult i32 %i, %length
145  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
146
147deopt2:
148  call void @unknown()
149  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
150  ret i32 %deoptret2
151
152guarded:
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
161
162exit:
163  %result = phi i32 [ %loop.acc.next, %guarded ]
164  ret i32 %result
165}
166
167
168define 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(
170; CHECK-NEXT:  entry:
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
184; CHECK:       deopt:
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:%.*]]
189; CHECK:       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
195; CHECK:       deopt2:
196; CHECK-NEXT:    call void @unknown()
197; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
198; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
199; CHECK:       guarded:
200; CHECK-NEXT:    [[WITHIN_BOUNDS2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]]
201; CHECK-NEXT:    br i1 true, label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0
202; CHECK:       deopt3:
203; CHECK-NEXT:    call void @unknown()
204; CHECK-NEXT:    [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
205; CHECK-NEXT:    ret i32 [[DEOPTRET3]]
206; CHECK:       guarded2:
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:%.*]]
215; CHECK:       exit:
216; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
217; CHECK-NEXT:    ret i32 [[RESULT]]
218;
219entry:
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
223
224deopt:
225  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
226  ret i32 %deoptret
227
228loop.preheader:
229  br label %loop
230
231loop:
232  %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]
233  %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
234  call void @unknown()
235  %within.bounds = icmp ult i32 %i, %length.1
236  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
237
238deopt2:
239  call void @unknown()
240  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
241  ret i32 %deoptret2
242
243guarded:
244  %within.bounds2 = icmp ult i32 %i, %length.2
245  br i1 %within.bounds2, label %guarded2, label %deopt3, !prof !0
246
247deopt3:
248  call void @unknown()
249  %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
250  ret i32 %deoptret3
251
252guarded2:
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
261
262exit:
263  %result = phi i32 [ %loop.acc.next, %guarded2 ]
264  ret i32 %result
265}
266
267@G = external global i32
268
269define i32 @test_unanalyzeable_exit(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
270; CHECK-LABEL: @test_unanalyzeable_exit(
271; CHECK-NEXT:  entry:
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
275; CHECK:       deopt:
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:%.*]]
280; CHECK:       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
287; CHECK:       deopt3:
288; CHECK-NEXT:    call void @unknown()
289; CHECK-NEXT:    [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
290; CHECK-NEXT:    ret i32 [[DEOPTRET3]]
291; CHECK:       guarded2:
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:%.*]]
300; CHECK:       exit:
301; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
302; CHECK-NEXT:    ret i32 [[RESULT]]
303;
304entry:
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
308
309deopt:
310  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
311  ret i32 %deoptret
312
313loop.preheader:
314  br label %loop
315
316loop:
317  %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]
318  %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
319  call void @unknown()
320  %vol = load volatile i32, i32* @G
321  %unknown = icmp eq i32 %vol, 0
322  br i1 %unknown, label %guarded2, label %deopt3, !prof !0
323
324deopt3:
325  call void @unknown()
326  %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
327  ret i32 %deoptret3
328
329guarded2:
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
338
339exit:
340  %result = phi i32 [ %loop.acc.next, %guarded2 ]
341  ret i32 %result
342}
343
344define i32 @test_unanalyzeable_exit2(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
345; CHECK-LABEL: @test_unanalyzeable_exit2(
346; CHECK-NEXT:  entry:
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
356; CHECK:       deopt:
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:%.*]]
361; CHECK:       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
367; CHECK:       deopt2:
368; CHECK-NEXT:    call void @unknown()
369; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
370; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
371; CHECK:       guarded:
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
375; CHECK:       deopt3:
376; CHECK-NEXT:    call void @unknown()
377; CHECK-NEXT:    [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
378; CHECK-NEXT:    ret i32 [[DEOPTRET3]]
379; CHECK:       guarded2:
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:%.*]]
388; CHECK:       exit:
389; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
390; CHECK-NEXT:    ret i32 [[RESULT]]
391;
392entry:
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
396
397deopt:
398  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
399  ret i32 %deoptret
400
401loop.preheader:
402  br label %loop
403
404loop:
405  %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]
406  %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
407  call void @unknown()
408  %within.bounds = icmp ult i32 %i, %length
409  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
410
411deopt2:
412  call void @unknown()
413  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
414  ret i32 %deoptret2
415
416guarded:
417  %vol = load volatile i32, i32* @G
418  %unknown = icmp eq i32 %vol, 0
419  br i1 %unknown, label %guarded2, label %deopt3, !prof !0
420
421deopt3:
422  call void @unknown()
423  %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
424  ret i32 %deoptret3
425
426guarded2:
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
435
436exit:
437  %result = phi i32 [ %loop.acc.next, %guarded2 ]
438  ret i32 %result
439}
440
441
442define i32 @test_unanalyzeable_latch(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
443; CHECK-LABEL: @test_unanalyzeable_latch(
444; CHECK-NEXT:  entry:
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
448; CHECK:       deopt:
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:%.*]]
453; CHECK:       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
459; CHECK:       deopt2:
460; CHECK-NEXT:    call void @unknown()
461; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
462; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
463; CHECK:       guarded:
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:%.*]]
473; CHECK:       exit:
474; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
475; CHECK-NEXT:    ret i32 [[RESULT]]
476;
477entry:
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
481
482deopt:
483  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
484  ret i32 %deoptret
485
486loop.preheader:
487  br label %loop
488
489loop:
490  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
491  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
492  call void @unknown()
493  %within.bounds = icmp ult i32 %i, %length
494  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
495
496deopt2:
497  call void @unknown()
498  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
499  ret i32 %deoptret2
500
501guarded:
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
511
512exit:
513  %result = phi i32 [ %loop.acc.next, %guarded ]
514  ret i32 %result
515}
516
517
518define i32 @provably_taken(i32* %array, i1 %cond_0) {
519; CHECK-LABEL: @provably_taken(
520; CHECK-NEXT:  entry:
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
526; CHECK:       deopt:
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:%.*]]
531; CHECK:       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
537; CHECK:       deopt2:
538; CHECK-NEXT:    call void @unknown()
539; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
540; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
541; CHECK:       guarded:
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:%.*]]
550; CHECK:       exit:
551; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
552; CHECK-NEXT:    ret i32 [[RESULT]]
553;
554entry:
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
558
559deopt:
560  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
561  ret i32 %deoptret
562
563loop.preheader:
564  br label %loop
565
566loop:
567  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
568  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
569  call void @unknown()
570  %within.bounds = icmp ult i32 %i, 198
571  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
572
573deopt2:
574  call void @unknown()
575  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
576  ret i32 %deoptret2
577
578guarded:
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
587
588exit:
589  %result = phi i32 [ %loop.acc.next, %guarded ]
590  ret i32 %result
591}
592
593define i32 @provably_not_taken(i32* %array, i1 %cond_0) {
594; CHECK-LABEL: @provably_not_taken(
595; CHECK-NEXT:  entry:
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
601; CHECK:       deopt:
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:%.*]]
606; CHECK:       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
612; CHECK:       deopt2:
613; CHECK-NEXT:    call void @unknown()
614; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
615; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
616; CHECK:       guarded:
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:%.*]]
625; CHECK:       exit:
626; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
627; CHECK-NEXT:    ret i32 [[RESULT]]
628;
629entry:
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
633
634deopt:
635  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
636  ret i32 %deoptret
637
638loop.preheader:
639  br label %loop
640
641loop:
642  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
643  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
644  call void @unknown()
645  %within.bounds = icmp ult i32 %i, 205
646  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
647
648deopt2:
649  call void @unknown()
650  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
651  ret i32 %deoptret2
652
653guarded:
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
662
663exit:
664  %result = phi i32 [ %loop.acc.next, %guarded ]
665  ret i32 %result
666}
667
668
669;; Unswitch likes to produce some ugly exit blocks without simplifications
670;; being applied.  Make sure we can handle that form.
671define i32 @unswitch_exit_form(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
672; CHECK-LABEL: @unswitch_exit_form(
673; CHECK-NEXT:  entry:
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]]
685; CHECK:       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:%.*]]
694; CHECK:       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
700; CHECK:       guarded:
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:%.*]]
709; CHECK:       exit:
710; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
711; CHECK-NEXT:    ret i32 [[RESULT]]
712;
713entry:
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
717
718deopt:
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
724
725actual_deopt:
726  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %phi) ]
727  ret i32 %deoptret
728
729loop.preheader:
730  br label %loop
731
732loop:
733  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
734  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
735  call void @unknown()
736  %within.bounds = icmp ult i32 %i, %length
737  br i1 %within.bounds, label %guarded, label %deopt, !prof !0
738
739guarded:
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
748
749exit:
750  %result = phi i32 [ %loop.acc.next, %guarded ]
751  ret i32 %result
752}
753
754define i32 @swapped_wb(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
755; CHECK-LABEL: @swapped_wb(
756; CHECK-NEXT:  entry:
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
766; CHECK:       deopt:
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:%.*]]
771; CHECK:       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
777; CHECK:       deopt2:
778; CHECK-NEXT:    call void @unknown()
779; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
780; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
781; CHECK:       guarded:
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:%.*]]
790; CHECK:       exit:
791; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
792; CHECK-NEXT:    ret i32 [[RESULT]]
793;
794entry:
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
798
799deopt:
800  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
801  ret i32 %deoptret
802
803loop.preheader:
804  br label %loop
805
806loop:
807  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
808  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
809  call void @unknown()
810  %within.bounds = icmp ult i32 %i, %length
811  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
812
813deopt2:
814  call void @unknown()
815  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
816  ret i32 %deoptret2
817
818guarded:
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
827
828exit:
829  %result = phi i32 [ %loop.acc.next, %guarded ]
830  ret i32 %result
831}
832
833define i32 @trivial_wb(i32* %array, i32 %length, i32 %n) {
834; CHECK-LABEL: @trivial_wb(
835; CHECK-NEXT:  entry:
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
844; CHECK:       deopt:
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:%.*]]
849; CHECK:       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
855; CHECK:       deopt2:
856; CHECK-NEXT:    call void @unknown()
857; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
858; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
859; CHECK:       guarded:
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:%.*]]
868; CHECK:       exit:
869; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
870; CHECK-NEXT:    ret i32 [[RESULT]]
871;
872entry:
873  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
874  br i1 %widenable_cond, label %loop.preheader, label %deopt, !prof !0
875
876deopt:
877  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
878  ret i32 %deoptret
879
880loop.preheader:
881  br label %loop
882
883loop:
884  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
885  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
886  call void @unknown()
887  %within.bounds = icmp ult i32 %i, %length
888  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
889
890deopt2:
891  call void @unknown()
892  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
893  ret i32 %deoptret2
894
895guarded:
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
904
905exit:
906  %result = phi i32 [ %loop.acc.next, %guarded ]
907  ret i32 %result
908}
909
910; TODO: Non-latch exits can still be predicated
911; This is currently prevented by an overly restrictive profitability check.
912define i32 @todo_unconditional_latch(i32* %array, i32 %length, i1 %cond_0) {
913; CHECK-LABEL: @todo_unconditional_latch(
914; CHECK-NEXT:  entry:
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
918; CHECK:       deopt:
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:%.*]]
923; CHECK:       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
929; CHECK:       deopt2:
930; CHECK-NEXT:    call void @unknown()
931; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
932; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
933; CHECK:       guarded:
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]]
941;
942entry:
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
946
947deopt:
948  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
949  ret i32 %deoptret
950
951loop.preheader:
952  br label %loop
953
954loop:
955  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
956  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
957  call void @unknown()
958  %within.bounds = icmp ult i32 %i, %length
959  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
960
961deopt2:
962  call void @unknown()
963  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
964  ret i32 %deoptret2
965
966guarded:
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
973  br label %loop
974}
975
976
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
979; branches.
980define i32 @wb_in_loop(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
981; CHECK-LABEL: @wb_in_loop(
982; CHECK-NEXT:  entry:
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
996; CHECK:       deopt:
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:%.*]]
1001; CHECK:       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
1007; CHECK:       deopt2:
1008; CHECK-NEXT:    call void @unknown()
1009; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1010; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
1011; CHECK:       guarded:
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
1016; CHECK:       deopt3:
1017; CHECK-NEXT:    call void @unknown()
1018; CHECK-NEXT:    [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1019; CHECK-NEXT:    ret i32 [[DEOPTRET3]]
1020; CHECK:       guarded2:
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:%.*]]
1029; CHECK:       exit:
1030; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
1031; CHECK-NEXT:    ret i32 [[RESULT]]
1032;
1033entry:
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
1038
1039deopt:
1040  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1041  ret i32 %deoptret
1042
1043loop.preheader:
1044  br label %loop
1045
1046loop:
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
1052
1053deopt2:
1054  call void @unknown()
1055  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1056  ret i32 %deoptret2
1057
1058guarded:
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
1063
1064deopt3:
1065  call void @unknown()
1066  %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1067  ret i32 %deoptret3
1068
1069guarded2:
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
1078
1079exit:
1080  %result = phi i32 [ %loop.acc.next, %guarded2 ]
1081  ret i32 %result
1082}
1083
1084
1085
1086declare void @unknown()
1087
1088declare i1 @llvm.experimental.widenable.condition()
1089declare i32 @llvm.experimental.deoptimize.i32(...)
1090
1091!0 = !{!"branch_weights", i32 1048576, i32 1}
1092!1 = !{i32 1, i32 -2147483648}
1093!2 = !{i32 0, i32 50}
1094