1 ; RUN: opt < %s -basic-aa -sink -S | FileCheck %s
3 declare i32 @f_load_global() nounwind readonly
4 declare i32 @f_load_global_throwable() readonly
5 declare i32 @f_load_arg(i32*) nounwind readonly argmemonly
6 declare void @f_store_global(i32) nounwind
7 declare void @f_store_arg(i32*) nounwind argmemonly
8 declare void @f_readonly_arg(i32* readonly, i32*) nounwind argmemonly
9 declare i32 @f_readnone(i32) nounwind readnone
11 @A = external global i32
12 @B = external global i32
14 ; Sink readonly call if no stores are in the way.
16 ; CHECK-LABEL: @test_sink_no_stores(
18 ; CHECK-NEXT: %l = call i32 @f_load_global
19 ; CHECK-NEXT: ret i32 %l
20 define i32 @test_sink_no_stores(i1 %z) {
21 %l = call i32 @f_load_global()
22 br i1 %z, label %true, label %false
29 ; CHECK-LABEL: @test_throwable_no_stores(
30 ; CHECK: %l = call i32 @f_load_global
31 ; CHECK-NEXT: br i1 %z
32 define i32 @test_throwable_no_stores(i1 %z) {
33 %l = call i32 @f_load_global_throwable()
34 br i1 %z, label %true, label %false
41 ; CHECK-LABEL: @test_sink_argmem_store(
43 ; CHECK-NEXT: %l = call i32 @f_load_arg
44 ; CHECK-NEXT: ret i32 %l
45 define i32 @test_sink_argmem_store(i1 %z) {
46 %l = call i32 @f_load_arg(i32* @A)
48 br i1 %z, label %true, label %false
55 ; CHECK-LABEL: @test_sink_argmem_call(
57 ; CHECK-NEXT: %l = call i32 @f_load_arg
58 ; CHECK-NEXT: ret i32 %l
59 define i32 @test_sink_argmem_call(i1 %z) {
60 %l = call i32 @f_load_arg(i32* @A)
61 call void @f_store_arg(i32* @B)
62 br i1 %z, label %true, label %false
69 ; CHECK-LABEL: @test_sink_argmem_multiple(
71 ; CHECK-NEXT: %l = call i32 @f_load_arg
72 ; CHECK-NEXT: ret i32 %l
73 define i32 @test_sink_argmem_multiple(i1 %z) {
74 %l = call i32 @f_load_arg(i32* @A)
75 call void @f_readonly_arg(i32* @A, i32* @B)
76 br i1 %z, label %true, label %false
83 ; But don't sink if there is a store.
85 ; CHECK-LABEL: @test_nosink_store(
86 ; CHECK: call i32 @f_load_global
87 ; CHECK-NEXT: store i32
88 define i32 @test_nosink_store(i1 %z) {
89 %l = call i32 @f_load_global()
91 br i1 %z, label %true, label %false
98 ; CHECK-LABEL: @test_nosink_call(
99 ; CHECK: call i32 @f_load_global
100 ; CHECK-NEXT: call void @f_store_global
101 define i32 @test_nosink_call(i1 %z) {
102 %l = call i32 @f_load_global()
103 call void @f_store_global(i32 0)
104 br i1 %z, label %true, label %false
111 ; readnone calls are sunk across stores.
113 ; CHECK-LABEL: @test_sink_readnone(
115 ; CHECK-NEXT: %l = call i32 @f_readnone(
116 ; CHECK-NEXT: ret i32 %l
117 define i32 @test_sink_readnone(i1 %z) {
118 %l = call i32 @f_readnone(i32 0)
120 br i1 %z, label %true, label %false