Create a call to function malloc using LLVM API

Hi, I encountered an issue when attempting to create a call to function malloc.
I just want to do a simple thing, suppose there is a variable p, if p is a pointer
then allocate memory to p.
Source code:
int *p;
p = (int *) malloc(sizeof(*p));

Try to generate LLVM IR for it:
Type tp = p->getType();
AllocaInst
arg_alloc = builder.CreateAlloca(tp);//builder is IRBuilder

if(tp->isPointerTy()){
Type* tpp = tp->getPointerElementType();

Type* ITy = Type::getInt32Ty(getGlobalContext());

Constant* AllocSize = ConstantExpr::getSizeOf(tpp)
AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, ITy);

CallInst::CreateMalloc(arg_alloc, ITy, tpp, AllocSize);

}
But the generated LLVM IR seems incorrect:
%malloccall = tail call i8* bitcast (i8* (i64)* @malloc to i8* (i32))(i32 ptrtoint (i32 getelementptr (i32* null, i32 1) to i32))

I don’t quite understand the arguments of the function CallInst::CreateMalloc.
Is the second argument type of p and the third one type of the element
that p points to?
The size of an integer variable is 4, but if I pass 4 as the last argument to CallInst::CreateMalloc, then an assertion failure will occur.

Hi,

Is the second argument type of p and the third one type of the element
that p points to?

Looking at http://llvm.org/docs/doxygen/html/classllvm_1_1CallInst.html:

The second argument is an integer on your machine that can hold a
pointer. Most likely i64 on a 64-bit CPU and i32 on a 32-bit CPU. It
corresponds to the type of argument malloc expects for its size.
You've passed i32 here, but it looks like your malloc has been
previously declared to take an i64 so there's a good chance that's
wrong.

The third argument is the type being allocated. It's not used for size
calculations (oddly, in my view), but just to cast the Malloc result
back to something your program is expecting. So in C terms, if you
were allocating space for "struct Foo", that's what you'd pass here.

The size of an integer variable is 4, but if I pass 4 as the last argument
to CallInst::CreateMalloc, then an assertion failure will occur.

I'm not *quite* sure what you're doing here, but it sounds like you
may have passed an integer constant 4 to a function expecting a
pointer to a Value. That's going to interpret "4" as a pointer, which
is almost guaranteed to go very badly indeed. What you might be able
to do is pass "ConstantInt::get(ITy, 4)" (though your getSizeOf looks
like a better idea all round).

Putting it all together, I'd expect the output (assuming tpp == i32,
as seems to be the case here) to be:

    %malloccall = call i8* @malloc(i64 ptrtoint(i32*
getelementptr(i32* null, i32 1) to i64)
    %res = bitcast i8* %malloccall to i32*

(If you don't actually use the result, later optimisations may remove
that final bitcast and even convert the malloc to a "tail call").

Cheers.

Tim.

Thanks for your reply.
I’m running the program in a 64 bit machine.
I think I get the correct result:

%malloccall = tail call i8* @malloc(i64 ptrtoint (i32* getelementptr (i32* null, i32 1) to i64))
%0 = bitcast i8* %malloccall to i32*

Another problem is that I like using IRbuilder to insert instructions, but IRbuilder has no method to create a call malloc .
AllocaInst* arg_alloc = builder.CreateAlloca(tp); //allocate memory to the pointer

Is there any way to insert the malloc instruction after the arg_alloc instruction?
The only way that I can think of is not using IRbuilder.

You can use IRBuilder to create calls to any functions. You just need a reference to the Function*.

builder.CreateCall(module->getFunction(“malloc”), AllocSize);

or

builder.CreateCall(module->getOrInsertFunction(“malloc”, [todo], …), AllocSize);