Skip to content

Commit 889a20c

Browse files
committedJul 11, 2016
[Sink] Don't move calls to readonly functions across stores
Summary: Reviewers: hfinkel, majnemer, tstellarAMD, sunfish Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D17279 llvm-svn: 275066
1 parent 9343f36 commit 889a20c

File tree

2 files changed

+118
-2
lines changed

2 files changed

+118
-2
lines changed
 

‎llvm/lib/Transforms/Scalar/Sink.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,15 @@ static bool isSafeToMove(Instruction *Inst, AliasAnalysis &AA,
7676
Inst->mayThrow())
7777
return false;
7878

79-
// Convergent operations cannot be made control-dependent on additional
80-
// values.
8179
if (auto CS = CallSite(Inst)) {
80+
// Convergent operations cannot be made control-dependent on additional
81+
// values.
8282
if (CS.hasFnAttr(Attribute::Convergent))
8383
return false;
84+
85+
for (Instruction *S : Stores)
86+
if (AA.getModRefInfo(S, CS) & MRI_Mod)
87+
return false;
8488
}
8589

8690
return true;

‎llvm/test/Transforms/Sink/call.ll

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
; RUN: opt < %s -basicaa -sink -S | FileCheck %s
2+
3+
declare i32 @f_load_global() nounwind readonly
4+
declare i32 @f_load_arg(i32*) nounwind readonly argmemonly
5+
declare void @f_store_global(i32) nounwind
6+
declare void @f_store_arg(i32*) nounwind argmemonly
7+
declare void @f_readonly_arg(i32* readonly, i32*) nounwind argmemonly
8+
declare i32 @f_readnone(i32) nounwind readnone
9+
10+
@A = external global i32
11+
@B = external global i32
12+
13+
; Sink readonly call if no stores are in the way.
14+
;
15+
; CHECK-LABEL: @test_sink_no_stores(
16+
; CHECK: true:
17+
; CHECK-NEXT: %l = call i32 @f_load_global
18+
; CHECK-NEXT: ret i32 %l
19+
define i32 @test_sink_no_stores(i1 %z) {
20+
%l = call i32 @f_load_global()
21+
br i1 %z, label %true, label %false
22+
true:
23+
ret i32 %l
24+
false:
25+
ret i32 0
26+
}
27+
28+
; CHECK-LABEL: @test_sink_argmem_store(
29+
; CHECK: true:
30+
; CHECK-NEXT: %l = call i32 @f_load_arg
31+
; CHECK-NEXT: ret i32 %l
32+
define i32 @test_sink_argmem_store(i1 %z) {
33+
%l = call i32 @f_load_arg(i32* @A)
34+
store i32 0, i32* @B
35+
br i1 %z, label %true, label %false
36+
true:
37+
ret i32 %l
38+
false:
39+
ret i32 0
40+
}
41+
42+
; CHECK-LABEL: @test_sink_argmem_call(
43+
; CHECK: true:
44+
; CHECK-NEXT: %l = call i32 @f_load_arg
45+
; CHECK-NEXT: ret i32 %l
46+
define i32 @test_sink_argmem_call(i1 %z) {
47+
%l = call i32 @f_load_arg(i32* @A)
48+
call void @f_store_arg(i32* @B)
49+
br i1 %z, label %true, label %false
50+
true:
51+
ret i32 %l
52+
false:
53+
ret i32 0
54+
}
55+
56+
; CHECK-LABEL: @test_sink_argmem_multiple(
57+
; CHECK: true:
58+
; CHECK-NEXT: %l = call i32 @f_load_arg
59+
; CHECK-NEXT: ret i32 %l
60+
define i32 @test_sink_argmem_multiple(i1 %z) {
61+
%l = call i32 @f_load_arg(i32* @A)
62+
call void @f_readonly_arg(i32* @A, i32* @B)
63+
br i1 %z, label %true, label %false
64+
true:
65+
ret i32 %l
66+
false:
67+
ret i32 0
68+
}
69+
70+
; But don't sink if there is a store.
71+
;
72+
; CHECK-LABEL: @test_nosink_store(
73+
; CHECK: call i32 @f_load_global
74+
; CHECK-NEXT: store i32
75+
define i32 @test_nosink_store(i1 %z) {
76+
%l = call i32 @f_load_global()
77+
store i32 0, i32* @A
78+
br i1 %z, label %true, label %false
79+
true:
80+
ret i32 %l
81+
false:
82+
ret i32 0
83+
}
84+
85+
; CHECK-LABEL: @test_nosink_call(
86+
; CHECK: call i32 @f_load_global
87+
; CHECK-NEXT: call void @f_store_global
88+
define i32 @test_nosink_call(i1 %z) {
89+
%l = call i32 @f_load_global()
90+
call void @f_store_global(i32 0)
91+
br i1 %z, label %true, label %false
92+
true:
93+
ret i32 %l
94+
false:
95+
ret i32 0
96+
}
97+
98+
; readnone calls are sunk across stores.
99+
;
100+
; CHECK-LABEL: @test_sink_readnone(
101+
; CHECK: true:
102+
; CHECK-NEXT: %l = call i32 @f_readnone(
103+
; CHECK-NEXT: ret i32 %l
104+
define i32 @test_sink_readnone(i1 %z) {
105+
%l = call i32 @f_readnone(i32 0)
106+
store i32 0, i32* @A
107+
br i1 %z, label %true, label %false
108+
true:
109+
ret i32 %l
110+
false:
111+
ret i32 0
112+
}

0 commit comments

Comments
 (0)
Please sign in to comment.