summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/BrainF/BrainF.cpp7
-rw-r--r--include/llvm/Instructions.h7
-rw-r--r--lib/AsmParser/LLLexer.cpp4
-rw-r--r--lib/AsmParser/LLParser.cpp44
-rw-r--r--lib/AsmParser/LLParser.h7
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp11
-rw-r--r--lib/Transforms/IPO/IndMemRemoval.cpp37
-rw-r--r--lib/Transforms/IPO/RaiseAllocations.cpp118
-rw-r--r--lib/Transforms/Scalar/Reassociate.cpp3
-rw-r--r--lib/VMCore/Core.cpp8
-rw-r--r--lib/VMCore/Instructions.cpp40
-rw-r--r--test/Transforms/GlobalOpt/malloc-promote-2.ll4
-rw-r--r--test/Transforms/GlobalOpt/malloc-promote-3.ll4
-rw-r--r--test/Transforms/IndMemRem/2009-01-24-Noalias.ll2
-rw-r--r--test/Transforms/InstCombine/cast-malloc.ll2
-rw-r--r--test/Transforms/InstCombine/cast.ll10
-rw-r--r--test/Transforms/InstCombine/getelementptr.ll2
-rw-r--r--test/Transforms/InstCombine/malloc-free-delete.ll2
-rw-r--r--test/Transforms/InstCombine/malloc2.ll1
-rw-r--r--test/Transforms/InstCombine/malloc3.ll2
20 files changed, 155 insertions, 160 deletions
diff --git a/examples/BrainF/BrainF.cpp b/examples/BrainF/BrainF.cpp
index 5cf2b883bc..c64b87f2f3 100644
--- a/examples/BrainF/BrainF.cpp
+++ b/examples/BrainF/BrainF.cpp
@@ -25,6 +25,7 @@
#include "BrainF.h"
#include "llvm/Constants.h"
+#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include "llvm/ADT/STLExtras.h"
#include <iostream>
@@ -78,7 +79,11 @@ void BrainF::header(LLVMContext& C) {
//%arr = malloc i8, i32 %d
ConstantInt *val_mem = ConstantInt::get(C, APInt(32, memtotal));
- ptr_arr = builder->CreateMalloc(IntegerType::getInt8Ty(C), val_mem, "arr");
+ BasicBlock* BB = builder->GetInsertBlock();
+ const Type* IntPtrTy = IntegerType::getInt32Ty(C);
+ ptr_arr = CallInst::CreateMalloc(BB, IntPtrTy, IntegerType::getInt8Ty(C),
+ val_mem, NULL, "arr");
+ BB->getInstList().push_back(cast<Instruction>(ptr_arr));
//call void @llvm.memset.i32(i8 *%arr, i8 0, i32 %d, i32 1)
{
diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h
index b28fcbb951..d9e59ed3a2 100644
--- a/include/llvm/Instructions.h
+++ b/include/llvm/Instructions.h
@@ -1047,7 +1047,7 @@ public:
const Twine &Name = "");
static Value *CreateMalloc(BasicBlock *InsertAtEnd, const Type *IntPtrTy,
const Type *AllocTy, Value *ArraySize = 0,
- const Twine &Name = "");
+ Function* MallocF = 0, const Twine &Name = "");
~CallInst();
@@ -1152,6 +1152,11 @@ public:
const Value *getCalledValue() const { return Op<0>(); }
Value *getCalledValue() { return Op<0>(); }
+ /// setCalledFunction - Set the function called
+ void setCalledFunction(Value* Fn) {
+ Op<0>() = Fn;
+ }
+
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const CallInst *) { return true; }
static inline bool classof(const Instruction *I) {
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index 0e9f1a05fe..6d660111ac 100644
--- a/lib/AsmParser/LLLexer.cpp
+++ b/lib/AsmParser/LLLexer.cpp
@@ -602,6 +602,9 @@ lltok::Kind LLLexer::LexIdentifier() {
// Scan CurPtr ahead, seeing if there is just whitespace before the newline.
if (JustWhitespaceNewLine(CurPtr))
return lltok::kw_zeroext;
+ } else if (Len == 6 && !memcmp(StartChar, "malloc", 6)) {
+ // Autoupgrade malloc instruction
+ return lltok::kw_malloc;
}
// Keywords for instructions.
@@ -641,7 +644,6 @@ lltok::Kind LLLexer::LexIdentifier() {
INSTKEYWORD(unwind, Unwind);
INSTKEYWORD(unreachable, Unreachable);
- INSTKEYWORD(malloc, Malloc);
INSTKEYWORD(alloca, Alloca);
INSTKEYWORD(free, Free);
INSTKEYWORD(load, Load);
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index 1e1ddf07d2..001d56d538 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -69,6 +69,27 @@ 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".
+ if (MallocF) {
+ MallocF->setName("malloc");
+ // If setName() does not set the name to "malloc", then there is already a
+ // 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<CallInst>(user))
+ Call->setCalledFunction(realMallocF);
+ }
+ if (!realMallocF->doesNotAlias(0)) realMallocF->setDoesNotAlias(0);
+ MallocF->eraseFromParent();
+ MallocF = NULL;
+ }
+ }
+
if (!ForwardRefTypes.empty())
return Error(ForwardRefTypes.begin()->second.second,
"use of undefined type named '" +
@@ -2783,8 +2804,8 @@ bool LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
case lltok::kw_call: return ParseCall(Inst, PFS, false);
case lltok::kw_tail: return ParseCall(Inst, PFS, true);
// Memory.
- case lltok::kw_alloca:
- case lltok::kw_malloc: return ParseAlloc(Inst, PFS, KeywordVal);
+ case lltok::kw_alloca: return ParseAlloc(Inst, PFS);
+ case lltok::kw_malloc: return ParseAlloc(Inst, PFS, BB, false);
case lltok::kw_free: return ParseFree(Inst, PFS);
case lltok::kw_load: return ParseLoad(Inst, PFS, false);
case lltok::kw_store: return ParseStore(Inst, PFS, false);
@@ -3445,7 +3466,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
/// ::= 'malloc' Type (',' TypeAndValue)? (',' OptionalInfo)?
/// ::= 'alloca' Type (',' TypeAndValue)? (',' OptionalInfo)?
bool LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS,
- unsigned Opc) {
+ BasicBlock* BB, bool isAlloca) {
PATypeHolder Ty(Type::getVoidTy(Context));
Value *Size = 0;
LocTy SizeLoc;
@@ -3466,10 +3487,21 @@ bool LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS,
if (Size && Size->getType() != Type::getInt32Ty(Context))
return Error(SizeLoc, "element count must be i32");
- if (Opc == Instruction::Malloc)
- Inst = new MallocInst(Ty, Size, Alignment);
- else
+ 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<Function>(M->getOrInsertFunction("autoupgrade_malloc",
+ Int8PtrTy, IntPtrTy, NULL));
+ // "autoupgrade_malloc" updated to "malloc" in ValidateEndOfModule().
+
+ Inst = cast<Instruction>(CallInst::CreateMalloc(BB, IntPtrTy, Ty,
+ Size, MallocF));
+ }
return false;
}
diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h
index 97bf2f309f..5dd6a2e700 100644
--- a/lib/AsmParser/LLParser.h
+++ b/lib/AsmParser/LLParser.h
@@ -75,9 +75,11 @@ namespace llvm {
std::map<std::string, std::pair<GlobalValue*, LocTy> > ForwardRefVals;
std::map<unsigned, std::pair<GlobalValue*, LocTy> > ForwardRefValIDs;
std::vector<GlobalValue*> NumberedVals;
+ Function* MallocF;
public:
LLParser(MemoryBuffer *F, SourceMgr &SM, SMDiagnostic &Err, Module *m) :
- Context(m->getContext()), Lex(F, SM, Err, m->getContext()), M(m) {}
+ Context(m->getContext()), Lex(F, SM, Err, m->getContext()),
+ M(m), MallocF(NULL) {}
bool Run();
LLVMContext& getContext() { return Context; }
@@ -276,7 +278,8 @@ namespace llvm {
bool ParseShuffleVector(Instruction *&I, PerFunctionState &PFS);
bool ParsePHI(Instruction *&I, PerFunctionState &PFS);
bool ParseCall(Instruction *&I, PerFunctionState &PFS, bool isTail);
- bool ParseAlloc(Instruction *&I, PerFunctionState &PFS, unsigned Opc);
+ bool ParseAlloc(Instruction *&I, PerFunctionState &PFS,
+ BasicBlock *BB = 0, bool isAlloca = true);
bool ParseFree(Instruction *&I, PerFunctionState &PFS);
bool ParseLoad(Instruction *&I, PerFunctionState &PFS, bool isVolatile);
bool ParseStore(Instruction *&I, PerFunctionState &PFS, bool isVolatile);
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 4eb12c69eb..fe4556f0a2 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -2044,14 +2044,21 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
}
case bitc::FUNC_CODE_INST_MALLOC: { // MALLOC: [instty, op, align]
+ // Autoupgrade malloc instruction to malloc call.
if (Record.size() < 3)
return Error("Invalid MALLOC record");
const PointerType *Ty =
dyn_cast_or_null<PointerType>(getTypeByID(Record[0]));
Value *Size = getFnValueByID(Record[1], Type::getInt32Ty(Context));
- unsigned Align = Record[2];
if (!Ty || !Size) return Error("Invalid MALLOC record");
- I = new MallocInst(Ty->getElementType(), Size, (1 << Align) >> 1);
+ 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<Instruction>(Malloc);
InstructionList.push_back(I);
break;
}
diff --git a/lib/Transforms/IPO/IndMemRemoval.cpp b/lib/Transforms/IPO/IndMemRemoval.cpp
index e7884ec634..9bd5a92772 100644
--- a/lib/Transforms/IPO/IndMemRemoval.cpp
+++ b/lib/Transforms/IPO/IndMemRemoval.cpp
@@ -24,6 +24,7 @@
#include "llvm/DerivedTypes.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Target/TargetData.h"
using namespace llvm;
STATISTIC(NumBounceSites, "Number of sites modified");
@@ -66,20 +67,28 @@ bool IndMemRemPass::runOnModule(Module &M) {
}
if (Function* F = M.getFunction("malloc")) {
if (F->isDeclaration() && F->arg_size() == 1 && !F->use_empty()) {
- Function* FN = Function::Create(F->getFunctionType(),
- GlobalValue::LinkOnceAnyLinkage,
- "malloc_llvm_bounce", &M);
- FN->setDoesNotAlias(0);
- BasicBlock* bb = BasicBlock::Create(M.getContext(), "entry",FN);
- Instruction* c = CastInst::CreateIntegerCast(
- FN->arg_begin(), Type::getInt32Ty(M.getContext()), false, "c", bb);
- Instruction* a = new MallocInst(Type::getInt8Ty(M.getContext()),
- c, "m", bb);
- ReturnInst::Create(M.getContext(), a, bb);
- ++NumBounce;
- NumBounceSites += F->getNumUses();
- F->replaceAllUsesWith(FN);
- changed = true;
+ TargetData* TD = getAnalysisIfAvailable<TargetData>();
+ if (TD) {
+ Function* FN = Function::Create(F->getFunctionType(),
+ GlobalValue::LinkOnceAnyLinkage,
+ "malloc_llvm_bounce", &M);
+ F->replaceAllUsesWith(FN);
+ FN->setDoesNotAlias(0);
+ BasicBlock* bb = BasicBlock::Create(M.getContext(), "entry", FN);
+ const Type* IntPtrTy = TD->getIntPtrType(M.getContext());
+ Value* c = FN->arg_begin();
+ if (FN->arg_begin()->getType() != IntPtrTy)
+ c = CastInst::CreateIntegerCast(FN->arg_begin(), IntPtrTy, false,
+ "c", bb);
+ Value* a = CallInst::CreateMalloc(bb, IntPtrTy,
+ Type::getInt8Ty(M.getContext()),
+ c, NULL, "m");
+ bb->getInstList().push_back(cast<Instruction>(a));
+ ReturnInst::Create(M.getContext(), a, bb);
+ ++NumBounce;
+ NumBounceSites += F->getNumUses();
+ changed = true;
+ }
}
}
return changed;
diff --git a/lib/Transforms/IPO/RaiseAllocations.cpp b/lib/Transforms/IPO/RaiseAllocations.cpp
index 4c1f26d50d..deb4405754 100644
--- a/lib/Transforms/IPO/RaiseAllocations.cpp
+++ b/lib/Transforms/IPO/RaiseAllocations.cpp
@@ -1,4 +1,4 @@
-//===- RaiseAllocations.cpp - Convert @malloc & @free calls to insts ------===//
+//===- RaiseAllocations.cpp - Convert @free calls to insts ------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines the RaiseAllocations pass which convert malloc and free
-// calls to malloc and free instructions.
+// This file defines the RaiseAllocations pass which convert free calls to free
+// instructions.
//
//===----------------------------------------------------------------------===//
@@ -29,19 +29,19 @@ using namespace llvm;
STATISTIC(NumRaised, "Number of allocations raised");
namespace {
- // RaiseAllocations - Turn @malloc and @free calls into the appropriate
+ // RaiseAllocations - Turn @free calls into the appropriate
// instruction.
//
class VISIBILITY_HIDDEN RaiseAllocations : public ModulePass {
- Function *MallocFunc; // Functions in the module we are processing
- Function *FreeFunc; // Initialized by doPassInitializationVirt
+ Function *FreeFunc; // Functions in the module we are processing
+ // Initialized by doPassInitializationVirt
public:
static char ID; // Pass identification, replacement for typeid
RaiseAllocations()
- : ModulePass(&ID), MallocFunc(0), FreeFunc(0) {}
+ : ModulePass(&ID), FreeFunc(0) {}
// doPassInitialization - For the raise allocations pass, this finds a
- // declaration for malloc and free if they exist.
+ // declaration for free if it exists.
//
void doInitialization(Module &M);
@@ -61,50 +61,16 @@ ModulePass *llvm::createRaiseAllocationsPass() {
}
-// If the module has a symbol table, they might be referring to the malloc and
-// free functions. If this is the case, grab the method pointers that the
-// module is using.
+// If the module has a symbol table, they might be referring to the free
+// function. If this is the case, grab the method pointers that the module is
+// using.
//
-// Lookup @malloc and @free in the symbol table, for later use. If they don't
+// Lookup @free in the symbol table, for later use. If they don't
// exist, or are not external, we do not worry about converting calls to that
// function into the appropriate instruction.
//
void RaiseAllocations::doInitialization(Module &M) {
- // Get Malloc and free prototypes if they exist!
- MallocFunc = M.getFunction("malloc");
- if (MallocFunc) {
- const FunctionType* TyWeHave = MallocFunc->getFunctionType();
-
- // Get the expected prototype for malloc
- const FunctionType *Malloc1Type =
- FunctionType::get(Type::getInt8PtrTy(M.getContext()),
- std::vector<const Type*>(1,
- Type::getInt64Ty(M.getContext())), false);
-
- // Chck to see if we got the expected malloc
- if (TyWeHave != Malloc1Type) {
- // Check to see if the prototype is wrong, giving us i8*(i32) * malloc
- // This handles the common declaration of: 'void *malloc(unsigned);'
- const FunctionType *Malloc2Type =
- FunctionType::get(PointerType::getUnqual(
- Type::getInt8Ty(M.getContext())),
- std::vector<const Type*>(1,
- Type::getInt32Ty(M.getContext())), false);
- if (TyWeHave != Malloc2Type) {
- // Check to see if the prototype is missing, giving us
- // i8*(...) * malloc
- // This handles the common declaration of: 'void *malloc();'
- const FunctionType *Malloc3Type =
- FunctionType::get(PointerType::getUnqual(
- Type::getInt8Ty(M.getContext())),
- true);
- if (TyWeHave != Malloc3Type)
- // Give up
- MallocFunc = 0;
- }
- }
- }
-
+ // Get free prototype if it exists!
FreeFunc = M.getFunction("free");
if (FreeFunc) {
const FunctionType* TyWeHave = FreeFunc->getFunctionType();
@@ -138,72 +104,18 @@ void RaiseAllocations::doInitialization(Module &M) {
}
// Don't mess with locally defined versions of these functions...
- if (MallocFunc && !MallocFunc->isDeclaration()) MallocFunc = 0;
if (FreeFunc && !FreeFunc->isDeclaration()) FreeFunc = 0;
}
// run - Transform calls into instructions...
//
bool RaiseAllocations::runOnModule(Module &M) {
- // Find the malloc/free prototypes...
+ // Find the free prototype...
doInitialization(M);
bool Changed = false;
- // First, process all of the malloc calls...
- if (MallocFunc) {
- std::vector<User*> Users(MallocFunc->use_begin(), MallocFunc->use_end());
- std::vector<Value*> EqPointers; // Values equal to MallocFunc
- while (!Users.empty()) {
- User *U = Users.back();
- Users.pop_back();
-
- if (Instruction *I = dyn_cast<Instruction>(U)) {
- CallSite CS = CallSite::get(I);
- if (CS.getInstruction() && !CS.arg_empty() &&
- (CS.getCalledFunction() == MallocFunc ||
- std::find(EqPointers.begin(), EqPointers.end(),
- CS.getCalledValue()) != EqPointers.end())) {
-
- Value *Source = *CS.arg_begin();
-
- // If no prototype was provided for malloc, we may need to cast the
- // source size.
- if (Source->getType() != Type::getInt32Ty(M.getContext()))
- Source =
- CastInst::CreateIntegerCast(Source,
- Type::getInt32Ty(M.getContext()),
- false/*ZExt*/,
- "MallocAmtCast", I);
-
- MallocInst *MI = new MallocInst(Type::getInt8Ty(M.getContext()),
- Source, "", I);
- MI->takeName(I);
- I->replaceAllUsesWith(MI);
-
- // If the old instruction was an invoke, add an unconditional branch
- // before the invoke, which will become the new terminator.
- if (InvokeInst *II = dyn_cast<InvokeInst>(I))
- BranchInst::Create(II->getNormalDest(), I);
-
- // Delete the old call site
- I->eraseFromParent();
- Changed = true;
- ++NumRaised;
- }
- } else if (GlobalValue *GV = dyn_cast<GlobalValue>(U)) {
- Users.insert(Users.end(), GV->use_begin(), GV->use_end());
- EqPointers.push_back(GV);
- } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) {
- if (CE->isCast()) {
- Users.insert(Users.end(), CE->use_begin(), CE->use_end());
- EqPointers.push_back(CE);
- }
- }
- }
- }
-
- // Next, process all free calls...
+ // Process all free calls...
if (FreeFunc) {
std::vector<User*> Users(FreeFunc->use_begin(), FreeFunc->use_end());
std::vector<Value*> EqPointers; // Values equal to FreeFunc
diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp
index e6ffac251b..9160654c3d 100644
--- a/lib/Transforms/Scalar/Reassociate.cpp
+++ b/lib/Transforms/Scalar/Reassociate.cpp
@@ -29,6 +29,7 @@
#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"
@@ -121,7 +122,7 @@ static bool isUnmovableInstruction(Instruction *I) {
if (I->getOpcode() == Instruction::PHI ||
I->getOpcode() == Instruction::Alloca ||
I->getOpcode() == Instruction::Load ||
- I->getOpcode() == Instruction::Malloc ||
+ I->getOpcode() == Instruction::Malloc || isMalloc(I) ||
I->getOpcode() == Instruction::Invoke ||
(I->getOpcode() == Instruction::Call &&
!isa<DbgInfoIntrinsic>(I)) ||
diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp
index bff308727f..5b8295f60d 100644
--- a/lib/VMCore/Core.cpp
+++ b/lib/VMCore/Core.cpp
@@ -1699,12 +1699,16 @@ LLVMValueRef LLVMBuildNot(LLVMBuilderRef B, LLVMValueRef V, const char *Name) {
LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef B, LLVMTypeRef Ty,
const char *Name) {
- return wrap(unwrap(B)->CreateMalloc(unwrap(Ty), 0, Name));
+ const Type* IntPtrT = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext());
+ return wrap(CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(), IntPtrT,
+ unwrap(Ty), 0, 0, Twine(Name)));
}
LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef B, LLVMTypeRef Ty,
LLVMValueRef Val, const char *Name) {
- return wrap(unwrap(B)->CreateMalloc(unwrap(Ty), unwrap(Val), Name));
+ const Type* IntPtrT = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext());
+ return wrap(CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(), IntPtrT,
+ unwrap(Ty), unwrap(Val), 0, Twine(Name)));
}
LLVMValueRef LLVMBuildAlloca(LLVMBuilderRef B, LLVMTypeRef Ty,
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index f3d15cb2b8..4ff253a7db 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -462,7 +462,8 @@ static Value *checkArraySize(Value *Amt, const Type *IntPtrTy) {
static Value *createMalloc(Instruction *InsertBefore, BasicBlock *InsertAtEnd,
const Type *IntPtrTy, const Type *AllocTy,
- Value *ArraySize, const Twine &NameStr) {
+ Value *ArraySize, Function* MallocF,
+ const Twine &NameStr) {
assert(((!InsertBefore && InsertAtEnd) || (InsertBefore && !InsertAtEnd)) &&
"createMalloc needs either InsertBefore or InsertAtEnd");
@@ -499,27 +500,34 @@ static Value *createMalloc(Instruction *InsertBefore, BasicBlock *InsertAtEnd,
BasicBlock* BB = InsertBefore ? InsertBefore->getParent() : InsertAtEnd;
Module* M = BB->getParent()->getParent();
const Type *BPTy = Type::getInt8PtrTy(BB->getContext());
- // prototype malloc as "void *malloc(size_t)"
- Constant *MallocF = M->getOrInsertFunction("malloc", BPTy, IntPtrTy, NULL);
- if (!cast<Function>(MallocF)->doesNotAlias(0))
- cast<Function>(MallocF)->setDoesNotAlias(0);
+ if (!MallocF)
+ // prototype malloc as "void *malloc(size_t)"
+ MallocF = cast<Function>(M->getOrInsertFunction("malloc", BPTy,
+ IntPtrTy, NULL));
+ if (!MallocF->doesNotAlias(0)) MallocF->setDoesNotAlias(0);
const PointerType *AllocPtrType = PointerType::getUnqual(AllocTy);
CallInst *MCall = NULL;
- Value *MCast = NULL;
+ Value *Result = NULL;
if (InsertBefore) {
MCall = CallInst::Create(MallocF, AllocSize, "malloccall", InsertBefore);
- // Create a cast instruction to convert to the right type...
- MCast = new BitCastInst(MCall, AllocPtrType, NameStr, InsertBefore);
+ Result = MCall;
+ if (Result->getType() != AllocPtrType)
+ // Create a cast instruction to convert to the right type...
+ Result = new BitCastInst(MCall, AllocPtrType, NameStr, InsertBefore);
} else {
- MCall = CallInst::Create(MallocF, AllocSize, "malloccall", InsertAtEnd);
- // Create a cast instruction to convert to the right type...
- MCast = new BitCastInst(MCall, AllocPtrType, NameStr);
+ MCall = CallInst::Create(MallocF, AllocSize, "malloccall");
+ Result = MCall;
+ if (Result->getType() != AllocPtrType) {
+ InsertAtEnd->getInstList().push_back(MCall);
+ // Create a cast instruction to convert to the right type...
+ Result = new BitCastInst(MCall, AllocPtrType, NameStr);
+ }
}
MCall->setTailCall();
assert(MCall->getType() != Type::getVoidTy(BB->getContext()) &&
"Malloc has void return type");
- return MCast;
+ return Result;
}
/// CreateMalloc - Generate the IR for a call to malloc:
@@ -531,7 +539,8 @@ static Value *createMalloc(Instruction *InsertBefore, BasicBlock *InsertAtEnd,
Value *CallInst::CreateMalloc(Instruction *InsertBefore, const Type *IntPtrTy,
const Type *AllocTy, Value *ArraySize,
const Twine &Name) {
- return createMalloc(InsertBefore, NULL, IntPtrTy, AllocTy, ArraySize, Name);
+ return createMalloc(InsertBefore, NULL, IntPtrTy, AllocTy,
+ ArraySize, NULL, Name);
}
/// CreateMalloc - Generate the IR for a call to malloc:
@@ -544,8 +553,9 @@ Value *CallInst::CreateMalloc(Instruction *InsertBefore, const Type *IntPtrTy,
/// responsibility of the caller.
Value *CallInst::CreateMalloc(BasicBlock *InsertAtEnd, const Type *IntPtrTy,
const Type *AllocTy, Value *ArraySize,
- const Twine &Name) {
- return createMalloc(NULL, InsertAtEnd, IntPtrTy, AllocTy, ArraySize, Name);
+ Function* MallocF, const Twine &Name) {
+ return createMalloc(NULL, InsertAtEnd, IntPtrTy, AllocTy,
+ ArraySize, MallocF, Name);
}
//===----------------------------------------------------------------------===//
diff --git a/test/Transforms/GlobalOpt/malloc-promote-2.ll b/test/Transforms/GlobalOpt/malloc-promote-2.ll
index 0d03835cf5..d3d225260a 100644
--- a/test/Transforms/GlobalOpt/malloc-promote-2.ll
+++ b/test/Transforms/GlobalOpt/malloc-promote-2.ll
@@ -1,4 +1,6 @@
-; RUN: opt < %s -globalopt -S | not grep malloc
+; RUN: opt < %s -globalopt -globaldce -S | not grep malloc
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "i686-apple-darwin8"
@G = internal global i32* null ; <i32**> [#uses=3]
diff --git a/test/Transforms/GlobalOpt/malloc-promote-3.ll b/test/Transforms/GlobalOpt/malloc-promote-3.ll
index d4ee4e861c..a920b61150 100644
--- a/test/Transforms/GlobalOpt/malloc-promote-3.ll
+++ b/test/Transforms/GlobalOpt/malloc-promote-3.ll
@@ -1,4 +1,6 @@
-; RUN: opt < %s -globalopt -S | not grep malloc
+; RUN: opt < %s -globalopt -globaldce -S | not grep malloc
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "i686-apple-darwin8"
@G = internal global i32* null ; <i32**> [#uses=4]
diff --git a/test/Transforms/IndMemRem/2009-01-24-Noalias.ll b/test/Transforms/IndMemRem/2009-01-24-Noalias.ll
index b6d98031b7..043291e756 100644
--- a/test/Transforms/IndMemRem/2009-01-24-Noalias.ll
+++ b/test/Transforms/IndMemRem/2009-01-24-Noalias.ll
@@ -1,4 +1,6 @@
; RUN: opt < %s -indmemrem -S | grep bounce | grep noalias
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "i686-apple-darwin8"
declare i8* @malloc(i32)
diff --git a/test/Transforms/InstCombine/cast-malloc.ll b/test/Transforms/InstCombine/cast-malloc.ll
index 3754032cc2..43a1489277 100644
--- a/test/Transforms/InstCombine/cast-malloc.ll
+++ b/test/Transforms/InstCombine/cast-malloc.ll
@@ -1,6 +1,6 @@
; test that casted mallocs get converted to malloc of the right type
; RUN: opt < %s -instcombine -S | \
-; RUN: not grep bitcast
+; RUN: grep bitcast | count 1
; The target datalayout is important for this test case. We have to tell
; instcombine that the ABI alignment for a long is 4-bytes, not 8, otherwise
diff --git a/test/Transforms/InstCombine/cast.ll b/test/Transforms/InstCombine/cast.ll
index 9835d657c9..c5266f3b86 100644
--- a/test/Transforms/InstCombine/cast.ll
+++ b/test/Transforms/InstCombine/cast.ll
@@ -102,8 +102,8 @@ define i32* @test12() {
%p = malloc [4 x i8] ; <[4 x i8]*> [#uses=1]
%c = bitcast [4 x i8]* %p to i32* ; <i32*> [#uses=1]
ret i32* %c
-; CHECK: %p = malloc i32
-; CHECK: ret i32* %p
+; CHECK: %malloccall = tail call i8* @malloc(i32 ptrtoint ([4 x i8]* getelementptr ([4 x i8]* null, i32 1) to i32))
+; CHECK: ret i32* %c
}
define i8* @test13(i64 %A) {
@@ -274,9 +274,9 @@ define void @test32(double** %tmp) {
%tmp8.upgrd.1 = bitcast [16 x i8]* %tmp8 to double* ; <double*> [#uses=1]
store double* %tmp8.upgrd.1, double** %tmp
ret void
-; CHECK: %tmp81 = malloc [2 x double]
-; CHECK: %tmp81.sub = getelementptr inbounds [2 x double]* %tmp81, i64 0, i64 0
-; CHECK: store double* %tmp81.sub, double** %tmp
+; CHECK: %malloccall = tail call i8* @malloc(i32 ptrtoint ([16 x i8]* getelementptr ([16 x i8]* null, i32 1) to i32))
+; CHECK: %tmp8.upgrd.1 = bitcast i8* %malloccall to double*
+; CHECK: store double* %tmp8.upgrd.1, double** %tmp
; CHECK: ret void
}
diff --git a/test/Transforms/InstCombine/getelementptr.ll b/test/Transforms/InstCombine/getelementptr.ll
index ffaa6afa85..285e0ba602 100644
--- a/test/Transforms/InstCombine/getelementptr.ll
+++ b/test/Transforms/InstCombine/getelementptr.ll
@@ -58,7 +58,7 @@ define i32* @test6() {
%B = getelementptr i32* %A, i64 2
ret i32* %B
; CHECK: @test6
-; CHECK: getelementptr [4 x i32]* %M, i64 0, i64 2
+; CHECK: getelementptr i8* %malloccall, i64 8
}
define i32* @test7(i32* %I, i64 %C, i64 %D) {
diff --git a/test/Transforms/InstCombine/malloc-free-delete.ll b/test/Transforms/InstCombine/malloc-free-delete.ll
index 2ed5ec6996..fd91e447bd 100644
--- a/test/Transforms/InstCombine/malloc-free-delete.ll
+++ b/test/Transforms/InstCombine/malloc-free-delete.ll
@@ -1,5 +1,5 @@
; RUN: opt < %s -instcombine -S | grep {ret i32 0}
-; RUN: opt < %s -instcombine -S | not grep malloc
+; RUN: opt < %s -instcombine -globaldce -S | not grep malloc
; PR1201
define i32 @main(i32 %argc, i8** %argv) {
%c_19 = alloca i8* ; <i8**> [#uses=2]
diff --git a/test/Transforms/InstCombine/malloc2.ll b/test/Transforms/InstCombine/malloc2.ll
index 102422ee5f..cc1506b6b1 100644
--- a/test/Transforms/InstCombine/malloc2.ll
+++ b/test/Transforms/InstCombine/malloc2.ll
@@ -1,5 +1,4 @@
; RUN: opt < %s -instcombine -S | grep {ret i32 0}
-; RUN: opt < %s -instcombine -S | not grep malloc
; PR1313
define i32 @test1(i32 %argc, i8* %argv, i8* %envp) {
diff --git a/test/Transforms/InstCombine/malloc3.ll b/test/Transforms/InstCombine/malloc3.ll
index cd407ffb02..f1c0cae15a 100644
--- a/test/Transforms/InstCombine/malloc3.ll
+++ b/test/Transforms/InstCombine/malloc3.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -instcombine -S | grep {malloc.*struct.foo} | count 2
+; RUN: opt < %s -instcombine -S | not grep load
; PR1728
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"