summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnna Thomas <anna@azul.com>2016-07-07 20:51:42 +0000
committerAnna Thomas <anna@azul.com>2016-07-07 20:51:42 +0000
commit6a78c78a03d8426afc6b5203813ec4b11d9e8df2 (patch)
tree267272193c28e681f3b13ac54d6b971dd75c3341
parenta7e11a5d34117e5fd26b4aa028f0ac0c5ec29cb4 (diff)
downloadbcm5719-llvm-6a78c78a03d8426afc6b5203813ec4b11d9e8df2.tar.gz
bcm5719-llvm-6a78c78a03d8426afc6b5203813ec4b11d9e8df2.zip
[DSE] Remove dead stores in end blocks containing fence
We can remove dead stores in the presence of fence instructions. Fence does not change an otherwise thread local store to visible. reviewers: reames, dexonsmith, jfb Differential Revision: http://reviews.llvm.org/D22001 llvm-svn: 274795
-rw-r--r--llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp8
-rw-r--r--llvm/test/Transforms/DeadStoreElimination/fence.ll48
2 files changed, 56 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
index 55d06a53faf..45e11a50752 100644
--- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -778,6 +778,14 @@ static bool handleEndBlock(BasicBlock &BB, AliasAnalysis *AA,
continue;
}
+ // We can remove the dead stores, irrespective of the fence and its ordering
+ // (release/acquire/seq_cst). Fences only constraints the ordering of
+ // already visible stores, it does not make a store visible to other
+ // threads. So, skipping over a fence does not change a store from being
+ // dead.
+ if (isa<FenceInst>(*BBI))
+ continue;
+
MemoryLocation LoadedLoc;
// If we encounter a use of the pointer, it is no longer considered dead
diff --git a/llvm/test/Transforms/DeadStoreElimination/fence.ll b/llvm/test/Transforms/DeadStoreElimination/fence.ll
index 66cfc7dd774..667f9428775 100644
--- a/llvm/test/Transforms/DeadStoreElimination/fence.ll
+++ b/llvm/test/Transforms/DeadStoreElimination/fence.ll
@@ -46,3 +46,51 @@ define void @test2(i32* %addr.i) {
store i32 5, i32* %addr.i, align 4
ret void
}
+
+; We DSE stack alloc'ed and byval locations, in the presence of fences.
+; Fence does not make an otherwise thread local store visible.
+; Right now the DSE in presence of fence is only done in end blocks (with no successors),
+; but the same logic applies to other basic blocks as well.
+; The store to %addr.i can be removed since it is a byval attribute
+define void @test3(i32* byval %addr.i) {
+; CHECK-LABEL: @test3
+; CHECK-NOT: store
+; CHECK: fence
+; CHECK: ret
+ store i32 5, i32* %addr.i, align 4
+ fence release
+ ret void
+}
+
+declare void @foo(i8* nocapture %p)
+
+declare noalias i8* @malloc(i32)
+
+; DSE of stores in locations allocated through library calls.
+define void @test_nocapture() {
+; CHECK-LABEL: @test_nocapture
+; CHECK: malloc
+; CHECK: foo
+; CHECK-NOT: store
+; CHECK: fence
+ %m = call i8* @malloc(i32 24)
+ call void @foo(i8* %m)
+ store i8 4, i8* %m
+ fence release
+ ret void
+}
+
+
+; This is a full fence, but it does not make a thread local store visible.
+; We can DSE the store in presence of the fence.
+define void @fence_seq_cst() {
+; CHECK-LABEL: @fence_seq_cst
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: ret void
+ %P1 = alloca i32
+ store i32 0, i32* %P1, align 4
+ fence seq_cst
+ store i32 4, i32* %P1, align 4
+ ret void
+}
+
OpenPOWER on IntegriCloud