Handle allocations that, even after removing dead uses, still have more than
authorChris Lattner <sabre@nondot.org>
Mon, 24 Oct 2005 06:35:18 +0000 (06:35 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 24 Oct 2005 06:35:18 +0000 (06:35 +0000)
one use (but one is a cast).  This handles the very common case of:

 X = alloc [n x byte]
 Y = cast X to somethingbetter
 seteq X, null

In order to avoid infinite looping when there are multiple casts, we only
allow this if the xform is strictly increasing the alignment of the
allocation.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23961 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp

index bd85b4abd5d0adc6839e176af64951ece6253b54..9ba0512a78b29b7a02c9e4e314c4bb4414f3805c 100644 (file)
@@ -3788,9 +3788,6 @@ Instruction *InstCombiner::PromoteCastOfAllocation(CastInst &CI,
     }
   }
   
-  // Finally, if the instruction now has one use, delete it.
-  if (!AI.hasOneUse()) return 0;
-  
   // Get the type really allocated and the type casted to.
   const Type *AllocElTy = AI.getAllocatedType();
   const Type *CastElTy = PTy->getElementType();
@@ -3800,6 +3797,11 @@ Instruction *InstCombiner::PromoteCastOfAllocation(CastInst &CI,
   unsigned CastElTyAlign = TD->getTypeSize(CastElTy);
   if (CastElTyAlign < AllocElTyAlign) return 0;
 
+  // If the allocation has multiple uses, only promote it if we are strictly
+  // increasing the alignment of the resultant allocation.  If we keep it the
+  // same, we open the door to infinite loops of various kinds.
+  if (!AI.hasOneUse() && CastElTyAlign == AllocElTyAlign) return 0;
+
   uint64_t AllocElTySize = TD->getTypeSize(AllocElTy);
   uint64_t CastElTySize = TD->getTypeSize(CastElTy);
 
@@ -3815,6 +3817,16 @@ Instruction *InstCombiner::PromoteCastOfAllocation(CastInst &CI,
   else
     New = new AllocaInst(CastElTy, Amt, Name);
   InsertNewInstBefore(New, AI);
+  
+  // If the allocation has multiple uses, insert a cast and change all things
+  // that used it to use the new cast.  This will also hack on CI, but it will
+  // die soon.
+  if (!AI.hasOneUse()) {
+    AddUsesToWorkList(AI);
+    CastInst *NewCast = new CastInst(New, AI.getType(), "tmpcast");
+    InsertNewInstBefore(NewCast, AI);
+    AI.replaceAllUsesWith(NewCast);
+  }
   return ReplaceInstUsesWith(CI, New);
 }