• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:    [[TMP0:%.*]] = icmp ugt i32 [[N:%.*]], 1
12; CHECK-NEXT:    [[UMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 1
13; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[UMAX]], -1
14; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[LENGTH:%.*]], [[TMP1]]
15; CHECK-NEXT:    [[UMIN:%.*]] = select i1 [[TMP2]], i32 [[LENGTH]], i32 [[TMP1]]
16; CHECK-NEXT:    [[TMP3:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
17; CHECK-NEXT:    [[TMP4:%.*]] = freeze i1 [[TMP3]]
18; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[COND_0:%.*]]
19; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP5]], [[WIDENABLE_COND]]
20; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
21; CHECK:       deopt:
22; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
23; CHECK-NEXT:    ret i32 [[DEOPTRET]]
24; CHECK:       loop.preheader:
25; CHECK-NEXT:    br label [[LOOP:%.*]]
26; CHECK:       loop:
27; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
28; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
29; CHECK-NEXT:    call void @unknown()
30; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
31; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
32; CHECK:       deopt2:
33; CHECK-NEXT:    call void @unknown()
34; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
35; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
36; CHECK:       guarded:
37; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
38; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
39; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
40; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
41; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
42; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
43; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
44; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
45; CHECK:       exit:
46; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
47; CHECK-NEXT:    ret i32 [[RESULT]]
48;
49entry:
50  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
51  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
52  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
53
54deopt:
55  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
56  ret i32 %deoptret
57
58loop.preheader:
59  br label %loop
60
61loop:
62  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
63  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
64  call void @unknown()
65  %within.bounds = icmp ult i32 %i, %length
66  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
67
68deopt2:
69  call void @unknown()
70  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
71  ret i32 %deoptret2
72
73guarded:
74  %i.i64 = zext i32 %i to i64
75  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
76  %array.i = load i32, i32* %array.i.ptr, align 4
77  store i32 0, i32* %array.i.ptr
78  %loop.acc.next = add i32 %loop.acc, %array.i
79  %i.next = add nuw i32 %i, 1
80  %continue = icmp ult i32 %i.next, %n
81  br i1 %continue, label %loop, label %exit
82
83exit:
84  %result = phi i32 [ %loop.acc.next, %guarded ]
85  ret i32 %result
86}
87
88
89
90define i32 @test_non_canonical(i32* %array, i32 %length, i1 %cond_0) {
91; CHECK-LABEL: @test_non_canonical(
92; CHECK-NEXT:  entry:
93; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
94; CHECK-NEXT:    [[TMP0:%.*]] = icmp ugt i32 [[LENGTH:%.*]], 1
95; CHECK-NEXT:    [[UMAX:%.*]] = select i1 [[TMP0]], i32 [[LENGTH]], i32 1
96; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[UMAX]], -1
97; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[LENGTH]], [[TMP1]]
98; CHECK-NEXT:    [[UMIN:%.*]] = select i1 [[TMP2]], i32 [[LENGTH]], i32 [[TMP1]]
99; CHECK-NEXT:    [[TMP3:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
100; CHECK-NEXT:    [[TMP4:%.*]] = freeze i1 [[TMP3]]
101; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[COND_0:%.*]]
102; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP5]], [[WIDENABLE_COND]]
103; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
104; CHECK:       deopt:
105; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
106; CHECK-NEXT:    ret i32 [[DEOPTRET]]
107; CHECK:       loop.preheader:
108; CHECK-NEXT:    br label [[LOOP:%.*]]
109; CHECK:       loop:
110; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
111; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
112; CHECK-NEXT:    call void @unknown()
113; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
114; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
115; CHECK:       deopt2:
116; CHECK-NEXT:    call void @unknown()
117; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
118; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
119; CHECK:       guarded:
120; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
121; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
122; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
123; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
124; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
125; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
126; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[LENGTH]]
127; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
128; CHECK:       exit:
129; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
130; CHECK-NEXT:    ret i32 [[RESULT]]
131;
132entry:
133  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
134  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
135  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
136
137deopt:
138  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
139  ret i32 %deoptret
140
141loop.preheader:
142  br label %loop
143
144loop:
145  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
146  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
147  call void @unknown()
148  %within.bounds = icmp ult i32 %i, %length
149  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
150
151deopt2:
152  call void @unknown()
153  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
154  ret i32 %deoptret2
155
156guarded:
157  %i.i64 = zext i32 %i to i64
158  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
159  %array.i = load i32, i32* %array.i.ptr, align 4
160  store i32 0, i32* %array.i.ptr
161  %loop.acc.next = add i32 %loop.acc, %array.i
162  %i.next = add nuw i32 %i, 1
163  %continue = icmp ult i32 %i.next, %length
164  br i1 %continue, label %loop, label %exit
165
166exit:
167  %result = phi i32 [ %loop.acc.next, %guarded ]
168  ret i32 %result
169}
170
171
172define i32 @test_two_range_checks(i32* %array, i32 %length.1, i32 %length.2, i32 %n, i1 %cond_0) {
173; CHECK-LABEL: @test_two_range_checks(
174; CHECK-NEXT:  entry:
175; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
176; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 [[LENGTH_2:%.*]], [[LENGTH_1:%.*]]
177; CHECK-NEXT:    [[UMIN:%.*]] = select i1 [[TMP0]], i32 [[LENGTH_2]], i32 [[LENGTH_1]]
178; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[N:%.*]], 1
179; CHECK-NEXT:    [[UMAX:%.*]] = select i1 [[TMP1]], i32 [[N]], i32 1
180; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[UMAX]], -1
181; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i32 [[UMIN]], [[TMP2]]
182; CHECK-NEXT:    [[UMIN1:%.*]] = select i1 [[TMP3]], i32 [[UMIN]], i32 [[TMP2]]
183; CHECK-NEXT:    [[TMP4:%.*]] = icmp ugt i32 [[LENGTH_1]], [[UMIN1]]
184; CHECK-NEXT:    [[TMP5:%.*]] = freeze i1 [[TMP4]]
185; CHECK-NEXT:    [[TMP6:%.*]] = and i1 [[TMP5]], [[COND_0:%.*]]
186; CHECK-NEXT:    [[TMP7:%.*]] = icmp ugt i32 [[LENGTH_2]], [[UMIN1]]
187; CHECK-NEXT:    [[TMP8:%.*]] = freeze i1 [[TMP7]]
188; CHECK-NEXT:    [[TMP9:%.*]] = and i1 [[TMP8]], [[TMP6]]
189; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP9]], [[WIDENABLE_COND]]
190; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
191; CHECK:       deopt:
192; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
193; CHECK-NEXT:    ret i32 [[DEOPTRET]]
194; CHECK:       loop.preheader:
195; CHECK-NEXT:    br label [[LOOP:%.*]]
196; CHECK:       loop:
197; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
198; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]
199; CHECK-NEXT:    call void @unknown()
200; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]]
201; CHECK-NEXT:    br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof !0
202; CHECK:       deopt2:
203; CHECK-NEXT:    call void @unknown()
204; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
205; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
206; CHECK:       guarded:
207; CHECK-NEXT:    [[WITHIN_BOUNDS2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]]
208; CHECK-NEXT:    br i1 true, label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0
209; CHECK:       deopt3:
210; CHECK-NEXT:    call void @unknown()
211; CHECK-NEXT:    [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
212; CHECK-NEXT:    ret i32 [[DEOPTRET3]]
213; CHECK:       guarded2:
214; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
215; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
216; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
217; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
218; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
219; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
220; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
221; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
222; CHECK:       exit:
223; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
224; CHECK-NEXT:    ret i32 [[RESULT]]
225;
226entry:
227  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
228  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
229  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
230
231deopt:
232  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
233  ret i32 %deoptret
234
235loop.preheader:
236  br label %loop
237
238loop:
239  %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]
240  %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
241  call void @unknown()
242  %within.bounds = icmp ult i32 %i, %length.1
243  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
244
245deopt2:
246  call void @unknown()
247  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
248  ret i32 %deoptret2
249
250guarded:
251  %within.bounds2 = icmp ult i32 %i, %length.2
252  br i1 %within.bounds2, label %guarded2, label %deopt3, !prof !0
253
254deopt3:
255  call void @unknown()
256  %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
257  ret i32 %deoptret3
258
259guarded2:
260  %i.i64 = zext i32 %i to i64
261  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
262  %array.i = load i32, i32* %array.i.ptr, align 4
263  store i32 0, i32* %array.i.ptr
264  %loop.acc.next = add i32 %loop.acc, %array.i
265  %i.next = add nuw i32 %i, 1
266  %continue = icmp ult i32 %i.next, %n
267  br i1 %continue, label %loop, label %exit
268
269exit:
270  %result = phi i32 [ %loop.acc.next, %guarded2 ]
271  ret i32 %result
272}
273
274@G = external global i32
275
276define i32 @test_unanalyzeable_exit(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
277; CHECK-LABEL: @test_unanalyzeable_exit(
278; CHECK-NEXT:  entry:
279; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
280; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
281; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
282; CHECK:       deopt:
283; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
284; CHECK-NEXT:    ret i32 [[DEOPTRET]]
285; CHECK:       loop.preheader:
286; CHECK-NEXT:    br label [[LOOP:%.*]]
287; CHECK:       loop:
288; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
289; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]
290; CHECK-NEXT:    call void @unknown()
291; CHECK-NEXT:    [[VOL:%.*]] = load volatile i32, i32* @G
292; CHECK-NEXT:    [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0
293; CHECK-NEXT:    br i1 [[UNKNOWN]], label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0
294; CHECK:       deopt3:
295; CHECK-NEXT:    call void @unknown()
296; CHECK-NEXT:    [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
297; CHECK-NEXT:    ret i32 [[DEOPTRET3]]
298; CHECK:       guarded2:
299; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
300; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
301; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
302; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
303; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
304; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
305; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N:%.*]]
306; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
307; CHECK:       exit:
308; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
309; CHECK-NEXT:    ret i32 [[RESULT]]
310;
311entry:
312  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
313  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
314  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
315
316deopt:
317  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
318  ret i32 %deoptret
319
320loop.preheader:
321  br label %loop
322
323loop:
324  %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]
325  %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
326  call void @unknown()
327  %vol = load volatile i32, i32* @G
328  %unknown = icmp eq i32 %vol, 0
329  br i1 %unknown, label %guarded2, label %deopt3, !prof !0
330
331deopt3:
332  call void @unknown()
333  %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
334  ret i32 %deoptret3
335
336guarded2:
337  %i.i64 = zext i32 %i to i64
338  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
339  %array.i = load i32, i32* %array.i.ptr, align 4
340  store i32 0, i32* %array.i.ptr
341  %loop.acc.next = add i32 %loop.acc, %array.i
342  %i.next = add nuw i32 %i, 1
343  %continue = icmp ult i32 %i.next, %n
344  br i1 %continue, label %loop, label %exit
345
346exit:
347  %result = phi i32 [ %loop.acc.next, %guarded2 ]
348  ret i32 %result
349}
350
351define i32 @test_unanalyzeable_exit2(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
352; CHECK-LABEL: @test_unanalyzeable_exit2(
353; CHECK-NEXT:  entry:
354; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
355; CHECK-NEXT:    [[TMP0:%.*]] = icmp ugt i32 [[N:%.*]], 1
356; CHECK-NEXT:    [[UMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 1
357; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[UMAX]], -1
358; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[LENGTH:%.*]], [[TMP1]]
359; CHECK-NEXT:    [[UMIN:%.*]] = select i1 [[TMP2]], i32 [[LENGTH]], i32 [[TMP1]]
360; CHECK-NEXT:    [[TMP3:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
361; CHECK-NEXT:    [[TMP4:%.*]] = freeze i1 [[TMP3]]
362; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[COND_0:%.*]]
363; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP5]], [[WIDENABLE_COND]]
364; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
365; CHECK:       deopt:
366; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
367; CHECK-NEXT:    ret i32 [[DEOPTRET]]
368; CHECK:       loop.preheader:
369; CHECK-NEXT:    br label [[LOOP:%.*]]
370; CHECK:       loop:
371; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
372; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]
373; CHECK-NEXT:    call void @unknown()
374; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
375; CHECK-NEXT:    br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof !0
376; CHECK:       deopt2:
377; CHECK-NEXT:    call void @unknown()
378; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
379; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
380; CHECK:       guarded:
381; CHECK-NEXT:    [[VOL:%.*]] = load volatile i32, i32* @G
382; CHECK-NEXT:    [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0
383; CHECK-NEXT:    br i1 [[UNKNOWN]], label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0
384; CHECK:       deopt3:
385; CHECK-NEXT:    call void @unknown()
386; CHECK-NEXT:    [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
387; CHECK-NEXT:    ret i32 [[DEOPTRET3]]
388; CHECK:       guarded2:
389; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
390; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
391; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
392; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
393; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
394; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
395; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
396; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
397; CHECK:       exit:
398; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
399; CHECK-NEXT:    ret i32 [[RESULT]]
400;
401entry:
402  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
403  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
404  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
405
406deopt:
407  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
408  ret i32 %deoptret
409
410loop.preheader:
411  br label %loop
412
413loop:
414  %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]
415  %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
416  call void @unknown()
417  %within.bounds = icmp ult i32 %i, %length
418  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
419
420deopt2:
421  call void @unknown()
422  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
423  ret i32 %deoptret2
424
425guarded:
426  %vol = load volatile i32, i32* @G
427  %unknown = icmp eq i32 %vol, 0
428  br i1 %unknown, label %guarded2, label %deopt3, !prof !0
429
430deopt3:
431  call void @unknown()
432  %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
433  ret i32 %deoptret3
434
435guarded2:
436  %i.i64 = zext i32 %i to i64
437  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
438  %array.i = load i32, i32* %array.i.ptr, align 4
439  store i32 0, i32* %array.i.ptr
440  %loop.acc.next = add i32 %loop.acc, %array.i
441  %i.next = add nuw i32 %i, 1
442  %continue = icmp ult i32 %i.next, %n
443  br i1 %continue, label %loop, label %exit
444
445exit:
446  %result = phi i32 [ %loop.acc.next, %guarded2 ]
447  ret i32 %result
448}
449
450
451define i32 @test_unanalyzeable_latch(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
452; CHECK-LABEL: @test_unanalyzeable_latch(
453; CHECK-NEXT:  entry:
454; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
455; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
456; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
457; CHECK:       deopt:
458; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
459; CHECK-NEXT:    ret i32 [[DEOPTRET]]
460; CHECK:       loop.preheader:
461; CHECK-NEXT:    br label [[LOOP:%.*]]
462; CHECK:       loop:
463; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
464; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
465; CHECK-NEXT:    call void @unknown()
466; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
467; CHECK-NEXT:    br i1 [[WITHIN_BOUNDS]], label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
468; CHECK:       deopt2:
469; CHECK-NEXT:    call void @unknown()
470; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
471; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
472; CHECK:       guarded:
473; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
474; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
475; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
476; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
477; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
478; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
479; CHECK-NEXT:    [[VOL:%.*]] = load volatile i32, i32* @G
480; CHECK-NEXT:    [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0
481; CHECK-NEXT:    br i1 [[UNKNOWN]], label [[LOOP]], label [[EXIT:%.*]]
482; CHECK:       exit:
483; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
484; CHECK-NEXT:    ret i32 [[RESULT]]
485;
486entry:
487  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
488  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
489  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
490
491deopt:
492  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
493  ret i32 %deoptret
494
495loop.preheader:
496  br label %loop
497
498loop:
499  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
500  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
501  call void @unknown()
502  %within.bounds = icmp ult i32 %i, %length
503  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
504
505deopt2:
506  call void @unknown()
507  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
508  ret i32 %deoptret2
509
510guarded:
511  %i.i64 = zext i32 %i to i64
512  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
513  %array.i = load i32, i32* %array.i.ptr, align 4
514  store i32 0, i32* %array.i.ptr
515  %loop.acc.next = add i32 %loop.acc, %array.i
516  %i.next = add nuw i32 %i, 1
517  %vol = load volatile i32, i32* @G
518  %unknown = icmp eq i32 %vol, 0
519  br i1 %unknown, label %loop, label %exit
520
521exit:
522  %result = phi i32 [ %loop.acc.next, %guarded ]
523  ret i32 %result
524}
525
526
527define i32 @provably_taken(i32* %array, i1 %cond_0) {
528; CHECK-LABEL: @provably_taken(
529; CHECK-NEXT:  entry:
530; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
531; CHECK-NEXT:    [[TMP0:%.*]] = freeze i1 false
532; CHECK-NEXT:    [[TMP1:%.*]] = and i1 [[TMP0]], [[COND_0:%.*]]
533; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]]
534; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
535; CHECK:       deopt:
536; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
537; CHECK-NEXT:    ret i32 [[DEOPTRET]]
538; CHECK:       loop.preheader:
539; CHECK-NEXT:    br label [[LOOP:%.*]]
540; CHECK:       loop:
541; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
542; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
543; CHECK-NEXT:    call void @unknown()
544; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], 198
545; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
546; CHECK:       deopt2:
547; CHECK-NEXT:    call void @unknown()
548; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
549; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
550; CHECK:       guarded:
551; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
552; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
553; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
554; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
555; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
556; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
557; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], 200
558; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
559; CHECK:       exit:
560; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
561; CHECK-NEXT:    ret i32 [[RESULT]]
562;
563entry:
564  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
565  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
566  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
567
568deopt:
569  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
570  ret i32 %deoptret
571
572loop.preheader:
573  br label %loop
574
575loop:
576  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
577  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
578  call void @unknown()
579  %within.bounds = icmp ult i32 %i, 198
580  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
581
582deopt2:
583  call void @unknown()
584  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
585  ret i32 %deoptret2
586
587guarded:
588  %i.i64 = zext i32 %i to i64
589  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
590  %array.i = load i32, i32* %array.i.ptr, align 4
591  store i32 0, i32* %array.i.ptr
592  %loop.acc.next = add i32 %loop.acc, %array.i
593  %i.next = add nuw i32 %i, 1
594  %continue = icmp ult i32 %i.next, 200
595  br i1 %continue, label %loop, label %exit
596
597exit:
598  %result = phi i32 [ %loop.acc.next, %guarded ]
599  ret i32 %result
600}
601
602define i32 @provably_not_taken(i32* %array, i1 %cond_0) {
603; CHECK-LABEL: @provably_not_taken(
604; CHECK-NEXT:  entry:
605; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
606; CHECK-NEXT:    [[TMP0:%.*]] = freeze i1 true
607; CHECK-NEXT:    [[TMP1:%.*]] = and i1 [[TMP0]], [[COND_0:%.*]]
608; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]]
609; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
610; CHECK:       deopt:
611; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
612; CHECK-NEXT:    ret i32 [[DEOPTRET]]
613; CHECK:       loop.preheader:
614; CHECK-NEXT:    br label [[LOOP:%.*]]
615; CHECK:       loop:
616; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
617; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
618; CHECK-NEXT:    call void @unknown()
619; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], 205
620; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
621; CHECK:       deopt2:
622; CHECK-NEXT:    call void @unknown()
623; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
624; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
625; CHECK:       guarded:
626; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
627; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
628; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
629; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
630; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
631; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
632; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], 200
633; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
634; CHECK:       exit:
635; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
636; CHECK-NEXT:    ret i32 [[RESULT]]
637;
638entry:
639  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
640  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
641  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
642
643deopt:
644  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
645  ret i32 %deoptret
646
647loop.preheader:
648  br label %loop
649
650loop:
651  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
652  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
653  call void @unknown()
654  %within.bounds = icmp ult i32 %i, 205
655  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
656
657deopt2:
658  call void @unknown()
659  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
660  ret i32 %deoptret2
661
662guarded:
663  %i.i64 = zext i32 %i to i64
664  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
665  %array.i = load i32, i32* %array.i.ptr, align 4
666  store i32 0, i32* %array.i.ptr
667  %loop.acc.next = add i32 %loop.acc, %array.i
668  %i.next = add nuw i32 %i, 1
669  %continue = icmp ult i32 %i.next, 200
670  br i1 %continue, label %loop, label %exit
671
672exit:
673  %result = phi i32 [ %loop.acc.next, %guarded ]
674  ret i32 %result
675}
676
677
678;; Unswitch likes to produce some ugly exit blocks without simplifications
679;; being applied.  Make sure we can handle that form.
680define i32 @unswitch_exit_form(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
681; CHECK-LABEL: @unswitch_exit_form(
682; CHECK-NEXT:  entry:
683; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
684; CHECK-NEXT:    [[TMP0:%.*]] = icmp ugt i32 [[N:%.*]], 1
685; CHECK-NEXT:    [[UMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 1
686; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[UMAX]], -1
687; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[LENGTH:%.*]], [[TMP1]]
688; CHECK-NEXT:    [[UMIN:%.*]] = select i1 [[TMP2]], i32 [[LENGTH]], i32 [[TMP1]]
689; CHECK-NEXT:    [[TMP3:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
690; CHECK-NEXT:    [[TMP4:%.*]] = freeze i1 [[TMP3]]
691; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[COND_0:%.*]]
692; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP5]], [[WIDENABLE_COND]]
693; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
694; CHECK:       deopt.loopexit:
695; CHECK-NEXT:    br label [[DEOPT]]
696; CHECK:       deopt:
697; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[DEOPT_LOOPEXIT:%.*]] ]
698; CHECK-NEXT:    call void @unknown()
699; CHECK-NEXT:    br label [[ACTUAL_DEOPT:%.*]]
700; CHECK:       actual_deopt:
701; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[PHI]]) ]
702; CHECK-NEXT:    ret i32 [[DEOPTRET]]
703; CHECK:       loop.preheader:
704; CHECK-NEXT:    br label [[LOOP:%.*]]
705; CHECK:       loop:
706; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
707; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
708; CHECK-NEXT:    call void @unknown()
709; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
710; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT_LOOPEXIT]], !prof !0
711; CHECK:       guarded:
712; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
713; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
714; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
715; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
716; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
717; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
718; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
719; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
720; CHECK:       exit:
721; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
722; CHECK-NEXT:    ret i32 [[RESULT]]
723;
724entry:
725  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
726  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
727  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
728
729deopt:
730  ;; This is written to look like an unsimplified loop exit after unswitch
731  ;; (i.e. phis, merge, and branch to actual block)
732  %phi = phi i32 [0, %entry], [1, %loop]
733  call void @unknown() ;; it's okay to skip possible throws
734  br label %actual_deopt
735
736actual_deopt:
737  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %phi) ]
738  ret i32 %deoptret
739
740loop.preheader:
741  br label %loop
742
743loop:
744  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
745  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
746  call void @unknown()
747  %within.bounds = icmp ult i32 %i, %length
748  br i1 %within.bounds, label %guarded, label %deopt, !prof !0
749
750guarded:
751  %i.i64 = zext i32 %i to i64
752  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
753  %array.i = load i32, i32* %array.i.ptr, align 4
754  store i32 0, i32* %array.i.ptr
755  %loop.acc.next = add i32 %loop.acc, %array.i
756  %i.next = add nuw i32 %i, 1
757  %continue = icmp ult i32 %i.next, %n
758  br i1 %continue, label %loop, label %exit
759
760exit:
761  %result = phi i32 [ %loop.acc.next, %guarded ]
762  ret i32 %result
763}
764
765define i32 @swapped_wb(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
766; CHECK-LABEL: @swapped_wb(
767; CHECK-NEXT:  entry:
768; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
769; CHECK-NEXT:    [[TMP0:%.*]] = icmp ugt i32 [[N:%.*]], 1
770; CHECK-NEXT:    [[UMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 1
771; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[UMAX]], -1
772; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[LENGTH:%.*]], [[TMP1]]
773; CHECK-NEXT:    [[UMIN:%.*]] = select i1 [[TMP2]], i32 [[LENGTH]], i32 [[TMP1]]
774; CHECK-NEXT:    [[TMP3:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
775; CHECK-NEXT:    [[TMP4:%.*]] = freeze i1 [[TMP3]]
776; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[COND_0:%.*]]
777; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP5]]
778; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
779; CHECK:       deopt:
780; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
781; CHECK-NEXT:    ret i32 [[DEOPTRET]]
782; CHECK:       loop.preheader:
783; CHECK-NEXT:    br label [[LOOP:%.*]]
784; CHECK:       loop:
785; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
786; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
787; CHECK-NEXT:    call void @unknown()
788; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
789; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
790; CHECK:       deopt2:
791; CHECK-NEXT:    call void @unknown()
792; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
793; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
794; CHECK:       guarded:
795; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
796; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
797; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
798; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
799; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
800; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
801; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
802; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
803; CHECK:       exit:
804; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
805; CHECK-NEXT:    ret i32 [[RESULT]]
806;
807entry:
808  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
809  %exiplicit_guard_cond = and i1 %widenable_cond, %cond_0
810  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
811
812deopt:
813  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
814  ret i32 %deoptret
815
816loop.preheader:
817  br label %loop
818
819loop:
820  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
821  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
822  call void @unknown()
823  %within.bounds = icmp ult i32 %i, %length
824  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
825
826deopt2:
827  call void @unknown()
828  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
829  ret i32 %deoptret2
830
831guarded:
832  %i.i64 = zext i32 %i to i64
833  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
834  %array.i = load i32, i32* %array.i.ptr, align 4
835  store i32 0, i32* %array.i.ptr
836  %loop.acc.next = add i32 %loop.acc, %array.i
837  %i.next = add nuw i32 %i, 1
838  %continue = icmp ult i32 %i.next, %n
839  br i1 %continue, label %loop, label %exit
840
841exit:
842  %result = phi i32 [ %loop.acc.next, %guarded ]
843  ret i32 %result
844}
845
846define i32 @trivial_wb(i32* %array, i32 %length, i32 %n) {
847; CHECK-LABEL: @trivial_wb(
848; CHECK-NEXT:  entry:
849; CHECK-NEXT:    [[TMP0:%.*]] = icmp ugt i32 [[N:%.*]], 1
850; CHECK-NEXT:    [[UMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 1
851; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[UMAX]], -1
852; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[LENGTH:%.*]], [[TMP1]]
853; CHECK-NEXT:    [[UMIN:%.*]] = select i1 [[TMP2]], i32 [[LENGTH]], i32 [[TMP1]]
854; CHECK-NEXT:    [[TMP3:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
855; CHECK-NEXT:    [[TMP4:%.*]] = freeze i1 [[TMP3]]
856; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
857; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[WIDENABLE_COND]]
858; CHECK-NEXT:    br i1 [[TMP5]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
859; CHECK:       deopt:
860; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
861; CHECK-NEXT:    ret i32 [[DEOPTRET]]
862; CHECK:       loop.preheader:
863; CHECK-NEXT:    br label [[LOOP:%.*]]
864; CHECK:       loop:
865; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
866; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
867; CHECK-NEXT:    call void @unknown()
868; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
869; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
870; CHECK:       deopt2:
871; CHECK-NEXT:    call void @unknown()
872; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
873; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
874; CHECK:       guarded:
875; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
876; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
877; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
878; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
879; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
880; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
881; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
882; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
883; CHECK:       exit:
884; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
885; CHECK-NEXT:    ret i32 [[RESULT]]
886;
887entry:
888  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
889  br i1 %widenable_cond, label %loop.preheader, label %deopt, !prof !0
890
891deopt:
892  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
893  ret i32 %deoptret
894
895loop.preheader:
896  br label %loop
897
898loop:
899  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
900  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
901  call void @unknown()
902  %within.bounds = icmp ult i32 %i, %length
903  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
904
905deopt2:
906  call void @unknown()
907  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
908  ret i32 %deoptret2
909
910guarded:
911  %i.i64 = zext i32 %i to i64
912  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
913  %array.i = load i32, i32* %array.i.ptr, align 4
914  store i32 0, i32* %array.i.ptr
915  %loop.acc.next = add i32 %loop.acc, %array.i
916  %i.next = add nuw i32 %i, 1
917  %continue = icmp ult i32 %i.next, %n
918  br i1 %continue, label %loop, label %exit
919
920exit:
921  %result = phi i32 [ %loop.acc.next, %guarded ]
922  ret i32 %result
923}
924
925; TODO: Non-latch exits can still be predicated
926; This is currently prevented by an overly restrictive profitability check.
927define i32 @todo_unconditional_latch(i32* %array, i32 %length, i1 %cond_0) {
928; CHECK-LABEL: @todo_unconditional_latch(
929; CHECK-NEXT:  entry:
930; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
931; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
932; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
933; CHECK:       deopt:
934; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
935; CHECK-NEXT:    ret i32 [[DEOPTRET]]
936; CHECK:       loop.preheader:
937; CHECK-NEXT:    br label [[LOOP:%.*]]
938; CHECK:       loop:
939; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
940; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
941; CHECK-NEXT:    call void @unknown()
942; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
943; CHECK-NEXT:    br i1 [[WITHIN_BOUNDS]], label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
944; CHECK:       deopt2:
945; CHECK-NEXT:    call void @unknown()
946; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
947; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
948; CHECK:       guarded:
949; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
950; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
951; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
952; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
953; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
954; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
955; CHECK-NEXT:    br label [[LOOP]]
956;
957entry:
958  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
959  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
960  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
961
962deopt:
963  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
964  ret i32 %deoptret
965
966loop.preheader:
967  br label %loop
968
969loop:
970  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
971  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
972  call void @unknown()
973  %within.bounds = icmp ult i32 %i, %length
974  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
975
976deopt2:
977  call void @unknown()
978  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
979  ret i32 %deoptret2
980
981guarded:
982  %i.i64 = zext i32 %i to i64
983  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
984  %array.i = load i32, i32* %array.i.ptr, align 4
985  store i32 0, i32* %array.i.ptr
986  %loop.acc.next = add i32 %loop.acc, %array.i
987  %i.next = add nuw i32 %i, 1
988  br label %loop
989}
990
991
992; If we have a stray widenable branch in the loop, we should still be able to
993; run.  This can happen when unswitching's cost model avoids unswitching some
994; branches.
995define i32 @wb_in_loop(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
996; CHECK-LABEL: @wb_in_loop(
997; CHECK-NEXT:  entry:
998; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
999; CHECK-NEXT:    [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition()
1000; CHECK-NEXT:    [[TMP0:%.*]] = icmp ugt i32 [[N:%.*]], 1
1001; CHECK-NEXT:    [[UMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 1
1002; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[UMAX]], -1
1003; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[LENGTH:%.*]], [[TMP1]]
1004; CHECK-NEXT:    [[UMIN:%.*]] = select i1 [[TMP2]], i32 [[LENGTH]], i32 [[TMP1]]
1005; CHECK-NEXT:    [[TMP3:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
1006; CHECK-NEXT:    [[TMP4:%.*]] = freeze i1 [[TMP3]]
1007; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[COND_0:%.*]]
1008; CHECK-NEXT:    [[TMP6:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
1009; CHECK-NEXT:    [[TMP7:%.*]] = freeze i1 [[TMP6]]
1010; CHECK-NEXT:    [[TMP8:%.*]] = and i1 [[TMP7]], [[TMP5]]
1011; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP8]], [[WIDENABLE_COND]]
1012; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
1013; CHECK:       deopt:
1014; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1015; CHECK-NEXT:    ret i32 [[DEOPTRET]]
1016; CHECK:       loop.preheader:
1017; CHECK-NEXT:    br label [[LOOP:%.*]]
1018; CHECK:       loop:
1019; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1020; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]
1021; CHECK-NEXT:    call void @unknown()
1022; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
1023; CHECK-NEXT:    br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof !0
1024; CHECK:       deopt2:
1025; CHECK-NEXT:    call void @unknown()
1026; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1027; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
1028; CHECK:       guarded:
1029; CHECK-NEXT:    call void @unknown()
1030; CHECK-NEXT:    [[WITHIN_BOUNDS2:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
1031; CHECK-NEXT:    [[WB_COND:%.*]] = and i1 [[WITHIN_BOUNDS2]], true
1032; CHECK-NEXT:    br i1 true, label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0
1033; CHECK:       deopt3:
1034; CHECK-NEXT:    call void @unknown()
1035; CHECK-NEXT:    [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1036; CHECK-NEXT:    ret i32 [[DEOPTRET3]]
1037; CHECK:       guarded2:
1038; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1039; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1040; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1041; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
1042; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1043; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1044; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1045; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
1046; CHECK:       exit:
1047; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
1048; CHECK-NEXT:    ret i32 [[RESULT]]
1049;
1050entry:
1051  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1052  %wc2 = call i1 @llvm.experimental.widenable.condition()
1053  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
1054  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
1055
1056deopt:
1057  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1058  ret i32 %deoptret
1059
1060loop.preheader:
1061  br label %loop
1062
1063loop:
1064  %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]
1065  %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
1066  call void @unknown()
1067  %within.bounds = icmp ult i32 %i, %length
1068  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
1069
1070deopt2:
1071  call void @unknown()
1072  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1073  ret i32 %deoptret2
1074
1075guarded:
1076  call void @unknown()
1077  %within.bounds2 = icmp ult i32 %i, %length
1078  %wb_cond = and i1 %within.bounds2, %wc2
1079  br i1 %wb_cond, label %guarded2, label %deopt3, !prof !0
1080
1081deopt3:
1082  call void @unknown()
1083  %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1084  ret i32 %deoptret3
1085
1086guarded2:
1087  %i.i64 = zext i32 %i to i64
1088  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1089  %array.i = load i32, i32* %array.i.ptr, align 4
1090  store i32 0, i32* %array.i.ptr
1091  %loop.acc.next = add i32 %loop.acc, %array.i
1092  %i.next = add nuw i32 %i, 1
1093  %continue = icmp ult i32 %i.next, %n
1094  br i1 %continue, label %loop, label %exit
1095
1096exit:
1097  %result = phi i32 [ %loop.acc.next, %guarded2 ]
1098  ret i32 %result
1099}
1100
1101
1102
1103declare void @unknown()
1104
1105declare i1 @llvm.experimental.widenable.condition()
1106declare i32 @llvm.experimental.deoptimize.i32(...)
1107
1108!0 = !{!"branch_weights", i32 1048576, i32 1}
1109!1 = !{i32 1, i32 -2147483648}
1110!2 = !{i32 0, i32 50}
1111