1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

Autoupgrade malloc insts to malloc calls.

Update testcases that rely on malloc insts being present.

Also prematurely remove MallocInst handling from IndMemRemoval and RaiseAllocations to help pass tests in this incremental step.

llvm-svn: 84292
This commit is contained in:
Victor Hernandez 2009-10-17 00:00:19 +00:00
parent 00adf339dd
commit 4d7283f82c
20 changed files with 155 additions and 160 deletions

View File

@ -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)
{

View File

@ -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) {

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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,22 +67,30 @@ bool IndMemRemPass::runOnModule(Module &M) {
}
if (Function* F = M.getFunction("malloc")) {
if (F->isDeclaration() && F->arg_size() == 1 && !F->use_empty()) {
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);
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);
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();
F->replaceAllUsesWith(FN);
changed = true;
}
}
}
return changed;
}

View File

@ -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

View File

@ -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)) ||

View File

@ -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,

View File

@ -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());
if (!MallocF)
// 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);
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);
Result = MCall;
if (Result->getType() != AllocPtrType)
// Create a cast instruction to convert to the right type...
MCast = new BitCastInst(MCall, AllocPtrType, NameStr, InsertBefore);
Result = new BitCastInst(MCall, AllocPtrType, NameStr, InsertBefore);
} else {
MCall = CallInst::Create(MallocF, AllocSize, "malloccall", InsertAtEnd);
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...
MCast = new BitCastInst(MCall, AllocPtrType, NameStr);
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);
}
//===----------------------------------------------------------------------===//

View File

@ -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]

View File

@ -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]

View File

@ -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)

View File

@ -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

View File

@ -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
}

View File

@ -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) {

View File

@ -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]

View File

@ -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) {

View File

@ -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"