mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-27 02:31:09 +00:00
Auto-upgrade malloc instructions to malloc calls.
Reviewed by Devang Patel. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82694 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c34666ee18
commit
96b930ddc7
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "BrainF.h"
|
#include "BrainF.h"
|
||||||
#include "llvm/Constants.h"
|
#include "llvm/Constants.h"
|
||||||
|
#include "llvm/Instructions.h"
|
||||||
#include "llvm/Intrinsics.h"
|
#include "llvm/Intrinsics.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -78,7 +79,11 @@ void BrainF::header(LLVMContext& C) {
|
|||||||
|
|
||||||
//%arr = malloc i8, i32 %d
|
//%arr = malloc i8, i32 %d
|
||||||
ConstantInt *val_mem = ConstantInt::get(C, APInt(32, memtotal));
|
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)
|
//call void @llvm.memset.i32(i8 *%arr, i8 0, i32 %d, i32 1)
|
||||||
{
|
{
|
||||||
|
@ -1044,7 +1044,7 @@ public:
|
|||||||
const Twine &Name = "");
|
const Twine &Name = "");
|
||||||
static Value *CreateMalloc(BasicBlock *InsertAtEnd, const Type *IntPtrTy,
|
static Value *CreateMalloc(BasicBlock *InsertAtEnd, const Type *IntPtrTy,
|
||||||
const Type *AllocTy, Value *ArraySize = 0,
|
const Type *AllocTy, Value *ArraySize = 0,
|
||||||
const Twine &Name = "");
|
Function* MallocF = 0, const Twine &Name = "");
|
||||||
|
|
||||||
~CallInst();
|
~CallInst();
|
||||||
|
|
||||||
@ -1149,6 +1149,11 @@ public:
|
|||||||
const Value *getCalledValue() const { return Op<0>(); }
|
const Value *getCalledValue() const { return Op<0>(); }
|
||||||
Value *getCalledValue() { 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:
|
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||||
static inline bool classof(const CallInst *) { return true; }
|
static inline bool classof(const CallInst *) { return true; }
|
||||||
static inline bool classof(const Instruction *I) {
|
static inline bool classof(const Instruction *I) {
|
||||||
|
@ -602,6 +602,9 @@ lltok::Kind LLLexer::LexIdentifier() {
|
|||||||
// Scan CurPtr ahead, seeing if there is just whitespace before the newline.
|
// Scan CurPtr ahead, seeing if there is just whitespace before the newline.
|
||||||
if (JustWhitespaceNewLine(CurPtr))
|
if (JustWhitespaceNewLine(CurPtr))
|
||||||
return lltok::kw_zeroext;
|
return lltok::kw_zeroext;
|
||||||
|
} else if (Len == 6 && !memcmp(StartChar, "malloc", 6)) {
|
||||||
|
// Autoupgrade malloc instruction
|
||||||
|
return lltok::kw_malloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keywords for instructions.
|
// Keywords for instructions.
|
||||||
@ -641,7 +644,6 @@ lltok::Kind LLLexer::LexIdentifier() {
|
|||||||
INSTKEYWORD(unwind, Unwind);
|
INSTKEYWORD(unwind, Unwind);
|
||||||
INSTKEYWORD(unreachable, Unreachable);
|
INSTKEYWORD(unreachable, Unreachable);
|
||||||
|
|
||||||
INSTKEYWORD(malloc, Malloc);
|
|
||||||
INSTKEYWORD(alloca, Alloca);
|
INSTKEYWORD(alloca, Alloca);
|
||||||
INSTKEYWORD(free, Free);
|
INSTKEYWORD(free, Free);
|
||||||
INSTKEYWORD(load, Load);
|
INSTKEYWORD(load, Load);
|
||||||
|
@ -69,6 +69,27 @@ bool LLParser::Run() {
|
|||||||
/// ValidateEndOfModule - Do final validity and sanity checks at the end of the
|
/// ValidateEndOfModule - Do final validity and sanity checks at the end of the
|
||||||
/// module.
|
/// module.
|
||||||
bool LLParser::ValidateEndOfModule() {
|
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())
|
if (!ForwardRefTypes.empty())
|
||||||
return Error(ForwardRefTypes.begin()->second.second,
|
return Error(ForwardRefTypes.begin()->second.second,
|
||||||
"use of undefined type named '" +
|
"use of undefined type named '" +
|
||||||
@ -2776,8 +2797,8 @@ bool LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
|
|||||||
case lltok::kw_call: return ParseCall(Inst, PFS, false);
|
case lltok::kw_call: return ParseCall(Inst, PFS, false);
|
||||||
case lltok::kw_tail: return ParseCall(Inst, PFS, true);
|
case lltok::kw_tail: return ParseCall(Inst, PFS, true);
|
||||||
// Memory.
|
// Memory.
|
||||||
case lltok::kw_alloca:
|
case lltok::kw_alloca: return ParseAlloc(Inst, PFS);
|
||||||
case lltok::kw_malloc: return ParseAlloc(Inst, PFS, KeywordVal);
|
case lltok::kw_malloc: return ParseAlloc(Inst, PFS, BB, false);
|
||||||
case lltok::kw_free: return ParseFree(Inst, PFS);
|
case lltok::kw_free: return ParseFree(Inst, PFS);
|
||||||
case lltok::kw_load: return ParseLoad(Inst, PFS, false);
|
case lltok::kw_load: return ParseLoad(Inst, PFS, false);
|
||||||
case lltok::kw_store: return ParseStore(Inst, PFS, false);
|
case lltok::kw_store: return ParseStore(Inst, PFS, false);
|
||||||
@ -3286,7 +3307,7 @@ bool LLParser::ParseShuffleVector(Instruction *&Inst, PerFunctionState &PFS) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// ParsePHI
|
/// ParsePHI
|
||||||
/// ::= 'phi' Type '[' Value ',' Value ']' (',' '[' Value ',' Valueß ']')*
|
/// ::= 'phi' Type '[' Value ',' Value ']' (',' '[' Value ',' Valueß ']')*
|
||||||
bool LLParser::ParsePHI(Instruction *&Inst, PerFunctionState &PFS) {
|
bool LLParser::ParsePHI(Instruction *&Inst, PerFunctionState &PFS) {
|
||||||
PATypeHolder Ty(Type::getVoidTy(Context));
|
PATypeHolder Ty(Type::getVoidTy(Context));
|
||||||
Value *Op0, *Op1;
|
Value *Op0, *Op1;
|
||||||
@ -3431,7 +3452,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
|
|||||||
/// ::= 'malloc' Type (',' TypeAndValue)? (',' OptionalInfo)?
|
/// ::= 'malloc' Type (',' TypeAndValue)? (',' OptionalInfo)?
|
||||||
/// ::= 'alloca' Type (',' TypeAndValue)? (',' OptionalInfo)?
|
/// ::= 'alloca' Type (',' TypeAndValue)? (',' OptionalInfo)?
|
||||||
bool LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS,
|
bool LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS,
|
||||||
unsigned Opc) {
|
BasicBlock* BB, bool isAlloca) {
|
||||||
PATypeHolder Ty(Type::getVoidTy(Context));
|
PATypeHolder Ty(Type::getVoidTy(Context));
|
||||||
Value *Size = 0;
|
Value *Size = 0;
|
||||||
LocTy SizeLoc;
|
LocTy SizeLoc;
|
||||||
@ -3451,10 +3472,21 @@ bool LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS,
|
|||||||
if (Size && Size->getType() != Type::getInt32Ty(Context))
|
if (Size && Size->getType() != Type::getInt32Ty(Context))
|
||||||
return Error(SizeLoc, "element count must be i32");
|
return Error(SizeLoc, "element count must be i32");
|
||||||
|
|
||||||
if (Opc == Instruction::Malloc)
|
if (isAlloca)
|
||||||
Inst = new MallocInst(Ty, Size, Alignment);
|
|
||||||
else
|
|
||||||
Inst = new AllocaInst(Ty, Size, Alignment);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,9 +75,11 @@ namespace llvm {
|
|||||||
std::map<std::string, std::pair<GlobalValue*, LocTy> > ForwardRefVals;
|
std::map<std::string, std::pair<GlobalValue*, LocTy> > ForwardRefVals;
|
||||||
std::map<unsigned, std::pair<GlobalValue*, LocTy> > ForwardRefValIDs;
|
std::map<unsigned, std::pair<GlobalValue*, LocTy> > ForwardRefValIDs;
|
||||||
std::vector<GlobalValue*> NumberedVals;
|
std::vector<GlobalValue*> NumberedVals;
|
||||||
|
Function* MallocF;
|
||||||
public:
|
public:
|
||||||
LLParser(MemoryBuffer *F, SourceMgr &SM, SMDiagnostic &Err, Module *m) :
|
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();
|
bool Run();
|
||||||
|
|
||||||
LLVMContext& getContext() { return Context; }
|
LLVMContext& getContext() { return Context; }
|
||||||
@ -276,7 +278,8 @@ namespace llvm {
|
|||||||
bool ParseShuffleVector(Instruction *&I, PerFunctionState &PFS);
|
bool ParseShuffleVector(Instruction *&I, PerFunctionState &PFS);
|
||||||
bool ParsePHI(Instruction *&I, PerFunctionState &PFS);
|
bool ParsePHI(Instruction *&I, PerFunctionState &PFS);
|
||||||
bool ParseCall(Instruction *&I, PerFunctionState &PFS, bool isTail);
|
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 ParseFree(Instruction *&I, PerFunctionState &PFS);
|
||||||
bool ParseLoad(Instruction *&I, PerFunctionState &PFS, bool isVolatile);
|
bool ParseLoad(Instruction *&I, PerFunctionState &PFS, bool isVolatile);
|
||||||
bool ParseStore(Instruction *&I, PerFunctionState &PFS, bool isVolatile);
|
bool ParseStore(Instruction *&I, PerFunctionState &PFS, bool isVolatile);
|
||||||
|
@ -2046,14 +2046,21 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case bitc::FUNC_CODE_INST_MALLOC: { // MALLOC: [instty, op, align]
|
case bitc::FUNC_CODE_INST_MALLOC: { // MALLOC: [instty, op, align]
|
||||||
|
// Autoupgrade malloc instruction to malloc call.
|
||||||
if (Record.size() < 3)
|
if (Record.size() < 3)
|
||||||
return Error("Invalid MALLOC record");
|
return Error("Invalid MALLOC record");
|
||||||
const PointerType *Ty =
|
const PointerType *Ty =
|
||||||
dyn_cast_or_null<PointerType>(getTypeByID(Record[0]));
|
dyn_cast_or_null<PointerType>(getTypeByID(Record[0]));
|
||||||
Value *Size = getFnValueByID(Record[1], Type::getInt32Ty(Context));
|
Value *Size = getFnValueByID(Record[1], Type::getInt32Ty(Context));
|
||||||
unsigned Align = Record[2];
|
|
||||||
if (!Ty || !Size) return Error("Invalid MALLOC record");
|
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);
|
InstructionList.push_back(I);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1636,12 +1636,16 @@ LLVMValueRef LLVMBuildNot(LLVMBuilderRef B, LLVMValueRef V, const char *Name) {
|
|||||||
|
|
||||||
LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef B, LLVMTypeRef Ty,
|
LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef B, LLVMTypeRef Ty,
|
||||||
const char *Name) {
|
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 LLVMBuildArrayMalloc(LLVMBuilderRef B, LLVMTypeRef Ty,
|
||||||
LLVMValueRef Val, const char *Name) {
|
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,
|
LLVMValueRef LLVMBuildAlloca(LLVMBuilderRef B, LLVMTypeRef Ty,
|
||||||
|
@ -462,7 +462,8 @@ static Value *checkArraySize(Value *Amt, const Type *IntPtrTy) {
|
|||||||
|
|
||||||
static Value *createMalloc(Instruction *InsertBefore, BasicBlock *InsertAtEnd,
|
static Value *createMalloc(Instruction *InsertBefore, BasicBlock *InsertAtEnd,
|
||||||
const Type *IntPtrTy, const Type *AllocTy,
|
const Type *IntPtrTy, const Type *AllocTy,
|
||||||
Value *ArraySize, const Twine &NameStr) {
|
Value *ArraySize, Function* MallocF,
|
||||||
|
const Twine &NameStr) {
|
||||||
assert(((!InsertBefore && InsertAtEnd) || (InsertBefore && !InsertAtEnd)) &&
|
assert(((!InsertBefore && InsertAtEnd) || (InsertBefore && !InsertAtEnd)) &&
|
||||||
"createMalloc needs either InsertBefore or InsertAtEnd");
|
"createMalloc needs either InsertBefore or InsertAtEnd");
|
||||||
|
|
||||||
@ -499,10 +500,11 @@ static Value *createMalloc(Instruction *InsertBefore, BasicBlock *InsertAtEnd,
|
|||||||
BasicBlock* BB = InsertBefore ? InsertBefore->getParent() : InsertAtEnd;
|
BasicBlock* BB = InsertBefore ? InsertBefore->getParent() : InsertAtEnd;
|
||||||
Module* M = BB->getParent()->getParent();
|
Module* M = BB->getParent()->getParent();
|
||||||
const Type *BPTy = PointerType::getUnqual(Type::getInt8Ty(BB->getContext()));
|
const Type *BPTy = PointerType::getUnqual(Type::getInt8Ty(BB->getContext()));
|
||||||
|
if (!MallocF)
|
||||||
// prototype malloc as "void *malloc(size_t)"
|
// prototype malloc as "void *malloc(size_t)"
|
||||||
Constant *MallocF = M->getOrInsertFunction("malloc", BPTy, IntPtrTy, NULL);
|
MallocF = cast<Function>(M->getOrInsertFunction("malloc", BPTy,
|
||||||
if (!cast<Function>(MallocF)->doesNotAlias(0))
|
IntPtrTy, NULL));
|
||||||
cast<Function>(MallocF)->setDoesNotAlias(0);
|
if (!MallocF->doesNotAlias(0)) MallocF->setDoesNotAlias(0);
|
||||||
const PointerType *AllocPtrType = PointerType::getUnqual(AllocTy);
|
const PointerType *AllocPtrType = PointerType::getUnqual(AllocTy);
|
||||||
CallInst *MCall = NULL;
|
CallInst *MCall = NULL;
|
||||||
Value *MCast = NULL;
|
Value *MCast = NULL;
|
||||||
@ -531,7 +533,8 @@ static Value *createMalloc(Instruction *InsertBefore, BasicBlock *InsertAtEnd,
|
|||||||
Value *CallInst::CreateMalloc(Instruction *InsertBefore, const Type *IntPtrTy,
|
Value *CallInst::CreateMalloc(Instruction *InsertBefore, const Type *IntPtrTy,
|
||||||
const Type *AllocTy, Value *ArraySize,
|
const Type *AllocTy, Value *ArraySize,
|
||||||
const Twine &Name) {
|
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:
|
/// CreateMalloc - Generate the IR for a call to malloc:
|
||||||
@ -544,8 +547,9 @@ Value *CallInst::CreateMalloc(Instruction *InsertBefore, const Type *IntPtrTy,
|
|||||||
/// responsibility of the caller.
|
/// responsibility of the caller.
|
||||||
Value *CallInst::CreateMalloc(BasicBlock *InsertAtEnd, const Type *IntPtrTy,
|
Value *CallInst::CreateMalloc(BasicBlock *InsertAtEnd, const Type *IntPtrTy,
|
||||||
const Type *AllocTy, Value *ArraySize,
|
const Type *AllocTy, Value *ArraySize,
|
||||||
const Twine &Name) {
|
Function* MallocF, const Twine &Name) {
|
||||||
return createMalloc(NULL, InsertAtEnd, IntPtrTy, AllocTy, ArraySize, Name);
|
return createMalloc(NULL, InsertAtEnd, IntPtrTy, AllocTy,
|
||||||
|
ArraySize, MallocF, Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -63,7 +63,7 @@ entry:
|
|||||||
define i32 @foo2(i32 %n) nounwind {
|
define i32 @foo2(i32 %n) nounwind {
|
||||||
entry:
|
entry:
|
||||||
%call = malloc i8, i32 %n ; <i8*> [#uses=1]
|
%call = malloc i8, i32 %n ; <i8*> [#uses=1]
|
||||||
; CHECK: %call =
|
; CHECK: %malloccall =
|
||||||
; CHECK: ==> %n elements, %n bytes allocated
|
; CHECK: ==> %n elements, %n bytes allocated
|
||||||
%call2 = tail call i8* @calloc(i64 2, i64 4) nounwind ; <i8*> [#uses=1]
|
%call2 = tail call i8* @calloc(i64 2, i64 4) nounwind ; <i8*> [#uses=1]
|
||||||
; CHECK: %call2 =
|
; CHECK: %call2 =
|
||||||
|
@ -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]
|
@G = internal global i32* null ; <i32**> [#uses=3]
|
||||||
|
|
||||||
|
@ -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]
|
@G = internal global i32* null ; <i32**> [#uses=4]
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
; test that casted mallocs get converted to malloc of the right type
|
; test that casted mallocs get converted to malloc of the right type
|
||||||
; RUN: opt < %s -instcombine -S | \
|
; 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
|
; 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
|
; instcombine that the ABI alignment for a long is 4-bytes, not 8, otherwise
|
||||||
|
@ -79,9 +79,9 @@ define void @test11(i32* %P) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
define i32* @test12() {
|
define i32* @test12() {
|
||||||
%p = malloc [4 x i8] ; <[4 x i8]*> [#uses=1]
|
%c = malloc [4 x i8] ; <[4 x i8]*> [#uses=1]
|
||||||
%c = bitcast [4 x i8]* %p to i32* ; <i32*> [#uses=1]
|
%p = bitcast [4 x i8]* %c to i32* ; <i32*> [#uses=1]
|
||||||
ret i32* %c
|
ret i32* %p
|
||||||
}
|
}
|
||||||
define i8* @test13(i64 %A) {
|
define i8* @test13(i64 %A) {
|
||||||
%c = getelementptr [0 x i8]* bitcast ([32832 x i8]* @inbuf to [0 x i8]*), i64 0, i64 %A ; <i8*> [#uses=1]
|
%c = getelementptr [0 x i8]* bitcast ([32832 x i8]* @inbuf to [0 x i8]*), i64 0, i64 %A ; <i8*> [#uses=1]
|
||||||
|
@ -58,7 +58,7 @@ define i32* @test6() {
|
|||||||
%B = getelementptr i32* %A, i64 2
|
%B = getelementptr i32* %A, i64 2
|
||||||
ret i32* %B
|
ret i32* %B
|
||||||
; CHECK: @test6
|
; 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) {
|
define i32* @test7(i32* %I, i64 %C, i64 %D) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: opt < %s -instcombine -S | grep {ret i32 0}
|
; 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
|
; PR1201
|
||||||
define i32 @main(i32 %argc, i8** %argv) {
|
define i32 @main(i32 %argc, i8** %argv) {
|
||||||
%c_19 = alloca i8* ; <i8**> [#uses=2]
|
%c_19 = alloca i8* ; <i8**> [#uses=2]
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
; RUN: opt < %s -instcombine -S | grep {ret i32 0}
|
; RUN: opt < %s -instcombine -S | grep {ret i32 0}
|
||||||
; RUN: opt < %s -instcombine -S | not grep malloc
|
|
||||||
; PR1313
|
; PR1313
|
||||||
|
|
||||||
define i32 @test1(i32 %argc, i8* %argv, i8* %envp) {
|
define i32 @test1(i32 %argc, i8* %argv, i8* %envp) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user