xref: /llvm-project/llvm/test/Transforms/Sink/call.ll (revision a198d2041e8a5c9520d3df59887ca3c744b15d82)
17d452742SNikita Popov; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2211cf8a3SBjorn Pettersson; RUN: opt < %s -passes=sink -S | FileCheck %s
3cee313d2SEric Christopher
47d452742SNikita Popovdeclare i32 @f_load_global() nounwind willreturn readonly
57d452742SNikita Popovdeclare i32 @f_load_global_throwable() willreturn readonly
67d452742SNikita Popovdeclare i32 @f_load_global_may_not_return() nounwind readonly
7*a198d204SMatt Arsenaultdeclare i32 @f_load_arg(ptr) nounwind willreturn readonly argmemonly
8e22af03aSNikita Popovdeclare void @f_store_global(i32) nounwind willreturn
9*a198d204SMatt Arsenaultdeclare void @f_store_arg(ptr) nounwind willreturn argmemonly
10*a198d204SMatt Arsenaultdeclare void @f_readonly_arg(ptr readonly, ptr) nounwind willreturn argmemonly
11e22af03aSNikita Popovdeclare i32 @f_readnone(i32) nounwind willreturn readnone
12cee313d2SEric Christopher
13cee313d2SEric Christopher@A = external global i32
14cee313d2SEric Christopher@B = external global i32
15cee313d2SEric Christopher
16cee313d2SEric Christopher; Sink readonly call if no stores are in the way.
17cee313d2SEric Christopher;
18cee313d2SEric Christopherdefine i32 @test_sink_no_stores(i1 %z) {
197d452742SNikita Popov; CHECK-LABEL: @test_sink_no_stores(
207d452742SNikita Popov; CHECK-NEXT:    br i1 [[Z:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
217d452742SNikita Popov; CHECK:       true:
227d452742SNikita Popov; CHECK-NEXT:    [[L:%.*]] = call i32 @f_load_global()
237d452742SNikita Popov; CHECK-NEXT:    ret i32 [[L]]
247d452742SNikita Popov; CHECK:       false:
257d452742SNikita Popov; CHECK-NEXT:    ret i32 0
267d452742SNikita Popov;
27cee313d2SEric Christopher  %l = call i32 @f_load_global()
28cee313d2SEric Christopher  br i1 %z, label %true, label %false
29cee313d2SEric Christophertrue:
30cee313d2SEric Christopher  ret i32 %l
31cee313d2SEric Christopherfalse:
32cee313d2SEric Christopher  ret i32 0
33cee313d2SEric Christopher}
34cee313d2SEric Christopher
35389fd309SFangrui Songdefine i32 @test_throwable_no_stores(i1 %z) {
367d452742SNikita Popov; CHECK-LABEL: @test_throwable_no_stores(
377d452742SNikita Popov; CHECK-NEXT:    [[L:%.*]] = call i32 @f_load_global_throwable()
387d452742SNikita Popov; CHECK-NEXT:    br i1 [[Z:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
397d452742SNikita Popov; CHECK:       true:
407d452742SNikita Popov; CHECK-NEXT:    ret i32 [[L]]
417d452742SNikita Popov; CHECK:       false:
427d452742SNikita Popov; CHECK-NEXT:    ret i32 0
437d452742SNikita Popov;
44389fd309SFangrui Song  %l = call i32 @f_load_global_throwable()
45389fd309SFangrui Song  br i1 %z, label %true, label %false
46389fd309SFangrui Songtrue:
47389fd309SFangrui Song  ret i32 %l
48389fd309SFangrui Songfalse:
49389fd309SFangrui Song  ret i32 0
50389fd309SFangrui Song}
51389fd309SFangrui Song
527d452742SNikita Popovdefine i32 @test_may_not_return_no_stores(i1 %z) {
537d452742SNikita Popov; CHECK-LABEL: @test_may_not_return_no_stores(
54e22af03aSNikita Popov; CHECK-NEXT:    [[L:%.*]] = call i32 @f_load_global_may_not_return()
557d452742SNikita Popov; CHECK-NEXT:    br i1 [[Z:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
56cee313d2SEric Christopher; CHECK:       true:
577d452742SNikita Popov; CHECK-NEXT:    ret i32 [[L]]
587d452742SNikita Popov; CHECK:       false:
597d452742SNikita Popov; CHECK-NEXT:    ret i32 0
607d452742SNikita Popov;
617d452742SNikita Popov  %l = call i32 @f_load_global_may_not_return()
627d452742SNikita Popov  br i1 %z, label %true, label %false
637d452742SNikita Popovtrue:
647d452742SNikita Popov  ret i32 %l
657d452742SNikita Popovfalse:
667d452742SNikita Popov  ret i32 0
677d452742SNikita Popov}
687d452742SNikita Popov
69cee313d2SEric Christopherdefine i32 @test_sink_argmem_store(i1 %z) {
707d452742SNikita Popov; CHECK-LABEL: @test_sink_argmem_store(
71*a198d204SMatt Arsenault; CHECK-NEXT:    store i32 0, ptr @B, align 4
727d452742SNikita Popov; CHECK-NEXT:    br i1 [[Z:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
737d452742SNikita Popov; CHECK:       true:
74*a198d204SMatt Arsenault; CHECK-NEXT:    [[L:%.*]] = call i32 @f_load_arg(ptr @A)
757d452742SNikita Popov; CHECK-NEXT:    ret i32 [[L]]
767d452742SNikita Popov; CHECK:       false:
777d452742SNikita Popov; CHECK-NEXT:    ret i32 0
787d452742SNikita Popov;
79*a198d204SMatt Arsenault  %l = call i32 @f_load_arg(ptr @A)
80*a198d204SMatt Arsenault  store i32 0, ptr @B
81cee313d2SEric Christopher  br i1 %z, label %true, label %false
82cee313d2SEric Christophertrue:
83cee313d2SEric Christopher  ret i32 %l
84cee313d2SEric Christopherfalse:
85cee313d2SEric Christopher  ret i32 0
86cee313d2SEric Christopher}
87cee313d2SEric Christopher
88cee313d2SEric Christopherdefine i32 @test_sink_argmem_call(i1 %z) {
897d452742SNikita Popov; CHECK-LABEL: @test_sink_argmem_call(
90*a198d204SMatt Arsenault; CHECK-NEXT:    call void @f_store_arg(ptr @B)
917d452742SNikita Popov; CHECK-NEXT:    br i1 [[Z:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
927d452742SNikita Popov; CHECK:       true:
93*a198d204SMatt Arsenault; CHECK-NEXT:    [[L:%.*]] = call i32 @f_load_arg(ptr @A)
947d452742SNikita Popov; CHECK-NEXT:    ret i32 [[L]]
957d452742SNikita Popov; CHECK:       false:
967d452742SNikita Popov; CHECK-NEXT:    ret i32 0
977d452742SNikita Popov;
98*a198d204SMatt Arsenault  %l = call i32 @f_load_arg(ptr @A)
99*a198d204SMatt Arsenault  call void @f_store_arg(ptr @B)
100cee313d2SEric Christopher  br i1 %z, label %true, label %false
101cee313d2SEric Christophertrue:
102cee313d2SEric Christopher  ret i32 %l
103cee313d2SEric Christopherfalse:
104cee313d2SEric Christopher  ret i32 0
105cee313d2SEric Christopher}
106cee313d2SEric Christopher
107cee313d2SEric Christopherdefine i32 @test_sink_argmem_multiple(i1 %z) {
1087d452742SNikita Popov; CHECK-LABEL: @test_sink_argmem_multiple(
109*a198d204SMatt Arsenault; CHECK-NEXT:    call void @f_readonly_arg(ptr @A, ptr @B)
1107d452742SNikita Popov; CHECK-NEXT:    br i1 [[Z:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
1117d452742SNikita Popov; CHECK:       true:
112*a198d204SMatt Arsenault; CHECK-NEXT:    [[L:%.*]] = call i32 @f_load_arg(ptr @A)
1137d452742SNikita Popov; CHECK-NEXT:    ret i32 [[L]]
1147d452742SNikita Popov; CHECK:       false:
1157d452742SNikita Popov; CHECK-NEXT:    ret i32 0
1167d452742SNikita Popov;
117*a198d204SMatt Arsenault  %l = call i32 @f_load_arg(ptr @A)
118*a198d204SMatt Arsenault  call void @f_readonly_arg(ptr @A, ptr @B)
119cee313d2SEric Christopher  br i1 %z, label %true, label %false
120cee313d2SEric Christophertrue:
121cee313d2SEric Christopher  ret i32 %l
122cee313d2SEric Christopherfalse:
123cee313d2SEric Christopher  ret i32 0
124cee313d2SEric Christopher}
125cee313d2SEric Christopher
126cee313d2SEric Christopher; But don't sink if there is a store.
127cee313d2SEric Christopherdefine i32 @test_nosink_store(i1 %z) {
1287d452742SNikita Popov; CHECK-LABEL: @test_nosink_store(
1297d452742SNikita Popov; CHECK-NEXT:    [[L:%.*]] = call i32 @f_load_global()
130*a198d204SMatt Arsenault; CHECK-NEXT:    store i32 0, ptr @A, align 4
1317d452742SNikita Popov; CHECK-NEXT:    br i1 [[Z:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
1327d452742SNikita Popov; CHECK:       true:
1337d452742SNikita Popov; CHECK-NEXT:    ret i32 [[L]]
1347d452742SNikita Popov; CHECK:       false:
1357d452742SNikita Popov; CHECK-NEXT:    ret i32 0
1367d452742SNikita Popov;
137cee313d2SEric Christopher  %l = call i32 @f_load_global()
138*a198d204SMatt Arsenault  store i32 0, ptr @A
139cee313d2SEric Christopher  br i1 %z, label %true, label %false
140cee313d2SEric Christophertrue:
141cee313d2SEric Christopher  ret i32 %l
142cee313d2SEric Christopherfalse:
143cee313d2SEric Christopher  ret i32 0
144cee313d2SEric Christopher}
145cee313d2SEric Christopher
146cee313d2SEric Christopherdefine i32 @test_nosink_call(i1 %z) {
1477d452742SNikita Popov; CHECK-LABEL: @test_nosink_call(
1487d452742SNikita Popov; CHECK-NEXT:    [[L:%.*]] = call i32 @f_load_global()
1497d452742SNikita Popov; CHECK-NEXT:    call void @f_store_global(i32 0)
1507d452742SNikita Popov; CHECK-NEXT:    br i1 [[Z:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
1517d452742SNikita Popov; CHECK:       true:
1527d452742SNikita Popov; CHECK-NEXT:    ret i32 [[L]]
1537d452742SNikita Popov; CHECK:       false:
1547d452742SNikita Popov; CHECK-NEXT:    ret i32 0
1557d452742SNikita Popov;
156cee313d2SEric Christopher  %l = call i32 @f_load_global()
157cee313d2SEric Christopher  call void @f_store_global(i32 0)
158cee313d2SEric Christopher  br i1 %z, label %true, label %false
159cee313d2SEric Christophertrue:
160cee313d2SEric Christopher  ret i32 %l
161cee313d2SEric Christopherfalse:
162cee313d2SEric Christopher  ret i32 0
163cee313d2SEric Christopher}
164cee313d2SEric Christopher
165cee313d2SEric Christopher; readnone calls are sunk across stores.
166cee313d2SEric Christopherdefine i32 @test_sink_readnone(i1 %z) {
1677d452742SNikita Popov; CHECK-LABEL: @test_sink_readnone(
168*a198d204SMatt Arsenault; CHECK-NEXT:    store i32 0, ptr @A, align 4
1697d452742SNikita Popov; CHECK-NEXT:    br i1 [[Z:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
1707d452742SNikita Popov; CHECK:       true:
1717d452742SNikita Popov; CHECK-NEXT:    [[L:%.*]] = call i32 @f_readnone(i32 0)
1727d452742SNikita Popov; CHECK-NEXT:    ret i32 [[L]]
1737d452742SNikita Popov; CHECK:       false:
1747d452742SNikita Popov; CHECK-NEXT:    ret i32 0
1757d452742SNikita Popov;
176cee313d2SEric Christopher  %l = call i32 @f_readnone(i32 0)
177*a198d204SMatt Arsenault  store i32 0, ptr @A
178cee313d2SEric Christopher  br i1 %z, label %true, label %false
179cee313d2SEric Christophertrue:
180cee313d2SEric Christopher  ret i32 %l
181cee313d2SEric Christopherfalse:
182cee313d2SEric Christopher  ret i32 0
183cee313d2SEric Christopher}
184