Dingbao Xie
2015-Jan-27 01:50 UTC
[LLVMdev] 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. -- Dingbao Xie -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150126/5655da53/attachment.html>
Tim Northover
2015-Jan-27 04:13 UTC
[LLVMdev] Create a call to function malloc using LLVM API
Hi, On 26 January 2015 at 17:50, Dingbao Xie <xiedingbao at gmail.com> wrote:> 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.
Dingbao Xie
2015-Jan-27 06:19 UTC
[LLVMdev] Create a call to function malloc using LLVM API
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. On Mon, Jan 26, 2015 at 8:13 PM, Tim Northover <t.p.northover at gmail.com> wrote:> Hi, > > On 26 January 2015 at 17:50, Dingbao Xie <xiedingbao at gmail.com> wrote: > > 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. >-- Dingbao Xie -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150126/b7276bed/attachment.html>