[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