[AArch64][NFC] NFC for const vector as Instruction operand (#116790)
[llvm-project.git] / llvm / test / Transforms / LICM / hoist-mustexec.ll
bloba6f5a2be05ee41087b129fa5ba419cc28e8b01c1
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2 ; REQUIRES: asserts
3 ; RUN: opt -S -passes=licm -ipt-expensive-asserts=true < %s | FileCheck %s
5 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
7 declare void @f() nounwind
8 declare void @llvm.experimental.guard(i1,...)
10 ; constant fold on first ieration
11 define i32 @test1(ptr noalias nocapture readonly %a) nounwind uwtable {
12 ; CHECK-LABEL: define i32 @test1(
13 ; CHECK-SAME: ptr noalias nocapture readonly [[A:%.*]]) #[[ATTR1:[0-9]+]] {
14 ; CHECK-NEXT:  entry:
15 ; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[A]], align 4
16 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
17 ; CHECK:       for.body:
18 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[CONTINUE:%.*]] ]
19 ; CHECK-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[CONTINUE]] ]
20 ; CHECK-NEXT:    [[R_CHK:%.*]] = icmp ult i32 [[IV]], 2000
21 ; CHECK-NEXT:    br i1 [[R_CHK]], label [[CONTINUE]], label [[FAIL:%.*]]
22 ; CHECK:       continue:
23 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[I1]], [[ACC]]
24 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[IV]], 1
25 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1000
26 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
27 ; CHECK:       for.cond.cleanup:
28 ; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[CONTINUE]] ]
29 ; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]
30 ; CHECK:       fail:
31 ; CHECK-NEXT:    call void @f()
32 ; CHECK-NEXT:    ret i32 -1
34 entry:
35   br label %for.body
37 for.body:
38   %iv = phi i32 [ 0, %entry ], [ %inc, %continue ]
39   %acc = phi i32 [ 0, %entry ], [ %add, %continue ]
40   %r.chk = icmp ult i32 %iv, 2000
41   br i1 %r.chk, label %continue, label %fail
42 continue:
43   %i1 = load i32, ptr %a, align 4
44   %add = add nsw i32 %i1, %acc
45   %inc = add nuw nsw i32 %iv, 1
46   %exitcond = icmp eq i32 %inc, 1000
47   br i1 %exitcond, label %for.cond.cleanup, label %for.body
49 for.cond.cleanup:
50   ret i32 %add
52 fail:
53   call void @f()
54   ret i32 -1
57 ; Same as test1, but with a floating point IR and fcmp
58 define i32 @test_fcmp(ptr noalias nocapture readonly %a) nounwind uwtable {
59 ; CHECK-LABEL: define i32 @test_fcmp(
60 ; CHECK-SAME: ptr noalias nocapture readonly [[A:%.*]]) #[[ATTR1]] {
61 ; CHECK-NEXT:  entry:
62 ; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[A]], align 4
63 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
64 ; CHECK:       for.body:
65 ; CHECK-NEXT:    [[IV:%.*]] = phi float [ 0.000000e+00, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[CONTINUE:%.*]] ]
66 ; CHECK-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[CONTINUE]] ]
67 ; CHECK-NEXT:    [[R_CHK:%.*]] = fcmp olt float [[IV]], 2.000000e+03
68 ; CHECK-NEXT:    br i1 [[R_CHK]], label [[CONTINUE]], label [[FAIL:%.*]]
69 ; CHECK:       continue:
70 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[I1]], [[ACC]]
71 ; CHECK-NEXT:    [[INC]] = fadd float [[IV]], 1.000000e+00
72 ; CHECK-NEXT:    [[EXITCOND:%.*]] = fcmp ogt float [[INC]], 1.000000e+03
73 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
74 ; CHECK:       for.cond.cleanup:
75 ; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[CONTINUE]] ]
76 ; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]
77 ; CHECK:       fail:
78 ; CHECK-NEXT:    call void @f()
79 ; CHECK-NEXT:    ret i32 -1
81 entry:
82   br label %for.body
84 for.body:
85   %iv = phi float [ 0.0, %entry ], [ %inc, %continue ]
86   %acc = phi i32 [ 0, %entry ], [ %add, %continue ]
87   %r.chk = fcmp olt float %iv, 2000.0
88   br i1 %r.chk, label %continue, label %fail
89 continue:
90   %i1 = load i32, ptr %a, align 4
91   %add = add nsw i32 %i1, %acc
92   %inc = fadd float %iv, 1.0
93   %exitcond = fcmp ogt float %inc, 1000.0
94   br i1 %exitcond, label %for.cond.cleanup, label %for.body
96 for.cond.cleanup:
97   ret i32 %add
99 fail:
100   call void @f()
101   ret i32 -1
104 ; Count down from a.length w/entry guard
105 ; TODO: currently unable to prove the following:
106 ; ule i32 (add nsw i32 %len, -1), %len where len is [0, 512]
107 define i32 @test2(ptr noalias nocapture readonly %a) nounwind uwtable {
108 ; CHECK-LABEL: define i32 @test2(
109 ; CHECK-SAME: ptr noalias nocapture readonly [[A:%.*]]) #[[ATTR1]] {
110 ; CHECK-NEXT:  entry:
111 ; CHECK-NEXT:    [[LEN:%.*]] = load i32, ptr [[A]], align 4, !range [[RNG0:![0-9]+]]
112 ; CHECK-NEXT:    [[IS_NON_POS:%.*]] = icmp eq i32 [[LEN]], 0
113 ; CHECK-NEXT:    br i1 [[IS_NON_POS]], label [[FAIL:%.*]], label [[PREHEADER:%.*]]
114 ; CHECK:       preheader:
115 ; CHECK-NEXT:    [[LENMINUSONE:%.*]] = add nsw i32 [[LEN]], -1
116 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
117 ; CHECK:       for.body:
118 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[LENMINUSONE]], [[PREHEADER]] ], [ [[DEC:%.*]], [[CONTINUE:%.*]] ]
119 ; CHECK-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[PREHEADER]] ], [ [[ADD:%.*]], [[CONTINUE]] ]
120 ; CHECK-NEXT:    [[R_CHK:%.*]] = icmp ule i32 [[IV]], [[LEN]]
121 ; CHECK-NEXT:    br i1 [[R_CHK]], label [[CONTINUE]], label [[FAIL_LOOPEXIT:%.*]]
122 ; CHECK:       continue:
123 ; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[A]], align 4
124 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[I1]], [[ACC]]
125 ; CHECK-NEXT:    [[DEC]] = add nsw i32 [[IV]], -1
126 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[DEC]], 0
127 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
128 ; CHECK:       for.cond.cleanup:
129 ; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[CONTINUE]] ]
130 ; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]
131 ; CHECK:       fail.loopexit:
132 ; CHECK-NEXT:    br label [[FAIL]]
133 ; CHECK:       fail:
134 ; CHECK-NEXT:    call void @f()
135 ; CHECK-NEXT:    ret i32 -1
137 entry:
138   %len = load i32, ptr %a, align 4, !range !{i32 0, i32 512}
139   %is.non.pos = icmp eq i32 %len, 0
140   br i1 %is.non.pos, label %fail, label %preheader
141 preheader:
142   %lenminusone = add nsw i32 %len, -1
143   br label %for.body
144 for.body:
145   %iv = phi i32 [ %lenminusone, %preheader ], [ %dec, %continue ]
146   %acc = phi i32 [ 0, %preheader ], [ %add, %continue ]
147   %r.chk = icmp ule i32 %iv, %len
148   br i1 %r.chk, label %continue, label %fail
149 continue:
150   %i1 = load i32, ptr %a, align 4
151   %add = add nsw i32 %i1, %acc
152   %dec = add nsw i32 %iv, -1
153   %exitcond = icmp eq i32 %dec, 0
154   br i1 %exitcond, label %for.cond.cleanup, label %for.body
156 for.cond.cleanup:
157   ret i32 %add
159 fail:
160   call void @f()
161   ret i32 -1
164 ; trivially true for zero
165 define i32 @test3(ptr noalias nocapture readonly %a) nounwind uwtable {
166 ; CHECK-LABEL: define i32 @test3(
167 ; CHECK-SAME: ptr noalias nocapture readonly [[A:%.*]]) #[[ATTR1]] {
168 ; CHECK-NEXT:  entry:
169 ; CHECK-NEXT:    [[LEN:%.*]] = load i32, ptr [[A]], align 4, !range [[RNG0]]
170 ; CHECK-NEXT:    [[IS_ZERO:%.*]] = icmp eq i32 [[LEN]], 0
171 ; CHECK-NEXT:    br i1 [[IS_ZERO]], label [[FAIL:%.*]], label [[PREHEADER:%.*]]
172 ; CHECK:       preheader:
173 ; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[A]], align 4
174 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
175 ; CHECK:       for.body:
176 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[PREHEADER]] ], [ [[INC:%.*]], [[CONTINUE:%.*]] ]
177 ; CHECK-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[PREHEADER]] ], [ [[ADD:%.*]], [[CONTINUE]] ]
178 ; CHECK-NEXT:    [[R_CHK:%.*]] = icmp ule i32 [[IV]], [[LEN]]
179 ; CHECK-NEXT:    br i1 [[R_CHK]], label [[CONTINUE]], label [[FAIL_LOOPEXIT:%.*]]
180 ; CHECK:       continue:
181 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[I1]], [[ACC]]
182 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[IV]], 1
183 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1000
184 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
185 ; CHECK:       for.cond.cleanup:
186 ; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[CONTINUE]] ]
187 ; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]
188 ; CHECK:       fail.loopexit:
189 ; CHECK-NEXT:    br label [[FAIL]]
190 ; CHECK:       fail:
191 ; CHECK-NEXT:    call void @f()
192 ; CHECK-NEXT:    ret i32 -1
194 entry:
195   %len = load i32, ptr %a, align 4, !range !{i32 0, i32 512}
196   %is.zero = icmp eq i32 %len, 0
197   br i1 %is.zero, label %fail, label %preheader
198 preheader:
199   br label %for.body
200 for.body:
201   %iv = phi i32 [ 0, %preheader ], [ %inc, %continue ]
202   %acc = phi i32 [ 0, %preheader ], [ %add, %continue ]
203   %r.chk = icmp ule i32 %iv, %len
204   br i1 %r.chk, label %continue, label %fail
205 continue:
206   %i1 = load i32, ptr %a, align 4
207   %add = add nsw i32 %i1, %acc
208   %inc = add nuw nsw i32 %iv, 1
209   %exitcond = icmp eq i32 %inc, 1000
210   br i1 %exitcond, label %for.cond.cleanup, label %for.body
212 for.cond.cleanup:
213   ret i32 %add
215 fail:
216   call void @f()
217   ret i32 -1
220 ; Same as previous case, with commuted icmp.
221 define i32 @test3_commuted(ptr noalias nocapture readonly %a) nounwind uwtable {
222 ; CHECK-LABEL: define i32 @test3_commuted(
223 ; CHECK-SAME: ptr noalias nocapture readonly [[A:%.*]]) #[[ATTR1]] {
224 ; CHECK-NEXT:  entry:
225 ; CHECK-NEXT:    [[LEN:%.*]] = load i32, ptr [[A]], align 4, !range [[RNG0]]
226 ; CHECK-NEXT:    [[IS_ZERO:%.*]] = icmp eq i32 [[LEN]], 0
227 ; CHECK-NEXT:    br i1 [[IS_ZERO]], label [[FAIL:%.*]], label [[PREHEADER:%.*]]
228 ; CHECK:       preheader:
229 ; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[A]], align 4
230 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
231 ; CHECK:       for.body:
232 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[PREHEADER]] ], [ [[INC:%.*]], [[CONTINUE:%.*]] ]
233 ; CHECK-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[PREHEADER]] ], [ [[ADD:%.*]], [[CONTINUE]] ]
234 ; CHECK-NEXT:    [[R_CHK:%.*]] = icmp uge i32 [[LEN]], [[IV]]
235 ; CHECK-NEXT:    br i1 [[R_CHK]], label [[CONTINUE]], label [[FAIL_LOOPEXIT:%.*]]
236 ; CHECK:       continue:
237 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[I1]], [[ACC]]
238 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[IV]], 1
239 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1000
240 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
241 ; CHECK:       for.cond.cleanup:
242 ; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[CONTINUE]] ]
243 ; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]
244 ; CHECK:       fail.loopexit:
245 ; CHECK-NEXT:    br label [[FAIL]]
246 ; CHECK:       fail:
247 ; CHECK-NEXT:    call void @f()
248 ; CHECK-NEXT:    ret i32 -1
250 entry:
251   %len = load i32, ptr %a, align 4, !range !{i32 0, i32 512}
252   %is.zero = icmp eq i32 %len, 0
253   br i1 %is.zero, label %fail, label %preheader
254 preheader:
255   br label %for.body
256 for.body:
257   %iv = phi i32 [ 0, %preheader ], [ %inc, %continue ]
258   %acc = phi i32 [ 0, %preheader ], [ %add, %continue ]
259   %r.chk = icmp uge i32 %len, %iv
260   br i1 %r.chk, label %continue, label %fail
261 continue:
262   %i1 = load i32, ptr %a, align 4
263   %add = add nsw i32 %i1, %acc
264   %inc = add nuw nsw i32 %iv, 1
265   %exitcond = icmp eq i32 %inc, 1000
266   br i1 %exitcond, label %for.cond.cleanup, label %for.body
268 for.cond.cleanup:
269   ret i32 %add
271 fail:
272   call void @f()
273   ret i32 -1
276 ; requires fact length is non-zero
277 define i32 @test4(ptr noalias nocapture readonly %a) nounwind uwtable {
278 ; CHECK-LABEL: define i32 @test4(
279 ; CHECK-SAME: ptr noalias nocapture readonly [[A:%.*]]) #[[ATTR1]] {
280 ; CHECK-NEXT:  entry:
281 ; CHECK-NEXT:    [[LEN:%.*]] = load i32, ptr [[A]], align 4, !range [[RNG0]]
282 ; CHECK-NEXT:    [[IS_ZERO:%.*]] = icmp eq i32 [[LEN]], 0
283 ; CHECK-NEXT:    br i1 [[IS_ZERO]], label [[FAIL:%.*]], label [[PREHEADER:%.*]]
284 ; CHECK:       preheader:
285 ; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[A]], align 4
286 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
287 ; CHECK:       for.body:
288 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[PREHEADER]] ], [ [[INC:%.*]], [[CONTINUE:%.*]] ]
289 ; CHECK-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[PREHEADER]] ], [ [[ADD:%.*]], [[CONTINUE]] ]
290 ; CHECK-NEXT:    [[R_CHK:%.*]] = icmp ult i32 [[IV]], [[LEN]]
291 ; CHECK-NEXT:    br i1 [[R_CHK]], label [[CONTINUE]], label [[FAIL_LOOPEXIT:%.*]]
292 ; CHECK:       continue:
293 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[I1]], [[ACC]]
294 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[IV]], 1
295 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1000
296 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
297 ; CHECK:       for.cond.cleanup:
298 ; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[CONTINUE]] ]
299 ; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]
300 ; CHECK:       fail.loopexit:
301 ; CHECK-NEXT:    br label [[FAIL]]
302 ; CHECK:       fail:
303 ; CHECK-NEXT:    call void @f()
304 ; CHECK-NEXT:    ret i32 -1
306 entry:
307   %len = load i32, ptr %a, align 4, !range !{i32 0, i32 512}
308   %is.zero = icmp eq i32 %len, 0
309   br i1 %is.zero, label %fail, label %preheader
310 preheader:
311   br label %for.body
312 for.body:
313   %iv = phi i32 [ 0, %preheader ], [ %inc, %continue ]
314   %acc = phi i32 [ 0, %preheader ], [ %add, %continue ]
315   %r.chk = icmp ult i32 %iv, %len
316   br i1 %r.chk, label %continue, label %fail
317 continue:
318   %i1 = load i32, ptr %a, align 4
319   %add = add nsw i32 %i1, %acc
320   %inc = add nuw nsw i32 %iv, 1
321   %exitcond = icmp eq i32 %inc, 1000
322   br i1 %exitcond, label %for.cond.cleanup, label %for.body
324 for.cond.cleanup:
325   ret i32 %add
327 fail:
328   call void @f()
329   ret i32 -1
332 ; variation on test1 with branch swapped
333 define i32 @test-brswap(ptr noalias nocapture readonly %a) nounwind uwtable {
334 ; CHECK-LABEL: define i32 @test-brswap(
335 ; CHECK-SAME: ptr noalias nocapture readonly [[A:%.*]]) #[[ATTR1]] {
336 ; CHECK-NEXT:  entry:
337 ; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[A]], align 4
338 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
339 ; CHECK:       for.body:
340 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[CONTINUE:%.*]] ]
341 ; CHECK-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[CONTINUE]] ]
342 ; CHECK-NEXT:    [[R_CHK:%.*]] = icmp ugt i32 [[IV]], 2000
343 ; CHECK-NEXT:    br i1 [[R_CHK]], label [[FAIL:%.*]], label [[CONTINUE]]
344 ; CHECK:       continue:
345 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[I1]], [[ACC]]
346 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[IV]], 1
347 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1000
348 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
349 ; CHECK:       for.cond.cleanup:
350 ; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[CONTINUE]] ]
351 ; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]
352 ; CHECK:       fail:
353 ; CHECK-NEXT:    call void @f()
354 ; CHECK-NEXT:    ret i32 -1
356 entry:
357   br label %for.body
359 for.body:
360   %iv = phi i32 [ 0, %entry ], [ %inc, %continue ]
361   %acc = phi i32 [ 0, %entry ], [ %add, %continue ]
362   %r.chk = icmp ugt i32 %iv, 2000
363   br i1 %r.chk, label %fail, label %continue
364 continue:
365   %i1 = load i32, ptr %a, align 4
366   %add = add nsw i32 %i1, %acc
367   %inc = add nuw nsw i32 %iv, 1
368   %exitcond = icmp eq i32 %inc, 1000
369   br i1 %exitcond, label %for.cond.cleanup, label %for.body
371 for.cond.cleanup:
372   ret i32 %add
374 fail:
375   call void @f()
376   ret i32 -1
379 define i32 @test-nonphi(ptr noalias nocapture readonly %a) nounwind uwtable {
380 ; CHECK-LABEL: define i32 @test-nonphi(
381 ; CHECK-SAME: ptr noalias nocapture readonly [[A:%.*]]) #[[ATTR1]] {
382 ; CHECK-NEXT:  entry:
383 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
384 ; CHECK:       for.body:
385 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[CONTINUE:%.*]] ]
386 ; CHECK-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[CONTINUE]] ]
387 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[IV]], 72
388 ; CHECK-NEXT:    [[R_CHK:%.*]] = icmp ugt i32 [[XOR]], 2000
389 ; CHECK-NEXT:    br i1 [[R_CHK]], label [[FAIL:%.*]], label [[CONTINUE]]
390 ; CHECK:       continue:
391 ; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[A]], align 4
392 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[I1]], [[ACC]]
393 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[IV]], 1
394 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1000
395 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
396 ; CHECK:       for.cond.cleanup:
397 ; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[CONTINUE]] ]
398 ; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]
399 ; CHECK:       fail:
400 ; CHECK-NEXT:    call void @f()
401 ; CHECK-NEXT:    ret i32 -1
403 entry:
404   br label %for.body
406 for.body:
407   %iv = phi i32 [ 0, %entry ], [ %inc, %continue ]
408   %acc = phi i32 [ 0, %entry ], [ %add, %continue ]
409   %xor = xor i32 %iv, 72
410   %r.chk = icmp ugt i32 %xor, 2000
411   br i1 %r.chk, label %fail, label %continue
412 continue:
413   %i1 = load i32, ptr %a, align 4
414   %add = add nsw i32 %i1, %acc
415   %inc = add nuw nsw i32 %iv, 1
416   %exitcond = icmp eq i32 %inc, 1000
417   br i1 %exitcond, label %for.cond.cleanup, label %for.body
419 for.cond.cleanup:
420   ret i32 %add
422 fail:
423   call void @f()
424   ret i32 -1
427 define i32 @test-wrongphi(ptr noalias nocapture readonly %a) nounwind uwtable {
428 ; CHECK-LABEL: define i32 @test-wrongphi(
429 ; CHECK-SAME: ptr noalias nocapture readonly [[A:%.*]]) #[[ATTR1]] {
430 ; CHECK-NEXT:  entry:
431 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
432 ; CHECK:       for.body:
433 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[CONTINUE:%.*]] ]
434 ; CHECK-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[CONTINUE]] ]
435 ; CHECK-NEXT:    [[COND:%.*]] = icmp ult i32 [[IV]], 500
436 ; CHECK-NEXT:    br i1 [[COND]], label [[DUMMY_BLOCK1:%.*]], label [[DUMMY_BLOCK2:%.*]]
437 ; CHECK:       dummy_block1:
438 ; CHECK-NEXT:    br label [[DUMMY_BLOCK2]]
439 ; CHECK:       dummy_block2:
440 ; CHECK-NEXT:    [[WRONGPHI:%.*]] = phi i32 [ 11, [[FOR_BODY]] ], [ 12, [[DUMMY_BLOCK1]] ]
441 ; CHECK-NEXT:    [[R_CHK:%.*]] = icmp ugt i32 [[WRONGPHI]], 2000
442 ; CHECK-NEXT:    br i1 [[R_CHK]], label [[FAIL:%.*]], label [[CONTINUE]]
443 ; CHECK:       continue:
444 ; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[A]], align 4
445 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[I1]], [[ACC]]
446 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[IV]], 1
447 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1000
448 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
449 ; CHECK:       for.cond.cleanup:
450 ; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[CONTINUE]] ]
451 ; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]
452 ; CHECK:       fail:
453 ; CHECK-NEXT:    call void @f()
454 ; CHECK-NEXT:    ret i32 -1
456 entry:
457   br label %for.body
459 for.body:
460   %iv = phi i32 [ 0, %entry ], [ %inc, %continue ]
461   %acc = phi i32 [ 0, %entry ], [ %add, %continue ]
462   %cond = icmp ult i32 %iv, 500
463   br i1 %cond, label %dummy_block1, label %dummy_block2
465 dummy_block1:
466   br label %dummy_block2
468 dummy_block2:
469   %wrongphi = phi i32 [11, %for.body], [12, %dummy_block1]
470   %r.chk = icmp ugt i32 %wrongphi, 2000
471   br i1 %r.chk, label %fail, label %continue
472 continue:
473   %i1 = load i32, ptr %a, align 4
474   %add = add nsw i32 %i1, %acc
475   %inc = add nuw nsw i32 %iv, 1
476   %exitcond = icmp eq i32 %inc, 1000
477   br i1 %exitcond, label %for.cond.cleanup, label %for.body
479 for.cond.cleanup:
480   ret i32 %add
482 fail:
483   call void @f()
484   ret i32 -1
487 ; This works because loop-simplify is run implicitly, but test for it anyways
488 define i32 @test-multiple-latch(ptr noalias nocapture readonly %a) nounwind uwtable {
489 ; CHECK-LABEL: define i32 @test-multiple-latch(
490 ; CHECK-SAME: ptr noalias nocapture readonly [[A:%.*]]) #[[ATTR1]] {
491 ; CHECK-NEXT:  entry:
492 ; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[A]], align 4
493 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
494 ; CHECK:       for.body:
495 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY_BACKEDGE:%.*]] ]
496 ; CHECK-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY_BACKEDGE]] ]
497 ; CHECK-NEXT:    [[R_CHK:%.*]] = icmp ult i32 [[IV]], 2000
498 ; CHECK-NEXT:    br i1 [[R_CHK]], label [[CONTINUE1:%.*]], label [[FAIL:%.*]]
499 ; CHECK:       continue1:
500 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[I1]], [[ACC]]
501 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[IV]], 1
502 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[ADD]], 0
503 ; CHECK-NEXT:    br i1 [[CMP]], label [[CONTINUE2:%.*]], label [[FOR_BODY_BACKEDGE]]
504 ; CHECK:       for.body.backedge:
505 ; CHECK-NEXT:    br label [[FOR_BODY]]
506 ; CHECK:       continue2:
507 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1000
508 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY_BACKEDGE]]
509 ; CHECK:       for.cond.cleanup:
510 ; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[CONTINUE2]] ]
511 ; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]
512 ; CHECK:       fail:
513 ; CHECK-NEXT:    call void @f()
514 ; CHECK-NEXT:    ret i32 -1
516 entry:
517   br label %for.body
519 for.body:
520   %iv = phi i32 [ 0, %entry ], [ %inc, %continue1 ], [ %inc, %continue2 ]
521   %acc = phi i32 [ 0, %entry ], [ %add, %continue1 ], [ %add, %continue2 ]
522   %r.chk = icmp ult i32 %iv, 2000
523   br i1 %r.chk, label %continue1, label %fail
524 continue1:
525   %i1 = load i32, ptr %a, align 4
526   %add = add nsw i32 %i1, %acc
527   %inc = add nuw nsw i32 %iv, 1
528   %cmp = icmp eq i32 %add, 0
529   br i1 %cmp, label %continue2, label %for.body
530 continue2:
531   %exitcond = icmp eq i32 %inc, 1000
532   br i1 %exitcond, label %for.cond.cleanup, label %for.body
534 for.cond.cleanup:
535   ret i32 %add
537 fail:
538   call void @f()
539   ret i32 -1
542 define void @test-hoisting-in-presence-of-guards(i1 %c, ptr %p) {
543 ; CHECK-LABEL: define void @test-hoisting-in-presence-of-guards(
544 ; CHECK-SAME: i1 [[C:%.*]], ptr [[P:%.*]]) {
545 ; CHECK-NEXT:  entry:
546 ; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[P]], align 4
547 ; CHECK-NEXT:    [[INVARIANT_COND:%.*]] = icmp ne i32 [[A]], 100
548 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[INVARIANT_COND]]) [ "deopt"() ]
549 ; CHECK-NEXT:    br label [[LOOP:%.*]]
550 ; CHECK:       loop:
551 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
552 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
553 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000
554 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
555 ; CHECK:       exit:
556 ; CHECK-NEXT:    ret void
559 entry:
560   br label %loop
562 loop:
563   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
564   %iv.next = add i32 %iv, 1
565   %a = load i32, ptr %p
566   %invariant_cond = icmp ne i32 %a, 100
567   call void (i1, ...) @llvm.experimental.guard(i1 %invariant_cond) [ "deopt"() ]
568   %loop_cond = icmp slt i32 %iv.next, 1000
569   br i1 %loop_cond, label %loop, label %exit
571 exit:
572   ret void
576 declare void @may_throw() inaccessiblememonly
578 ; Test that we can sink a mustexecute load from loop header even in presence of
579 ; throwing instructions after it.
580 define void @test_hoist_from_header_01(ptr %p, i32 %n) {
581 ; CHECK-LABEL: define void @test_hoist_from_header_01(
582 ; CHECK-SAME: ptr [[P:%.*]], i32 [[N:%.*]]) {
583 ; CHECK-NEXT:  entry:
584 ; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[P]], align 4
585 ; CHECK-NEXT:    br label [[LOOP:%.*]]
586 ; CHECK:       loop:
587 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
588 ; CHECK-NEXT:    call void @may_throw()
589 ; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[IV]], [[N]]
590 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
591 ; CHECK:       if.true:
592 ; CHECK-NEXT:    [[A:%.*]] = add i32 [[IV]], [[IV]]
593 ; CHECK-NEXT:    br label [[BACKEDGE]]
594 ; CHECK:       if.false:
595 ; CHECK-NEXT:    [[B:%.*]] = mul i32 [[IV]], [[IV]]
596 ; CHECK-NEXT:    br label [[BACKEDGE]]
597 ; CHECK:       backedge:
598 ; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ [[A]], [[IF_TRUE]] ], [ [[B]], [[IF_FALSE]] ]
599 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[MERGE]]
600 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[LOAD]]
601 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
602 ; CHECK:       exit:
603 ; CHECK-NEXT:    ret void
606 entry:
607   br label %loop
609 loop:
610   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
611   %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]
612   %load = load i32, ptr %p
613   call void @may_throw()
614   %cond = icmp slt i32 %iv, %n
615   br i1 %cond, label %if.true, label %if.false
617 if.true:
618   %a = add i32 %iv, %iv
619   br label %backedge
621 if.false:
622   %b = mul i32 %iv, %iv
623   br label %backedge
625 backedge:
626   %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]
627   %iv.next = add i32 %iv, %merge
628   %loop.cond = icmp ult i32 %iv.next, %load
629   br i1 %loop.cond, label %loop, label %exit
631 exit:
632   ret void
635 define void @test_hoist_from_header_02(ptr %p, i32 %n) {
636 ; CHECK-LABEL: define void @test_hoist_from_header_02(
637 ; CHECK-SAME: ptr [[P:%.*]], i32 [[N:%.*]]) {
638 ; CHECK-NEXT:  entry:
639 ; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[P]], align 4
640 ; CHECK-NEXT:    br label [[LOOP:%.*]]
641 ; CHECK:       loop:
642 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
643 ; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[IV]], [[N]]
644 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
645 ; CHECK:       if.true:
646 ; CHECK-NEXT:    call void @may_throw()
647 ; CHECK-NEXT:    [[A:%.*]] = add i32 [[IV]], [[IV]]
648 ; CHECK-NEXT:    br label [[BACKEDGE]]
649 ; CHECK:       if.false:
650 ; CHECK-NEXT:    [[B:%.*]] = mul i32 [[IV]], [[IV]]
651 ; CHECK-NEXT:    br label [[BACKEDGE]]
652 ; CHECK:       backedge:
653 ; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ [[A]], [[IF_TRUE]] ], [ [[B]], [[IF_FALSE]] ]
654 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[MERGE]]
655 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[LOAD]]
656 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
657 ; CHECK:       exit:
658 ; CHECK-NEXT:    ret void
661 entry:
662   br label %loop
664 loop:
665   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
666   %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]
667   %load = load i32, ptr %p
668   %cond = icmp slt i32 %iv, %n
669   br i1 %cond, label %if.true, label %if.false
671 if.true:
672   call void @may_throw()
673   %a = add i32 %iv, %iv
674   br label %backedge
676 if.false:
677   %b = mul i32 %iv, %iv
678   br label %backedge
680 backedge:
681   %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]
682   %iv.next = add i32 %iv, %merge
683   %loop.cond = icmp ult i32 %iv.next, %load
684   br i1 %loop.cond, label %loop, label %exit
686 exit:
687   ret void
690 define void @test_hoist_from_header_03(ptr %p, i32 %n) {
691 ; CHECK-LABEL: define void @test_hoist_from_header_03(
692 ; CHECK-SAME: ptr [[P:%.*]], i32 [[N:%.*]]) {
693 ; CHECK-NEXT:  entry:
694 ; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[P]], align 4
695 ; CHECK-NEXT:    br label [[LOOP:%.*]]
696 ; CHECK:       loop:
697 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
698 ; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[IV]], [[N]]
699 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
700 ; CHECK:       if.true:
701 ; CHECK-NEXT:    [[A:%.*]] = add i32 [[IV]], [[IV]]
702 ; CHECK-NEXT:    br label [[BACKEDGE]]
703 ; CHECK:       if.false:
704 ; CHECK-NEXT:    [[B:%.*]] = mul i32 [[IV]], [[IV]]
705 ; CHECK-NEXT:    br label [[BACKEDGE]]
706 ; CHECK:       backedge:
707 ; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ [[A]], [[IF_TRUE]] ], [ [[B]], [[IF_FALSE]] ]
708 ; CHECK-NEXT:    call void @may_throw()
709 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[MERGE]]
710 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[LOAD]]
711 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
712 ; CHECK:       exit:
713 ; CHECK-NEXT:    ret void
716 entry:
717   br label %loop
719 loop:
720   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
721   %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]
722   %load = load i32, ptr %p
723   %cond = icmp slt i32 %iv, %n
724   br i1 %cond, label %if.true, label %if.false
726 if.true:
727   %a = add i32 %iv, %iv
728   br label %backedge
730 if.false:
731   %b = mul i32 %iv, %iv
732   br label %backedge
734 backedge:
735   %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]
736   call void @may_throw()
737   %iv.next = add i32 %iv, %merge
738   %loop.cond = icmp ult i32 %iv.next, %load
739   br i1 %loop.cond, label %loop, label %exit
741 exit:
742   ret void
745 ; Check that a throwing instruction prohibits hoisting across it.
746 define void @test_hoist_from_header_04(ptr %p, i32 %n) {
747 ; CHECK-LABEL: define void @test_hoist_from_header_04(
748 ; CHECK-SAME: ptr [[P:%.*]], i32 [[N:%.*]]) {
749 ; CHECK-NEXT:  entry:
750 ; CHECK-NEXT:    br label [[LOOP:%.*]]
751 ; CHECK:       loop:
752 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
753 ; CHECK-NEXT:    call void @may_throw()
754 ; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[P]], align 4
755 ; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[IV]], [[N]]
756 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
757 ; CHECK:       if.true:
758 ; CHECK-NEXT:    [[A:%.*]] = add i32 [[IV]], [[IV]]
759 ; CHECK-NEXT:    br label [[BACKEDGE]]
760 ; CHECK:       if.false:
761 ; CHECK-NEXT:    [[B:%.*]] = mul i32 [[IV]], [[IV]]
762 ; CHECK-NEXT:    br label [[BACKEDGE]]
763 ; CHECK:       backedge:
764 ; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ [[A]], [[IF_TRUE]] ], [ [[B]], [[IF_FALSE]] ]
765 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[MERGE]]
766 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[LOAD]]
767 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
768 ; CHECK:       exit:
769 ; CHECK-NEXT:    ret void
772 entry:
773   br label %loop
775 loop:
776   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
777   %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]
778   call void @may_throw()
779   %load = load i32, ptr %p
780   %cond = icmp slt i32 %iv, %n
781   br i1 %cond, label %if.true, label %if.false
783 if.true:
784   %a = add i32 %iv, %iv
785   br label %backedge
787 if.false:
788   %b = mul i32 %iv, %iv
789   br label %backedge
791 backedge:
792   %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]
793   %iv.next = add i32 %iv, %merge
794   %loop.cond = icmp ult i32 %iv.next, %load
795   br i1 %loop.cond, label %loop, label %exit
797 exit:
798   ret void
801 ; Check that we can hoist a mustexecute load from backedge even if something
802 ; throws after it.
803 define void @test_hoist_from_backedge_01(ptr %p, i32 %n) {
804 ; CHECK-LABEL: define void @test_hoist_from_backedge_01(
805 ; CHECK-SAME: ptr [[P:%.*]], i32 [[N:%.*]]) {
806 ; CHECK-NEXT:  entry:
807 ; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[P]], align 4
808 ; CHECK-NEXT:    br label [[LOOP:%.*]]
809 ; CHECK:       loop:
810 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
811 ; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[IV]], [[N]]
812 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
813 ; CHECK:       if.true:
814 ; CHECK-NEXT:    [[A:%.*]] = add i32 [[IV]], [[IV]]
815 ; CHECK-NEXT:    br label [[BACKEDGE]]
816 ; CHECK:       if.false:
817 ; CHECK-NEXT:    [[B:%.*]] = mul i32 [[IV]], [[IV]]
818 ; CHECK-NEXT:    br label [[BACKEDGE]]
819 ; CHECK:       backedge:
820 ; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ [[A]], [[IF_TRUE]] ], [ [[B]], [[IF_FALSE]] ]
821 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[MERGE]]
822 ; CHECK-NEXT:    call void @may_throw()
823 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[LOAD]]
824 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
825 ; CHECK:       exit:
826 ; CHECK-NEXT:    ret void
829 entry:
830   br label %loop
832 loop:
833   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
834   %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]
835   %cond = icmp slt i32 %iv, %n
836   br i1 %cond, label %if.true, label %if.false
838 if.true:
839   %a = add i32 %iv, %iv
840   br label %backedge
842 if.false:
843   %b = mul i32 %iv, %iv
844   br label %backedge
846 backedge:
847   %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]
848   %iv.next = add i32 %iv, %merge
849   %load = load i32, ptr %p
850   call void @may_throw()
851   %loop.cond = icmp ult i32 %iv.next, %load
852   br i1 %loop.cond, label %loop, label %exit
854 exit:
855   ret void
858 ; Check that we don't hoist the load if something before it can throw.
859 define void @test_hoist_from_backedge_02(ptr %p, i32 %n) {
860 ; CHECK-LABEL: define void @test_hoist_from_backedge_02(
861 ; CHECK-SAME: ptr [[P:%.*]], i32 [[N:%.*]]) {
862 ; CHECK-NEXT:  entry:
863 ; CHECK-NEXT:    br label [[LOOP:%.*]]
864 ; CHECK:       loop:
865 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
866 ; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[IV]], [[N]]
867 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
868 ; CHECK:       if.true:
869 ; CHECK-NEXT:    [[A:%.*]] = add i32 [[IV]], [[IV]]
870 ; CHECK-NEXT:    br label [[BACKEDGE]]
871 ; CHECK:       if.false:
872 ; CHECK-NEXT:    [[B:%.*]] = mul i32 [[IV]], [[IV]]
873 ; CHECK-NEXT:    br label [[BACKEDGE]]
874 ; CHECK:       backedge:
875 ; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ [[A]], [[IF_TRUE]] ], [ [[B]], [[IF_FALSE]] ]
876 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[MERGE]]
877 ; CHECK-NEXT:    call void @may_throw()
878 ; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[P]], align 4
879 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[LOAD]]
880 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
881 ; CHECK:       exit:
882 ; CHECK-NEXT:    ret void
885 entry:
886   br label %loop
888 loop:
889   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
890   %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]
891   %cond = icmp slt i32 %iv, %n
892   br i1 %cond, label %if.true, label %if.false
894 if.true:
895   %a = add i32 %iv, %iv
896   br label %backedge
898 if.false:
899   %b = mul i32 %iv, %iv
900   br label %backedge
902 backedge:
903   %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]
904   %iv.next = add i32 %iv, %merge
905   call void @may_throw()
906   %load = load i32, ptr %p
907   %loop.cond = icmp ult i32 %iv.next, %load
908   br i1 %loop.cond, label %loop, label %exit
910 exit:
911   ret void
914 define void @test_hoist_from_backedge_03(ptr %p, i32 %n) {
915 ; CHECK-LABEL: define void @test_hoist_from_backedge_03(
916 ; CHECK-SAME: ptr [[P:%.*]], i32 [[N:%.*]]) {
917 ; CHECK-NEXT:  entry:
918 ; CHECK-NEXT:    br label [[LOOP:%.*]]
919 ; CHECK:       loop:
920 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
921 ; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[IV]], [[N]]
922 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
923 ; CHECK:       if.true:
924 ; CHECK-NEXT:    [[A:%.*]] = add i32 [[IV]], [[IV]]
925 ; CHECK-NEXT:    br label [[BACKEDGE]]
926 ; CHECK:       if.false:
927 ; CHECK-NEXT:    [[B:%.*]] = mul i32 [[IV]], [[IV]]
928 ; CHECK-NEXT:    call void @may_throw()
929 ; CHECK-NEXT:    br label [[BACKEDGE]]
930 ; CHECK:       backedge:
931 ; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ [[A]], [[IF_TRUE]] ], [ [[B]], [[IF_FALSE]] ]
932 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[MERGE]]
933 ; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[P]], align 4
934 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[LOAD]]
935 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
936 ; CHECK:       exit:
937 ; CHECK-NEXT:    ret void
940 entry:
941   br label %loop
943 loop:
944   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
945   %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]
946   %cond = icmp slt i32 %iv, %n
947   br i1 %cond, label %if.true, label %if.false
949 if.true:
950   %a = add i32 %iv, %iv
951   br label %backedge
953 if.false:
954   %b = mul i32 %iv, %iv
955   call void @may_throw()
956   br label %backedge
958 backedge:
959   %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]
960   %iv.next = add i32 %iv, %merge
961   %load = load i32, ptr %p
962   %loop.cond = icmp ult i32 %iv.next, %load
963   br i1 %loop.cond, label %loop, label %exit
965 exit:
966   ret void
969 define void @test_hoist_from_backedge_04(ptr %p, i32 %n) {
970 ; CHECK-LABEL: define void @test_hoist_from_backedge_04(
971 ; CHECK-SAME: ptr [[P:%.*]], i32 [[N:%.*]]) {
972 ; CHECK-NEXT:  entry:
973 ; CHECK-NEXT:    br label [[LOOP:%.*]]
974 ; CHECK:       loop:
975 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
976 ; CHECK-NEXT:    call void @may_throw()
977 ; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[IV]], [[N]]
978 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
979 ; CHECK:       if.true:
980 ; CHECK-NEXT:    [[A:%.*]] = add i32 [[IV]], [[IV]]
981 ; CHECK-NEXT:    br label [[BACKEDGE]]
982 ; CHECK:       if.false:
983 ; CHECK-NEXT:    [[B:%.*]] = mul i32 [[IV]], [[IV]]
984 ; CHECK-NEXT:    br label [[BACKEDGE]]
985 ; CHECK:       backedge:
986 ; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ [[A]], [[IF_TRUE]] ], [ [[B]], [[IF_FALSE]] ]
987 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[MERGE]]
988 ; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[P]], align 4
989 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[LOAD]]
990 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
991 ; CHECK:       exit:
992 ; CHECK-NEXT:    ret void
995 entry:
996   br label %loop
998 loop:
999   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
1000   %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]
1001   call void @may_throw()
1002   %cond = icmp slt i32 %iv, %n
1003   br i1 %cond, label %if.true, label %if.false
1005 if.true:
1006   %a = add i32 %iv, %iv
1007   br label %backedge
1009 if.false:
1010   %b = mul i32 %iv, %iv
1011   br label %backedge
1013 backedge:
1014   %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]
1015   %iv.next = add i32 %iv, %merge
1016   %load = load i32, ptr %p
1017   %loop.cond = icmp ult i32 %iv.next, %load
1018   br i1 %loop.cond, label %loop, label %exit
1020 exit:
1021   ret void
1024 ; CHECK: [[RNG0]] = !{i32 0, i32 512}