[PATCH] Remove dead zero store to calloc initialized memory
Philip Reames
listmail at philipreames.com
Tue Aug 5 10:57:24 PDT 2014
Closed by commit rL214897 (authored by @reames).
REPOSITORY
rL LLVM
http://reviews.llvm.org/D3942
Files:
llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp
llvm/trunk/test/Transforms/DeadStoreElimination/calloc-store.ll
Index: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp
===================================================================
--- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -514,30 +514,50 @@
if (!InstDep.isDef() && !InstDep.isClobber())
continue;
- // If we're storing the same value back to a pointer that we just
- // loaded from, then the store can be removed.
+ // Check for cases where the store is redundant.
if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
+ bool DeleteStore = false;
+ // If we're storing the same value back to a pointer that we just
+ // loaded from, then the store can be removed.
if (LoadInst *DepLoad = dyn_cast<LoadInst>(InstDep.getInst())) {
if (SI->getPointerOperand() == DepLoad->getPointerOperand() &&
SI->getOperand(0) == DepLoad && isRemovable(SI)) {
DEBUG(dbgs() << "DSE: Remove Store Of Load from same pointer:\n "
<< "LOAD: " << *DepLoad << "\n STORE: " << *SI << '\n');
+ DeleteStore = true;
+ }
+ }
- // DeleteDeadInstruction can delete the current instruction. Save BBI
- // in case we need it.
- WeakVH NextInst(BBI);
-
- DeleteDeadInstruction(SI, *MD, TLI);
-
- if (!NextInst) // Next instruction deleted.
- BBI = BB.begin();
- else if (BBI != BB.begin()) // Revisit this instruction if possible.
- --BBI;
- ++NumFastStores;
- MadeChange = true;
- continue;
+ // If we find a store to memory which was defined by calloc
+ // we can remove the store if the value being stored is a
+ // constant zero (since calloc initialized the memory to
+ // that same value) or the store is undefined (if out of
+ // bounds).
+ if (isCallocLikeFn(InstDep.getInst(), TLI) && isRemovable(SI)) {
+ Value *V = SI->getValueOperand();
+ if (isa<Constant>(V) && cast<Constant>(V)->isNullValue()) {
+ DEBUG(dbgs() << "DSE: Remove Store Of Zero to Calloc:\n "
+ << "CALLOC: " << *InstDep.getInst() << "\n"
+ << "STORE: " << *SI << '\n');
+ DeleteStore = true;
}
}
+
+ if (DeleteStore) {
+ // DeleteDeadInstruction can delete the current instruction. Save BBI
+ // in case we need it.
+ WeakVH NextInst(BBI);
+
+ DeleteDeadInstruction(SI, *MD, TLI);
+
+ if (!NextInst) // Next instruction deleted.
+ BBI = BB.begin();
+ else if (BBI != BB.begin()) // Revisit this instruction if possible.
+ --BBI;
+ ++NumFastStores;
+ MadeChange = true;
+ continue;
+ }
}
// Figure out what location is being stored to.
Index: llvm/trunk/test/Transforms/DeadStoreElimination/calloc-store.ll
===================================================================
--- llvm/trunk/test/Transforms/DeadStoreElimination/calloc-store.ll
+++ llvm/trunk/test/Transforms/DeadStoreElimination/calloc-store.ll
@@ -0,0 +1,17 @@
+; RUN: opt < %s -basicaa -dse -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+
+; Function Attrs: nounwind
+declare noalias i8* @calloc(i64, i64)
+
+; Function Attrs: nounwind uwtable
+define noalias i32* @test_store() {
+; CHECK-LABEL: test_store
+ %1 = tail call noalias i8* @calloc(i64 1, i64 4)
+ %2 = bitcast i8* %1 to i32*
+ ; This store is dead and should be removed
+ store i32 0, i32* %2, align 4
+; CHECK-NOT: store i32 0, i32* %2, align 4
+ ret i32* %2
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3942.12203.patch
Type: text/x-patch
Size: 3791 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140805/6d980beb/attachment.bin>
More information about the llvm-commits
mailing list