diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index f1d5e4ffbb7..d21f98707fe 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -69,7 +69,7 @@ bool LLParser::Run() { /// ValidateEndOfModule - Do final validity and sanity checks at the end of the /// module. bool LLParser::ValidateEndOfModule() { - // Update auto-upgraded malloc calls from "autoupgrade_malloc" to "malloc". + // Update auto-upgraded malloc calls to "malloc". // FIXME: Remove in LLVM 3.0. if (MallocF) { MallocF->setName("malloc"); @@ -77,15 +77,10 @@ bool LLParser::ValidateEndOfModule() { // declaration of "malloc". In that case, iterate over all calls to MallocF // and get them to call the declared "malloc" instead. if (MallocF->getName() != "malloc") { - Function* realMallocF = M->getFunction("malloc"); - for (User::use_iterator UI = MallocF->use_begin(), UE= MallocF->use_end(); - UI != UE; ) { - User* user = *UI; - UI++; - if (CallInst *Call = dyn_cast(user)) - Call->setCalledFunction(realMallocF); - } - if (!realMallocF->doesNotAlias(0)) realMallocF->setDoesNotAlias(0); + Constant* RealMallocF = M->getFunction("malloc"); + if (RealMallocF->getType() != MallocF->getType()) + RealMallocF = ConstantExpr::getBitCast(RealMallocF, MallocF->getType()); + MallocF->replaceAllUsesWith(RealMallocF); MallocF->eraseFromParent(); MallocF = NULL; } @@ -3482,21 +3477,21 @@ bool LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS, if (Size && Size->getType() != Type::getInt32Ty(Context)) return Error(SizeLoc, "element count must be i32"); - if (isAlloca) + if (isAlloca) { Inst = new AllocaInst(Ty, Size, Alignment); - else { - // Autoupgrade old malloc instruction to malloc call. - const Type* IntPtrTy = Type::getInt32Ty(Context); - const Type* Int8PtrTy = PointerType::getUnqual(Type::getInt8Ty(Context)); - if (!MallocF) - // Prototype malloc as "void *autoupgrade_malloc(int32)". - MallocF = cast(M->getOrInsertFunction("autoupgrade_malloc", - Int8PtrTy, IntPtrTy, NULL)); - // "autoupgrade_malloc" updated to "malloc" in ValidateEndOfModule(). - - Inst = cast(CallInst::CreateMalloc(BB, IntPtrTy, Ty, - Size, MallocF)); + return false; } + + // Autoupgrade old malloc instruction to malloc call. + // FIXME: Remove in LLVM 3.0. + const Type *IntPtrTy = Type::getInt32Ty(Context); + const Type *Int8PtrTy = Type::getInt8PtrTy(Context); + if (!MallocF) + // Prototype malloc as "void *(int32)". + // This function is renamed as "malloc" in ValidateEndOfModule(). + MallocF = cast(M->getOrInsertFunction(NULL, Int8PtrTy, + IntPtrTy, NULL)); + Inst = CallInst::CreateMalloc(BB, IntPtrTy, Ty, Size, MallocF); return false; } diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index fe4556f0a29..c9eba24b823 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2045,6 +2045,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_MALLOC: { // MALLOC: [instty, op, align] // Autoupgrade malloc instruction to malloc call. + // FIXME: Remove in LLVM 3.0. if (Record.size() < 3) return Error("Invalid MALLOC record"); const PointerType *Ty = @@ -2052,13 +2053,9 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { Value *Size = getFnValueByID(Record[1], Type::getInt32Ty(Context)); if (!Ty || !Size) return Error("Invalid MALLOC record"); if (!CurBB) return Error("Invalid malloc instruction with no BB"); - const Type* Int32Ty = IntegerType::getInt32Ty(CurBB->getContext()); - if (Size->getType() != Int32Ty) - Size = CastInst::CreateIntegerCast(Size, Int32Ty, false /*ZExt*/, - "", CurBB); - Value* Malloc = CallInst::CreateMalloc(CurBB, Int32Ty, - Ty->getElementType(), Size, NULL); - I = cast(Malloc); + const Type *Int32Ty = IntegerType::getInt32Ty(CurBB->getContext()); + I = CallInst::CreateMalloc(CurBB, Int32Ty, Ty->getElementType(), + Size, NULL); InstructionList.push_back(I); break; } diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 46fac196dbb..1088684b0a6 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -6359,10 +6359,28 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { // can assume it is successful and remove the malloc. if (isMalloc(LHSI) && LHSI->hasOneUse() && isa(RHSC)) { - Worklist.Add(LHSI); - return ReplaceInstUsesWith(I, + // Need to explicitly erase malloc call here, instead of adding it to + // Worklist, because it won't get DCE'd from the Worklist since + // isInstructionTriviallyDead() returns false for function calls. + // It is OK to replace LHSI/MallocCall with Undef because the + // instruction that uses it will be erased via Worklist. + if (extractMallocCall(LHSI)) { + LHSI->replaceAllUsesWith(UndefValue::get(LHSI->getType())); + EraseInstFromFunction(*LHSI); + return ReplaceInstUsesWith(I, ConstantInt::get(Type::getInt1Ty(*Context), !I.isTrueWhenEqual())); + } + if (CallInst* MallocCall = extractMallocCallFromBitCast(LHSI)) + if (MallocCall->hasOneUse()) { + MallocCall->replaceAllUsesWith( + UndefValue::get(MallocCall->getType())); + EraseInstFromFunction(*MallocCall); + Worklist.Add(LHSI); // The malloc's bitcast use. + return ReplaceInstUsesWith(I, + ConstantInt::get(Type::getInt1Ty(*Context), + !I.isTrueWhenEqual())); + } } break; } diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp index 00d450812c0..af29f978084 100644 --- a/lib/Transforms/Scalar/Reassociate.cpp +++ b/lib/Transforms/Scalar/Reassociate.cpp @@ -29,7 +29,6 @@ #include "llvm/IntrinsicInst.h" #include "llvm/LLVMContext.h" #include "llvm/Pass.h" -#include "llvm/Analysis/MallocHelper.h" #include "llvm/Assembly/Writer.h" #include "llvm/Support/CFG.h" #include "llvm/Support/Debug.h" @@ -122,7 +121,6 @@ static bool isUnmovableInstruction(Instruction *I) { if (I->getOpcode() == Instruction::PHI || I->getOpcode() == Instruction::Alloca || I->getOpcode() == Instruction::Load || - isMalloc(I) || I->getOpcode() == Instruction::Invoke || (I->getOpcode() == Instruction::Call && !isa(I)) || diff --git a/test/Transforms/InstCombine/malloc2.ll b/test/Transforms/InstCombine/malloc2.ll index cc1506b6b19..8462dacf857 100644 --- a/test/Transforms/InstCombine/malloc2.ll +++ b/test/Transforms/InstCombine/malloc2.ll @@ -1,18 +1,22 @@ -; RUN: opt < %s -instcombine -S | grep {ret i32 0} +; RUN: opt < %s -instcombine -S | FileCheck %s ; PR1313 define i32 @test1(i32 %argc, i8* %argv, i8* %envp) { %tmp15.i.i.i23 = malloc [2564 x i32] ; <[2564 x i32]*> [#uses=1] +; CHECK-NOT: call i8* @malloc %c = icmp eq [2564 x i32]* %tmp15.i.i.i23, null ; :0 [#uses=1] %retval = zext i1 %c to i32 ; [#uses=1] ret i32 %retval +; CHECK: ret i32 0 } define i32 @test2(i32 %argc, i8* %argv, i8* %envp) { %tmp15.i.i.i23 = malloc [2564 x i32] ; <[2564 x i32]*> [#uses=1] +; CHECK-NOT: call i8* @malloc %X = bitcast [2564 x i32]* %tmp15.i.i.i23 to i32* %c = icmp ne i32* %X, null %retval = zext i1 %c to i32 ; [#uses=1] ret i32 %retval +; CHECK: ret i32 1 }