Implement PR1201 and test/Transforms/InstCombine/malloc-free-delete.ll
authorChris Lattner <sabre@nondot.org>
Sat, 14 Apr 2007 00:20:02 +0000 (00:20 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 14 Apr 2007 00:20:02 +0000 (00:20 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35981 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp

index ec27055f72e4a26987680985235b4b2e977b43bc..17d2f93ca653a36721e5c3656c571030828d0e0c 100644 (file)
@@ -8367,13 +8367,6 @@ Instruction *InstCombiner::visitAllocationInst(AllocationInst &AI) {
 Instruction *InstCombiner::visitFreeInst(FreeInst &FI) {
   Value *Op = FI.getOperand(0);
 
-  // Change free <ty>* (cast <ty2>* X to <ty>*) into free <ty2>* X
-  if (CastInst *CI = dyn_cast<CastInst>(Op))
-    if (isa<PointerType>(CI->getOperand(0)->getType())) {
-      FI.setOperand(0, CI->getOperand(0));
-      return &FI;
-    }
-
   // free undef -> unreachable.
   if (isa<UndefValue>(Op)) {
     // Insert a new store to null because we cannot modify the CFG here.
@@ -8381,11 +8374,33 @@ Instruction *InstCombiner::visitFreeInst(FreeInst &FI) {
                   UndefValue::get(PointerType::get(Type::Int1Ty)), &FI);
     return EraseInstFromFunction(FI);
   }
-
+  
   // If we have 'free null' delete the instruction.  This can happen in stl code
   // when lots of inlining happens.
   if (isa<ConstantPointerNull>(Op))
     return EraseInstFromFunction(FI);
+  
+  // Change free <ty>* (cast <ty2>* X to <ty>*) into free <ty2>* X
+  if (BitCastInst *CI = dyn_cast<BitCastInst>(Op)) {
+    FI.setOperand(0, CI->getOperand(0));
+    return &FI;
+  }
+  
+  // Change free (gep X, 0,0,0,0) into free(X)
+  if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(Op)) {
+    if (GEPI->hasAllZeroIndices()) {
+      AddToWorkList(GEPI);
+      FI.setOperand(0, GEPI->getOperand(0));
+      return &FI;
+    }
+  }
+  
+  // Change free(malloc) into nothing, if the malloc has a single use.
+  if (MallocInst *MI = dyn_cast<MallocInst>(Op))
+    if (MI->hasOneUse()) {
+      EraseInstFromFunction(FI);
+      return EraseInstFromFunction(*MI);
+    }
 
   return 0;
 }