150
|
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
252
|
2 ; RUN: opt < %s -passes=loop-predication -S | FileCheck %s
|
236
|
3 ; RUN: opt -S -passes='require<scalar-evolution>,loop-mssa(loop-predication)' -verify-memoryssa < %s 2>&1 | FileCheck %s
|
150
|
4
|
|
5 declare void @prevent_merging()
|
|
6
|
|
7 ; Base case - with side effects in loop
|
252
|
8 define i32 @test1(ptr %array, i32 %length, i32 %n, i1 %cond_0) {
|
150
|
9 ; CHECK-LABEL: @test1(
|
|
10 ; CHECK-NEXT: entry:
|
|
11 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
221
|
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]]
|
252
|
19 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]]
|
150
|
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]]
|
252
|
30 ; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof [[PROF0]]
|
150
|
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
|
252
|
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
|
150
|
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 ;
|
|
48 entry:
|
|
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
|
|
53 deopt:
|
|
54 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
55 ret i32 %deoptret
|
|
56
|
|
57 loop.preheader:
|
|
58 br label %loop
|
|
59
|
|
60 loop:
|
|
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
|
|
67 deopt2:
|
|
68 call void @unknown()
|
|
69 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
70 ret i32 %deoptret2
|
|
71
|
|
72 guarded:
|
|
73 %i.i64 = zext i32 %i to i64
|
252
|
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
|
150
|
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
|
|
82 exit:
|
|
83 %result = phi i32 [ %loop.acc.next, %guarded ]
|
|
84 ret i32 %result
|
|
85 }
|
|
86
|
|
87
|
|
88
|
252
|
89 define i32 @test_non_canonical(ptr %array, i32 %length, i1 %cond_0) {
|
150
|
90 ; CHECK-LABEL: @test_non_canonical(
|
|
91 ; CHECK-NEXT: entry:
|
|
92 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
221
|
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]]
|
252
|
100 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
150
|
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]]
|
252
|
111 ; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof [[PROF0]]
|
150
|
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
|
252
|
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
|
150
|
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 ;
|
|
129 entry:
|
|
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
|
|
134 deopt:
|
|
135 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
136 ret i32 %deoptret
|
|
137
|
|
138 loop.preheader:
|
|
139 br label %loop
|
|
140
|
|
141 loop:
|
|
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
|
|
148 deopt2:
|
|
149 call void @unknown()
|
|
150 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
151 ret i32 %deoptret2
|
|
152
|
|
153 guarded:
|
|
154 %i.i64 = zext i32 %i to i64
|
252
|
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
|
150
|
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
|
|
163 exit:
|
|
164 %result = phi i32 [ %loop.acc.next, %guarded ]
|
|
165 ret i32 %result
|
|
166 }
|
|
167
|
|
168
|
252
|
169 define i32 @test_two_range_checks(ptr %array, i32 %length.1, i32 %length.2, i32 %n, i1 %cond_0) {
|
150
|
170 ; CHECK-LABEL: @test_two_range_checks(
|
|
171 ; CHECK-NEXT: entry:
|
|
172 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
221
|
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]]
|
150
|
181 ; CHECK-NEXT: [[TMP5:%.*]] = freeze i1 [[TMP4]]
|
221
|
182 ; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP3]]
|
|
183 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP6]], [[WIDENABLE_COND]]
|
252
|
184 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
150
|
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]]
|
252
|
195 ; CHECK-NEXT: br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
|
150
|
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]]
|
252
|
202 ; CHECK-NEXT: br i1 true, label [[GUARDED2]], label [[DEOPT3:%.*]], !prof [[PROF0]]
|
150
|
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
|
252
|
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
|
150
|
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 ;
|
|
220 entry:
|
|
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
|
|
225 deopt:
|
|
226 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
227 ret i32 %deoptret
|
|
228
|
|
229 loop.preheader:
|
|
230 br label %loop
|
|
231
|
|
232 loop:
|
|
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
|
|
239 deopt2:
|
|
240 call void @unknown()
|
|
241 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
242 ret i32 %deoptret2
|
|
243
|
|
244 guarded:
|
|
245 %within.bounds2 = icmp ult i32 %i, %length.2
|
|
246 br i1 %within.bounds2, label %guarded2, label %deopt3, !prof !0
|
|
247
|
|
248 deopt3:
|
|
249 call void @unknown()
|
|
250 %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
251 ret i32 %deoptret3
|
|
252
|
|
253 guarded2:
|
|
254 %i.i64 = zext i32 %i to i64
|
252
|
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
|
150
|
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
|
|
263 exit:
|
|
264 %result = phi i32 [ %loop.acc.next, %guarded2 ]
|
|
265 ret i32 %result
|
|
266 }
|
|
267
|
|
268 @G = external global i32
|
|
269
|
252
|
270 define i32 @test_unanalyzeable_exit(ptr %array, i32 %length, i32 %n, i1 %cond_0) {
|
150
|
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]]
|
252
|
275 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
150
|
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()
|
252
|
285 ; CHECK-NEXT: [[VOL:%.*]] = load volatile i32, ptr @G, align 4
|
150
|
286 ; CHECK-NEXT: [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0
|
252
|
287 ; CHECK-NEXT: br i1 [[UNKNOWN]], label [[GUARDED2]], label [[DEOPT3:%.*]], !prof [[PROF0]]
|
150
|
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
|
252
|
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
|
150
|
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 ;
|
|
305 entry:
|
|
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
|
|
310 deopt:
|
|
311 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
312 ret i32 %deoptret
|
|
313
|
|
314 loop.preheader:
|
|
315 br label %loop
|
|
316
|
|
317 loop:
|
|
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()
|
252
|
321 %vol = load volatile i32, ptr @G
|
150
|
322 %unknown = icmp eq i32 %vol, 0
|
|
323 br i1 %unknown, label %guarded2, label %deopt3, !prof !0
|
|
324
|
|
325 deopt3:
|
|
326 call void @unknown()
|
|
327 %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
328 ret i32 %deoptret3
|
|
329
|
|
330 guarded2:
|
|
331 %i.i64 = zext i32 %i to i64
|
252
|
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
|
150
|
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
|
|
340 exit:
|
|
341 %result = phi i32 [ %loop.acc.next, %guarded2 ]
|
|
342 ret i32 %result
|
|
343 }
|
|
344
|
252
|
345 define i32 @test_unanalyzeable_exit2(ptr %array, i32 %length, i32 %n, i1 %cond_0) {
|
150
|
346 ; CHECK-LABEL: @test_unanalyzeable_exit2(
|
|
347 ; CHECK-NEXT: entry:
|
|
348 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
221
|
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]]
|
252
|
356 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
150
|
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]]
|
252
|
367 ; CHECK-NEXT: br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
|
150
|
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:
|
252
|
373 ; CHECK-NEXT: [[VOL:%.*]] = load volatile i32, ptr @G, align 4
|
150
|
374 ; CHECK-NEXT: [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0
|
252
|
375 ; CHECK-NEXT: br i1 [[UNKNOWN]], label [[GUARDED2]], label [[DEOPT3:%.*]], !prof [[PROF0]]
|
150
|
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
|
252
|
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
|
150
|
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 ;
|
|
393 entry:
|
|
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
|
|
398 deopt:
|
|
399 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
400 ret i32 %deoptret
|
|
401
|
|
402 loop.preheader:
|
|
403 br label %loop
|
|
404
|
|
405 loop:
|
|
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
|
|
412 deopt2:
|
|
413 call void @unknown()
|
|
414 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
415 ret i32 %deoptret2
|
|
416
|
|
417 guarded:
|
252
|
418 %vol = load volatile i32, ptr @G
|
150
|
419 %unknown = icmp eq i32 %vol, 0
|
|
420 br i1 %unknown, label %guarded2, label %deopt3, !prof !0
|
|
421
|
|
422 deopt3:
|
|
423 call void @unknown()
|
|
424 %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
425 ret i32 %deoptret3
|
|
426
|
|
427 guarded2:
|
|
428 %i.i64 = zext i32 %i to i64
|
252
|
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
|
150
|
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
|
|
437 exit:
|
|
438 %result = phi i32 [ %loop.acc.next, %guarded2 ]
|
|
439 ret i32 %result
|
|
440 }
|
|
441
|
|
442
|
252
|
443 define i32 @test_unanalyzeable_latch(ptr %array, i32 %length, i32 %n, i1 %cond_0) {
|
150
|
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]]
|
252
|
448 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
150
|
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:%.*]]
|
252
|
459 ; CHECK-NEXT: br i1 [[WITHIN_BOUNDS]], label [[GUARDED]], label [[DEOPT2:%.*]], !prof [[PROF0]]
|
150
|
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
|
252
|
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
|
150
|
469 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
470 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
|
252
|
471 ; CHECK-NEXT: [[VOL:%.*]] = load volatile i32, ptr @G, align 4
|
150
|
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 ;
|
|
478 entry:
|
|
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
|
|
483 deopt:
|
|
484 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
485 ret i32 %deoptret
|
|
486
|
|
487 loop.preheader:
|
|
488 br label %loop
|
|
489
|
|
490 loop:
|
|
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
|
|
497 deopt2:
|
|
498 call void @unknown()
|
|
499 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
500 ret i32 %deoptret2
|
|
501
|
|
502 guarded:
|
|
503 %i.i64 = zext i32 %i to i64
|
252
|
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
|
150
|
507 %loop.acc.next = add i32 %loop.acc, %array.i
|
|
508 %i.next = add nuw i32 %i, 1
|
252
|
509 %vol = load volatile i32, ptr @G
|
150
|
510 %unknown = icmp eq i32 %vol, 0
|
|
511 br i1 %unknown, label %loop, label %exit
|
|
512
|
|
513 exit:
|
|
514 %result = phi i32 [ %loop.acc.next, %guarded ]
|
|
515 ret i32 %result
|
|
516 }
|
|
517
|
|
518
|
252
|
519 define i32 @provably_taken(ptr %array, i1 %cond_0) {
|
150
|
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]]
|
252
|
526 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
150
|
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
|
252
|
537 ; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof [[PROF0]]
|
150
|
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
|
252
|
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
|
150
|
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 ;
|
|
555 entry:
|
|
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
|
|
560 deopt:
|
|
561 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
562 ret i32 %deoptret
|
|
563
|
|
564 loop.preheader:
|
|
565 br label %loop
|
|
566
|
|
567 loop:
|
|
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
|
|
574 deopt2:
|
|
575 call void @unknown()
|
|
576 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
577 ret i32 %deoptret2
|
|
578
|
|
579 guarded:
|
|
580 %i.i64 = zext i32 %i to i64
|
252
|
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
|
150
|
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
|
|
589 exit:
|
|
590 %result = phi i32 [ %loop.acc.next, %guarded ]
|
|
591 ret i32 %result
|
|
592 }
|
|
593
|
252
|
594 define i32 @provably_not_taken(ptr %array, i1 %cond_0) {
|
150
|
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]]
|
252
|
601 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
150
|
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
|
252
|
612 ; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof [[PROF0]]
|
150
|
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
|
252
|
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
|
150
|
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 ;
|
|
630 entry:
|
|
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
|
|
635 deopt:
|
|
636 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
637 ret i32 %deoptret
|
|
638
|
|
639 loop.preheader:
|
|
640 br label %loop
|
|
641
|
|
642 loop:
|
|
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
|
|
649 deopt2:
|
|
650 call void @unknown()
|
|
651 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
652 ret i32 %deoptret2
|
|
653
|
|
654 guarded:
|
|
655 %i.i64 = zext i32 %i to i64
|
252
|
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
|
150
|
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
|
|
664 exit:
|
|
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.
|
252
|
672 define i32 @unswitch_exit_form(ptr %array, i32 %length, i32 %n, i1 %cond_0) {
|
150
|
673 ; CHECK-LABEL: @unswitch_exit_form(
|
|
674 ; CHECK-NEXT: entry:
|
|
675 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
221
|
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]]
|
252
|
683 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
150
|
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]]
|
252
|
700 ; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT_LOOPEXIT]], !prof [[PROF0]]
|
150
|
701 ; CHECK: guarded:
|
|
702 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
252
|
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
|
150
|
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 ;
|
|
714 entry:
|
|
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
|
|
719 deopt:
|
|
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
|
|
726 actual_deopt:
|
|
727 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %phi) ]
|
|
728 ret i32 %deoptret
|
|
729
|
|
730 loop.preheader:
|
|
731 br label %loop
|
|
732
|
|
733 loop:
|
|
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
|
|
740 guarded:
|
|
741 %i.i64 = zext i32 %i to i64
|
252
|
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
|
150
|
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
|
|
750 exit:
|
|
751 %result = phi i32 [ %loop.acc.next, %guarded ]
|
|
752 ret i32 %result
|
|
753 }
|
|
754
|
252
|
755 define i32 @swapped_wb(ptr %array, i32 %length, i32 %n, i1 %cond_0) {
|
150
|
756 ; CHECK-LABEL: @swapped_wb(
|
|
757 ; CHECK-NEXT: entry:
|
|
758 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
221
|
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]]
|
252
|
766 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
150
|
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]]
|
252
|
777 ; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof [[PROF0]]
|
150
|
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
|
252
|
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
|
150
|
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 ;
|
|
795 entry:
|
|
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
|
|
800 deopt:
|
|
801 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
802 ret i32 %deoptret
|
|
803
|
|
804 loop.preheader:
|
|
805 br label %loop
|
|
806
|
|
807 loop:
|
|
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
|
|
814 deopt2:
|
|
815 call void @unknown()
|
|
816 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
817 ret i32 %deoptret2
|
|
818
|
|
819 guarded:
|
|
820 %i.i64 = zext i32 %i to i64
|
252
|
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
|
150
|
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
|
|
829 exit:
|
|
830 %result = phi i32 [ %loop.acc.next, %guarded ]
|
|
831 ret i32 %result
|
|
832 }
|
|
833
|
252
|
834 define i32 @trivial_wb(ptr %array, i32 %length, i32 %n) {
|
150
|
835 ; CHECK-LABEL: @trivial_wb(
|
|
836 ; CHECK-NEXT: entry:
|
221
|
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]]
|
150
|
842 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
221
|
843 ; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
|
252
|
844 ; CHECK-NEXT: br i1 [[TMP3]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
150
|
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]]
|
252
|
855 ; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof [[PROF0]]
|
150
|
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
|
252
|
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
|
150
|
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 ;
|
|
873 entry:
|
|
874 %widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
875 br i1 %widenable_cond, label %loop.preheader, label %deopt, !prof !0
|
|
876
|
|
877 deopt:
|
|
878 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
879 ret i32 %deoptret
|
|
880
|
|
881 loop.preheader:
|
|
882 br label %loop
|
|
883
|
|
884 loop:
|
|
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
|
|
891 deopt2:
|
|
892 call void @unknown()
|
|
893 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
894 ret i32 %deoptret2
|
|
895
|
|
896 guarded:
|
|
897 %i.i64 = zext i32 %i to i64
|
252
|
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
|
150
|
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
|
|
906 exit:
|
|
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.
|
252
|
913 define i32 @todo_unconditional_latch(ptr %array, i32 %length, i1 %cond_0) {
|
150
|
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]]
|
252
|
918 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
150
|
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:%.*]]
|
252
|
929 ; CHECK-NEXT: br i1 [[WITHIN_BOUNDS]], label [[GUARDED]], label [[DEOPT2:%.*]], !prof [[PROF0]]
|
150
|
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
|
252
|
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
|
150
|
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 ;
|
|
943 entry:
|
|
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
|
|
948 deopt:
|
|
949 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
950 ret i32 %deoptret
|
|
951
|
|
952 loop.preheader:
|
|
953 br label %loop
|
|
954
|
|
955 loop:
|
|
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
|
|
962 deopt2:
|
|
963 call void @unknown()
|
|
964 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
965 ret i32 %deoptret2
|
|
966
|
|
967 guarded:
|
|
968 %i.i64 = zext i32 %i to i64
|
252
|
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
|
150
|
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.
|
252
|
981 define i32 @wb_in_loop(ptr %array, i32 %length, i32 %n, i1 %cond_0) {
|
150
|
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()
|
221
|
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]]
|
252
|
996 ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
150
|
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]]
|
252
|
1007 ; CHECK-NEXT: br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
|
150
|
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
|
252
|
1016 ; CHECK-NEXT: br i1 true, label [[GUARDED2]], label [[DEOPT3:%.*]], !prof [[PROF0]]
|
150
|
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
|
252
|
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
|
150
|
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 ;
|
|
1034 entry:
|
|
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
|
|
1040 deopt:
|
|
1041 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
1042 ret i32 %deoptret
|
|
1043
|
|
1044 loop.preheader:
|
|
1045 br label %loop
|
|
1046
|
|
1047 loop:
|
|
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
|
|
1054 deopt2:
|
|
1055 call void @unknown()
|
|
1056 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
1057 ret i32 %deoptret2
|
|
1058
|
|
1059 guarded:
|
|
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
|
|
1065 deopt3:
|
|
1066 call void @unknown()
|
|
1067 %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
|
|
1068 ret i32 %deoptret3
|
|
1069
|
|
1070 guarded2:
|
|
1071 %i.i64 = zext i32 %i to i64
|
252
|
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
|
150
|
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
|
|
1080 exit:
|
|
1081 %result = phi i32 [ %loop.acc.next, %guarded2 ]
|
|
1082 ret i32 %result
|
|
1083 }
|
|
1084
|
236
|
1085 define void @test_memssa() {
|
252
|
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 ;
|
236
|
1107 bb:
|
|
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
|
|
1112 bb2: ; preds = %bb
|
|
1113 unreachable
|
|
1114
|
|
1115 bb3: ; preds = %bb
|
|
1116 br label %bb4
|
|
1117
|
|
1118 bb4: ; preds = %bb6, %bb3
|
|
1119 %tmp5 = phi i32 [ %tmp7, %bb6 ], [ 0, %bb3 ]
|
|
1120 br i1 undef, label %bb10, label %bb6
|
|
1121
|
|
1122 bb6: ; 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
|
|
1127 bb9: ; preds = %bb6
|
|
1128 ret void
|
|
1129
|
|
1130 bb10: ; preds = %bb4
|
|
1131 ret void
|
|
1132 }
|
|
1133
|
150
|
1134
|
|
1135
|
|
1136 declare void @unknown()
|
|
1137
|
|
1138 declare i1 @llvm.experimental.widenable.condition()
|
|
1139 declare 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}
|