summaryrefslogtreecommitdiffstats
path: root/lib/Transforms/InstCombine/InstructionCombining.cpp
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2011-08-02 22:08:01 +0000
committerNick Lewycky <nicholas@mxc.ca>2011-08-02 22:08:01 +0000
commitd8030c79fd4531a691381e7e870fe99b8a4cb8a4 (patch)
tree7b239073981a96487c4da6b27e7657e7c762e8af /lib/Transforms/InstCombine/InstructionCombining.cpp
parent0e0a8806d49038b60a0c20427d9f410b01cbb012 (diff)
downloadexternal_llvm-d8030c79fd4531a691381e7e870fe99b8a4cb8a4.zip
external_llvm-d8030c79fd4531a691381e7e870fe99b8a4cb8a4.tar.gz
external_llvm-d8030c79fd4531a691381e7e870fe99b8a4cb8a4.tar.bz2
Teach InstCombine that lifetime intrincs aren't a real user on the result of a
malloc call. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136732 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/InstCombine/InstructionCombining.cpp')
-rw-r--r--lib/Transforms/InstCombine/InstructionCombining.cpp46
1 files changed, 35 insertions, 11 deletions
diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp
index b4a2e2a..5b763c0 100644
--- a/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -1043,7 +1043,10 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
-static bool IsOnlyNullComparedAndFreed(const Value &V) {
+static bool IsOnlyNullComparedAndFreed(const Value &V, int Depth = 0) {
+ if (Depth == 8)
+ return false;
+
for (Value::const_use_iterator UI = V.use_begin(), UE = V.use_end();
UI != UE; ++UI) {
const User *U = *UI;
@@ -1052,6 +1055,20 @@ static bool IsOnlyNullComparedAndFreed(const Value &V) {
if (const ICmpInst *ICI = dyn_cast<ICmpInst>(U))
if (ICI->isEquality() && isa<ConstantPointerNull>(ICI->getOperand(1)))
continue;
+ if (const BitCastInst *BCI = dyn_cast<BitCastInst>(U)) {
+ if (IsOnlyNullComparedAndFreed(*BCI, Depth+1))
+ continue;
+ }
+ if (const GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(U)) {
+ if (GEPI->hasAllZeroIndices() &&
+ IsOnlyNullComparedAndFreed(*GEPI, Depth+1))
+ continue;
+ }
+ if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(U)) {
+ if (II->getIntrinsicID() == Intrinsic::lifetime_start ||
+ II->getIntrinsicID() == Intrinsic::lifetime_end)
+ continue;
+ }
return false;
}
return true;
@@ -1064,22 +1081,29 @@ Instruction *InstCombiner::visitMalloc(Instruction &MI) {
if (IsOnlyNullComparedAndFreed(MI)) {
for (Value::use_iterator UI = MI.use_begin(), UE = MI.use_end();
UI != UE;) {
- // We can assume that every remaining use is a free call or an icmp eq/ne
- // to null, so the cast is safe.
+ // All the users permitted by IsOnlyNullComparedAndFreed are Instructions.
Instruction *I = cast<Instruction>(*UI);
// Early increment here, as we're about to get rid of the user.
++UI;
- if (isFreeCall(I)) {
- EraseInstFromFunction(*cast<CallInst>(I));
- continue;
+ if (CallInst *CI = isFreeCall(I)) {
+ if (CI != I)
+ EraseInstFromFunction(*CI);
+ EraseInstFromFunction(*I);
+ } else if (ICmpInst *C = dyn_cast<ICmpInst>(I)) {
+ ReplaceInstUsesWith(*C,
+ ConstantInt::get(Type::getInt1Ty(C->getContext()),
+ C->isFalseWhenEqual()));
+ EraseInstFromFunction(*C);
+ } else if (I->getType()->isVoidTy()) {
+ // An all-zero GEP or a bitcast.
+ ReplaceInstUsesWith(*I, UndefValue::get(I->getType()));
+ EraseInstFromFunction(*I);
+ } else {
+ // A lifetime intrinsic.
+ EraseInstFromFunction(*I);
}
- // Again, the cast is safe.
- ICmpInst *C = cast<ICmpInst>(I);
- ReplaceInstUsesWith(*C, ConstantInt::get(Type::getInt1Ty(C->getContext()),
- C->isFalseWhenEqual()));
- EraseInstFromFunction(*C);
}
return EraseInstFromFunction(MI);
}