1 ; RUN: opt -S -verify-memoryssa -passes=loop-sink < %s | FileCheck %s
2 ; RUN: opt -S -verify-memoryssa -aa-pipeline=basic-aa -passes=loop-sink < %s | FileCheck %s
4 @g = global i32 0, align 4
22 ; CHECK: load i32, ptr @g
24 ; CHECK-NOT: load i32, ptr @g
25 define i32 @t1(i32, i32) #0 !prof !0 {
26 %3 = icmp eq i32 %1, 0
27 br i1 %3, label %.exit, label %.preheader
30 %invariant = load i32, ptr @g
34 %iv = phi i32 [ %t7, %.b7 ], [ 0, %.preheader ]
35 %c1 = icmp sgt i32 %iv, %0
36 br i1 %c1, label %.b2, label %.b6, !prof !1
39 %c2 = icmp sgt i32 %iv, 1
40 br i1 %c2, label %.b3, label %.b4
43 %t3 = sub nsw i32 %invariant, %iv
47 %t4 = add nsw i32 %invariant, %iv
51 %p5 = phi i32 [ %t3, %.b3 ], [ %t4, %.b4 ]
52 %t5 = mul nsw i32 %p5, 5
56 %t6 = add nsw i32 %iv, 100
60 %p7 = phi i32 [ %t6, %.b6 ], [ %t5, %.b5 ]
61 %t7 = add nuw nsw i32 %iv, 1
62 %c7 = icmp eq i32 %t7, %p7
63 br i1 %c7, label %.b1, label %.exit, !prof !3
82 ; Sink load to b3 and b6
85 ; CHECK-NOT: load i32, ptr @g
87 ; CHECK: load i32, ptr @g
90 ; CHECK: load i32, ptr @g
92 define i32 @t2(i32, i32) #0 !prof !0 {
93 %3 = icmp eq i32 %1, 0
94 br i1 %3, label %.exit, label %.preheader
97 %invariant = load i32, ptr @g
101 %iv = phi i32 [ %t7, %.b7 ], [ 0, %.preheader ]
102 %c1 = icmp sgt i32 %iv, %0
103 br i1 %c1, label %.b2, label %.b6, !prof !2
106 %c2 = icmp sgt i32 %iv, 1
107 br i1 %c2, label %.b3, label %.b4, !prof !1
110 %t3 = sub nsw i32 %invariant, %iv
114 %t4 = add nsw i32 5, %iv
118 %p5 = phi i32 [ %t3, %.b3 ], [ %t4, %.b4 ]
119 %t5 = mul nsw i32 %p5, 5
123 %t6 = add nsw i32 %iv, %invariant
127 %p7 = phi i32 [ %t6, %.b6 ], [ %t5, %.b5 ]
128 %t7 = add nuw nsw i32 %iv, 1
129 %c7 = icmp eq i32 %t7, %p7
130 br i1 %c7, label %.b1, label %.exit, !prof !3
148 ; Do not sink load from preheader.
151 ; CHECK: load i32, ptr @g
153 ; CHECK-NOT: load i32, ptr @g
154 define i32 @t3(i32, i32) #0 !prof !0 {
155 %3 = icmp eq i32 %1, 0
156 br i1 %3, label %.exit, label %.preheader
159 %invariant = load i32, ptr @g
163 %iv = phi i32 [ %t7, %.b7 ], [ 0, %.preheader ]
164 %c1 = icmp sgt i32 %iv, %0
165 br i1 %c1, label %.b2, label %.b6, !prof !2
168 %c2 = icmp sgt i32 %iv, 1
169 br i1 %c2, label %.b3, label %.b4, !prof !1
172 %t3 = sub nsw i32 %invariant, %iv
176 %t4 = add nsw i32 5, %iv
180 %p5 = phi i32 [ %t3, %.b3 ], [ %t4, %.b4 ]
181 %t5 = mul nsw i32 %p5, %invariant
185 %t6 = add nsw i32 %iv, 5
189 %p7 = phi i32 [ %t6, %.b6 ], [ %t5, %.b5 ]
190 %t7 = add nuw nsw i32 %iv, 1
191 %c7 = icmp eq i32 %t7, %p7
192 br i1 %c7, label %.b1, label %.exit, !prof !3
198 ; For single-BB loop with <=1 avg trip count, sink load to body
201 ; CHECK-NOT: load i32, ptr @g
203 ; CHECK: load i32, ptr @g
205 define i32 @t4(i32, i32) #0 !prof !0 {
207 %invariant = load i32, ptr @g
211 %iv = phi i32 [ %t1, %.body ], [ 0, %.entry ]
212 %c0 = icmp sgt i32 %iv, %0
213 br i1 %c0, label %.body, label %.exit, !prof !1
216 %t1 = add nsw i32 %invariant, %iv
217 %c1 = icmp sgt i32 %iv, %0
237 ; There is alias store in loop, do not sink load
240 ; CHECK: load i32, ptr @g
242 ; CHECK-NOT: load i32, ptr @g
243 define i32 @t5(i32, ptr) #0 !prof !0 {
244 %3 = icmp eq i32 %0, 0
245 br i1 %3, label %.exit, label %.preheader
248 %invariant = load i32, ptr @g
252 %iv = phi i32 [ %t7, %.b7 ], [ 0, %.preheader ]
253 %c1 = icmp sgt i32 %iv, %0
254 br i1 %c1, label %.b2, label %.b6, !prof !1
257 %c2 = icmp sgt i32 %iv, 1
258 br i1 %c2, label %.b3, label %.b4
261 %t3 = sub nsw i32 %invariant, %iv
265 %t4 = add nsw i32 %invariant, %iv
269 %p5 = phi i32 [ %t3, %.b3 ], [ %t4, %.b4 ]
270 %t5 = mul nsw i32 %p5, 5
274 %t6 = call i32 @foo()
278 %p7 = phi i32 [ %t6, %.b6 ], [ %t5, %.b5 ]
279 %t7 = add nuw nsw i32 %iv, 1
280 %c7 = icmp eq i32 %t7, %p7
281 br i1 %c7, label %.b1, label %.exit, !prof !3
300 ; Regardless of aliasing store in loop this load from constant memory can be sunk.
301 ; CHECK: t5_const_memory
303 ; CHECK-NOT: load i32, ptr @g_const
305 ; CHECK: load i32, ptr @g_const
306 ; CHECK: br i1 %c2, label %.b3, label %.b4
307 define i32 @t5_const_memory(i32, ptr) #0 !prof !0 {
308 %3 = icmp eq i32 %0, 0
309 br i1 %3, label %.exit, label %.preheader
312 %invariant = load i32, ptr @g_const
316 %iv = phi i32 [ %t7, %.b7 ], [ 0, %.preheader ]
317 %c1 = icmp sgt i32 %iv, %0
318 br i1 %c1, label %.b2, label %.b6, !prof !1
321 %c2 = icmp sgt i32 %iv, 1
322 br i1 %c2, label %.b3, label %.b4
325 %t3 = sub nsw i32 %invariant, %iv
329 %t4 = add nsw i32 %invariant, %iv
333 %p5 = phi i32 [ %t3, %.b3 ], [ %t4, %.b4 ]
334 %t5 = mul nsw i32 %p5, 5
338 %t6 = call i32 @foo()
342 %p7 = phi i32 [ %t6, %.b6 ], [ %t5, %.b5 ]
343 %t7 = add nuw nsw i32 %iv, 1
344 %c7 = icmp eq i32 %t7, %p7
345 br i1 %c7, label %.b1, label %.exit, !prof !3
359 ; Do not sink unordered atomic load to b2
362 ; CHECK: load atomic i32, ptr @g unordered, align 4
364 ; CHECK-NOT: load atomic i32, ptr @g unordered, align 4
365 define i32 @t6(i32, i32) #0 !prof !0 {
366 %3 = icmp eq i32 %1, 0
367 br i1 %3, label %.exit, label %.preheader
370 %invariant = load atomic i32, ptr @g unordered, align 4
374 %iv = phi i32 [ %t3, %.b4 ], [ 0, %.preheader ]
375 %c1 = icmp sgt i32 %iv, %0
376 br i1 %c1, label %.b2, label %.b3, !prof !1
379 %t1 = add nsw i32 %invariant, %iv
383 %t2 = add nsw i32 %iv, 100
387 %p1 = phi i32 [ %t2, %.b3 ], [ %t1, %.b2 ]
388 %t3 = add nuw nsw i32 %iv, 1
389 %c2 = icmp eq i32 %t3, %p1
390 br i1 %c2, label %.b1, label %.exit, !prof !3
396 @g_const = constant i32 0, align 4
406 ; Sink unordered atomic load to b2. It is allowed to sink into loop unordered
407 ; load from constant.
410 ; CHECK-NOT: load atomic i32, ptr @g_const unordered, align 4
412 ; CHECK: load atomic i32, ptr @g_const unordered, align 4
413 define i32 @t7(i32, i32) #0 !prof !0 {
414 %3 = icmp eq i32 %1, 0
415 br i1 %3, label %.exit, label %.preheader
418 %invariant = load atomic i32, ptr @g_const unordered, align 4
422 %iv = phi i32 [ %t3, %.b4 ], [ 0, %.preheader ]
423 %c1 = icmp sgt i32 %iv, %0
424 br i1 %c1, label %.b2, label %.b3, !prof !1
427 %t1 = add nsw i32 %invariant, %iv
431 %t2 = add nsw i32 %iv, 100
435 %p1 = phi i32 [ %t2, %.b3 ], [ %t1, %.b2 ]
436 %t3 = add nuw nsw i32 %iv, 1
437 %c2 = icmp eq i32 %t3, %p1
438 br i1 %c2, label %.b1, label %.exit, !prof !3
446 !0 = !{!"function_entry_count", i64 1}
447 !1 = !{!"branch_weights", i32 1, i32 2000}
448 !2 = !{!"branch_weights", i32 2000, i32 1}
449 !3 = !{!"branch_weights", i32 100, i32 1}