summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-10-24 06:35:18 +0000
committerChris Lattner <sabre@nondot.org>2005-10-24 06:35:18 +0000
commit46705b2f2d9cf796aecadb1c9a60047f922f800e (patch)
treefada75b6fae1264e92300f5ba5a50f033ea9b619 /llvm/lib/Transforms
parent355ecc09f84271830a1fef121d38d4df3407a119 (diff)
downloadbcm5719-llvm-46705b2f2d9cf796aecadb1c9a60047f922f800e.tar.gz
bcm5719-llvm-46705b2f2d9cf796aecadb1c9a60047f922f800e.zip
Handle allocations that, even after removing dead uses, still have more than
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. llvm-svn: 23961
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Scalar/InstructionCombining.cpp18
1 files changed, 15 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
index bd85b4abd5d..9ba0512a78b 100644
--- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -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);
}
OpenPOWER on IntegriCloud