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