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